Repository: sxs-collaboration/spectre Branch: develop Commit: 2a5c5b65198a Files: 7092 Total size: 43.4 MB Directory structure: gitextract_tzqpsthm/ ├── .clang-format ├── .clang-tidy ├── .claude/ │ ├── hooks/ │ │ └── PostFormat.sh │ ├── rules/ │ │ ├── CMake.md │ │ └── Cxx.md │ ├── settings.json │ └── skills/ │ ├── spectre-fix-ci/ │ │ └── SKILL.md │ ├── spectre-fix-issue/ │ │ └── SKILL.md │ ├── spectre-fix-pr/ │ │ └── SKILL.md │ └── spectre-review/ │ └── SKILL.md ├── .codecov.yaml ├── .devcontainer/ │ ├── cmake-kits.json │ └── devcontainer.json ├── .dockerignore ├── .github/ │ ├── ISSUE_TEMPLATE.md │ ├── PULL_REQUEST_TEMPLATE.md │ ├── actions/ │ │ └── parse-compiler/ │ │ └── action.yaml │ ├── problem_matchers/ │ │ └── ClangTidy.json │ ├── scripts/ │ │ ├── Release.py │ │ └── requirements-release.txt │ └── workflows/ │ ├── BuildDockerContainer.yaml │ ├── ClobberCache.yaml │ ├── DemoContainer.yaml │ ├── DeployStaticExecutables.yaml │ ├── NewContributors.yaml │ ├── PostRelease.yaml │ ├── Spack.yaml │ └── Tests.yaml ├── .gitignore ├── .skills/ │ ├── scripts/ │ │ ├── FetchCiLog.py │ │ ├── FetchIssue.py │ │ └── FetchPrComments.py │ ├── spectre-fix-ci/ │ │ └── SKILL.md │ ├── spectre-fix-issue/ │ │ ├── RANDOM_FAILURE.md │ │ └── SKILL.md │ ├── spectre-fix-pr/ │ │ └── SKILL.md │ └── spectre-review/ │ ├── SKILL.md │ └── references/ │ ├── coverage-steps.md │ └── report-template.md ├── CITATION.cff ├── CMakeLists.txt ├── LICENSE.txt ├── Metadata.yaml ├── README.md ├── citation.bib ├── cmake/ │ ├── AddCxxFlag.cmake │ ├── AddInputFileTests.cmake │ ├── AddSpectreExecutable.cmake │ ├── AddStandaloneTests.cmake │ ├── BootstrapPyDeps.cmake │ ├── CheckBrokenArray0.cmake │ ├── CheckBrokenArray0.cpp │ ├── CheckCompilerVersion.cmake │ ├── CodeCoverage.cmake │ ├── CodeCoverageDetection.cmake │ ├── EnableWarnings.cmake │ ├── FindBlaze.cmake │ ├── FindBreathe.cmake │ ├── FindCharm.cmake │ ├── FindClangFormat.cmake │ ├── FindFFTW.cmake │ ├── FindFUKA.cmake │ ├── FindGoogleBenchmark.cmake │ ├── FindJEMALLOC.cmake │ ├── FindLIBCXX.cmake │ ├── FindLIBXSMM.cmake │ ├── FindNumPy.cmake │ ├── FindPAPI.cmake │ ├── FindParaView.cmake │ ├── FindPythonModule.cmake │ ├── FindScotch.cmake │ ├── FindSleef.cmake │ ├── FindSpEC.cmake │ ├── FindTCMALLOC.cmake │ ├── Findccache.cmake │ ├── PrintUsefulCMakeInfo.cmake │ ├── ProhibitInSourceBuild.cmake │ ├── RunInputFileTest.sh │ ├── SetBuildType.cmake │ ├── SetCxxStandard.cmake │ ├── SetOutputDirectory.cmake │ ├── SetupAllocator.cmake │ ├── SetupAutodiff.cmake │ ├── SetupBlas.cmake │ ├── SetupBlaze.cmake │ ├── SetupBoost.cmake │ ├── SetupCCache.cmake │ ├── SetupCatch.cmake │ ├── SetupCharm.cmake │ ├── SetupCharmModuleFunctions.cmake │ ├── SetupClangFormat.cmake │ ├── SetupClangTidy.cmake │ ├── SetupCxxFlags.cmake │ ├── SetupDoxygen.cmake │ ├── SetupFormaline.cmake │ ├── SetupFortran.cmake │ ├── SetupFuka.cmake │ ├── SetupGitHooks.cmake │ ├── SetupGoldOrLldLinker.cmake │ ├── SetupGoogleBenchmark.cmake │ ├── SetupGsl.cmake │ ├── SetupHdf5.cmake │ ├── SetupInformer.cmake │ ├── SetupJemalloc.cmake │ ├── SetupKokkos.cmake │ ├── SetupLIBCXX.cmake │ ├── SetupLIBCXXCharm.cmake │ ├── SetupLIBXSMM.cmake │ ├── SetupLapack.cmake │ ├── SetupLicenseInfo.cmake │ ├── SetupLinkTimeOptimization.cmake │ ├── SetupListTargets.cmake │ ├── SetupNinjaColors.cmake │ ├── SetupOpenMP.cmake │ ├── SetupPapi.cmake │ ├── SetupParaView.cmake │ ├── SetupPch.cmake │ ├── SetupPic.cmake │ ├── SetupProfiling.cmake │ ├── SetupPybind11.cmake │ ├── SetupPypp.cmake │ ├── SetupSanitizers.cmake │ ├── SetupSpec.cmake │ ├── SetupSpectreInlining.cmake │ ├── SetupSphinx.cmake │ ├── SetupStl.cmake │ ├── SetupTcmalloc.cmake │ ├── SetupXsimd.cmake │ ├── SetupYamlCpp.cmake │ ├── SpectreAddCatchTests.cmake │ ├── SpectreAddInterfaceLibraryHeaders.cmake │ ├── SpectreAddLibraries.cmake │ ├── SpectreAddTestLibs.cmake │ ├── SpectreCheckDependencies.cmake │ ├── SpectreCheckTargetDependencies.cmake │ ├── SpectreGetGitHash.cmake │ ├── SpectreInitializeVariables.cmake │ ├── SpectreLoadMetadata.cmake │ ├── SpectreParseTests.py │ ├── SpectrePythonExecutable.sh │ ├── SpectreSetSiteName.cmake │ ├── SpectreSetupFlagsTarget.cmake │ ├── SpectreSetupPythonPackage.cmake │ ├── SpectreSetupTesting.cmake │ ├── SpectreTargetHeaders.cmake │ ├── SpectreTargetSources.cmake │ ├── StripSymbols.cmake │ └── UpdateAddExecutables.cmake ├── containers/ │ └── Dockerfile.buildenv ├── docs/ │ ├── .nojekyll │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── Changelog.md │ ├── Contributing/ │ │ ├── Contributing.md │ │ └── ReportingGuide.md │ ├── Dependencies.bib │ ├── DevGuide/ │ │ ├── Amr.md │ │ ├── AutomaticVersioning.md │ │ ├── Brigand.md │ │ ├── BuildOptimization.md │ │ ├── CodeReviewGuide.md │ │ ├── CompilerLinkerErrors.md │ │ ├── Connectivity.md │ │ ├── CreatingExecutables.md │ │ ├── Databox.md │ │ ├── DebuggingTips.md │ │ ├── DevGuide.md │ │ ├── DomainConcepts.md │ │ ├── GitHubActions.md │ │ ├── GpuSupport.md │ │ ├── ImplementingVectors.md │ │ ├── ImportingData.md │ │ ├── LoadBalancingNotes.md │ │ ├── Observers.md │ │ ├── OptionParsing.md │ │ ├── ParallelExecutable/ │ │ │ ├── Concepts.md │ │ │ └── MinimalExecutable.md │ │ ├── Parallelization.md │ │ ├── PerformanceGuidelines.md │ │ ├── Profiling.md │ │ ├── Protocols.md │ │ ├── PythonBindings.md │ │ ├── QuickStartDockerVSCode.md │ │ ├── RedistributingGridpoints.md │ │ ├── StaticAnalysis.md │ │ ├── TensorExpressions.md │ │ ├── Tmp.md │ │ ├── Variables.md │ │ ├── WritingDox.md │ │ └── WritingTests.md │ ├── Doxyfile.in │ ├── Examples/ │ │ ├── BbhInitialData/ │ │ │ ├── .gitignore │ │ │ └── BbhInitialData.ipynb │ │ ├── Examples.md │ │ └── plots.mplstyle │ ├── Gallery.md │ ├── GroupDefs.hpp │ ├── Images/ │ │ └── Tutorials/ │ │ └── make_multicube_figures.py │ ├── Installation/ │ │ ├── BuildSystem.md │ │ ├── Installation.md │ │ ├── InstallationOnAppleSilicon.md │ │ ├── InstallationOnClusters.md │ │ └── VersioningAndReleases.md │ ├── Main.md │ ├── PublicationPolicy.md │ ├── References.bib │ ├── Tutorials/ │ │ ├── BeginnersTutorial.md │ │ ├── CCE.md │ │ ├── CheckpointRestart.md │ │ ├── Cli.md │ │ ├── DomainCreation.md │ │ ├── EventsAndTriggers.md │ │ ├── Imex.md │ │ ├── Orientation.md │ │ ├── ParallelExecutable/ │ │ │ └── Tutorials.md │ │ ├── Python.md │ │ ├── Tutorials.md │ │ ├── Visualization.md │ │ └── VisualizationWithPython.ipynb │ ├── _templates/ │ │ └── autosummary/ │ │ └── module.rst │ ├── cli.rst │ ├── conf.py │ ├── config/ │ │ ├── DoxygenLayout_1_8_10.xml │ │ ├── DoxygenLayout_1_9_8.xml │ │ ├── MathJax.js │ │ ├── cppreference-doxygen-web.tag.xml │ │ ├── custom.css │ │ ├── doxygen-awesome-fragment-copy-button.js │ │ ├── doxygen-awesome-interactive-toc.js │ │ ├── doxygen-awesome-paragraph-link.js │ │ ├── doxygen-awesome-sidebar-only.css │ │ ├── doxygen-awesome.css │ │ ├── footer.html │ │ ├── header.html │ │ ├── icons/ │ │ │ └── octicons.css │ │ ├── js/ │ │ │ ├── doxygen-navtree-hacks.js │ │ │ └── spectre.js │ │ ├── markdown-math-filter.pl │ │ ├── octicons.css │ │ └── postprocess_docs.py │ └── index.rst ├── external/ │ ├── CMakeLists.txt │ ├── EffectiveSource/ │ │ ├── CMakeLists.txt │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── effsource.h │ │ ├── effsource.hpp │ │ └── kerr-circular.c │ ├── GravitationalEffectiveSource/ │ │ ├── CMakeLists.txt │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── effsource_gr.h │ │ ├── effsource_gr.hpp │ │ └── kerr-circular.c │ ├── Licenses/ │ │ ├── BlazeCopyright.txt │ │ ├── BlazeLicense.txt │ │ ├── BoostCopyright.txt │ │ ├── BoostLicense.txt │ │ ├── BrigandCopyright.txt │ │ ├── BrigandLicense.txt │ │ ├── Catch2Copyright.txt │ │ ├── Catch2License.txt │ │ ├── CharmCopyright.txt │ │ ├── CharmLicense.txt │ │ ├── GslCopyright.txt │ │ ├── GslLicense.txt │ │ ├── Hdf5Copyright.txt │ │ ├── Hdf5License.txt │ │ ├── JemallocCopyright.txt │ │ ├── JemallocLicense.txt │ │ ├── LibbacktraceCopyright.txt │ │ ├── LibbacktraceLicense.txt │ │ ├── LibsharpCopyright.txt │ │ ├── LibsharpLicense.txt │ │ ├── LibxsmmCopyright.txt │ │ ├── LibxsmmLicense.txt │ │ ├── OpenBlasCopyright.txt │ │ ├── OpenBlasLicense.txt │ │ ├── Pybind11Copyright.txt │ │ ├── Pybind11License.txt │ │ ├── SpectreGpl3License.txt │ │ ├── XsimdCopyright.txt │ │ ├── XsimdLicense.txt │ │ ├── YamlCppCopyright.txt │ │ └── YamlCppLicense.txt │ ├── SPHEREPACK/ │ │ ├── CMakeLists.txt │ │ ├── LICENSE.txt │ │ ├── README.txt │ │ ├── alf.f │ │ ├── divgs.f │ │ ├── gaqd.f │ │ ├── gradgs.f │ │ ├── hrfft.f │ │ ├── shags.f │ │ ├── shsgs.f │ │ ├── slapgs.f │ │ ├── sphcom.f │ │ ├── vhags.f │ │ ├── vhsgs.f │ │ ├── vrtgs.f │ │ └── vtsgs.f │ ├── brigand/ │ │ ├── CMakeLists.txt │ │ ├── LICENSE │ │ ├── README.md │ │ └── include/ │ │ └── brigand/ │ │ └── brigand.hpp │ ├── libsharp/ │ │ ├── .gitignore │ │ ├── COPYING │ │ ├── Makefile │ │ ├── README.md │ │ ├── c_utils/ │ │ │ ├── c_utils.c │ │ │ ├── c_utils.h │ │ │ ├── memusage.c │ │ │ ├── memusage.h │ │ │ ├── planck.make │ │ │ ├── walltime_c.c │ │ │ └── walltime_c.h │ │ ├── config/ │ │ │ ├── config.auto.in │ │ │ └── rules.common │ │ ├── configure.ac │ │ ├── docsrc/ │ │ │ ├── c_utils.dox │ │ │ ├── footer.html │ │ │ ├── index_code.html │ │ │ ├── libfftpack.dox │ │ │ ├── libsharp.dox │ │ │ └── planck.make │ │ ├── fortran/ │ │ │ ├── sharp.f90 │ │ │ └── test_sharp.f90 │ │ ├── libfftpack/ │ │ │ ├── README │ │ │ ├── bluestein.c │ │ │ ├── bluestein.h │ │ │ ├── fftpack.c │ │ │ ├── fftpack.h │ │ │ ├── fftpack_inc.c │ │ │ ├── libfftpack.dox │ │ │ ├── ls_fft.c │ │ │ ├── ls_fft.h │ │ │ └── planck.make │ │ ├── libsharp/ │ │ │ ├── libsharp.dox │ │ │ ├── planck.make │ │ │ ├── sharp.c │ │ │ ├── sharp.h │ │ │ ├── sharp_almhelpers.c │ │ │ ├── sharp_almhelpers.h │ │ │ ├── sharp_announce.c │ │ │ ├── sharp_announce.h │ │ │ ├── sharp_complex_hacks.h │ │ │ ├── sharp_core.c │ │ │ ├── sharp_core.h │ │ │ ├── sharp_core_inc.c │ │ │ ├── sharp_core_inc2.c │ │ │ ├── sharp_core_inchelper.c │ │ │ ├── sharp_cxx.h │ │ │ ├── sharp_geomhelpers.c │ │ │ ├── sharp_geomhelpers.h │ │ │ ├── sharp_internal.h │ │ │ ├── sharp_legendre.c │ │ │ ├── sharp_legendre.c.in │ │ │ ├── sharp_legendre.h │ │ │ ├── sharp_legendre_roots.c │ │ │ ├── sharp_legendre_roots.h │ │ │ ├── sharp_legendre_table.c │ │ │ ├── sharp_legendre_table.h │ │ │ ├── sharp_lowlevel.h │ │ │ ├── sharp_mpi.c │ │ │ ├── sharp_mpi.h │ │ │ ├── sharp_testsuite.c │ │ │ ├── sharp_vecsupport.h │ │ │ ├── sharp_vecutil.h │ │ │ ├── sharp_ylmgen_c.c │ │ │ └── sharp_ylmgen_c.h │ │ ├── python/ │ │ │ ├── fake_pyrex/ │ │ │ │ ├── Pyrex/ │ │ │ │ │ ├── Distutils/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ └── build_ext.py │ │ │ │ │ └── __init__.py │ │ │ │ └── README │ │ │ ├── libsharp/ │ │ │ │ ├── __init__.py │ │ │ │ ├── libsharp.pxd │ │ │ │ ├── libsharp.pyx │ │ │ │ ├── libsharp_mpi.pyx │ │ │ │ └── tests/ │ │ │ │ ├── __init__.py │ │ │ │ ├── test_legendre.py │ │ │ │ ├── test_legendre_table.py │ │ │ │ ├── test_sht.py │ │ │ │ └── test_smoothing_noise_pol_mpi.py │ │ │ └── setup.py │ │ └── runjinja.py │ └── slatec/ │ ├── CMakeLists.txt │ ├── LICENSE.txt │ ├── README.txt │ └── drc3jj.f ├── pyproject.toml ├── setup.cfg ├── src/ │ ├── CMakeLists.txt │ ├── ControlSystem/ │ │ ├── Actions/ │ │ │ ├── CMakeLists.txt │ │ │ ├── GridCenters.cpp │ │ │ ├── GridCenters.hpp │ │ │ ├── Initialization.hpp │ │ │ ├── InitializeMeasurements.hpp │ │ │ ├── LimitTimeStep.hpp │ │ │ └── PrintCurrentMeasurement.hpp │ │ ├── Averager.cpp │ │ ├── Averager.hpp │ │ ├── CMakeLists.txt │ │ ├── CalculateMeasurementTimescales.cpp │ │ ├── CalculateMeasurementTimescales.hpp │ │ ├── CleanFunctionsOfTime.cpp │ │ ├── CleanFunctionsOfTime.hpp │ │ ├── CombinedName.hpp │ │ ├── Component.hpp │ │ ├── ControlErrors/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Expansion.hpp │ │ │ ├── GridCenters.cpp │ │ │ ├── GridCenters.hpp │ │ │ ├── Rotation.hpp │ │ │ ├── Shape.hpp │ │ │ ├── Size/ │ │ │ │ ├── AhSpeed.cpp │ │ │ │ ├── AhSpeed.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ComovingCharSpeedDerivative.cpp │ │ │ │ ├── ComovingCharSpeedDerivative.hpp │ │ │ │ ├── DeltaR.cpp │ │ │ │ ├── DeltaR.hpp │ │ │ │ ├── DeltaRDriftInward.cpp │ │ │ │ ├── DeltaRDriftInward.hpp │ │ │ │ ├── DeltaRDriftOutward.cpp │ │ │ │ ├── DeltaRDriftOutward.hpp │ │ │ │ ├── DeltaRNoDrift.cpp │ │ │ │ ├── DeltaRNoDrift.hpp │ │ │ │ ├── Error.cpp │ │ │ │ ├── Error.hpp │ │ │ │ ├── Factory.hpp │ │ │ │ ├── Info.cpp │ │ │ │ ├── Info.hpp │ │ │ │ ├── Initial.cpp │ │ │ │ ├── Initial.hpp │ │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ │ ├── State.hpp │ │ │ │ ├── StateHistory.cpp │ │ │ │ ├── StateHistory.hpp │ │ │ │ └── Update.hpp │ │ │ ├── Size.cpp │ │ │ ├── Size.hpp │ │ │ ├── Skew.cpp │ │ │ ├── Skew.hpp │ │ │ └── Translation.hpp │ │ ├── Controller.cpp │ │ ├── Controller.hpp │ │ ├── ExpirationTimes.cpp │ │ ├── ExpirationTimes.hpp │ │ ├── FutureMeasurements.cpp │ │ ├── FutureMeasurements.hpp │ │ ├── IsSize.hpp │ │ ├── Measurements/ │ │ │ ├── BNSCenterOfMass.cpp │ │ │ ├── BNSCenterOfMass.hpp │ │ │ ├── BothHorizons.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CharSpeed.hpp │ │ │ ├── Measurements.hpp │ │ │ ├── NonFactoryCreatable.hpp │ │ │ └── SingleHorizon.hpp │ │ ├── Metafunctions.hpp │ │ ├── NamespaceDocs.hpp │ │ ├── Protocols/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ControlError.hpp │ │ │ ├── ControlSystem.hpp │ │ │ ├── Measurement.hpp │ │ │ ├── NamespaceDocs.hpp │ │ │ └── Submeasurement.hpp │ │ ├── RunCallbacks.hpp │ │ ├── Systems/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Expansion.hpp │ │ │ ├── GridCenters.hpp │ │ │ ├── Rotation.hpp │ │ │ ├── Shape.hpp │ │ │ ├── Size.hpp │ │ │ ├── Skew.hpp │ │ │ └── Translation.hpp │ │ ├── Tags/ │ │ │ ├── CMakeLists.txt │ │ │ ├── FunctionsOfTimeInitialize.cpp │ │ │ ├── FunctionsOfTimeInitialize.hpp │ │ │ ├── FutureMeasurements.hpp │ │ │ ├── IsActiveMap.hpp │ │ │ ├── MeasurementTimescales.hpp │ │ │ ├── OptionTags.hpp │ │ │ ├── QueueTags.hpp │ │ │ ├── SystemTags.cpp │ │ │ └── SystemTags.hpp │ │ ├── TimescaleTuner.cpp │ │ ├── TimescaleTuner.hpp │ │ ├── Trigger.hpp │ │ ├── UpdateControlSystem.hpp │ │ ├── UpdateFunctionOfTime.cpp │ │ ├── UpdateFunctionOfTime.hpp │ │ ├── UpdateTimescaleTuner.hpp │ │ └── WriteData.hpp │ ├── DataStructures/ │ │ ├── ApplyMatrices.cpp │ │ ├── ApplyMatrices.hpp │ │ ├── Blaze/ │ │ │ ├── Blaze.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── IntegerPow.hpp │ │ │ └── StepFunction.hpp │ │ ├── BoostMultiArray.hpp │ │ ├── CMakeLists.txt │ │ ├── CachedTempBuffer.hpp │ │ ├── CircularDeque.hpp │ │ ├── ComplexDataVector.hpp │ │ ├── ComplexDiagonalModalOperator.hpp │ │ ├── ComplexModalVector.hpp │ │ ├── CompressedMatrix.cpp │ │ ├── CompressedMatrix.hpp │ │ ├── CompressedVector.cpp │ │ ├── CompressedVector.hpp │ │ ├── DataBox/ │ │ │ ├── Access.hpp │ │ │ ├── AsAccess.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── DataBox.hpp │ │ │ ├── DataBoxTag.hpp │ │ │ ├── DataOnSlice.hpp │ │ │ ├── IsApplyCallable.hpp │ │ │ ├── Item.hpp │ │ │ ├── MetavariablesTag.hpp │ │ │ ├── ObservationBox.hpp │ │ │ ├── PrefixHelpers.hpp │ │ │ ├── Prefixes.hpp │ │ │ ├── Protocols/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Mutator.hpp │ │ │ ├── SubitemTag.hpp │ │ │ ├── Subitems.hpp │ │ │ ├── Tag.hpp │ │ │ ├── TagName.hpp │ │ │ ├── TagTraits.hpp │ │ │ └── ValidateSelection.hpp │ │ ├── DataVector.hpp │ │ ├── DiagonalModalOperator.hpp │ │ ├── DynamicBuffer.cpp │ │ ├── DynamicBuffer.hpp │ │ ├── DynamicMatrix.cpp │ │ ├── DynamicMatrix.hpp │ │ ├── DynamicVector.cpp │ │ ├── DynamicVector.hpp │ │ ├── ExtractPoint.hpp │ │ ├── FixedHashMap.hpp │ │ ├── FloatingPointType.cpp │ │ ├── FloatingPointType.hpp │ │ ├── IdPair.hpp │ │ ├── Index.cpp │ │ ├── Index.hpp │ │ ├── IndexIterator.cpp │ │ ├── IndexIterator.hpp │ │ ├── LeviCivitaIterator.cpp │ │ ├── LeviCivitaIterator.hpp │ │ ├── LinkedMessageId.hpp │ │ ├── LinkedMessageQueue.hpp │ │ ├── MathWrapper.hpp │ │ ├── Matrix.hpp │ │ ├── ModalVector.hpp │ │ ├── Python/ │ │ │ ├── Bindings.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── DataVector.cpp │ │ │ ├── DataVector.hpp │ │ │ ├── Matrix.cpp │ │ │ ├── Matrix.hpp │ │ │ ├── ModalVector.cpp │ │ │ ├── ModalVector.hpp │ │ │ └── __init__.py │ │ ├── SimpleSparseMatrix.cpp │ │ ├── SimpleSparseMatrix.hpp │ │ ├── SliceIterator.cpp │ │ ├── SliceIterator.hpp │ │ ├── SliceTensorToVariables.hpp │ │ ├── SliceVariables.hpp │ │ ├── SparseMatrixFiller.cpp │ │ ├── SparseMatrixFiller.hpp │ │ ├── SpinWeighted.hpp │ │ ├── StaticDeque.hpp │ │ ├── StaticMatrix.hpp │ │ ├── StaticVector.hpp │ │ ├── StripeIterator.cpp │ │ ├── StripeIterator.hpp │ │ ├── TaggedContainers.hpp │ │ ├── TaggedTuple.hpp │ │ ├── TaggedVariant.hpp │ │ ├── Tags/ │ │ │ ├── CMakeLists.txt │ │ │ └── TempTensor.hpp │ │ ├── Tags.hpp │ │ ├── TempBuffer.hpp │ │ ├── Tensor/ │ │ │ ├── AtIndex.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CombineSpacetimeView.hpp │ │ │ ├── ContractFirstNIndices.hpp │ │ │ ├── EagerMath/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CartesianToSpherical.cpp │ │ │ │ ├── CartesianToSpherical.hpp │ │ │ │ ├── CrossProduct.hpp │ │ │ │ ├── Determinant.hpp │ │ │ │ ├── DeterminantAndInverse.hpp │ │ │ │ ├── DotProduct.hpp │ │ │ │ ├── FrameTransform.cpp │ │ │ │ ├── FrameTransform.hpp │ │ │ │ ├── GramSchmidtOrthonormalize.cpp │ │ │ │ ├── GramSchmidtOrthonormalize.hpp │ │ │ │ ├── Magnitude.hpp │ │ │ │ ├── Norms.hpp │ │ │ │ ├── OrthonormalOneform.cpp │ │ │ │ ├── OrthonormalOneform.hpp │ │ │ │ ├── OuterProduct.hpp │ │ │ │ ├── Python/ │ │ │ │ │ ├── Bindings.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Determinant.cpp │ │ │ │ │ ├── Determinant.hpp │ │ │ │ │ ├── Magnitude.cpp │ │ │ │ │ ├── Magnitude.hpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── RaiseOrLowerIndex.cpp │ │ │ │ ├── RaiseOrLowerIndex.hpp │ │ │ │ ├── Trace.cpp │ │ │ │ └── Trace.hpp │ │ │ ├── Expressions/ │ │ │ │ ├── AddSubtract.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Contract.hpp │ │ │ │ ├── DataTypeSupport.hpp │ │ │ │ ├── Divide.hpp │ │ │ │ ├── Evaluate.hpp │ │ │ │ ├── IndexPropertyCheck.hpp │ │ │ │ ├── LhsTensorSymmAndIndices.hpp │ │ │ │ ├── Negate.hpp │ │ │ │ ├── NumberAsExpression.hpp │ │ │ │ ├── Product.hpp │ │ │ │ ├── SpatialSpacetimeIndex.hpp │ │ │ │ ├── SquareRoot.hpp │ │ │ │ ├── TensorAsExpression.hpp │ │ │ │ ├── TensorExpression.hpp │ │ │ │ ├── TensorIndex.hpp │ │ │ │ ├── TensorIndexTransformation.hpp │ │ │ │ └── TimeIndex.hpp │ │ │ ├── Identity.hpp │ │ │ ├── IndexType.hpp │ │ │ ├── Metafunctions.hpp │ │ │ ├── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Frame.py │ │ │ │ ├── InstantiateScalar.cpp │ │ │ │ ├── InstantiateTensor1d.cpp │ │ │ │ ├── InstantiateTensor2d.cpp │ │ │ │ ├── InstantiateTensor3d.cpp │ │ │ │ ├── Tensor.hpp │ │ │ │ ├── Tensor.tpp │ │ │ │ ├── __init__.py │ │ │ │ └── tnsr.py │ │ │ ├── Slice.hpp │ │ │ ├── Structure.hpp │ │ │ ├── Symmetry.hpp │ │ │ ├── Tensor.hpp │ │ │ └── TypeAliases.hpp │ │ ├── Transpose.cpp │ │ ├── Transpose.hpp │ │ ├── Variables/ │ │ │ └── FrameTransform.hpp │ │ ├── Variables.hpp │ │ ├── VariablesTag.hpp │ │ └── VectorImpl.hpp │ ├── Domain/ │ │ ├── Amr/ │ │ │ ├── Amr.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Flag.cpp │ │ │ ├── Flag.hpp │ │ │ ├── Helpers.cpp │ │ │ ├── Helpers.hpp │ │ │ ├── Info.cpp │ │ │ ├── Info.hpp │ │ │ ├── NeighborsOfChild.cpp │ │ │ ├── NeighborsOfChild.hpp │ │ │ ├── NeighborsOfParent.cpp │ │ │ ├── NeighborsOfParent.hpp │ │ │ ├── NewNeighborIds.cpp │ │ │ ├── NewNeighborIds.hpp │ │ │ ├── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Flags.hpp │ │ │ │ ├── NeighborFlags.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── UpdateAmrDecision.cpp │ │ │ └── UpdateAmrDecision.hpp │ │ ├── AreaElement.cpp │ │ ├── AreaElement.hpp │ │ ├── Block.cpp │ │ ├── Block.hpp │ │ ├── BlockLogicalCoordinates.cpp │ │ ├── BlockLogicalCoordinates.hpp │ │ ├── BoundaryConditions/ │ │ │ ├── BoundaryCondition.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── GetBoundaryConditionsBase.hpp │ │ │ ├── None.cpp │ │ │ ├── None.hpp │ │ │ ├── Periodic.cpp │ │ │ └── Periodic.hpp │ │ ├── CMakeLists.txt │ │ ├── CoordinateMaps/ │ │ │ ├── Affine.cpp │ │ │ ├── Affine.hpp │ │ │ ├── AutodiffInstantiationTypes.hpp │ │ │ ├── BulgedCube.cpp │ │ │ ├── BulgedCube.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Composition.cpp │ │ │ ├── Composition.hpp │ │ │ ├── CoordinateMap.hpp │ │ │ ├── CoordinateMap.tpp │ │ │ ├── CoordinateMapHelpers.hpp │ │ │ ├── CylindricalEndcap.cpp │ │ │ ├── CylindricalEndcap.hpp │ │ │ ├── CylindricalEndcapHelpers.cpp │ │ │ ├── CylindricalEndcapHelpers.hpp │ │ │ ├── CylindricalFlatEndcap.cpp │ │ │ ├── CylindricalFlatEndcap.hpp │ │ │ ├── CylindricalFlatSide.cpp │ │ │ ├── CylindricalFlatSide.hpp │ │ │ ├── CylindricalSide.cpp │ │ │ ├── CylindricalSide.hpp │ │ │ ├── DiscreteRotation.cpp │ │ │ ├── DiscreteRotation.hpp │ │ │ ├── Distribution.cpp │ │ │ ├── Distribution.hpp │ │ │ ├── EquatorialCompression.cpp │ │ │ ├── EquatorialCompression.hpp │ │ │ ├── Equiangular.cpp │ │ │ ├── Equiangular.hpp │ │ │ ├── FlatOffsetSphericalWedge.cpp │ │ │ ├── FlatOffsetSphericalWedge.hpp │ │ │ ├── FlatOffsetWedge.cpp │ │ │ ├── FlatOffsetWedge.hpp │ │ │ ├── FocallyLiftedEndcap.cpp │ │ │ ├── FocallyLiftedEndcap.hpp │ │ │ ├── FocallyLiftedFlatEndcap.cpp │ │ │ ├── FocallyLiftedFlatEndcap.hpp │ │ │ ├── FocallyLiftedFlatSide.cpp │ │ │ ├── FocallyLiftedFlatSide.hpp │ │ │ ├── FocallyLiftedMap.cpp │ │ │ ├── FocallyLiftedMap.hpp │ │ │ ├── FocallyLiftedMapHelpers.cpp │ │ │ ├── FocallyLiftedMapHelpers.hpp │ │ │ ├── FocallyLiftedSide.cpp │ │ │ ├── FocallyLiftedSide.hpp │ │ │ ├── Frustum.cpp │ │ │ ├── Frustum.hpp │ │ │ ├── Identity.cpp │ │ │ ├── Identity.hpp │ │ │ ├── Interval.cpp │ │ │ ├── Interval.hpp │ │ │ ├── KerrHorizonConforming.cpp │ │ │ ├── KerrHorizonConforming.hpp │ │ │ ├── MapInstantiationMacros.hpp │ │ │ ├── PolarToCartesian.cpp │ │ │ ├── PolarToCartesian.hpp │ │ │ ├── ProductMaps.hpp │ │ │ ├── ProductMaps.tpp │ │ │ ├── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Composition.cpp │ │ │ │ ├── Composition.hpp │ │ │ │ ├── CoordinateMap.cpp │ │ │ │ ├── CoordinateMap.hpp │ │ │ │ └── __init__.py │ │ │ ├── Rotation.cpp │ │ │ ├── Rotation.hpp │ │ │ ├── SpecialMobius.cpp │ │ │ ├── SpecialMobius.hpp │ │ │ ├── SphericalToCartesianPfaffian.cpp │ │ │ ├── SphericalToCartesianPfaffian.hpp │ │ │ ├── Tags.hpp │ │ │ ├── TimeDependent/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CubicScale.cpp │ │ │ │ ├── CubicScale.hpp │ │ │ │ ├── ProductMaps.hpp │ │ │ │ ├── ProductMaps.tpp │ │ │ │ ├── RotScaleTrans.cpp │ │ │ │ ├── RotScaleTrans.hpp │ │ │ │ ├── Rotation.cpp │ │ │ │ ├── Rotation.hpp │ │ │ │ ├── RotationMatrixHelpers.cpp │ │ │ │ ├── RotationMatrixHelpers.hpp │ │ │ │ ├── Shape.cpp │ │ │ │ ├── Shape.hpp │ │ │ │ ├── ShapeMapTransitionFunctions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ │ │ ├── ShapeMapTransitionFunction.hpp │ │ │ │ │ ├── SphereTransition.cpp │ │ │ │ │ ├── SphereTransition.hpp │ │ │ │ │ ├── Wedge.cpp │ │ │ │ │ └── Wedge.hpp │ │ │ │ ├── Skew.cpp │ │ │ │ ├── Skew.hpp │ │ │ │ ├── SphericalCompression.cpp │ │ │ │ ├── SphericalCompression.hpp │ │ │ │ ├── Translation.cpp │ │ │ │ └── Translation.hpp │ │ │ ├── TimeDependentHelpers.hpp │ │ │ ├── UniformCylindricalEndcap.cpp │ │ │ ├── UniformCylindricalEndcap.hpp │ │ │ ├── UniformCylindricalFlatEndcap.cpp │ │ │ ├── UniformCylindricalFlatEndcap.hpp │ │ │ ├── UniformCylindricalSide.cpp │ │ │ ├── UniformCylindricalSide.hpp │ │ │ ├── Wedge.cpp │ │ │ └── Wedge.hpp │ │ ├── CoordsToDifferentFrame.cpp │ │ ├── CoordsToDifferentFrame.hpp │ │ ├── CreateInitialElement.cpp │ │ ├── CreateInitialElement.hpp │ │ ├── Creators/ │ │ │ ├── AlignedLattice.cpp │ │ │ ├── AlignedLattice.hpp │ │ │ ├── AngularCylinder.cpp │ │ │ ├── AngularCylinder.hpp │ │ │ ├── AngularDisk.cpp │ │ │ ├── AngularDisk.hpp │ │ │ ├── BinaryCompactObject.cpp │ │ │ ├── BinaryCompactObject.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CartoonCylinder.cpp │ │ │ ├── CartoonCylinder.hpp │ │ │ ├── CartoonSphere1D.cpp │ │ │ ├── CartoonSphere1D.hpp │ │ │ ├── CartoonSphere2D.cpp │ │ │ ├── CartoonSphere2D.hpp │ │ │ ├── Cylinder.cpp │ │ │ ├── Cylinder.hpp │ │ │ ├── CylindricalBinaryCompactObject.cpp │ │ │ ├── CylindricalBinaryCompactObject.hpp │ │ │ ├── Disk.cpp │ │ │ ├── Disk.hpp │ │ │ ├── DomainCreator.hpp │ │ │ ├── ExpandOverBlocks.cpp │ │ │ ├── ExpandOverBlocks.hpp │ │ │ ├── ExpandOverBlocks.tpp │ │ │ ├── Factory.hpp │ │ │ ├── Factory1D.hpp │ │ │ ├── Factory2D.hpp │ │ │ ├── Factory3D.hpp │ │ │ ├── FrustalCloak.cpp │ │ │ ├── FrustalCloak.hpp │ │ │ ├── NonconformingSphericalShells.cpp │ │ │ ├── NonconformingSphericalShells.hpp │ │ │ ├── OptionTags.hpp │ │ │ ├── Python/ │ │ │ │ ├── BinaryCompactObject.cpp │ │ │ │ ├── BinaryCompactObject.hpp │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Cylinder.cpp │ │ │ │ ├── Cylinder.hpp │ │ │ │ ├── DomainCreator.cpp │ │ │ │ ├── DomainCreator.hpp │ │ │ │ ├── Rectilinear.cpp │ │ │ │ ├── Rectilinear.hpp │ │ │ │ ├── Sphere.cpp │ │ │ │ ├── Sphere.hpp │ │ │ │ └── __init__.py │ │ │ ├── Rectilinear.cpp │ │ │ ├── Rectilinear.hpp │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ ├── RotatedBricks.cpp │ │ │ ├── RotatedBricks.hpp │ │ │ ├── RotatedIntervals.cpp │ │ │ ├── RotatedIntervals.hpp │ │ │ ├── RotatedRectangles.cpp │ │ │ ├── RotatedRectangles.hpp │ │ │ ├── ShellDistribution.cpp │ │ │ ├── ShellDistribution.hpp │ │ │ ├── Sphere.cpp │ │ │ ├── Sphere.hpp │ │ │ ├── SphericalShells.cpp │ │ │ ├── SphericalShells.hpp │ │ │ ├── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Domain.cpp │ │ │ │ ├── Domain.hpp │ │ │ │ ├── ExternalBoundaryConditions.hpp │ │ │ │ ├── FunctionsOfTime.hpp │ │ │ │ ├── InitialExtents.cpp │ │ │ │ ├── InitialExtents.hpp │ │ │ │ ├── InitialRefinementLevels.cpp │ │ │ │ ├── InitialRefinementLevels.hpp │ │ │ │ ├── ObjectCenter.cpp │ │ │ │ └── ObjectCenter.hpp │ │ │ ├── TimeDependence/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CubicScale.cpp │ │ │ │ ├── CubicScale.hpp │ │ │ │ ├── GenerateCoordinateMap.hpp │ │ │ │ ├── None.cpp │ │ │ │ ├── None.hpp │ │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ │ ├── RotationAboutZAxis.cpp │ │ │ │ ├── RotationAboutZAxis.hpp │ │ │ │ ├── ScalingAndZRotation.cpp │ │ │ │ ├── ScalingAndZRotation.hpp │ │ │ │ ├── Shape.cpp │ │ │ │ ├── Shape.hpp │ │ │ │ ├── SphericalCompression.cpp │ │ │ │ ├── SphericalCompression.hpp │ │ │ │ ├── TimeDependence.hpp │ │ │ │ ├── UniformTranslation.cpp │ │ │ │ └── UniformTranslation.hpp │ │ │ └── TimeDependentOptions/ │ │ │ ├── BinaryCompactObject.cpp │ │ │ ├── BinaryCompactObject.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── ExpansionMap.cpp │ │ │ ├── ExpansionMap.hpp │ │ │ ├── FromVolumeFile.cpp │ │ │ ├── FromVolumeFile.hpp │ │ │ ├── GridCenters.cpp │ │ │ ├── GridCenters.hpp │ │ │ ├── Python/ │ │ │ │ ├── BinaryCompactObject.cpp │ │ │ │ ├── BinaryCompactObject.hpp │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ExpansionMap.cpp │ │ │ │ ├── ExpansionMap.hpp │ │ │ │ ├── GridCenters.cpp │ │ │ │ ├── GridCenters.hpp │ │ │ │ ├── RotationMap.cpp │ │ │ │ ├── RotationMap.hpp │ │ │ │ ├── ShapeMap.cpp │ │ │ │ ├── ShapeMap.hpp │ │ │ │ ├── SkewMap.cpp │ │ │ │ ├── SkewMap.hpp │ │ │ │ ├── TranslationMap.cpp │ │ │ │ ├── TranslationMap.hpp │ │ │ │ └── __init__.py │ │ │ ├── RotationMap.cpp │ │ │ ├── RotationMap.hpp │ │ │ ├── ShapeMap.cpp │ │ │ ├── ShapeMap.hpp │ │ │ ├── SkewMap.cpp │ │ │ ├── SkewMap.hpp │ │ │ ├── Sphere.cpp │ │ │ ├── Sphere.hpp │ │ │ ├── TranslationMap.cpp │ │ │ └── TranslationMap.hpp │ │ ├── Domain.cpp │ │ ├── Domain.hpp │ │ ├── DomainHelpers.cpp │ │ ├── DomainHelpers.hpp │ │ ├── ElementDistribution.cpp │ │ ├── ElementDistribution.hpp │ │ ├── ElementLogicalCoordinates.cpp │ │ ├── ElementLogicalCoordinates.hpp │ │ ├── ElementMap.cpp │ │ ├── ElementMap.hpp │ │ ├── ElementToBlockLogicalMap.cpp │ │ ├── ElementToBlockLogicalMap.hpp │ │ ├── ExcisionSphere.cpp │ │ ├── ExcisionSphere.hpp │ │ ├── FaceNormal.cpp │ │ ├── FaceNormal.hpp │ │ ├── FlatLogicalMetric.cpp │ │ ├── FlatLogicalMetric.hpp │ │ ├── FunctionsOfTime/ │ │ │ ├── CMakeLists.txt │ │ │ ├── FixedSpeedCubic.cpp │ │ │ ├── FixedSpeedCubic.hpp │ │ │ ├── FunctionOfTime.hpp │ │ │ ├── IntegratedFunctionOfTime.cpp │ │ │ ├── IntegratedFunctionOfTime.hpp │ │ │ ├── OptionTags.hpp │ │ │ ├── OutputTimeBounds.cpp │ │ │ ├── OutputTimeBounds.hpp │ │ │ ├── PiecewisePolynomial.cpp │ │ │ ├── PiecewisePolynomial.hpp │ │ │ ├── QuaternionFunctionOfTime.cpp │ │ │ ├── QuaternionFunctionOfTime.hpp │ │ │ ├── QuaternionHelpers.cpp │ │ │ ├── QuaternionHelpers.hpp │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ ├── SettleToConstant.cpp │ │ │ ├── SettleToConstant.hpp │ │ │ ├── SettleToConstantQuaternion.cpp │ │ │ ├── SettleToConstantQuaternion.hpp │ │ │ ├── Tags.hpp │ │ │ ├── ThreadsafeList.hpp │ │ │ └── ThreadsafeList.tpp │ │ ├── InterfaceComputeTags.hpp │ │ ├── InterfaceHelpers.hpp │ │ ├── InterfaceLogicalCoordinates.cpp │ │ ├── InterfaceLogicalCoordinates.hpp │ │ ├── JacobianDiagnostic.cpp │ │ ├── JacobianDiagnostic.hpp │ │ ├── MinimumGridSpacing.cpp │ │ ├── MinimumGridSpacing.hpp │ │ ├── Python/ │ │ │ ├── Bindings.cpp │ │ │ ├── Block.cpp │ │ │ ├── Block.hpp │ │ │ ├── BlockLogicalCoordinates.cpp │ │ │ ├── BlockLogicalCoordinates.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Direction.cpp │ │ │ ├── Direction.hpp │ │ │ ├── Domain.cpp │ │ │ ├── Domain.hpp │ │ │ ├── ElementId.cpp │ │ │ ├── ElementId.hpp │ │ │ ├── ElementLogicalCoordinates.cpp │ │ │ ├── ElementLogicalCoordinates.hpp │ │ │ ├── ElementMap.cpp │ │ │ ├── ElementMap.hpp │ │ │ ├── FunctionsOfTime.cpp │ │ │ ├── FunctionsOfTime.hpp │ │ │ ├── JacobianDiagnostic.cpp │ │ │ ├── JacobianDiagnostic.hpp │ │ │ ├── RadiallyCompressedCoordinates.cpp │ │ │ ├── RadiallyCompressedCoordinates.hpp │ │ │ ├── SegmentId.cpp │ │ │ ├── SegmentId.hpp │ │ │ ├── StrahlkorperTransformations.cpp │ │ │ ├── StrahlkorperTransformations.hpp │ │ │ └── __init__.py │ │ ├── RadiallyCompressedCoordinates.cpp │ │ ├── RadiallyCompressedCoordinates.hpp │ │ ├── SizeOfElement.cpp │ │ ├── SizeOfElement.hpp │ │ ├── StrahlkorperTransformations.cpp │ │ ├── StrahlkorperTransformations.hpp │ │ ├── Structure/ │ │ │ ├── BlockGroups.cpp │ │ │ ├── BlockGroups.hpp │ │ │ ├── BlockId.hpp │ │ │ ├── BlockNeighbors.cpp │ │ │ ├── BlockNeighbors.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── ChildSize.cpp │ │ │ ├── ChildSize.hpp │ │ │ ├── CreateInitialMesh.cpp │ │ │ ├── CreateInitialMesh.hpp │ │ │ ├── Direction.cpp │ │ │ ├── Direction.hpp │ │ │ ├── DirectionMap.hpp │ │ │ ├── DirectionalId.cpp │ │ │ ├── DirectionalId.hpp │ │ │ ├── DirectionalIdMap.hpp │ │ │ ├── Element.cpp │ │ │ ├── Element.hpp │ │ │ ├── ElementId.cpp │ │ │ ├── ElementId.hpp │ │ │ ├── ElementSearchTree.cpp │ │ │ ├── ElementSearchTree.hpp │ │ │ ├── FaceType.cpp │ │ │ ├── FaceType.hpp │ │ │ ├── HasBoundary.cpp │ │ │ ├── HasBoundary.hpp │ │ │ ├── Hypercube.cpp │ │ │ ├── Hypercube.hpp │ │ │ ├── IndexToSliceAt.hpp │ │ │ ├── InitialElementIds.cpp │ │ │ ├── InitialElementIds.hpp │ │ │ ├── MaxNumberOfNeighbors.hpp │ │ │ ├── NeighborIsConforming.cpp │ │ │ ├── NeighborIsConforming.hpp │ │ │ ├── Neighbors.cpp │ │ │ ├── Neighbors.hpp │ │ │ ├── ObjectLabel.cpp │ │ │ ├── ObjectLabel.hpp │ │ │ ├── OrientationMap.cpp │ │ │ ├── OrientationMap.hpp │ │ │ ├── OrientationMapHelpers.cpp │ │ │ ├── OrientationMapHelpers.hpp │ │ │ ├── SegmentId.cpp │ │ │ ├── SegmentId.hpp │ │ │ ├── Side.cpp │ │ │ ├── Side.hpp │ │ │ ├── Topology.cpp │ │ │ ├── Topology.hpp │ │ │ ├── TrimMap.hpp │ │ │ ├── ZCurve.cpp │ │ │ └── ZCurve.hpp │ │ ├── Tags/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ElementDistribution.hpp │ │ │ ├── FaceNormal.hpp │ │ │ ├── Faces.hpp │ │ │ ├── NeighborMesh.hpp │ │ │ └── SurfaceJacobian.hpp │ │ ├── Tags.hpp │ │ ├── TagsCharacteristicSpeeds.hpp │ │ ├── TagsTimeDependent.cpp │ │ └── TagsTimeDependent.hpp │ ├── Elliptic/ │ │ ├── Actions/ │ │ │ ├── CMakeLists.txt │ │ │ ├── InitializeAnalyticSolution.hpp │ │ │ ├── InitializeBackgroundFields.hpp │ │ │ ├── InitializeFields.hpp │ │ │ ├── InitializeFixedSources.hpp │ │ │ └── RunEventsAndTriggers.hpp │ │ ├── Amr/ │ │ │ ├── Actions.hpp │ │ │ └── CMakeLists.txt │ │ ├── BoundaryConditions/ │ │ │ ├── AnalyticSolution.hpp │ │ │ ├── ApplyBoundaryCondition.hpp │ │ │ ├── BoundaryCondition.hpp │ │ │ ├── BoundaryConditionType.cpp │ │ │ ├── BoundaryConditionType.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Tags/ │ │ │ │ └── BoundaryFields.hpp │ │ │ └── Tags.hpp │ │ ├── CMakeLists.txt │ │ ├── DiscontinuousGalerkin/ │ │ │ ├── Actions/ │ │ │ │ ├── ApplyOperator.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── InitializeDomain.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── DgElementArray.hpp │ │ │ ├── DgOperator.hpp │ │ │ ├── Initialization.cpp │ │ │ ├── Initialization.hpp │ │ │ ├── Penalty.cpp │ │ │ ├── Penalty.hpp │ │ │ ├── SubdomainOperator/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── InitializeSubdomain.cpp │ │ │ │ ├── InitializeSubdomain.hpp │ │ │ │ ├── SubdomainOperator.hpp │ │ │ │ └── Tags.hpp │ │ │ └── Tags.hpp │ │ ├── Executables/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Elasticity/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── SolveElasticity.cpp │ │ │ │ └── SolveElasticity.hpp │ │ │ ├── Poisson/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── SolvePoisson.cpp │ │ │ │ └── SolvePoisson.hpp │ │ │ ├── Punctures/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── SolvePunctures.cpp │ │ │ │ └── SolvePunctures.hpp │ │ │ ├── SelfForce/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── GeneralRelativity/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── SolveGrSelfForce.cpp │ │ │ │ │ └── SolveGrSelfForce.hpp │ │ │ │ └── Scalar/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── SolveScalarSelfForce.cpp │ │ │ │ └── SolveScalarSelfForce.hpp │ │ │ ├── Solver.hpp │ │ │ └── Xcts/ │ │ │ ├── CMakeLists.txt │ │ │ ├── SolveXcts.cpp │ │ │ └── SolveXcts.hpp │ │ ├── Protocols/ │ │ │ ├── CMakeLists.txt │ │ │ └── FirstOrderSystem.hpp │ │ ├── Python/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ReadH5.py │ │ │ └── __init__.py │ │ ├── SubdomainPreconditioners/ │ │ │ ├── CMakeLists.txt │ │ │ ├── MinusLaplacian.hpp │ │ │ ├── RegisterDerived.cpp │ │ │ └── RegisterDerived.hpp │ │ ├── Systems/ │ │ │ ├── BnsInitialData/ │ │ │ │ ├── BnsInitialData.hpp │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── StarSurface.cpp │ │ │ │ │ └── StarSurface.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Equations.cpp │ │ │ │ ├── Equations.hpp │ │ │ │ ├── FirstOrderSystem.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Elasticity/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── InitializeConstitutiveRelation.cpp │ │ │ │ │ └── InitializeConstitutiveRelation.hpp │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── LaserBeam.cpp │ │ │ │ │ ├── LaserBeam.hpp │ │ │ │ │ ├── Zero.cpp │ │ │ │ │ └── Zero.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Equations.cpp │ │ │ │ ├── Equations.hpp │ │ │ │ ├── FirstOrderSystem.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── GetFluxesComputer.hpp │ │ │ ├── GetModifyBoundaryData.hpp │ │ │ ├── GetSourcesComputer.hpp │ │ │ ├── Poisson/ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── Robin.cpp │ │ │ │ │ └── Robin.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Equations.cpp │ │ │ │ ├── Equations.hpp │ │ │ │ ├── FirstOrderSystem.hpp │ │ │ │ ├── Geometry.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── Punctures/ │ │ │ │ ├── AmrCriteria/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── RefineAtPunctures.cpp │ │ │ │ │ └── RefineAtPunctures.hpp │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── Flatness.cpp │ │ │ │ │ └── Flatness.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── FirstOrderSystem.hpp │ │ │ │ ├── Punctures.hpp │ │ │ │ ├── Sources.cpp │ │ │ │ ├── Sources.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── ScalarGaussBonnet/ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DoNothing.hpp │ │ │ │ │ └── Factory.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Equations.cpp │ │ │ │ ├── Equations.hpp │ │ │ │ ├── FirstOrderSystem.hpp │ │ │ │ ├── ScalarGaussBonnet.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── SelfForce/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── GeneralRelativity/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── InitializeEffectiveSource.hpp │ │ │ │ │ ├── AnalyticData/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── CircularOrbit.cpp │ │ │ │ │ │ ├── CircularOrbit.hpp │ │ │ │ │ │ ├── CircularOrbitCoeffs.cpp │ │ │ │ │ │ ├── CircularOrbitCoeffs.hpp │ │ │ │ │ │ ├── CircularOrbitConvertEffsource.cpp │ │ │ │ │ │ └── CircularOrbitConvertEffsource.hpp │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── Angular.cpp │ │ │ │ │ │ ├── Angular.hpp │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ │ ├── None.cpp │ │ │ │ │ │ ├── None.hpp │ │ │ │ │ │ ├── Sommerfeld.cpp │ │ │ │ │ │ └── Sommerfeld.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Equations.cpp │ │ │ │ │ ├── Equations.hpp │ │ │ │ │ ├── FirstOrderSystem.hpp │ │ │ │ │ └── Tags.hpp │ │ │ │ └── Scalar/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── InitializeEffectiveSource.hpp │ │ │ │ ├── AmrCriteria/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── RefineAtPuncture.cpp │ │ │ │ │ └── RefineAtPuncture.hpp │ │ │ │ ├── AnalyticData/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── CircularOrbit.cpp │ │ │ │ │ └── CircularOrbit.hpp │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── None.cpp │ │ │ │ │ ├── None.hpp │ │ │ │ │ ├── Sommerfeld.cpp │ │ │ │ │ └── Sommerfeld.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Equations.cpp │ │ │ │ ├── Equations.hpp │ │ │ │ ├── Events/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ObserveSelfForce.cpp │ │ │ │ │ └── ObserveSelfForce.hpp │ │ │ │ ├── FirstOrderSystem.hpp │ │ │ │ └── Tags.hpp │ │ │ └── Xcts/ │ │ │ ├── BoundaryConditions/ │ │ │ │ ├── ApparentHorizon.cpp │ │ │ │ ├── ApparentHorizon.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── Flatness.cpp │ │ │ │ ├── Flatness.hpp │ │ │ │ ├── Robin.cpp │ │ │ │ └── Robin.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Equations.cpp │ │ │ ├── Equations.hpp │ │ │ ├── Events/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ObserveAdmIntegrals.cpp │ │ │ │ └── ObserveAdmIntegrals.hpp │ │ │ ├── FirstOrderSystem.hpp │ │ │ ├── FluxesAndSources.cpp │ │ │ ├── FluxesAndSources.hpp │ │ │ ├── Geometry.hpp │ │ │ ├── HydroQuantities.hpp │ │ │ ├── Tags.hpp │ │ │ └── Xcts.hpp │ │ ├── Tags.hpp │ │ ├── Triggers/ │ │ │ ├── CMakeLists.txt │ │ │ ├── EveryNIterations.hpp │ │ │ ├── Factory.hpp │ │ │ └── HasConverged.hpp │ │ └── Utilities/ │ │ ├── ApplyAt.hpp │ │ ├── CMakeLists.txt │ │ └── GetAnalyticData.hpp │ ├── Evolution/ │ │ ├── Actions/ │ │ │ ├── CMakeLists.txt │ │ │ ├── RunEventsAndDenseTriggers.hpp │ │ │ └── RunEventsAndTriggers.hpp │ │ ├── Ader/ │ │ │ ├── Ader.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Matrices.cpp │ │ │ └── Matrices.hpp │ │ ├── BoundaryConditions/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Type.cpp │ │ │ └── Type.hpp │ │ ├── BoundaryCorrection.hpp │ │ ├── BoundaryCorrectionTags.hpp │ │ ├── CMakeLists.txt │ │ ├── ComputeTags.hpp │ │ ├── Conservative/ │ │ │ ├── CMakeLists.txt │ │ │ ├── UpdateConservatives.hpp │ │ │ └── UpdatePrimitives.hpp │ │ ├── Deadlock/ │ │ │ ├── CMakeLists.txt │ │ │ ├── PrintDgElementArray.hpp │ │ │ └── PrintFunctionsOfTime.hpp │ │ ├── DgSubcell/ │ │ │ ├── Actions/ │ │ │ │ ├── Actions.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Initialize.hpp │ │ │ │ ├── Labels.hpp │ │ │ │ ├── ReconstructionCommunication.hpp │ │ │ │ ├── SelectNumericalMethod.hpp │ │ │ │ ├── TakeTimeStep.hpp │ │ │ │ ├── TciAndRollback.hpp │ │ │ │ └── TciAndSwitchToDg.hpp │ │ │ ├── ActiveGrid.cpp │ │ │ ├── ActiveGrid.hpp │ │ │ ├── BackgroundGrVars.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CartesianFluxDivergence.cpp │ │ │ ├── CartesianFluxDivergence.hpp │ │ │ ├── CellCenteredFlux.hpp │ │ │ ├── CombineVolumeGhostData.cpp │ │ │ ├── CombineVolumeGhostData.hpp │ │ │ ├── ComputeBoundaryTerms.hpp │ │ │ ├── CorrectPackagedData.hpp │ │ │ ├── DgSubcell.hpp │ │ │ ├── DisableLts.cpp │ │ │ ├── DisableLts.hpp │ │ │ ├── GetActiveTag.hpp │ │ │ ├── GetTciDecision.hpp │ │ │ ├── GhostData.cpp │ │ │ ├── GhostData.hpp │ │ │ ├── GhostZoneInverseJacobian.hpp │ │ │ ├── GhostZoneLogicalCoordinates.cpp │ │ │ ├── GhostZoneLogicalCoordinates.hpp │ │ │ ├── InitialTciData.cpp │ │ │ ├── InitialTciData.hpp │ │ │ ├── Matrices.cpp │ │ │ ├── Matrices.hpp │ │ │ ├── Mesh.cpp │ │ │ ├── Mesh.hpp │ │ │ ├── NeighborRdmpAndVolumeData.cpp │ │ │ ├── NeighborRdmpAndVolumeData.hpp │ │ │ ├── NeighborReconstructedFaceSolution.hpp │ │ │ ├── NeighborReconstructedFaceSolution.tpp │ │ │ ├── NeighborTciDecision.cpp │ │ │ ├── NeighborTciDecision.hpp │ │ │ ├── PerssonTci.cpp │ │ │ ├── PerssonTci.hpp │ │ │ ├── PrepareNeighborData.hpp │ │ │ ├── Projection.cpp │ │ │ ├── Projection.hpp │ │ │ ├── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── __init__.py │ │ │ ├── RdmpTci.cpp │ │ │ ├── RdmpTci.hpp │ │ │ ├── RdmpTciData.cpp │ │ │ ├── RdmpTciData.hpp │ │ │ ├── ReceiveSubcellDataForDg.cpp │ │ │ ├── ReceiveSubcellDataForDg.hpp │ │ │ ├── Reconstruction.cpp │ │ │ ├── Reconstruction.hpp │ │ │ ├── ReconstructionMethod.cpp │ │ │ ├── ReconstructionMethod.hpp │ │ │ ├── ReconstructionOrder.hpp │ │ │ ├── SetInterpolators.hpp │ │ │ ├── SliceData.cpp │ │ │ ├── SliceData.hpp │ │ │ ├── SliceTensor.hpp │ │ │ ├── SliceVariable.hpp │ │ │ ├── SubcellOptions.cpp │ │ │ ├── SubcellOptions.hpp │ │ │ ├── Tags/ │ │ │ │ ├── ActiveGrid.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CellCenteredFlux.hpp │ │ │ │ ├── Coordinates.hpp │ │ │ │ ├── DataForRdmpTci.hpp │ │ │ │ ├── DidRollback.hpp │ │ │ │ ├── GhostDataForReconstruction.hpp │ │ │ │ ├── GhostZoneInverseJacobian.hpp │ │ │ │ ├── Inactive.hpp │ │ │ │ ├── InitialTciData.hpp │ │ │ │ ├── Interpolators.hpp │ │ │ │ ├── Jacobians.hpp │ │ │ │ ├── Mesh.cpp │ │ │ │ ├── Mesh.hpp │ │ │ │ ├── MeshForGhostData.hpp │ │ │ │ ├── MethodOrder.cpp │ │ │ │ ├── MethodOrder.hpp │ │ │ │ ├── ObserverCoordinates.hpp │ │ │ │ ├── ObserverMesh.cpp │ │ │ │ ├── ObserverMesh.hpp │ │ │ │ ├── ObserverMeshVelocity.cpp │ │ │ │ ├── ObserverMeshVelocity.hpp │ │ │ │ ├── OnSubcellFaces.hpp │ │ │ │ ├── OnSubcells.hpp │ │ │ │ ├── ReconstructionOrder.hpp │ │ │ │ ├── StepsSinceTciCall.hpp │ │ │ │ ├── SubcellOptions.hpp │ │ │ │ ├── SubcellSolver.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── TciCallsSinceRollback.hpp │ │ │ │ ├── TciGridHistory.hpp │ │ │ │ ├── TciStatus.cpp │ │ │ │ └── TciStatus.hpp │ │ │ └── TwoMeshRdmpTci.hpp │ │ ├── DiscontinuousGalerkin/ │ │ │ ├── Actions/ │ │ │ │ ├── ApplyBoundaryCorrections.hpp │ │ │ │ ├── BoundaryConditionsImpl.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ComputeTimeDerivative.hpp │ │ │ │ ├── ComputeTimeDerivativeHelpers.hpp │ │ │ │ ├── InternalMortarDataImpl.hpp │ │ │ │ ├── NormalCovectorAndMagnitude.hpp │ │ │ │ ├── PackageDataImpl.hpp │ │ │ │ ├── VolumeTermsImpl.hpp │ │ │ │ └── VolumeTermsImpl.tpp │ │ │ ├── AtomicInboxBoundaryData.cpp │ │ │ ├── AtomicInboxBoundaryData.hpp │ │ │ ├── BackgroundGrVars.hpp │ │ │ ├── BoundaryData.cpp │ │ │ ├── BoundaryData.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CleanMortarHistory.cpp │ │ │ ├── CleanMortarHistory.hpp │ │ │ ├── DgElementArray.hpp │ │ │ ├── InboxBoundaryData.cpp │ │ │ ├── InboxBoundaryData.hpp │ │ │ ├── InboxTags.cpp │ │ │ ├── InboxTags.hpp │ │ │ ├── Initialization/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Mortars.cpp │ │ │ │ ├── Mortars.hpp │ │ │ │ └── QuadratureTag.hpp │ │ │ ├── InstantiateBoundaryHistory.cpp │ │ │ ├── InterfaceDataPolicy.cpp │ │ │ ├── InterfaceDataPolicy.hpp │ │ │ ├── InterpolatedBoundaryData.cpp │ │ │ ├── InterpolatedBoundaryData.hpp │ │ │ ├── Limiters/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── HwenoImpl.cpp │ │ │ │ ├── HwenoImpl.hpp │ │ │ │ ├── Krivodonova.hpp │ │ │ │ ├── Limiters.hpp │ │ │ │ ├── Minmod.hpp │ │ │ │ ├── MinmodHelpers.cpp │ │ │ │ ├── MinmodHelpers.hpp │ │ │ │ ├── MinmodImpl.cpp │ │ │ │ ├── MinmodImpl.hpp │ │ │ │ ├── MinmodTci.cpp │ │ │ │ ├── MinmodTci.hpp │ │ │ │ ├── MinmodType.cpp │ │ │ │ ├── MinmodType.hpp │ │ │ │ ├── SimpleWenoImpl.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── Tci.hpp │ │ │ │ ├── Weno.hpp │ │ │ │ ├── WenoGridHelpers.cpp │ │ │ │ ├── WenoGridHelpers.hpp │ │ │ │ ├── WenoHelpers.cpp │ │ │ │ ├── WenoHelpers.hpp │ │ │ │ ├── WenoOscillationIndicator.cpp │ │ │ │ ├── WenoOscillationIndicator.hpp │ │ │ │ ├── WenoType.cpp │ │ │ │ └── WenoType.hpp │ │ │ ├── Messages/ │ │ │ │ ├── BoundaryMessage.ci │ │ │ │ ├── BoundaryMessage.cpp │ │ │ │ ├── BoundaryMessage.hpp │ │ │ │ └── CMakeLists.txt │ │ │ ├── MortarData.cpp │ │ │ ├── MortarData.hpp │ │ │ ├── MortarDataHolder.cpp │ │ │ ├── MortarDataHolder.hpp │ │ │ ├── MortarInfo.cpp │ │ │ ├── MortarInfo.hpp │ │ │ ├── MortarTags.hpp │ │ │ ├── NormalVectorTags.hpp │ │ │ ├── TimeDerivativeDecisions.hpp │ │ │ ├── TimeSteppingPolicy.cpp │ │ │ ├── TimeSteppingPolicy.hpp │ │ │ └── UsingSubcell.hpp │ │ ├── Evolution.hpp │ │ ├── Executables/ │ │ │ ├── Burgers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── EvolveBurgers.cpp │ │ │ │ └── EvolveBurgers.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Cce/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CharacteristicExtract.cpp │ │ │ │ ├── CharacteristicExtract.hpp │ │ │ │ ├── CharacteristicExtractBase.hpp │ │ │ │ ├── KleinGordonCharacteristicExtract.cpp │ │ │ │ └── KleinGordonCharacteristicExtract.hpp │ │ │ ├── CurvedScalarWave/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── EvolveCurvedScalarWave.cpp │ │ │ │ ├── EvolveCurvedScalarWave.hpp │ │ │ │ ├── EvolveWorldtubeCurvedScalarWave.cpp │ │ │ │ └── EvolveWorldtubeCurvedScalarWave.hpp │ │ │ ├── ForceFree/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── EvolveForceFree.cpp │ │ │ │ └── EvolveForceFree.hpp │ │ │ ├── GeneralizedHarmonic/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Deadlock.hpp │ │ │ │ ├── EvolveGhBinaryBlackHole.cpp │ │ │ │ ├── EvolveGhBinaryBlackHole.hpp │ │ │ │ ├── EvolveGhNoBlackHole.cpp │ │ │ │ ├── EvolveGhNoBlackHole.hpp │ │ │ │ ├── EvolveGhSingleBlackHole.cpp │ │ │ │ ├── EvolveGhSingleBlackHole.hpp │ │ │ │ └── GeneralizedHarmonicBase.hpp │ │ │ ├── GrMhd/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── GhValenciaDivClean/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── EvolveGhValenciaDivClean.cpp │ │ │ │ │ ├── EvolveGhValenciaDivClean.hpp │ │ │ │ │ ├── EvolveGhValenciaDivCleanWithHorizon.cpp │ │ │ │ │ ├── EvolveGhValenciaDivCleanWithHorizon.hpp │ │ │ │ │ └── GhValenciaDivCleanBase.hpp │ │ │ │ └── ValenciaDivClean/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── EvolveValenciaDivClean.cpp │ │ │ │ └── EvolveValenciaDivClean.hpp │ │ │ ├── NewtonianEuler/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── EvolveNewtonianEuler.cpp │ │ │ │ ├── EvolveNewtonianEuler.hpp │ │ │ │ ├── VolumeTermsInstantiation.tpp │ │ │ │ ├── VolumeTermsInstantiation1D.cpp │ │ │ │ ├── VolumeTermsInstantiation2D.cpp │ │ │ │ └── VolumeTermsInstantiation3D.cpp │ │ │ ├── RadiationTransport/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── M1Grey/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── EvolveM1Grey.cpp │ │ │ │ │ └── EvolveM1Grey.hpp │ │ │ │ └── MonteCarlo/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── EvolveMonteCarlo.cpp │ │ │ │ └── EvolveMonteCarlo.hpp │ │ │ ├── ScalarAdvection/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── EvolveScalarAdvection.cpp │ │ │ │ └── EvolveScalarAdvection.hpp │ │ │ ├── ScalarTensor/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── EvolveScalarTensorSingleBlackHole.cpp │ │ │ │ ├── EvolveScalarTensorSingleBlackHole.hpp │ │ │ │ └── ScalarTensorBase.hpp │ │ │ └── ScalarWave/ │ │ │ ├── CMakeLists.txt │ │ │ ├── EvolveScalarWave.cpp │ │ │ └── EvolveScalarWave.hpp │ │ ├── Imex/ │ │ │ ├── Actions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── DoImplicitStep.hpp │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ └── RecordTimeStepperData.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CleanHistory.hpp │ │ │ ├── CleanHistory.tpp │ │ │ ├── GuessResult.cpp │ │ │ ├── GuessResult.hpp │ │ │ ├── ImplicitDenseOutput.hpp │ │ │ ├── Initialize.hpp │ │ │ ├── Mode.cpp │ │ │ ├── Mode.hpp │ │ │ ├── NamespaceDocs.hpp │ │ │ ├── Protocols/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ImexSystem.hpp │ │ │ │ ├── ImplicitSector.hpp │ │ │ │ ├── ImplicitSource.hpp │ │ │ │ ├── ImplicitSourceJacobian.hpp │ │ │ │ └── NamespaceDocs.hpp │ │ │ ├── SolveImplicitSector.hpp │ │ │ ├── SolveImplicitSector.tpp │ │ │ └── Tags/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ImplicitHistory.hpp │ │ │ ├── Jacobian.hpp │ │ │ ├── Mode.hpp │ │ │ ├── NamespaceDocs.hpp │ │ │ ├── OptionGroup.hpp │ │ │ ├── SolveFailures.hpp │ │ │ └── SolveTolerance.hpp │ │ ├── Initialization/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ConservativeSystem.hpp │ │ │ ├── DgDomain.cpp │ │ │ ├── DgDomain.hpp │ │ │ ├── Evolution.hpp │ │ │ ├── InitialData.hpp │ │ │ ├── Limiter.hpp │ │ │ ├── NonconservativeSystem.hpp │ │ │ ├── SetVariables.hpp │ │ │ └── Tags.hpp │ │ ├── NumericInitialData.hpp │ │ ├── Particles/ │ │ │ ├── CMakeLists.txt │ │ │ └── MonteCarlo/ │ │ │ ├── Actions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── FluidCouplingAction.hpp │ │ │ │ ├── InitializeMonteCarlo.hpp │ │ │ │ ├── Labels.hpp │ │ │ │ ├── TimeStepActions.hpp │ │ │ │ └── TriggerMonteCarloEvolution.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CellCrossingTime.cpp │ │ │ ├── CellCrossingTime.hpp │ │ │ ├── CellVolume.cpp │ │ │ ├── CellVolume.hpp │ │ │ ├── CouplingTermsForPropagation.cpp │ │ │ ├── CouplingTermsForPropagation.hpp │ │ │ ├── EmitPackets.tpp │ │ │ ├── EvolvePackets.cpp │ │ │ ├── EvolvePackets.hpp │ │ │ ├── EvolvePacketsInElement.tpp │ │ │ ├── GhostZoneCommunication.hpp │ │ │ ├── GhostZoneCommunicationStep.hpp │ │ │ ├── GhostZoneCommunicationTags.hpp │ │ │ ├── ImplicitMonteCarloCorrections.tpp │ │ │ ├── InverseJacobianInertialToFluidCompute.cpp │ │ │ ├── InverseJacobianInertialToFluidCompute.hpp │ │ │ ├── MonteCarloOptions.cpp │ │ │ ├── MonteCarloOptions.hpp │ │ │ ├── MortarData.hpp │ │ │ ├── NeutrinoInteractionTable.cpp │ │ │ ├── NeutrinoInteractionTable.hpp │ │ │ ├── NeutrinoMomentsFromMonteCarlo.cpp │ │ │ ├── NeutrinoMomentsFromMonteCarlo.hpp │ │ │ ├── Packet.cpp │ │ │ ├── Packet.hpp │ │ │ ├── Scattering.cpp │ │ │ ├── Scattering.hpp │ │ │ ├── SwapGrTags.cpp │ │ │ ├── SwapGrTags.hpp │ │ │ ├── System.hpp │ │ │ ├── Tags.hpp │ │ │ ├── TakeTimeStep.tpp │ │ │ ├── TemplatedLocalFunctions.cpp │ │ │ └── TemplatedLocalFunctions.hpp │ │ ├── PassVariables.hpp │ │ ├── Protocols.hpp │ │ ├── Python/ │ │ │ ├── CMakeLists.txt │ │ │ └── __init__.py │ │ ├── Ringdown/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ComputeRingdownShapeAndTranslationFoT.py │ │ │ │ └── __init__.py │ │ │ ├── StrahlkorperCoefsAndCenters.cpp │ │ │ └── StrahlkorperCoefsAndCenters.hpp │ │ ├── Systems/ │ │ │ ├── Burgers/ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── BoundaryCondition.cpp │ │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DemandOutgoingCharSpeeds.cpp │ │ │ │ │ ├── DemandOutgoingCharSpeeds.hpp │ │ │ │ │ ├── Dirichlet.cpp │ │ │ │ │ ├── Dirichlet.hpp │ │ │ │ │ ├── DirichletAnalytic.cpp │ │ │ │ │ ├── DirichletAnalytic.hpp │ │ │ │ │ └── Factory.hpp │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── Hll.cpp │ │ │ │ │ ├── Hll.hpp │ │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ │ ├── Rusanov.cpp │ │ │ │ │ └── Rusanov.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Characteristics.cpp │ │ │ │ ├── Characteristics.hpp │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ ├── BoundaryConditionGhostData.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── FiniteDifference.hpp │ │ │ │ │ ├── MonotonisedCentral.cpp │ │ │ │ │ ├── MonotonisedCentral.hpp │ │ │ │ │ ├── ReconstructWork.hpp │ │ │ │ │ ├── ReconstructWork.tpp │ │ │ │ │ ├── Reconstructor.cpp │ │ │ │ │ ├── Reconstructor.hpp │ │ │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ │ │ └── Tags.hpp │ │ │ │ ├── Fluxes.cpp │ │ │ │ ├── Fluxes.hpp │ │ │ │ ├── Instantiations/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Divergence.cpp │ │ │ │ │ ├── Events.cpp │ │ │ │ │ ├── TimeStepping.cpp │ │ │ │ │ └── VolumeTerms.cpp │ │ │ │ ├── Subcell/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ComputeFluxes.hpp │ │ │ │ │ ├── GhostData.cpp │ │ │ │ │ ├── GhostData.hpp │ │ │ │ │ ├── NeighborPackagedData.cpp │ │ │ │ │ ├── NeighborPackagedData.hpp │ │ │ │ │ ├── SetInitialRdmpData.cpp │ │ │ │ │ ├── SetInitialRdmpData.hpp │ │ │ │ │ ├── Subcell.hpp │ │ │ │ │ ├── TciOnDgGrid.cpp │ │ │ │ │ ├── TciOnDgGrid.hpp │ │ │ │ │ ├── TciOnFdGrid.cpp │ │ │ │ │ ├── TciOnFdGrid.hpp │ │ │ │ │ └── TimeDerivative.hpp │ │ │ │ ├── System.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── TimeDerivativeTerms.cpp │ │ │ │ └── TimeDerivativeTerms.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Cce/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── BoundaryComputeAndSendToEvolution.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── CalculateScriInputs.hpp │ │ │ │ │ ├── CharacteristicEvolutionBondiCalculations.hpp │ │ │ │ │ ├── FilterSwshVolumeQuantity.hpp │ │ │ │ │ ├── InitializeCharacteristicEvolutionScri.hpp │ │ │ │ │ ├── InitializeCharacteristicEvolutionTime.hpp │ │ │ │ │ ├── InitializeCharacteristicEvolutionVariables.hpp │ │ │ │ │ ├── InitializeFirstHypersurface.hpp │ │ │ │ │ ├── InitializeKleinGordonFirstHypersurface.hpp │ │ │ │ │ ├── InitializeKleinGordonVariables.hpp │ │ │ │ │ ├── InitializeWorldtubeBoundary.hpp │ │ │ │ │ ├── InsertInterpolationScriData.hpp │ │ │ │ │ ├── PrecomputeKleinGordonSourceVariables.hpp │ │ │ │ │ ├── Psi0Matching.hpp │ │ │ │ │ ├── ReceiveGhWorldtubeData.hpp │ │ │ │ │ ├── ReceiveWorldtubeData.hpp │ │ │ │ │ ├── RequestBoundaryData.hpp │ │ │ │ │ ├── ScriObserveInterpolated.cpp │ │ │ │ │ ├── ScriObserveInterpolated.hpp │ │ │ │ │ ├── SendGhVarsToCce.hpp │ │ │ │ │ ├── TimeManagement.hpp │ │ │ │ │ ├── UpdateGauge.hpp │ │ │ │ │ └── WriteScriBondiQuantities.hpp │ │ │ │ ├── AnalyticBoundaryDataManager.cpp │ │ │ │ ├── AnalyticBoundaryDataManager.hpp │ │ │ │ ├── AnalyticSolutions/ │ │ │ │ │ ├── BouncingBlackHole.cpp │ │ │ │ │ ├── BouncingBlackHole.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── GaugeWave.cpp │ │ │ │ │ ├── GaugeWave.hpp │ │ │ │ │ ├── LinearizedBondiSachs.cpp │ │ │ │ │ ├── LinearizedBondiSachs.hpp │ │ │ │ │ ├── RobinsonTrautman.cpp │ │ │ │ │ ├── RobinsonTrautman.hpp │ │ │ │ │ ├── RotatingSchwarzschild.cpp │ │ │ │ │ ├── RotatingSchwarzschild.hpp │ │ │ │ │ ├── SphericalMetricData.cpp │ │ │ │ │ ├── SphericalMetricData.hpp │ │ │ │ │ ├── TeukolskyWave.cpp │ │ │ │ │ ├── TeukolskyWave.hpp │ │ │ │ │ ├── WorldtubeData.cpp │ │ │ │ │ └── WorldtubeData.hpp │ │ │ │ ├── BoundaryData.cpp │ │ │ │ ├── BoundaryData.hpp │ │ │ │ ├── BoundaryDataTags.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Callbacks/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DumpBondiSachsOnWorldtube.cpp │ │ │ │ │ ├── DumpBondiSachsOnWorldtube.hpp │ │ │ │ │ └── SendGhWorldtubeData.hpp │ │ │ │ ├── Components/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── CharacteristicEvolution.hpp │ │ │ │ │ ├── KleinGordonCharacteristicEvolution.hpp │ │ │ │ │ └── WorldtubeBoundary.hpp │ │ │ │ ├── Equations.cpp │ │ │ │ ├── Equations.hpp │ │ │ │ ├── Events/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Events.hpp │ │ │ │ │ ├── ObserveFields.hpp │ │ │ │ │ └── ObserveTimeStep.hpp │ │ │ │ ├── ExtractionRadius.cpp │ │ │ │ ├── ExtractionRadius.hpp │ │ │ │ ├── GaugeTransformBoundaryData.cpp │ │ │ │ ├── GaugeTransformBoundaryData.hpp │ │ │ │ ├── Initialize/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ConformalFactor.cpp │ │ │ │ │ ├── ConformalFactor.hpp │ │ │ │ │ ├── InitializeJ.cpp │ │ │ │ │ ├── InitializeJ.hpp │ │ │ │ │ ├── InverseCubic.cpp │ │ │ │ │ ├── InverseCubic.hpp │ │ │ │ │ ├── NoIncomingRadiation.cpp │ │ │ │ │ ├── NoIncomingRadiation.hpp │ │ │ │ │ ├── RegisterInitializeJWithCharm.hpp │ │ │ │ │ ├── ZeroNonSmooth.cpp │ │ │ │ │ └── ZeroNonSmooth.hpp │ │ │ │ ├── Instantiations/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── TimeStepping.cpp │ │ │ │ ├── IntegrandInputSteps.hpp │ │ │ │ ├── InterfaceManagers/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── GhInterfaceManager.hpp │ │ │ │ │ ├── GhLocalTimeStepping.cpp │ │ │ │ │ ├── GhLocalTimeStepping.hpp │ │ │ │ │ ├── GhLockstep.cpp │ │ │ │ │ └── GhLockstep.hpp │ │ │ │ ├── KleinGordonSource.cpp │ │ │ │ ├── KleinGordonSource.hpp │ │ │ │ ├── KleinGordonSystem.hpp │ │ │ │ ├── LinearOperators.cpp │ │ │ │ ├── LinearOperators.hpp │ │ │ │ ├── LinearSolve.cpp │ │ │ │ ├── LinearSolve.hpp │ │ │ │ ├── NewmanPenrose.cpp │ │ │ │ ├── NewmanPenrose.hpp │ │ │ │ ├── OptionTags.hpp │ │ │ │ ├── PreSwshDerivatives.hpp │ │ │ │ ├── PrecomputeCceDependencies.cpp │ │ │ │ ├── PrecomputeCceDependencies.hpp │ │ │ │ ├── ReceiveTags.hpp │ │ │ │ ├── ScriPlusInterpolationManager.hpp │ │ │ │ ├── ScriPlusValues.cpp │ │ │ │ ├── ScriPlusValues.hpp │ │ │ │ ├── SpecBoundaryData.cpp │ │ │ │ ├── SpecBoundaryData.hpp │ │ │ │ ├── SwshDerivatives.hpp │ │ │ │ ├── System.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── WorldtubeBufferUpdater.cpp │ │ │ │ ├── WorldtubeBufferUpdater.hpp │ │ │ │ ├── WorldtubeDataManager.cpp │ │ │ │ ├── WorldtubeDataManager.hpp │ │ │ │ ├── WorldtubeModeRecorder.cpp │ │ │ │ └── WorldtubeModeRecorder.hpp │ │ │ ├── Ccz4/ │ │ │ │ ├── ATilde.cpp │ │ │ │ ├── ATilde.hpp │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── BoundaryCondition.cpp │ │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DirichletAnalytic.cpp │ │ │ │ │ ├── DirichletAnalytic.hpp │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── Sommerfeld.cpp │ │ │ │ │ └── Sommerfeld.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Ccz4WrappedGr.cpp │ │ │ │ ├── Ccz4WrappedGr.hpp │ │ │ │ ├── Ccz4WrappedGr.tpp │ │ │ │ ├── Christoffel.cpp │ │ │ │ ├── Christoffel.hpp │ │ │ │ ├── DerivChristoffel.cpp │ │ │ │ ├── DerivChristoffel.hpp │ │ │ │ ├── DerivLapse.cpp │ │ │ │ ├── DerivLapse.hpp │ │ │ │ ├── DerivZ4Constraint.cpp │ │ │ │ ├── DerivZ4Constraint.hpp │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ ├── ApplyFilter.cpp │ │ │ │ │ ├── ApplyFilter.hpp │ │ │ │ │ ├── BoundaryConditionGhostData.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Derivatives.cpp │ │ │ │ │ ├── Derivatives.hpp │ │ │ │ │ ├── DummyReconstructor.cpp │ │ │ │ │ ├── DummyReconstructor.hpp │ │ │ │ │ ├── EnforceConstrainedEvolution.cpp │ │ │ │ │ ├── EnforceConstrainedEvolution.hpp │ │ │ │ │ ├── Filter.cpp │ │ │ │ │ ├── Filter.hpp │ │ │ │ │ ├── GhostData.cpp │ │ │ │ │ ├── GhostData.hpp │ │ │ │ │ ├── Reconstructor.cpp │ │ │ │ │ ├── Reconstructor.hpp │ │ │ │ │ ├── SoTimeDerivative.hpp │ │ │ │ │ ├── System.hpp │ │ │ │ │ └── Tags.hpp │ │ │ │ ├── Instantiations/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Ricci1.cpp │ │ │ │ │ ├── Ricci2.cpp │ │ │ │ │ └── Ricci3.cpp │ │ │ │ ├── Ricci.hpp │ │ │ │ ├── Ricci.tpp │ │ │ │ ├── RicciScalarPlusDivergenceZ4Constraint.cpp │ │ │ │ ├── RicciScalarPlusDivergenceZ4Constraint.hpp │ │ │ │ ├── Solutions/ │ │ │ │ │ └── Factory.hpp │ │ │ │ ├── System.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── TagsDeclarations.hpp │ │ │ │ ├── TempTags.hpp │ │ │ │ ├── TimeDerivative.cpp │ │ │ │ ├── TimeDerivative.hpp │ │ │ │ ├── Z4Constraint.cpp │ │ │ │ └── Z4Constraint.hpp │ │ │ ├── CurvedScalarWave/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── SetInitialData.cpp │ │ │ │ │ └── SetInitialData.hpp │ │ │ │ ├── Actions.hpp │ │ │ │ ├── ApplyTensorYlmFilter.cpp │ │ │ │ ├── ApplyTensorYlmFilter.hpp │ │ │ │ ├── BackgroundSpacetime.hpp │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── AnalyticConstant.cpp │ │ │ │ │ ├── AnalyticConstant.hpp │ │ │ │ │ ├── BoundaryCondition.cpp │ │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ConstraintPreservingSphericalRadiation.cpp │ │ │ │ │ ├── ConstraintPreservingSphericalRadiation.hpp │ │ │ │ │ ├── DemandOutgoingCharSpeeds.cpp │ │ │ │ │ ├── DemandOutgoingCharSpeeds.hpp │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── Worldtube.cpp │ │ │ │ │ └── Worldtube.hpp │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ │ ├── UpwindPenalty.cpp │ │ │ │ │ └── UpwindPenalty.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CalculateGrVars.hpp │ │ │ │ ├── Characteristics.cpp │ │ │ │ ├── Characteristics.hpp │ │ │ │ ├── Constraints.cpp │ │ │ │ ├── Constraints.hpp │ │ │ │ ├── Initialize.hpp │ │ │ │ ├── Instantiations/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Events.cpp │ │ │ │ │ ├── TimeStepping.cpp │ │ │ │ │ └── VolumeTerms.cpp │ │ │ │ ├── PsiSquared.hpp │ │ │ │ ├── System.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── TagsDeclarations.hpp │ │ │ │ ├── TimeDerivative.cpp │ │ │ │ ├── TimeDerivative.hpp │ │ │ │ └── Worldtube/ │ │ │ │ ├── AccelerationTermsOrder0.cpp │ │ │ │ ├── AccelerationTermsOrder1.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ElementActions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── InitializeConstraintGammas.cpp │ │ │ │ │ ├── InitializeConstraintGammas.hpp │ │ │ │ │ ├── InitializeCurrentIteration.hpp │ │ │ │ │ ├── IteratePunctureField.hpp │ │ │ │ │ ├── ReceiveWorldtubeData.hpp │ │ │ │ │ └── SendToWorldtube.hpp │ │ │ │ ├── Inboxes.hpp │ │ │ │ ├── InitialData/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ZerothOrderPuncture.cpp │ │ │ │ │ └── ZerothOrderPuncture.hpp │ │ │ │ ├── Instantiations/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── TimeStepping.cpp │ │ │ │ ├── KerrSchildDerivatives.cpp │ │ │ │ ├── KerrSchildDerivatives.hpp │ │ │ │ ├── PunctureField.cpp │ │ │ │ ├── PunctureField.hpp │ │ │ │ ├── PunctureFieldOrder0.cpp │ │ │ │ ├── PunctureFieldOrder1.cpp │ │ │ │ ├── RadiusFunctions.cpp │ │ │ │ ├── RadiusFunctions.hpp │ │ │ │ ├── SelfForce.cpp │ │ │ │ ├── SelfForce.hpp │ │ │ │ ├── SingletonActions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ChangeSlabSize.hpp │ │ │ │ │ ├── InitializeElementFacesGridCoordinates.hpp │ │ │ │ │ ├── InitializeEvolvedVariables.hpp │ │ │ │ │ ├── IterateAccelerationTerms.cpp │ │ │ │ │ ├── IterateAccelerationTerms.hpp │ │ │ │ │ ├── ObserveWorldtubeSolution.hpp │ │ │ │ │ ├── ReceiveElementData.hpp │ │ │ │ │ ├── SendAccelerationTerms.hpp │ │ │ │ │ ├── SendToElements.hpp │ │ │ │ │ ├── UpdateAcceleration.cpp │ │ │ │ │ ├── UpdateAcceleration.hpp │ │ │ │ │ └── UpdateFunctionsOfTime.hpp │ │ │ │ ├── SingletonChare.hpp │ │ │ │ ├── System.hpp │ │ │ │ ├── Tags.cpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── Triggers/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── InsideHorizon.cpp │ │ │ │ │ ├── InsideHorizon.hpp │ │ │ │ │ ├── OrbitRadius.cpp │ │ │ │ │ └── OrbitRadius.hpp │ │ │ │ └── Worldtube.hpp │ │ │ ├── ForceFree/ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── BoundaryCondition.cpp │ │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DemandOutgoingCharSpeeds.cpp │ │ │ │ │ ├── DemandOutgoingCharSpeeds.hpp │ │ │ │ │ ├── DirichletAnalytic.cpp │ │ │ │ │ ├── DirichletAnalytic.hpp │ │ │ │ │ └── Factory.hpp │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ │ ├── Rusanov.cpp │ │ │ │ │ └── Rusanov.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Characteristics.cpp │ │ │ │ ├── Characteristics.hpp │ │ │ │ ├── ElectricCurrentDensity.cpp │ │ │ │ ├── ElectricCurrentDensity.hpp │ │ │ │ ├── ElectromagneticVariables.cpp │ │ │ │ ├── ElectromagneticVariables.hpp │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ ├── AdaptiveOrder.cpp │ │ │ │ │ ├── AdaptiveOrder.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── FiniteDifference.hpp │ │ │ │ │ ├── MonotonisedCentral.cpp │ │ │ │ │ ├── MonotonisedCentral.hpp │ │ │ │ │ ├── ReconstructWork.hpp │ │ │ │ │ ├── ReconstructWork.tpp │ │ │ │ │ ├── Reconstructor.cpp │ │ │ │ │ ├── Reconstructor.hpp │ │ │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ │ │ ├── Tags.hpp │ │ │ │ │ ├── Wcns5z.cpp │ │ │ │ │ └── Wcns5z.hpp │ │ │ │ ├── Fluxes.cpp │ │ │ │ ├── Fluxes.hpp │ │ │ │ ├── Imex/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Imex.hpp │ │ │ │ ├── Instantiations/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Events.cpp │ │ │ │ │ ├── TimeStepping.cpp │ │ │ │ │ └── VolumeTerms.cpp │ │ │ │ ├── MaskNeutronStarInterior.hpp │ │ │ │ ├── Sources.cpp │ │ │ │ ├── Sources.hpp │ │ │ │ ├── Subcell/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ComputeFluxes.hpp │ │ │ │ │ ├── GhostData.cpp │ │ │ │ │ ├── GhostData.hpp │ │ │ │ │ ├── NeighborPackagedData.cpp │ │ │ │ │ ├── NeighborPackagedData.hpp │ │ │ │ │ ├── SetInitialRdmpData.cpp │ │ │ │ │ ├── SetInitialRdmpData.hpp │ │ │ │ │ ├── Subcell.hpp │ │ │ │ │ ├── TciOnDgGrid.cpp │ │ │ │ │ ├── TciOnDgGrid.hpp │ │ │ │ │ ├── TciOnFdGrid.cpp │ │ │ │ │ ├── TciOnFdGrid.hpp │ │ │ │ │ ├── TciOptions.cpp │ │ │ │ │ └── TciOptions.hpp │ │ │ │ ├── System.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── TimeDerivativeTerms.cpp │ │ │ │ └── TimeDerivativeTerms.hpp │ │ │ ├── GeneralizedHarmonic/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── SetInitialData.cpp │ │ │ │ │ └── SetInitialData.hpp │ │ │ │ ├── ApplyTensorYlmFilter.cpp │ │ │ │ ├── ApplyTensorYlmFilter.hpp │ │ │ │ ├── Bbh/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Callbacks/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── UpdateCompletionCriteria.hpp │ │ │ │ │ ├── CompletionCriteria.hpp │ │ │ │ │ ├── CompletionSingleton.hpp │ │ │ │ │ ├── Events/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── CheckConstraintThresholds.cpp │ │ │ │ │ │ └── CheckConstraintThresholds.hpp │ │ │ │ │ └── PhaseControl/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── CheckpointAndExitIfComplete.cpp │ │ │ │ │ └── CheckpointAndExitIfComplete.hpp │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── Bjorhus.cpp │ │ │ │ │ ├── Bjorhus.hpp │ │ │ │ │ ├── BjorhusImpl.cpp │ │ │ │ │ ├── BjorhusImpl.hpp │ │ │ │ │ ├── BoundaryCondition.cpp │ │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DemandOutgoingCharSpeeds.cpp │ │ │ │ │ ├── DemandOutgoingCharSpeeds.hpp │ │ │ │ │ ├── DirichletAnalytic.cpp │ │ │ │ │ ├── DirichletAnalytic.hpp │ │ │ │ │ ├── DirichletMinkowski.cpp │ │ │ │ │ ├── DirichletMinkowski.hpp │ │ │ │ │ └── Factory.hpp │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ ├── AveragedUpwindPenalty.cpp │ │ │ │ │ ├── AveragedUpwindPenalty.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ │ ├── UpwindPenalty.cpp │ │ │ │ │ └── UpwindPenalty.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Characteristics.cpp │ │ │ │ ├── Characteristics.hpp │ │ │ │ ├── Constraints.cpp │ │ │ │ ├── Constraints.hpp │ │ │ │ ├── DuDtTempTags.hpp │ │ │ │ ├── Equations.cpp │ │ │ │ ├── Equations.hpp │ │ │ │ ├── GaugeSourceFunctions/ │ │ │ │ │ ├── AnalyticChristoffel.cpp │ │ │ │ │ ├── AnalyticChristoffel.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DampedHarmonic.cpp │ │ │ │ │ ├── DampedHarmonic.hpp │ │ │ │ │ ├── DampedWaveHelpers.cpp │ │ │ │ │ ├── DampedWaveHelpers.hpp │ │ │ │ │ ├── DhGaugeParameters.cpp │ │ │ │ │ ├── DhGaugeParameters.hpp │ │ │ │ │ ├── Dispatch.cpp │ │ │ │ │ ├── Dispatch.hpp │ │ │ │ │ ├── Dispatch.tpp │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── Gauges.cpp │ │ │ │ │ ├── Gauges.hpp │ │ │ │ │ ├── HalfPiPhiTwoNormals.cpp │ │ │ │ │ ├── HalfPiPhiTwoNormals.hpp │ │ │ │ │ ├── Harmonic.cpp │ │ │ │ │ ├── Harmonic.hpp │ │ │ │ │ ├── RegisterDerived.cpp │ │ │ │ │ ├── RegisterDerived.hpp │ │ │ │ │ ├── SetPiAndPhiFromConstraints.cpp │ │ │ │ │ ├── SetPiAndPhiFromConstraints.hpp │ │ │ │ │ ├── SetPiAndPhiFromConstraints.tpp │ │ │ │ │ └── Tags/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DhGaugeParameters.hpp │ │ │ │ │ ├── GaugeCondition.cpp │ │ │ │ │ ├── GaugeCondition.hpp │ │ │ │ │ └── GaugeCondition.tpp │ │ │ │ ├── Initialize.hpp │ │ │ │ ├── Instantiations/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Events.cpp │ │ │ │ │ ├── TimeStepping.cpp │ │ │ │ │ └── VolumeTerms.cpp │ │ │ │ ├── System.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── TagsDeclarations.hpp │ │ │ │ ├── TimeDerivative.cpp │ │ │ │ ├── TimeDerivative.hpp │ │ │ │ └── TimeDerivative.tpp │ │ │ ├── GrMhd/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── GhValenciaDivClean/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── SetInitialData.cpp │ │ │ │ │ │ └── SetInitialData.hpp │ │ │ │ │ ├── AllSolutions.hpp │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── BoundaryCondition.cpp │ │ │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── ConstraintPreservingFreeOutflow.cpp │ │ │ │ │ │ ├── ConstraintPreservingFreeOutflow.hpp │ │ │ │ │ │ ├── DirichletAnalytic.cpp │ │ │ │ │ │ ├── DirichletAnalytic.hpp │ │ │ │ │ │ ├── DirichletFreeOutflow.cpp │ │ │ │ │ │ ├── DirichletFreeOutflow.hpp │ │ │ │ │ │ └── Factory.hpp │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ │ │ └── ProductOfCorrections.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Characteristics.hpp │ │ │ │ │ ├── Constraints.hpp │ │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ │ ├── BoundaryConditionGhostData.hpp │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Derivatives.cpp │ │ │ │ │ │ ├── Derivatives.hpp │ │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ │ ├── FillNeighborSpacetimeVariables.hpp │ │ │ │ │ │ ├── FilterOptions.cpp │ │ │ │ │ │ ├── FilterOptions.hpp │ │ │ │ │ │ ├── Filters.cpp │ │ │ │ │ │ ├── Filters.hpp │ │ │ │ │ │ ├── FiniteDifference.hpp │ │ │ │ │ │ ├── MonotonisedCentral.cpp │ │ │ │ │ │ ├── MonotonisedCentral.hpp │ │ │ │ │ │ ├── PositivityPreservingAdaptiveOrder.cpp │ │ │ │ │ │ ├── PositivityPreservingAdaptiveOrder.hpp │ │ │ │ │ │ ├── ReconstructWork.hpp │ │ │ │ │ │ ├── ReconstructWork.tpp │ │ │ │ │ │ ├── Reconstructor.cpp │ │ │ │ │ │ ├── Reconstructor.hpp │ │ │ │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ │ │ │ ├── Tag.hpp │ │ │ │ │ │ ├── Wcns5z.cpp │ │ │ │ │ │ └── Wcns5z.hpp │ │ │ │ │ ├── Instantiations/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Events.cpp │ │ │ │ │ │ ├── TimeStepping.cpp │ │ │ │ │ │ └── VolumeTerms.cpp │ │ │ │ │ ├── NeutrinoSystems.hpp │ │ │ │ │ ├── SetPiAndPhiFromConstraints.hpp │ │ │ │ │ ├── StressEnergy.cpp │ │ │ │ │ ├── StressEnergy.hpp │ │ │ │ │ ├── Subcell/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── FixConservativesAndComputePrims.cpp │ │ │ │ │ │ ├── FixConservativesAndComputePrims.hpp │ │ │ │ │ │ ├── NeighborPackagedData.cpp │ │ │ │ │ │ ├── NeighborPackagedData.hpp │ │ │ │ │ │ ├── PrimitiveGhostData.cpp │ │ │ │ │ │ ├── PrimitiveGhostData.hpp │ │ │ │ │ │ ├── PrimsAfterRollback.cpp │ │ │ │ │ │ ├── PrimsAfterRollback.hpp │ │ │ │ │ │ ├── ResizeAndComputePrimitives.cpp │ │ │ │ │ │ ├── ResizeAndComputePrimitives.hpp │ │ │ │ │ │ ├── Subcell.hpp │ │ │ │ │ │ ├── TciOnDgGrid.hpp │ │ │ │ │ │ ├── TciOnFdGrid.hpp │ │ │ │ │ │ ├── TimeDerivative.hpp │ │ │ │ │ │ └── ZeroTimeDerivatives.hpp │ │ │ │ │ ├── System.hpp │ │ │ │ │ ├── SystemM1.hpp │ │ │ │ │ ├── Tags.hpp │ │ │ │ │ ├── TimeDerivativeTerms.cpp │ │ │ │ │ └── TimeDerivativeTerms.hpp │ │ │ │ └── ValenciaDivClean/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── NumericInitialData.cpp │ │ │ │ │ └── NumericInitialData.hpp │ │ │ │ ├── AllSolutions.hpp │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── BoundaryCondition.cpp │ │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DemandOutgoingCharSpeeds.cpp │ │ │ │ │ ├── DemandOutgoingCharSpeeds.hpp │ │ │ │ │ ├── DirichletAnalytic.cpp │ │ │ │ │ ├── DirichletAnalytic.hpp │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── HydroFreeOutflow.cpp │ │ │ │ │ ├── HydroFreeOutflow.hpp │ │ │ │ │ ├── Reflective.cpp │ │ │ │ │ └── Reflective.hpp │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── Hll.cpp │ │ │ │ │ ├── Hll.hpp │ │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ │ ├── Rusanov.cpp │ │ │ │ │ └── Rusanov.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Characteristics.cpp │ │ │ │ ├── Characteristics.hpp │ │ │ │ ├── ComovingMagneticFieldMagnitude.cpp │ │ │ │ ├── ComovingMagneticFieldMagnitude.hpp │ │ │ │ ├── ComputeFluxesFromPrimitives.hpp │ │ │ │ ├── ConservativeFromPrimitive.cpp │ │ │ │ ├── ConservativeFromPrimitive.hpp │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ ├── BoundaryConditionGhostData.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── FiniteDifference.hpp │ │ │ │ │ ├── MonotonicityPreserving5.cpp │ │ │ │ │ ├── MonotonicityPreserving5.hpp │ │ │ │ │ ├── MonotonisedCentral.cpp │ │ │ │ │ ├── MonotonisedCentral.hpp │ │ │ │ │ ├── PositivityPreservingAdaptiveOrder.cpp │ │ │ │ │ ├── PositivityPreservingAdaptiveOrder.hpp │ │ │ │ │ ├── ReconstructWork.hpp │ │ │ │ │ ├── ReconstructWork.tpp │ │ │ │ │ ├── Reconstructor.cpp │ │ │ │ │ ├── Reconstructor.hpp │ │ │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ │ │ ├── Tag.hpp │ │ │ │ │ ├── Wcns5z.cpp │ │ │ │ │ └── Wcns5z.hpp │ │ │ │ ├── FixConservatives.cpp │ │ │ │ ├── FixConservatives.hpp │ │ │ │ ├── Flattener.cpp │ │ │ │ ├── Flattener.hpp │ │ │ │ ├── Fluxes.cpp │ │ │ │ ├── Fluxes.hpp │ │ │ │ ├── Instantiations/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Events.cpp │ │ │ │ │ ├── TimeStepping.cpp │ │ │ │ │ └── VolumeTerms.cpp │ │ │ │ ├── KastaunEtAl.hpp │ │ │ │ ├── KastaunEtAl.tpp │ │ │ │ ├── KastaunEtAlHydro.hpp │ │ │ │ ├── KastaunEtAlHydro.tpp │ │ │ │ ├── NewmanHamlin.hpp │ │ │ │ ├── NewmanHamlin.tpp │ │ │ │ ├── PalenzuelaEtAl.hpp │ │ │ │ ├── PalenzuelaEtAl.tpp │ │ │ │ ├── PrimitiveFromConservative.cpp │ │ │ │ ├── PrimitiveFromConservative.hpp │ │ │ │ ├── PrimitiveFromConservativeOptions.cpp │ │ │ │ ├── PrimitiveFromConservativeOptions.hpp │ │ │ │ ├── PrimitiveRecoveryData.hpp │ │ │ │ ├── QuadrupoleFormula.hpp │ │ │ │ ├── SetVariablesNeededFixingToFalse.cpp │ │ │ │ ├── SetVariablesNeededFixingToFalse.hpp │ │ │ │ ├── Sources.cpp │ │ │ │ ├── Sources.hpp │ │ │ │ ├── Subcell/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ComputeFluxes.hpp │ │ │ │ │ ├── FixConservativesAndComputePrims.cpp │ │ │ │ │ ├── FixConservativesAndComputePrims.hpp │ │ │ │ │ ├── NeighborPackagedData.cpp │ │ │ │ │ ├── NeighborPackagedData.hpp │ │ │ │ │ ├── PrimitiveGhostData.cpp │ │ │ │ │ ├── PrimitiveGhostData.hpp │ │ │ │ │ ├── PrimsAfterRollback.cpp │ │ │ │ │ ├── PrimsAfterRollback.hpp │ │ │ │ │ ├── ResizeAndComputePrimitives.cpp │ │ │ │ │ ├── ResizeAndComputePrimitives.hpp │ │ │ │ │ ├── SetInitialRdmpData.cpp │ │ │ │ │ ├── SetInitialRdmpData.hpp │ │ │ │ │ ├── Subcell.hpp │ │ │ │ │ ├── SwapGrTags.cpp │ │ │ │ │ ├── SwapGrTags.hpp │ │ │ │ │ ├── TciOnDgGrid.cpp │ │ │ │ │ ├── TciOnDgGrid.hpp │ │ │ │ │ ├── TciOnFdGrid.cpp │ │ │ │ │ ├── TciOnFdGrid.hpp │ │ │ │ │ ├── TciOptions.cpp │ │ │ │ │ ├── TciOptions.hpp │ │ │ │ │ └── TimeDerivative.hpp │ │ │ │ ├── System.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── TagsDeclarations.hpp │ │ │ │ ├── TimeDerivativeTerms.cpp │ │ │ │ └── TimeDerivativeTerms.hpp │ │ │ ├── NewtonianEuler/ │ │ │ │ ├── AllSolutions.hpp │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── BoundaryCondition.cpp │ │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DemandOutgoingCharSpeeds.cpp │ │ │ │ │ ├── DemandOutgoingCharSpeeds.hpp │ │ │ │ │ ├── DirichletAnalytic.cpp │ │ │ │ │ ├── DirichletAnalytic.hpp │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── Reflection.cpp │ │ │ │ │ └── Reflection.hpp │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── Hll.cpp │ │ │ │ │ ├── Hll.hpp │ │ │ │ │ ├── Hllc.cpp │ │ │ │ │ ├── Hllc.hpp │ │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ │ ├── Rusanov.cpp │ │ │ │ │ └── Rusanov.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Characteristics.cpp │ │ │ │ ├── Characteristics.hpp │ │ │ │ ├── ConservativeFromPrimitive.cpp │ │ │ │ ├── ConservativeFromPrimitive.hpp │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ ├── AoWeno.cpp │ │ │ │ │ ├── AoWeno.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── FiniteDifference.hpp │ │ │ │ │ ├── MonotonisedCentral.cpp │ │ │ │ │ ├── MonotonisedCentral.hpp │ │ │ │ │ ├── ReconstructWork.hpp │ │ │ │ │ ├── ReconstructWork.tpp │ │ │ │ │ ├── Reconstructor.cpp │ │ │ │ │ ├── Reconstructor.hpp │ │ │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ │ │ └── Tag.hpp │ │ │ │ ├── Fluxes.cpp │ │ │ │ ├── Fluxes.hpp │ │ │ │ ├── Instantiations/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Events.cpp │ │ │ │ │ └── TimeStepping.cpp │ │ │ │ ├── InternalEnergyDensity.cpp │ │ │ │ ├── InternalEnergyDensity.hpp │ │ │ │ ├── KineticEnergyDensity.cpp │ │ │ │ ├── KineticEnergyDensity.hpp │ │ │ │ ├── Limiters/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── CharacteristicHelpers.cpp │ │ │ │ │ ├── CharacteristicHelpers.hpp │ │ │ │ │ ├── Flattener.cpp │ │ │ │ │ ├── Flattener.hpp │ │ │ │ │ ├── KxrcfTci.hpp │ │ │ │ │ ├── Minmod.cpp │ │ │ │ │ ├── Minmod.hpp │ │ │ │ │ ├── VariablesToLimit.cpp │ │ │ │ │ ├── VariablesToLimit.hpp │ │ │ │ │ ├── Weno.cpp │ │ │ │ │ └── Weno.hpp │ │ │ │ ├── MachNumber.cpp │ │ │ │ ├── MachNumber.hpp │ │ │ │ ├── PrimitiveFromConservative.cpp │ │ │ │ ├── PrimitiveFromConservative.hpp │ │ │ │ ├── RamPressure.cpp │ │ │ │ ├── RamPressure.hpp │ │ │ │ ├── SoundSpeedSquared.cpp │ │ │ │ ├── SoundSpeedSquared.hpp │ │ │ │ ├── Sources/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── LaneEmdenGravitationalField.cpp │ │ │ │ │ ├── LaneEmdenGravitationalField.hpp │ │ │ │ │ ├── NoSource.cpp │ │ │ │ │ ├── NoSource.hpp │ │ │ │ │ ├── Source.hpp │ │ │ │ │ ├── UniformAcceleration.cpp │ │ │ │ │ ├── UniformAcceleration.hpp │ │ │ │ │ ├── VortexPerturbation.cpp │ │ │ │ │ └── VortexPerturbation.hpp │ │ │ │ ├── SpecificKineticEnergy.cpp │ │ │ │ ├── SpecificKineticEnergy.hpp │ │ │ │ ├── Subcell/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ComputeFluxes.hpp │ │ │ │ │ ├── NeighborPackagedData.cpp │ │ │ │ │ ├── NeighborPackagedData.hpp │ │ │ │ │ ├── PrimitiveGhostData.cpp │ │ │ │ │ ├── PrimitiveGhostData.hpp │ │ │ │ │ ├── PrimsAfterRollback.cpp │ │ │ │ │ ├── PrimsAfterRollback.hpp │ │ │ │ │ ├── ResizeAndComputePrimitives.cpp │ │ │ │ │ ├── ResizeAndComputePrimitives.hpp │ │ │ │ │ ├── SetInitialRdmpData.cpp │ │ │ │ │ ├── SetInitialRdmpData.hpp │ │ │ │ │ ├── Subcell.hpp │ │ │ │ │ ├── TciOnDgGrid.cpp │ │ │ │ │ ├── TciOnDgGrid.hpp │ │ │ │ │ ├── TciOnFdGrid.cpp │ │ │ │ │ ├── TciOnFdGrid.hpp │ │ │ │ │ └── TimeDerivative.hpp │ │ │ │ ├── System.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── TagsDeclarations.hpp │ │ │ │ └── TimeDerivativeTerms.hpp │ │ │ ├── RadiationTransport/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── M1Grey/ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── DirichletAnalytic.cpp │ │ │ │ │ │ ├── DirichletAnalytic.hpp │ │ │ │ │ │ └── Factory.hpp │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ │ │ ├── Rusanov.cpp │ │ │ │ │ │ └── Rusanov.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Characteristics.cpp │ │ │ │ │ ├── Characteristics.hpp │ │ │ │ │ ├── Fluxes.cpp │ │ │ │ │ ├── Fluxes.hpp │ │ │ │ │ ├── Initialize.hpp │ │ │ │ │ ├── Instantiations/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Events.cpp │ │ │ │ │ │ ├── Imex.cpp │ │ │ │ │ │ └── TimeStepping.cpp │ │ │ │ │ ├── M1Closure.cpp │ │ │ │ │ ├── M1Closure.hpp │ │ │ │ │ ├── M1HydroCoupling.cpp │ │ │ │ │ ├── M1HydroCoupling.hpp │ │ │ │ │ ├── Sources.cpp │ │ │ │ │ ├── Sources.hpp │ │ │ │ │ ├── System.hpp │ │ │ │ │ ├── Tags.hpp │ │ │ │ │ └── TimeDerivativeTerms.hpp │ │ │ │ ├── NoNeutrinos/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── System.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── ScalarAdvection/ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── BoundaryCondition.cpp │ │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Factory.hpp │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ │ ├── Rusanov.cpp │ │ │ │ │ └── Rusanov.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Characteristics.cpp │ │ │ │ ├── Characteristics.hpp │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ ├── AoWeno.cpp │ │ │ │ │ ├── AoWeno.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── FiniteDifference.hpp │ │ │ │ │ ├── MonotonisedCentral.cpp │ │ │ │ │ ├── MonotonisedCentral.hpp │ │ │ │ │ ├── ReconstructWork.hpp │ │ │ │ │ ├── ReconstructWork.tpp │ │ │ │ │ ├── Reconstructor.cpp │ │ │ │ │ ├── Reconstructor.hpp │ │ │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ │ │ └── Tags.hpp │ │ │ │ ├── Fluxes.cpp │ │ │ │ ├── Fluxes.hpp │ │ │ │ ├── Instantiations/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Events.cpp │ │ │ │ │ ├── TimeStepping.cpp │ │ │ │ │ └── VolumeTerms.cpp │ │ │ │ ├── Subcell/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ComputeFluxes.hpp │ │ │ │ │ ├── GhostData.cpp │ │ │ │ │ ├── GhostData.hpp │ │ │ │ │ ├── NeighborPackagedData.cpp │ │ │ │ │ ├── NeighborPackagedData.hpp │ │ │ │ │ ├── SetInitialRdmpData.cpp │ │ │ │ │ ├── SetInitialRdmpData.hpp │ │ │ │ │ ├── Subcell.hpp │ │ │ │ │ ├── TciOnDgGrid.cpp │ │ │ │ │ ├── TciOnDgGrid.hpp │ │ │ │ │ ├── TciOnFdGrid.cpp │ │ │ │ │ ├── TciOnFdGrid.hpp │ │ │ │ │ ├── TciOptions.cpp │ │ │ │ │ ├── TciOptions.hpp │ │ │ │ │ ├── TimeDerivative.hpp │ │ │ │ │ └── VelocityAtFace.hpp │ │ │ │ ├── System.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── TimeDerivativeTerms.cpp │ │ │ │ ├── TimeDerivativeTerms.hpp │ │ │ │ ├── VelocityField.cpp │ │ │ │ └── VelocityField.hpp │ │ │ ├── ScalarTensor/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── SetInitialData.cpp │ │ │ │ │ └── SetInitialData.hpp │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── BoundaryCondition.cpp │ │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ConstraintPreserving.cpp │ │ │ │ │ ├── ConstraintPreserving.hpp │ │ │ │ │ ├── DemandOutgoingCharSpeeds.cpp │ │ │ │ │ ├── DemandOutgoingCharSpeeds.hpp │ │ │ │ │ ├── DirichletAnalytic.cpp │ │ │ │ │ ├── DirichletAnalytic.hpp │ │ │ │ │ └── Factory.hpp │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ │ └── ProductOfCorrections.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Characteristics.hpp │ │ │ │ ├── Constraints.hpp │ │ │ │ ├── Initialize.hpp │ │ │ │ ├── Instantiations/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Events.cpp │ │ │ │ │ ├── TimeStepping.cpp │ │ │ │ │ └── VolumeTerms.cpp │ │ │ │ ├── System.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── TimeDerivative.cpp │ │ │ │ └── TimeDerivative.hpp │ │ │ └── ScalarWave/ │ │ │ ├── BoundaryConditions/ │ │ │ │ ├── BoundaryCondition.cpp │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ConstraintPreservingSphericalRadiation.cpp │ │ │ │ ├── ConstraintPreservingSphericalRadiation.hpp │ │ │ │ ├── DirichletAnalytic.cpp │ │ │ │ ├── DirichletAnalytic.hpp │ │ │ │ ├── Factory.hpp │ │ │ │ ├── SphericalRadiation.cpp │ │ │ │ └── SphericalRadiation.hpp │ │ │ ├── BoundaryCorrections/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ ├── UpwindPenalty.cpp │ │ │ │ └── UpwindPenalty.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Characteristics.cpp │ │ │ ├── Characteristics.hpp │ │ │ ├── Constraints.cpp │ │ │ ├── Constraints.hpp │ │ │ ├── EnergyDensity.cpp │ │ │ ├── EnergyDensity.hpp │ │ │ ├── Equations.cpp │ │ │ ├── Equations.hpp │ │ │ ├── Initialize.hpp │ │ │ ├── Instantiations/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Events.cpp │ │ │ │ ├── TimeStepping.cpp │ │ │ │ └── VolumeTerms.cpp │ │ │ ├── MomentumDensity.cpp │ │ │ ├── MomentumDensity.hpp │ │ │ ├── System.hpp │ │ │ ├── Tags.hpp │ │ │ ├── TagsDeclarations.hpp │ │ │ ├── TimeDerivative.cpp │ │ │ └── TimeDerivative.hpp │ │ ├── Tags/ │ │ │ ├── CMakeLists.txt │ │ │ └── Filter.hpp │ │ ├── Tags.hpp │ │ ├── TagsDomain.cpp │ │ ├── TagsDomain.hpp │ │ ├── Triggers/ │ │ │ ├── CMakeLists.txt │ │ │ ├── SeparationLessThan.cpp │ │ │ └── SeparationLessThan.hpp │ │ ├── TypeTraits.hpp │ │ └── VariableFixing/ │ │ ├── Actions.hpp │ │ ├── CMakeLists.txt │ │ ├── FixToAtmosphere.cpp │ │ ├── FixToAtmosphere.hpp │ │ ├── LimitLorentzFactor.cpp │ │ ├── LimitLorentzFactor.hpp │ │ ├── ParameterizedDeleptonization.cpp │ │ ├── ParameterizedDeleptonization.hpp │ │ ├── RadiallyFallingFloor.cpp │ │ ├── RadiallyFallingFloor.hpp │ │ └── Tags.hpp │ ├── Executables/ │ │ ├── Benchmark/ │ │ │ ├── Benchmark.cpp │ │ │ └── CMakeLists.txt │ │ ├── CMakeLists.txt │ │ ├── ConvertComposeTable/ │ │ │ ├── CMakeLists.txt │ │ │ └── ConvertComposeTable.cpp │ │ ├── DebugPreprocessor/ │ │ │ ├── CMakeLists.txt │ │ │ └── DebugPreprocessor.cpp │ │ ├── Examples/ │ │ │ ├── CMakeLists.txt │ │ │ ├── HelloWorld/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── SingletonHelloWorld.cpp │ │ │ ├── HelloWorldNoCharm/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── HelloWorld.cpp │ │ │ ├── ParallelTutorial/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── MinimalExecutable.cpp │ │ │ ├── PiMonteCarlo/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── PiMonteCarlo.cpp │ │ │ │ └── PiMonteCarloTutorial.cpp │ │ │ └── RandomAmr/ │ │ │ ├── CMakeLists.txt │ │ │ ├── InitializeDomain.hpp │ │ │ ├── RandomAmr.cpp │ │ │ └── RandomAmr.hpp │ │ ├── ExportCoordinates/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ExportCoordinates.cpp │ │ │ └── ExportCoordinates.hpp │ │ ├── ExportEquationOfStateForRotNS/ │ │ │ ├── CMakeLists.txt │ │ │ └── ExportEquationOfStateForRotNS.cpp │ │ ├── ParallelInfo/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ParallelInfo.ci │ │ │ ├── ParallelInfo.cpp │ │ │ └── ParallelInfo.hpp │ │ ├── PreprocessCceWorldtube/ │ │ │ ├── CMakeLists.txt │ │ │ └── PreprocessCceWorldtube.cpp │ │ ├── TimeStepperSummary/ │ │ │ ├── CMakeLists.txt │ │ │ └── TimeStepperSummary.cpp │ │ └── WriteCceWorldtubeCoordsToFile/ │ │ ├── CMakeLists.txt │ │ └── WriteCceWorldtubeCoordsToFile.cpp │ ├── IO/ │ │ ├── CMakeLists.txt │ │ ├── ComposeTable.cpp │ │ ├── ComposeTable.hpp │ │ ├── Connectivity.cpp │ │ ├── Connectivity.hpp │ │ ├── Exporter/ │ │ │ ├── BundledExporter.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Exporter.cpp │ │ │ ├── Exporter.hpp │ │ │ ├── PointwiseInterpolator.cpp │ │ │ ├── PointwiseInterpolator.hpp │ │ │ ├── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── InterpolateToPoints.py │ │ │ │ └── __init__.py │ │ │ ├── SelectObservation.cpp │ │ │ ├── SelectObservation.hpp │ │ │ ├── SpacetimeInterpolator.cpp │ │ │ └── SpacetimeInterpolator.hpp │ │ ├── External/ │ │ │ ├── CMakeLists.txt │ │ │ ├── InterpolateFromFuka.cpp │ │ │ ├── InterpolateFromFuka.hpp │ │ │ └── InterpolateFromSpec.hpp │ │ ├── H5/ │ │ │ ├── AccessType.cpp │ │ │ ├── AccessType.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Cce.cpp │ │ │ ├── Cce.hpp │ │ │ ├── CheckH5.hpp │ │ │ ├── CheckH5PropertiesMatch.cpp │ │ │ ├── CheckH5PropertiesMatch.hpp │ │ │ ├── CombineH5.cpp │ │ │ ├── CombineH5.hpp │ │ │ ├── Dat.cpp │ │ │ ├── Dat.hpp │ │ │ ├── EosTable.cpp │ │ │ ├── EosTable.hpp │ │ │ ├── ExtendConnectivityHelpers.cpp │ │ │ ├── ExtendConnectivityHelpers.hpp │ │ │ ├── File.cpp │ │ │ ├── File.hpp │ │ │ ├── Header.cpp │ │ │ ├── Header.hpp │ │ │ ├── Helpers.cpp │ │ │ ├── Helpers.hpp │ │ │ ├── Object.hpp │ │ │ ├── OpenGroup.cpp │ │ │ ├── OpenGroup.hpp │ │ │ ├── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Cce.cpp │ │ │ │ ├── Cce.hpp │ │ │ │ ├── CombineH5.cpp │ │ │ │ ├── CombineH5.hpp │ │ │ │ ├── CombineH5.py │ │ │ │ ├── CombineH5Dat.py │ │ │ │ ├── Dat.cpp │ │ │ │ ├── Dat.hpp │ │ │ │ ├── DeleteSubfiles.py │ │ │ │ ├── ExtendConnectivityData.py │ │ │ │ ├── ExtractDatFromH5.py │ │ │ │ ├── ExtractInputSourceYamlFromH5.py │ │ │ │ ├── File.cpp │ │ │ │ ├── File.hpp │ │ │ │ ├── FunctionsOfTimeFromVolume.py │ │ │ │ ├── InterpolateToMesh.py │ │ │ │ ├── IterElements.py │ │ │ │ ├── OpenVolfiles.py │ │ │ │ ├── ReadH5.py │ │ │ │ ├── TensorData.cpp │ │ │ │ ├── TensorData.hpp │ │ │ │ ├── TransformVolumeData.py │ │ │ │ ├── VolumeData.cpp │ │ │ │ ├── VolumeData.hpp │ │ │ │ └── __init__.py │ │ │ ├── SourceArchive.cpp │ │ │ ├── SourceArchive.hpp │ │ │ ├── SpectralIo.cpp │ │ │ ├── SpectralIo.hpp │ │ │ ├── StellarCollapseEos.cpp │ │ │ ├── StellarCollapseEos.hpp │ │ │ ├── TensorData.cpp │ │ │ ├── TensorData.hpp │ │ │ ├── Type.hpp │ │ │ ├── Version.cpp │ │ │ ├── Version.hpp │ │ │ ├── VolumeData.cpp │ │ │ ├── VolumeData.hpp │ │ │ └── Wrappers.hpp │ │ ├── Importers/ │ │ │ ├── Actions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ReadVolumeData.hpp │ │ │ │ ├── ReceiveVolumeData.hpp │ │ │ │ └── RegisterWithElementDataReader.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── ElementDataReader.hpp │ │ │ ├── ObservationSelector.cpp │ │ │ ├── ObservationSelector.hpp │ │ │ └── Tags.hpp │ │ ├── Logging/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Tags.hpp │ │ │ ├── Verbosity.cpp │ │ │ └── Verbosity.hpp │ │ └── Observer/ │ │ ├── Actions/ │ │ │ ├── CMakeLists.txt │ │ │ ├── GetLockPointer.hpp │ │ │ ├── ObserverRegistration.hpp │ │ │ ├── RegisterEvents.hpp │ │ │ ├── RegisterSingleton.hpp │ │ │ └── RegisterWithObservers.hpp │ │ ├── CMakeLists.txt │ │ ├── GetSectionObservationKey.hpp │ │ ├── Helpers.hpp │ │ ├── Initialize.hpp │ │ ├── ObservationId.cpp │ │ ├── ObservationId.hpp │ │ ├── ObserverComponent.hpp │ │ ├── Protocols/ │ │ │ ├── CMakeLists.txt │ │ │ └── ReductionDataFormatter.hpp │ │ ├── ReductionActions.cpp │ │ ├── ReductionActions.hpp │ │ ├── Tags.hpp │ │ ├── TypeOfObservation.cpp │ │ ├── TypeOfObservation.hpp │ │ ├── VolumeActions.cpp │ │ ├── VolumeActions.hpp │ │ └── WriteSimpleData.hpp │ ├── Informer/ │ │ ├── CMakeLists.txt │ │ ├── InfoAtCompile.cpp │ │ ├── InfoAtLink.cpp │ │ ├── InfoAtLinkExtractFlags.py │ │ ├── InfoFromBuild.hpp │ │ ├── Informer.cpp │ │ ├── Informer.hpp │ │ └── Python/ │ │ ├── Bindings.cpp │ │ ├── CMakeLists.txt │ │ ├── InfoAtCompile.cpp │ │ ├── InfoAtCompile.hpp │ │ └── __init__.py │ ├── NumericalAlgorithms/ │ │ ├── CMakeLists.txt │ │ ├── Convergence/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Convergence.hpp │ │ │ ├── Criteria.cpp │ │ │ ├── Criteria.hpp │ │ │ ├── HasConverged.cpp │ │ │ ├── HasConverged.hpp │ │ │ ├── Reason.cpp │ │ │ ├── Reason.hpp │ │ │ └── Tags.hpp │ │ ├── DiscontinuousGalerkin/ │ │ │ ├── ApplyMassMatrix.cpp │ │ │ ├── ApplyMassMatrix.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Formulation.cpp │ │ │ ├── Formulation.hpp │ │ │ ├── HasReceivedFromAllMortars.hpp │ │ │ ├── InterpolateFromBoundary.cpp │ │ │ ├── InterpolateFromBoundary.hpp │ │ │ ├── LiftFlux.hpp │ │ │ ├── LiftFromBoundary.cpp │ │ │ ├── LiftFromBoundary.hpp │ │ │ ├── MetricIdentityJacobian.cpp │ │ │ ├── MetricIdentityJacobian.hpp │ │ │ ├── MortarHelpers.cpp │ │ │ ├── MortarHelpers.hpp │ │ │ ├── MortarInterpolator.cpp │ │ │ ├── MortarInterpolator.hpp │ │ │ ├── NormalDotFlux.hpp │ │ │ ├── ProjectToBoundary.hpp │ │ │ ├── SimpleBoundaryData.hpp │ │ │ ├── SimpleMortarData.hpp │ │ │ ├── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Formulation.cpp │ │ │ │ ├── Formulation.hpp │ │ │ │ └── OptionsGroup.hpp │ │ │ └── Tags.hpp │ │ ├── FiniteDifference/ │ │ │ ├── AoWeno.cpp │ │ │ ├── AoWeno.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── DerivativeOrder.cpp │ │ │ ├── DerivativeOrder.hpp │ │ │ ├── FallbackReconstructorType.cpp │ │ │ ├── FallbackReconstructorType.hpp │ │ │ ├── Filter.cpp │ │ │ ├── Filter.hpp │ │ │ ├── FiniteDifference.hpp │ │ │ ├── HighOrderFluxCorrection.hpp │ │ │ ├── Minmod.cpp │ │ │ ├── Minmod.hpp │ │ │ ├── MonotonicityPreserving5.cpp │ │ │ ├── MonotonicityPreserving5.hpp │ │ │ ├── MonotonisedCentral.cpp │ │ │ ├── MonotonisedCentral.hpp │ │ │ ├── NeighborDataAsVariables.hpp │ │ │ ├── NonUniform1D.cpp │ │ │ ├── NonUniform1D.hpp │ │ │ ├── PartialDerivatives.cpp │ │ │ ├── PartialDerivatives.hpp │ │ │ ├── PartialDerivatives.tpp │ │ │ ├── PositivityPreservingAdaptiveOrder.cpp │ │ │ ├── PositivityPreservingAdaptiveOrder.hpp │ │ │ ├── Reconstruct.hpp │ │ │ ├── Reconstruct.tpp │ │ │ ├── SecondPartialDerivatives.cpp │ │ │ ├── SecondPartialDerivatives.hpp │ │ │ ├── SecondPartialDerivatives.tpp │ │ │ ├── Unlimited.cpp │ │ │ ├── Unlimited.hpp │ │ │ ├── Wcns5z.cpp │ │ │ └── Wcns5z.hpp │ │ ├── Integration/ │ │ │ ├── CMakeLists.txt │ │ │ ├── GslQuadAdaptive.cpp │ │ │ └── GslQuadAdaptive.hpp │ │ ├── Interpolation/ │ │ │ ├── BarycentricRational.cpp │ │ │ ├── BarycentricRational.hpp │ │ │ ├── BarycentricRationalSpanInterpolator.cpp │ │ │ ├── BarycentricRationalSpanInterpolator.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CardinalInterpolator.cpp │ │ │ ├── CardinalInterpolator.hpp │ │ │ ├── CubicSpanInterpolator.cpp │ │ │ ├── CubicSpanInterpolator.hpp │ │ │ ├── CubicSpline.cpp │ │ │ ├── CubicSpline.hpp │ │ │ ├── IrregularInterpolant.cpp │ │ │ ├── IrregularInterpolant.hpp │ │ │ ├── LagrangePolynomial.hpp │ │ │ ├── LinearLeastSquares.cpp │ │ │ ├── LinearLeastSquares.hpp │ │ │ ├── LinearRegression.cpp │ │ │ ├── LinearRegression.hpp │ │ │ ├── LinearSpanInterpolator.cpp │ │ │ ├── LinearSpanInterpolator.hpp │ │ │ ├── MultiLinearSpanInterpolation.hpp │ │ │ ├── PolynomialInterpolation.cpp │ │ │ ├── PolynomialInterpolation.hpp │ │ │ ├── PredictedZeroCrossing.cpp │ │ │ ├── PredictedZeroCrossing.hpp │ │ │ ├── Python/ │ │ │ │ ├── BarycentricRational.cpp │ │ │ │ ├── BarycentricRational.hpp │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CubicSpline.cpp │ │ │ │ ├── CubicSpline.hpp │ │ │ │ ├── IrregularInterpolant.cpp │ │ │ │ ├── IrregularInterpolant.hpp │ │ │ │ ├── RegularGridInterpolant.cpp │ │ │ │ ├── RegularGridInterpolant.hpp │ │ │ │ └── __init__.py │ │ │ ├── RegularGridInterpolant.cpp │ │ │ ├── RegularGridInterpolant.hpp │ │ │ ├── SpanInterpolator.cpp │ │ │ ├── SpanInterpolator.hpp │ │ │ ├── ZeroCrossingPredictor.cpp │ │ │ └── ZeroCrossingPredictor.hpp │ │ ├── LinearAlgebra/ │ │ │ ├── CMakeLists.txt │ │ │ ├── FindGeneralizedEigenvalues.cpp │ │ │ └── FindGeneralizedEigenvalues.hpp │ │ ├── LinearOperators/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CoefficientTransforms.cpp │ │ │ ├── CoefficientTransforms.hpp │ │ │ ├── DefiniteIntegral.cpp │ │ │ ├── DefiniteIntegral.hpp │ │ │ ├── Divergence.cpp │ │ │ ├── Divergence.hpp │ │ │ ├── Divergence.tpp │ │ │ ├── ExponentialFilter.cpp │ │ │ ├── ExponentialFilter.hpp │ │ │ ├── IndefiniteIntegral.cpp │ │ │ ├── IndefiniteIntegral.hpp │ │ │ ├── Linearize.cpp │ │ │ ├── Linearize.hpp │ │ │ ├── MeanValue.cpp │ │ │ ├── MeanValue.hpp │ │ │ ├── PartialDerivatives.cpp │ │ │ ├── PartialDerivatives.hpp │ │ │ ├── PartialDerivatives.tpp │ │ │ ├── PowerMonitors.cpp │ │ │ ├── PowerMonitors.hpp │ │ │ ├── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── DefiniteIntegral.cpp │ │ │ │ ├── DefiniteIntegral.hpp │ │ │ │ ├── PartialDerivatives.cpp │ │ │ │ ├── PartialDerivatives.hpp │ │ │ │ ├── PowerMonitors.cpp │ │ │ │ ├── PowerMonitors.hpp │ │ │ │ └── __init__.py │ │ │ ├── WeakDivergence.cpp │ │ │ └── WeakDivergence.hpp │ │ ├── LinearSolver/ │ │ │ ├── BuildMatrix.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── ExplicitInverse.hpp │ │ │ ├── Gmres.cpp │ │ │ ├── Gmres.hpp │ │ │ ├── InnerProduct.hpp │ │ │ ├── Lapack.cpp │ │ │ ├── Lapack.hpp │ │ │ └── LinearSolver.hpp │ │ ├── OdeIntegration/ │ │ │ ├── CMakeLists.txt │ │ │ └── OdeIntegration.hpp │ │ ├── RootFinding/ │ │ │ ├── CMakeLists.txt │ │ │ ├── GslMultiRoot.cpp │ │ │ ├── GslMultiRoot.hpp │ │ │ ├── LICENSE_1_0.txt │ │ │ ├── NewtonRaphson.hpp │ │ │ ├── QuadraticEquation.cpp │ │ │ ├── QuadraticEquation.hpp │ │ │ ├── RootBracketing.hpp │ │ │ └── TOMS748.hpp │ │ ├── SpatialDiscretization/ │ │ │ ├── CMakeLists.txt │ │ │ └── OptionTags.hpp │ │ ├── Spectral/ │ │ │ ├── BarycentricWeights.cpp │ │ │ ├── BarycentricWeights.hpp │ │ │ ├── Basis.cpp │ │ │ ├── Basis.hpp │ │ │ ├── BasisFunctionNormalizationSquare.hpp │ │ │ ├── BasisFunctionValue.hpp │ │ │ ├── BasisFunctions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Chebyshev.cpp │ │ │ │ ├── Chebyshev.hpp │ │ │ │ ├── Fourier.cpp │ │ │ │ ├── Fourier.hpp │ │ │ │ ├── Jacobi.cpp │ │ │ │ ├── Jacobi.hpp │ │ │ │ ├── Legendre.cpp │ │ │ │ ├── Zernike.cpp │ │ │ │ └── Zernike.hpp │ │ │ ├── BoundaryInterpolationMatrices.cpp │ │ │ ├── BoundaryInterpolationMatrices.hpp │ │ │ ├── BoundaryInterpolationTerm.cpp │ │ │ ├── BoundaryInterpolationTerm.hpp │ │ │ ├── BoundaryLiftingTerm.cpp │ │ │ ├── BoundaryLiftingTerm.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Cartoon.cpp │ │ │ ├── Clenshaw.hpp │ │ │ ├── CollocationPoints.cpp │ │ │ ├── CollocationPoints.hpp │ │ │ ├── CollocationPointsAndWeights.cpp │ │ │ ├── CollocationPointsAndWeights.hpp │ │ │ ├── DifferentiationMatrix.cpp │ │ │ ├── DifferentiationMatrix.hpp │ │ │ ├── Filtering.cpp │ │ │ ├── Filtering.hpp │ │ │ ├── FiniteDifference.cpp │ │ │ ├── GetSpectralQuantityForMesh.hpp │ │ │ ├── IntegrationMatrix.cpp │ │ │ ├── IntegrationMatrix.hpp │ │ │ ├── InterpolationMatrix.cpp │ │ │ ├── InterpolationMatrix.hpp │ │ │ ├── InterpolationWeights.cpp │ │ │ ├── InterpolationWeights.hpp │ │ │ ├── InverseWeightFunctionValues.hpp │ │ │ ├── Legendre.hpp │ │ │ ├── LinearFilteringMatrix.cpp │ │ │ ├── LinearFilteringMatrix.hpp │ │ │ ├── LogicalCoordinates.cpp │ │ │ ├── LogicalCoordinates.hpp │ │ │ ├── MaximumNumberOfPoints.hpp │ │ │ ├── Mesh.cpp │ │ │ ├── Mesh.hpp │ │ │ ├── MinimumNumberOfPoints.hpp │ │ │ ├── ModalToNodalMatrix.cpp │ │ │ ├── ModalToNodalMatrix.hpp │ │ │ ├── Namespace.hpp │ │ │ ├── NodalToModalMatrix.cpp │ │ │ ├── NodalToModalMatrix.hpp │ │ │ ├── Parity.cpp │ │ │ ├── Parity.hpp │ │ │ ├── ParityFromSymmetry.hpp │ │ │ ├── PrecomputedSpectralQuantity.hpp │ │ │ ├── Projection.cpp │ │ │ ├── Projection.hpp │ │ │ ├── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── LogicalCoordinates.cpp │ │ │ │ ├── LogicalCoordinates.hpp │ │ │ │ ├── Mesh.cpp │ │ │ │ ├── Mesh.hpp │ │ │ │ ├── Spectral.cpp │ │ │ │ ├── Spectral.hpp │ │ │ │ └── __init__.py │ │ │ ├── Quadrature.cpp │ │ │ ├── Quadrature.hpp │ │ │ ├── QuadratureWeights.cpp │ │ │ ├── QuadratureWeights.hpp │ │ │ ├── SegmentSize.cpp │ │ │ ├── SegmentSize.hpp │ │ │ └── SpectralQuantityForMesh.hpp │ │ ├── SphericalHarmonics/ │ │ │ ├── AngularOrdering.cpp │ │ │ ├── AngularOrdering.hpp │ │ │ ├── ApplyTensorYlmFilter.hpp │ │ │ ├── ApplyTensorYlmFilter.tpp │ │ │ ├── CMakeLists.txt │ │ │ ├── ChangeCenterOfStrahlkorper.cpp │ │ │ ├── ChangeCenterOfStrahlkorper.hpp │ │ │ ├── IO/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── FillYlmLegendAndData.cpp │ │ │ │ ├── FillYlmLegendAndData.hpp │ │ │ │ ├── ReadSurfaceYlm.cpp │ │ │ │ ├── ReadSurfaceYlm.hpp │ │ │ │ ├── StrahlkorperCoordsToTextFile.cpp │ │ │ │ ├── StrahlkorperCoordsToTextFile.hpp │ │ │ │ └── StrahlkorperFromFile.cpp │ │ │ ├── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Spherepack.cpp │ │ │ │ ├── Spherepack.hpp │ │ │ │ ├── Strahlkorper.cpp │ │ │ │ ├── Strahlkorper.hpp │ │ │ │ ├── StrahlkorperFunctions.cpp │ │ │ │ ├── StrahlkorperFunctions.hpp │ │ │ │ └── __init__.py │ │ │ ├── RealSphericalHarmonics.cpp │ │ │ ├── RealSphericalHarmonics.hpp │ │ │ ├── Spherepack.cpp │ │ │ ├── Spherepack.hpp │ │ │ ├── SpherepackCache.cpp │ │ │ ├── SpherepackCache.hpp │ │ │ ├── SpherepackHelper.cpp │ │ │ ├── SpherepackHelper.hpp │ │ │ ├── SpherepackIterator.cpp │ │ │ ├── SpherepackIterator.hpp │ │ │ ├── Strahlkorper.cpp │ │ │ ├── Strahlkorper.hpp │ │ │ ├── StrahlkorperFunctions.cpp │ │ │ ├── StrahlkorperFunctions.hpp │ │ │ ├── Tags.cpp │ │ │ ├── Tags.hpp │ │ │ ├── TagsDeclarations.hpp │ │ │ ├── TagsTypeAliases.hpp │ │ │ ├── TensorYlm.hpp │ │ │ ├── TensorYlmCartToSphere.cpp │ │ │ ├── TensorYlmCartToSphere.hpp │ │ │ ├── TensorYlmFilter.cpp │ │ │ ├── TensorYlmFilter.hpp │ │ │ ├── TensorYlmHelpers.cpp │ │ │ ├── TensorYlmHelpers.hpp │ │ │ ├── TensorYlmSphereToCart.cpp │ │ │ ├── TensorYlmSphereToCart.hpp │ │ │ ├── WignerThreeJ.cpp │ │ │ ├── WignerThreeJ.hpp │ │ │ ├── YlmToStf.cpp │ │ │ └── YlmToStf.hpp │ │ └── SpinWeightedSphericalHarmonics/ │ │ ├── CMakeLists.txt │ │ ├── ComplexDataView.cpp │ │ ├── ComplexDataView.hpp │ │ ├── SwshCoefficients.cpp │ │ ├── SwshCoefficients.hpp │ │ ├── SwshCollocation.cpp │ │ ├── SwshCollocation.hpp │ │ ├── SwshDerivatives.cpp │ │ ├── SwshDerivatives.hpp │ │ ├── SwshFiltering.cpp │ │ ├── SwshFiltering.hpp │ │ ├── SwshInterpolation.cpp │ │ ├── SwshInterpolation.hpp │ │ ├── SwshSettings.hpp │ │ ├── SwshTags.cpp │ │ ├── SwshTags.hpp │ │ ├── SwshTransform.cpp │ │ └── SwshTransform.hpp │ ├── Options/ │ │ ├── Auto.hpp │ │ ├── CMakeLists.txt │ │ ├── Comparator.cpp │ │ ├── Comparator.hpp │ │ ├── Context.cpp │ │ ├── Context.hpp │ │ ├── Factory.hpp │ │ ├── FactoryHelpers.hpp │ │ ├── Options.hpp │ │ ├── OptionsDetails.hpp │ │ ├── ParseError.hpp │ │ ├── ParseOptions.cpp │ │ ├── ParseOptions.hpp │ │ ├── Protocols/ │ │ │ ├── CMakeLists.txt │ │ │ └── FactoryCreation.hpp │ │ ├── StdComplex.hpp │ │ ├── String.hpp │ │ └── Tags.hpp │ ├── Parallel/ │ │ ├── AlgorithmExecution.hpp │ │ ├── AlgorithmMetafunctions.hpp │ │ ├── Algorithms/ │ │ │ ├── AlgorithmArray.ci │ │ │ ├── AlgorithmArray.hpp │ │ │ ├── AlgorithmArrayDeclarations.hpp │ │ │ ├── AlgorithmGroup.ci │ │ │ ├── AlgorithmGroup.hpp │ │ │ ├── AlgorithmGroupDeclarations.hpp │ │ │ ├── AlgorithmNodegroup.ci │ │ │ ├── AlgorithmNodegroup.hpp │ │ │ ├── AlgorithmNodegroupDeclarations.hpp │ │ │ ├── AlgorithmSingleton.ci │ │ │ ├── AlgorithmSingleton.hpp │ │ │ ├── AlgorithmSingletonDeclarations.hpp │ │ │ └── CMakeLists.txt │ │ ├── ArrayCollection/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CreateElementCollection.hpp │ │ │ ├── CreateElementsUsingDistribution.hpp │ │ │ ├── DgElementArrayMember.hpp │ │ │ ├── DgElementArrayMemberBase.cpp │ │ │ ├── DgElementArrayMemberBase.hpp │ │ │ ├── DgElementCollection.hpp │ │ │ ├── IsDgElementArrayMember.hpp │ │ │ ├── IsDgElementCollection.hpp │ │ │ ├── PerformAlgorithmOnElement.hpp │ │ │ ├── ReceiveDataForElement.hpp │ │ │ ├── SendDataToElement.hpp │ │ │ ├── SetTerminateOnElement.hpp │ │ │ ├── SimpleActionOnElement.hpp │ │ │ ├── SpawnInitializeElementsInCollection.hpp │ │ │ ├── StartPhaseOnNodegroup.hpp │ │ │ ├── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ElementCollection.hpp │ │ │ │ ├── ElementLocations.hpp │ │ │ │ ├── ElementLocationsReference.hpp │ │ │ │ └── NumberOfElementsTerminated.hpp │ │ │ └── TransformPdalForNodegroup.hpp │ │ ├── ArrayComponentId.cpp │ │ ├── ArrayComponentId.hpp │ │ ├── ArrayIndex.hpp │ │ ├── CMakeLists.txt │ │ ├── Callback.hpp │ │ ├── CharmMain.tpp │ │ ├── CharmRegistration.cpp │ │ ├── CharmRegistration.hpp │ │ ├── CreateFromOptions.hpp │ │ ├── DistributedObject.hpp │ │ ├── DomainDiagnosticInfo.hpp │ │ ├── ElementRegistration.hpp │ │ ├── ExitCode.cpp │ │ ├── ExitCode.hpp │ │ ├── FifoCache.hpp │ │ ├── GetSection.hpp │ │ ├── GlobalCache.ci │ │ ├── GlobalCache.hpp │ │ ├── GlobalCacheDeclare.hpp │ │ ├── InboxInserters.hpp │ │ ├── Info.hpp │ │ ├── InitializationFunctions.cpp │ │ ├── InitializationFunctions.hpp │ │ ├── InitializationTag.hpp │ │ ├── Invoke.hpp │ │ ├── Local.hpp │ │ ├── Main.ci │ │ ├── Main.cpp │ │ ├── Main.hpp │ │ ├── MaxInlineMethodsReached.hpp │ │ ├── MemoryMonitor/ │ │ │ ├── CMakeLists.txt │ │ │ ├── MemoryMonitor.hpp │ │ │ └── Tags.hpp │ │ ├── MultiReaderSpinlock.hpp │ │ ├── NodeLock.cpp │ │ ├── NodeLock.hpp │ │ ├── OutputInbox.hpp │ │ ├── ParallelComponentHelpers.hpp │ │ ├── Phase.cpp │ │ ├── Phase.hpp │ │ ├── PhaseControl/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CheckpointAndExitAfterWallclock.cpp │ │ │ ├── CheckpointAndExitAfterWallclock.hpp │ │ │ ├── ContributeToPhaseChangeReduction.hpp │ │ │ ├── ExecutePhaseChange.hpp │ │ │ ├── Factory.hpp │ │ │ ├── InitializePhaseChangeDecisionData.hpp │ │ │ ├── PhaseChange.hpp │ │ │ ├── PhaseControlTags.cpp │ │ │ ├── PhaseControlTags.hpp │ │ │ └── VisitAndReturn.hpp │ │ ├── PhaseControlReductionHelpers.hpp │ │ ├── PhaseDependentActionList.hpp │ │ ├── Printf/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Printf.ci │ │ │ ├── Printf.cpp │ │ │ └── Printf.hpp │ │ ├── Protocols/ │ │ │ ├── ArrayElementsAllocator.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── ElementRegistrar.hpp │ │ │ └── RegistrationMetavariables.hpp │ │ ├── Reduction.cpp │ │ ├── Reduction.hpp │ │ ├── ReductionDeclare.hpp │ │ ├── ResourceInfo.hpp │ │ ├── Section.hpp │ │ ├── Spinlock.hpp │ │ ├── StaticSpscQueue.hpp │ │ ├── Tags/ │ │ │ ├── ArrayIndex.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── DistributedObjectTags.hpp │ │ │ ├── InputSource.hpp │ │ │ ├── Parallelization.hpp │ │ │ ├── ResourceInfo.hpp │ │ │ └── Section.hpp │ │ └── TypeTraits.hpp │ ├── ParallelAlgorithms/ │ │ ├── Actions/ │ │ │ ├── Actions.hpp │ │ │ ├── AddComputeTags.hpp │ │ │ ├── AddSimpleTags.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── FilterAction.hpp │ │ │ ├── FunctionsOfTimeAreReady.hpp │ │ │ ├── GetItemFromDistributedObject.hpp │ │ │ ├── Goto.hpp │ │ │ ├── InitializeItems.hpp │ │ │ ├── LimiterActions.hpp │ │ │ ├── MemoryMonitor/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ContributeMemoryData.hpp │ │ │ │ ├── ProcessArray.hpp │ │ │ │ ├── ProcessGroups.hpp │ │ │ │ └── ProcessSingleton.hpp │ │ │ ├── MutateApply.hpp │ │ │ ├── RandomizeVariables.hpp │ │ │ ├── SetData.hpp │ │ │ ├── TerminatePhase.hpp │ │ │ └── UpdateMessageQueue.hpp │ │ ├── Amr/ │ │ │ ├── Actions/ │ │ │ │ ├── Actions.hpp │ │ │ │ ├── AdjustDomain.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CollectDataFromChildren.hpp │ │ │ │ ├── Component.hpp │ │ │ │ ├── CreateChild.hpp │ │ │ │ ├── CreateParent.hpp │ │ │ │ ├── ElementsRegistration.hpp │ │ │ │ ├── EvaluateRefinementCriteria.hpp │ │ │ │ ├── Initialization.hpp │ │ │ │ ├── Initialize.hpp │ │ │ │ ├── InitializeChild.hpp │ │ │ │ ├── InitializeParent.hpp │ │ │ │ ├── RegisterCallbacks.hpp │ │ │ │ ├── RunAmrDiagnostics.hpp │ │ │ │ ├── SendAmrDiagnostics.hpp │ │ │ │ ├── SendDataToChildren.hpp │ │ │ │ └── UpdateAmrDecision.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Criteria/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Constraints.cpp │ │ │ │ ├── Constraints.hpp │ │ │ │ ├── Criteria.hpp │ │ │ │ ├── Criterion.hpp │ │ │ │ ├── DriveToTarget.cpp │ │ │ │ ├── DriveToTarget.hpp │ │ │ │ ├── Factory.hpp │ │ │ │ ├── IncreaseResolution.cpp │ │ │ │ ├── IncreaseResolution.hpp │ │ │ │ ├── Loehner.cpp │ │ │ │ ├── Loehner.hpp │ │ │ │ ├── Persson.cpp │ │ │ │ ├── Persson.hpp │ │ │ │ ├── Random.cpp │ │ │ │ ├── Random.hpp │ │ │ │ ├── Tags/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Criteria.hpp │ │ │ │ │ └── Tags.hpp │ │ │ │ ├── TruncationError.cpp │ │ │ │ ├── TruncationError.hpp │ │ │ │ ├── Type.cpp │ │ │ │ └── Type.hpp │ │ │ ├── Events/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Events.hpp │ │ │ │ ├── ObserveAmrCriteria.hpp │ │ │ │ ├── ObserveAmrStats.cpp │ │ │ │ ├── ObserveAmrStats.hpp │ │ │ │ ├── RefineMesh.cpp │ │ │ │ └── RefineMesh.hpp │ │ │ ├── Policies/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── EnforcePolicies.cpp │ │ │ │ ├── EnforcePolicies.hpp │ │ │ │ ├── Isotropy.cpp │ │ │ │ ├── Isotropy.hpp │ │ │ │ ├── Limits.cpp │ │ │ │ ├── Limits.hpp │ │ │ │ ├── Policies.cpp │ │ │ │ ├── Policies.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── Projectors/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CopyFromCreatorOrLeaveAsIs.hpp │ │ │ │ ├── DefaultInitialize.hpp │ │ │ │ ├── Mesh.cpp │ │ │ │ ├── Mesh.hpp │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ ├── Tensors.hpp │ │ │ │ └── Variables.hpp │ │ │ ├── Protocols/ │ │ │ │ ├── AmrMetavariables.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── NamespaceDocs.hpp │ │ │ │ └── Projector.hpp │ │ │ ├── Tags.cpp │ │ │ └── Tags.hpp │ │ ├── ApparentHorizonFinder/ │ │ │ ├── ApparentHorizon.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Callbacks/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Callbacks.hpp │ │ │ │ ├── FailedHorizonFind.hpp │ │ │ │ ├── InvokeCallbacks.hpp │ │ │ │ ├── ObserveCenters.hpp │ │ │ │ ├── ObserveFieldsOnHorizon.hpp │ │ │ │ ├── ObserveTimeSeriesOnHorizon.hpp │ │ │ │ └── SendDependencyToObserverWriter.hpp │ │ │ ├── CleanUp.cpp │ │ │ ├── CleanUp.hpp │ │ │ ├── Component.hpp │ │ │ ├── ComputeCoords.cpp │ │ │ ├── ComputeCoords.hpp │ │ │ ├── ComputeVarsToInterpolateToTarget.cpp │ │ │ ├── ComputeVarsToInterpolateToTarget.hpp │ │ │ ├── Criteria/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Criteria.hpp │ │ │ │ ├── Criterion.hpp │ │ │ │ ├── Factory.hpp │ │ │ │ ├── IncreaseResolution.cpp │ │ │ │ ├── IncreaseResolution.hpp │ │ │ │ ├── Residual.cpp │ │ │ │ ├── Residual.hpp │ │ │ │ ├── Shape.cpp │ │ │ │ ├── Shape.hpp │ │ │ │ └── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Criteria.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── CurrentTime.cpp │ │ │ ├── CurrentTime.hpp │ │ │ ├── Destination.cpp │ │ │ ├── Destination.hpp │ │ │ ├── Events/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── FindApparentHorizon.hpp │ │ │ │ └── FindCommonHorizon.hpp │ │ │ ├── FastFlow.cpp │ │ │ ├── FastFlow.hpp │ │ │ ├── FindApparentHorizon.hpp │ │ │ ├── HorizonAliases.hpp │ │ │ ├── Initialization.hpp │ │ │ ├── InterpolateVolumeVars.cpp │ │ │ ├── InterpolateVolumeVars.hpp │ │ │ ├── OptionTags.cpp │ │ │ ├── OptionTags.hpp │ │ │ ├── PrintDeadlockAnalysis.hpp │ │ │ ├── Protocols/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Callback.hpp │ │ │ │ └── HorizonMetavars.hpp │ │ │ ├── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── __init__.py │ │ │ ├── Storage.cpp │ │ │ ├── Storage.hpp │ │ │ └── Tags.hpp │ │ ├── CMakeLists.txt │ │ ├── Events/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Completion.cpp │ │ │ ├── Completion.hpp │ │ │ ├── ErrorIfDataTooBig.hpp │ │ │ ├── Factory.hpp │ │ │ ├── MonitorMemory.hpp │ │ │ ├── ObserveAdaptiveSteppingDiagnostics.cpp │ │ │ ├── ObserveAdaptiveSteppingDiagnostics.hpp │ │ │ ├── ObserveAtExtremum.hpp │ │ │ ├── ObserveConstantsPerElement.cpp │ │ │ ├── ObserveConstantsPerElement.hpp │ │ │ ├── ObserveDataBox.cpp │ │ │ ├── ObserveDataBox.hpp │ │ │ ├── ObserveFields.hpp │ │ │ ├── ObserveNorms.cpp │ │ │ ├── ObserveNorms.hpp │ │ │ ├── ObserveTimeStep.cpp │ │ │ ├── ObserveTimeStep.hpp │ │ │ ├── ObserveTimeStep.tpp │ │ │ ├── ObserveTimeStepVolume.hpp │ │ │ ├── ObserveTimeStepVolume.tpp │ │ │ └── Tags.hpp │ │ ├── EventsAndDenseTriggers/ │ │ │ ├── CMakeLists.txt │ │ │ ├── DenseTrigger.hpp │ │ │ ├── DenseTriggers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── Filter.cpp │ │ │ │ ├── Filter.hpp │ │ │ │ ├── Or.cpp │ │ │ │ ├── Or.hpp │ │ │ │ ├── Times.cpp │ │ │ │ └── Times.hpp │ │ │ ├── EventsAndDenseTriggers.cpp │ │ │ ├── EventsAndDenseTriggers.hpp │ │ │ └── Tags.hpp │ │ ├── EventsAndTriggers/ │ │ │ ├── Actions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── RunEventsOnFailure.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Event.hpp │ │ │ ├── EventsAndTriggers.cpp │ │ │ ├── EventsAndTriggers.hpp │ │ │ ├── LogicalTriggers.cpp │ │ │ ├── LogicalTriggers.hpp │ │ │ ├── Tags.hpp │ │ │ ├── Trigger.hpp │ │ │ ├── WhenToCheck.cpp │ │ │ └── WhenToCheck.hpp │ │ ├── Initialization/ │ │ │ ├── CMakeLists.txt │ │ │ └── MutateAssign.hpp │ │ ├── Interpolation/ │ │ │ ├── Actions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ElementInitInterpPoints.hpp │ │ │ │ ├── ElementReceiveInterpPoints.hpp │ │ │ │ ├── InitializeInterpolationTarget.hpp │ │ │ │ ├── InterpolationTargetSendPoints.hpp │ │ │ │ ├── InterpolationTargetVarsFromElement.hpp │ │ │ │ └── PrintInterpolationTargetForDeadlock.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Callbacks/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Callbacks.hpp │ │ │ │ ├── ObserveLineSegment.hpp │ │ │ │ ├── ObserveSurfaceData.hpp │ │ │ │ └── ObserveTimeSeriesOnSurface.hpp │ │ │ ├── ComputeExcisionBoundaryVolumeQuantities.hpp │ │ │ ├── ComputeExcisionBoundaryVolumeQuantities.tpp │ │ │ ├── Events/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── GetComputeItemsOnSource.hpp │ │ │ │ └── InterpolateWithoutInterpComponent.hpp │ │ │ ├── InterpolationTarget.hpp │ │ │ ├── InterpolationTargetDetail.hpp │ │ │ ├── Intrp.hpp │ │ │ ├── IntrpOptionHolders.hpp │ │ │ ├── PointInfoTag.hpp │ │ │ ├── Protocols/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ComputeTargetPoints.hpp │ │ │ │ ├── ComputeVarsToInterpolate.hpp │ │ │ │ ├── InterpolationTargetTag.hpp │ │ │ │ ├── PostInterpolationCallback.hpp │ │ │ │ └── ProtocolsNamespace.hpp │ │ │ ├── Tags.hpp │ │ │ ├── TagsMetafunctions.hpp │ │ │ └── Targets/ │ │ │ ├── CMakeLists.txt │ │ │ ├── KerrHorizon.cpp │ │ │ ├── KerrHorizon.hpp │ │ │ ├── LineSegment.cpp │ │ │ ├── LineSegment.hpp │ │ │ ├── SpecifiedPoints.cpp │ │ │ ├── SpecifiedPoints.hpp │ │ │ ├── Sphere.cpp │ │ │ ├── Sphere.hpp │ │ │ ├── WedgeSectionTorus.cpp │ │ │ └── WedgeSectionTorus.hpp │ │ ├── LinearSolver/ │ │ │ ├── Actions/ │ │ │ │ ├── BuildMatrix.cpp │ │ │ │ ├── BuildMatrix.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── MakeIdentityIfSkipped.hpp │ │ │ ├── AsynchronousSolvers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── ElementActions.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── ConjugateGradient/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ConjugateGradient.hpp │ │ │ │ ├── ElementActions.hpp │ │ │ │ ├── InitializeElement.hpp │ │ │ │ ├── ResidualMonitor.hpp │ │ │ │ ├── ResidualMonitorActions.hpp │ │ │ │ └── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── InboxTags.hpp │ │ │ ├── Gmres/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ElementActions.hpp │ │ │ │ ├── Gmres.hpp │ │ │ │ ├── InitializeElement.hpp │ │ │ │ ├── ResidualMonitor.hpp │ │ │ │ ├── ResidualMonitorActions.hpp │ │ │ │ └── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── InboxTags.hpp │ │ │ ├── Multigrid/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── RestrictFields.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ElementActions.hpp │ │ │ │ ├── ElementsAllocator.hpp │ │ │ │ ├── Hierarchy.cpp │ │ │ │ ├── Hierarchy.hpp │ │ │ │ ├── Multigrid.hpp │ │ │ │ ├── ObserveVolumeData.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── Observe.hpp │ │ │ ├── Richardson/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Richardson.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── Schwarz/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── CommunicateOverlapFields.hpp │ │ │ │ │ └── ResetSubdomainSolver.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ComputeTags.hpp │ │ │ │ ├── ElementActions.hpp │ │ │ │ ├── ElementCenteredSubdomainData.hpp │ │ │ │ ├── ObserveVolumeData.hpp │ │ │ │ ├── OverlapHelpers.cpp │ │ │ │ ├── OverlapHelpers.hpp │ │ │ │ ├── Schwarz.hpp │ │ │ │ ├── SubdomainOperator.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── Weighting.cpp │ │ │ │ └── Weighting.hpp │ │ │ └── Tags.hpp │ │ ├── NonlinearSolver/ │ │ │ ├── CMakeLists.txt │ │ │ ├── NewtonRaphson/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ElementActions.hpp │ │ │ │ ├── LineSearch.cpp │ │ │ │ ├── LineSearch.hpp │ │ │ │ ├── NewtonRaphson.hpp │ │ │ │ ├── ResidualMonitor.hpp │ │ │ │ ├── ResidualMonitorActions.hpp │ │ │ │ └── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── InboxTags.hpp │ │ │ ├── Observe.hpp │ │ │ └── Tags.hpp │ │ ├── RayTracer/ │ │ │ ├── BackgroundSpacetimes/ │ │ │ │ ├── BackgroundSpacetime.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── NumericData.cpp │ │ │ │ ├── NumericData.hpp │ │ │ │ └── WrappedGr.hpp │ │ │ └── CMakeLists.txt │ │ └── SurfaceFinder/ │ │ ├── CMakeLists.txt │ │ ├── Python/ │ │ │ ├── Bindings.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── FindRadialSurface.py │ │ │ └── __init__.py │ │ ├── SurfaceFinder.cpp │ │ └── SurfaceFinder.hpp │ ├── PointwiseFunctions/ │ │ ├── AnalyticData/ │ │ │ ├── AnalyticData.hpp │ │ │ ├── Burgers/ │ │ │ │ ├── AnalyticData.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── Sinusoid.cpp │ │ │ │ └── Sinusoid.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CurvedWaveEquation/ │ │ │ │ ├── AnalyticData.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── PureSphericalHarmonic.cpp │ │ │ │ └── PureSphericalHarmonic.hpp │ │ │ ├── ForceFree/ │ │ │ │ ├── AnalyticData.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── FfeBreakdown.cpp │ │ │ │ ├── FfeBreakdown.hpp │ │ │ │ ├── MagnetosphericWald.cpp │ │ │ │ ├── MagnetosphericWald.hpp │ │ │ │ ├── RotatingDipole.cpp │ │ │ │ └── RotatingDipole.hpp │ │ │ ├── GeneralRelativity/ │ │ │ │ ├── AnalyticData.hpp │ │ │ │ ├── BrillLindquist.cpp │ │ │ │ ├── BrillLindquist.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── SpecInitialData.cpp │ │ │ │ └── SpecInitialData.hpp │ │ │ ├── GhGrMhd/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ └── InstantiateWrappedGr.cpp │ │ │ ├── GhScalarTensor/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ └── InstantiateWrappedGr.cpp │ │ │ ├── GrMhd/ │ │ │ │ ├── AnalyticData.hpp │ │ │ │ ├── BlastWave.cpp │ │ │ │ ├── BlastWave.hpp │ │ │ │ ├── BondiHoyleAccretion.cpp │ │ │ │ ├── BondiHoyleAccretion.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CcsnCollapse.cpp │ │ │ │ ├── CcsnCollapse.hpp │ │ │ │ ├── FukaInitialData.cpp │ │ │ │ ├── FukaInitialData.hpp │ │ │ │ ├── InitialMagneticFields/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ ├── InitialMagneticField.hpp │ │ │ │ │ ├── Poloidal.cpp │ │ │ │ │ ├── Poloidal.hpp │ │ │ │ │ ├── Toroidal.cpp │ │ │ │ │ └── Toroidal.hpp │ │ │ │ ├── KhInstability.cpp │ │ │ │ ├── KhInstability.hpp │ │ │ │ ├── MagneticFieldLoop.cpp │ │ │ │ ├── MagneticFieldLoop.hpp │ │ │ │ ├── MagneticRotor.cpp │ │ │ │ ├── MagneticRotor.hpp │ │ │ │ ├── MagnetizedFmDisk.cpp │ │ │ │ ├── MagnetizedFmDisk.hpp │ │ │ │ ├── MagnetizedTovStar.cpp │ │ │ │ ├── MagnetizedTovStar.hpp │ │ │ │ ├── OrszagTangVortex.cpp │ │ │ │ ├── OrszagTangVortex.hpp │ │ │ │ ├── PolarMagnetizedFmDisk.cpp │ │ │ │ ├── PolarMagnetizedFmDisk.hpp │ │ │ │ ├── RiemannProblem.cpp │ │ │ │ ├── RiemannProblem.hpp │ │ │ │ ├── SlabJet.cpp │ │ │ │ ├── SlabJet.hpp │ │ │ │ ├── SpecInitialData.cpp │ │ │ │ ├── SpecInitialData.hpp │ │ │ │ ├── SphericalTorus.cpp │ │ │ │ └── SphericalTorus.hpp │ │ │ ├── NewtonianEuler/ │ │ │ │ ├── AnalyticData.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── KhInstability.cpp │ │ │ │ ├── KhInstability.hpp │ │ │ │ ├── ShuOsherTube.cpp │ │ │ │ ├── ShuOsherTube.hpp │ │ │ │ ├── SodExplosion.cpp │ │ │ │ └── SodExplosion.hpp │ │ │ ├── Punctures/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── MultiplePunctures.cpp │ │ │ │ └── MultiplePunctures.hpp │ │ │ ├── RadiationTransport/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── M1Grey/ │ │ │ │ ├── AnalyticData.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── HomogeneousSphere.cpp │ │ │ │ └── HomogeneousSphere.hpp │ │ │ ├── ScalarTensor/ │ │ │ │ ├── AnalyticData.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── KerrSphericalHarmonic.cpp │ │ │ │ └── KerrSphericalHarmonic.hpp │ │ │ ├── Tags.hpp │ │ │ └── Xcts/ │ │ │ ├── AnalyticData.hpp │ │ │ ├── Binary.cpp │ │ │ ├── Binary.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CommonVariables.hpp │ │ │ └── CommonVariables.tpp │ │ ├── AnalyticSolutions/ │ │ │ ├── AnalyticSolution.hpp │ │ │ ├── Burgers/ │ │ │ │ ├── Bump.cpp │ │ │ │ ├── Bump.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── Linear.cpp │ │ │ │ ├── Linear.hpp │ │ │ │ ├── Solutions.hpp │ │ │ │ ├── Step.cpp │ │ │ │ └── Step.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Elasticity/ │ │ │ │ ├── BentBeam.cpp │ │ │ │ ├── BentBeam.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── HalfSpaceMirror.cpp │ │ │ │ ├── HalfSpaceMirror.hpp │ │ │ │ └── Zero.hpp │ │ │ ├── ForceFree/ │ │ │ │ ├── AlfvenWave.cpp │ │ │ │ ├── AlfvenWave.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ExactWald.cpp │ │ │ │ ├── ExactWald.hpp │ │ │ │ ├── Factory.hpp │ │ │ │ ├── FastWave.cpp │ │ │ │ ├── FastWave.hpp │ │ │ │ └── Solutions.hpp │ │ │ ├── GeneralRelativity/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── GaugePlaneWave.cpp │ │ │ │ ├── GaugePlaneWave.hpp │ │ │ │ ├── GaugeWave.cpp │ │ │ │ ├── GaugeWave.hpp │ │ │ │ ├── HarmonicSchwarzschild.cpp │ │ │ │ ├── HarmonicSchwarzschild.hpp │ │ │ │ ├── KerrSchild.cpp │ │ │ │ ├── KerrSchild.hpp │ │ │ │ ├── Minkowski.cpp │ │ │ │ ├── Minkowski.hpp │ │ │ │ ├── Python/ │ │ │ │ │ ├── Bindings.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── __init__.py │ │ │ │ ├── Solutions.hpp │ │ │ │ ├── SphericalKerrSchild.cpp │ │ │ │ ├── SphericalKerrSchild.hpp │ │ │ │ ├── TeukolskyWave.cpp │ │ │ │ ├── TeukolskyWave.hpp │ │ │ │ ├── TrumpetSchwarzschild.cpp │ │ │ │ ├── TrumpetSchwarzschild.hpp │ │ │ │ ├── WrappedGr.cpp │ │ │ │ ├── WrappedGr.hpp │ │ │ │ └── WrappedGr.tpp │ │ │ ├── GhGrMhd/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ └── InstantiateWrappedGr.cpp │ │ │ ├── GhRelativisticEuler/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ └── InstantiateWrappedGr.cpp │ │ │ ├── GrMhd/ │ │ │ │ ├── AlfvenWave.cpp │ │ │ │ ├── AlfvenWave.hpp │ │ │ │ ├── BondiMichel.cpp │ │ │ │ ├── BondiMichel.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── KomissarovShock.cpp │ │ │ │ ├── KomissarovShock.hpp │ │ │ │ ├── SmoothFlow.cpp │ │ │ │ ├── SmoothFlow.hpp │ │ │ │ └── Solutions.hpp │ │ │ ├── Hydro/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── SmoothFlow.cpp │ │ │ │ ├── SmoothFlow.hpp │ │ │ │ └── Solutions.hpp │ │ │ ├── NewtonianEuler/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── IsentropicVortex.cpp │ │ │ │ ├── IsentropicVortex.hpp │ │ │ │ ├── LaneEmdenStar.cpp │ │ │ │ ├── LaneEmdenStar.hpp │ │ │ │ ├── RiemannProblem.cpp │ │ │ │ ├── RiemannProblem.hpp │ │ │ │ ├── SmoothFlow.cpp │ │ │ │ ├── SmoothFlow.hpp │ │ │ │ └── Solutions.hpp │ │ │ ├── Poisson/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── Lorentzian.cpp │ │ │ │ ├── Lorentzian.hpp │ │ │ │ ├── MathFunction.cpp │ │ │ │ ├── MathFunction.hpp │ │ │ │ ├── Moustache.cpp │ │ │ │ ├── Moustache.hpp │ │ │ │ ├── ProductOfSinusoids.cpp │ │ │ │ ├── ProductOfSinusoids.hpp │ │ │ │ └── Zero.hpp │ │ │ ├── Punctures/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Flatness.cpp │ │ │ │ └── Flatness.hpp │ │ │ ├── RadiationTransport/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── M1Grey/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ConstantM1.cpp │ │ │ │ │ ├── ConstantM1.hpp │ │ │ │ │ ├── Factory.hpp │ │ │ │ │ └── Solutions.hpp │ │ │ │ └── MonteCarlo/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── HomogeneousSphere.cpp │ │ │ │ ├── HomogeneousSphere.hpp │ │ │ │ └── Solutions.hpp │ │ │ ├── RelativisticEuler/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── FishboneMoncriefDisk.cpp │ │ │ │ ├── FishboneMoncriefDisk.hpp │ │ │ │ ├── Python/ │ │ │ │ │ ├── Bindings.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Tov.cpp │ │ │ │ │ ├── Tov.hpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── RotatingStar.cpp │ │ │ │ ├── RotatingStar.hpp │ │ │ │ ├── SmoothFlow.cpp │ │ │ │ ├── SmoothFlow.hpp │ │ │ │ ├── Solutions.hpp │ │ │ │ ├── Tov.cpp │ │ │ │ ├── Tov.hpp │ │ │ │ ├── TovStar.cpp │ │ │ │ └── TovStar.hpp │ │ │ ├── ScalarAdvection/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── Krivodonova.cpp │ │ │ │ ├── Krivodonova.hpp │ │ │ │ ├── Kuzmin.cpp │ │ │ │ ├── Kuzmin.hpp │ │ │ │ ├── Sinusoid.cpp │ │ │ │ ├── Sinusoid.hpp │ │ │ │ └── Solutions.hpp │ │ │ ├── Tags.hpp │ │ │ ├── WaveEquation/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Factory.hpp │ │ │ │ ├── PlaneWave.cpp │ │ │ │ ├── PlaneWave.hpp │ │ │ │ ├── RegularSphericalWave.cpp │ │ │ │ ├── RegularSphericalWave.hpp │ │ │ │ ├── SemidiscretizedDg.cpp │ │ │ │ ├── SemidiscretizedDg.hpp │ │ │ │ └── Solutions.hpp │ │ │ └── Xcts/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CommonVariables.hpp │ │ │ ├── CommonVariables.tpp │ │ │ ├── ConstantDensityStar.cpp │ │ │ ├── ConstantDensityStar.hpp │ │ │ ├── Factory.hpp │ │ │ ├── Flatness.cpp │ │ │ ├── Flatness.hpp │ │ │ ├── Schwarzschild.cpp │ │ │ ├── Schwarzschild.hpp │ │ │ ├── TovStar.cpp │ │ │ ├── TovStar.hpp │ │ │ ├── WrappedGr.cpp │ │ │ └── WrappedGr.hpp │ │ ├── CMakeLists.txt │ │ ├── ConstraintDamping/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Constant.cpp │ │ │ ├── Constant.hpp │ │ │ ├── DampingFunction.hpp │ │ │ ├── GaussianPlusConstant.cpp │ │ │ ├── GaussianPlusConstant.hpp │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ ├── TimeDependentTripleGaussian.cpp │ │ │ └── TimeDependentTripleGaussian.hpp │ │ ├── Elasticity/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ConstitutiveRelations/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ConstitutiveRelation.hpp │ │ │ │ ├── CubicCrystal.cpp │ │ │ │ ├── CubicCrystal.hpp │ │ │ │ ├── Factory.hpp │ │ │ │ ├── IsotropicHomogeneous.cpp │ │ │ │ ├── IsotropicHomogeneous.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── PotentialEnergy.cpp │ │ │ ├── PotentialEnergy.hpp │ │ │ ├── Strain.cpp │ │ │ ├── Strain.hpp │ │ │ └── Stress.hpp │ │ ├── GeneralRelativity/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Christoffel.cpp │ │ │ ├── Christoffel.hpp │ │ │ ├── CubicCurvatureScalars.cpp │ │ │ ├── CubicCurvatureScalars.hpp │ │ │ ├── DerivativeSpatialMetric.cpp │ │ │ ├── DerivativeSpatialMetric.hpp │ │ │ ├── DerivativesOfSpacetimeMetric.cpp │ │ │ ├── DerivativesOfSpacetimeMetric.hpp │ │ │ ├── DetAndInverseSpatialMetric.hpp │ │ │ ├── ExtrinsicCurvature.cpp │ │ │ ├── ExtrinsicCurvature.hpp │ │ │ ├── GeneralizedHarmonic/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Christoffel.cpp │ │ │ │ ├── Christoffel.hpp │ │ │ │ ├── ConstraintDampingTags.hpp │ │ │ │ ├── ConstraintGammas.hpp │ │ │ │ ├── CovariantDerivOfExtrinsicCurvature.cpp │ │ │ │ ├── CovariantDerivOfExtrinsicCurvature.hpp │ │ │ │ ├── DerivSpatialMetric.cpp │ │ │ │ ├── DerivSpatialMetric.hpp │ │ │ │ ├── Expansion1D.cpp │ │ │ │ ├── Expansion1D.hpp │ │ │ │ ├── ExtrinsicCurvature.cpp │ │ │ │ ├── ExtrinsicCurvature.hpp │ │ │ │ ├── GaugeSource.cpp │ │ │ │ ├── GaugeSource.hpp │ │ │ │ ├── Phi.cpp │ │ │ │ ├── Phi.hpp │ │ │ │ ├── Pi.cpp │ │ │ │ ├── Pi.hpp │ │ │ │ ├── Python/ │ │ │ │ │ ├── Bindings.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── __init__.py │ │ │ │ ├── Ricci.cpp │ │ │ │ ├── Ricci.hpp │ │ │ │ ├── SecondTimeDerivOfSpacetimeMetric.cpp │ │ │ │ ├── SecondTimeDerivOfSpacetimeMetric.hpp │ │ │ │ ├── SpacetimeDerivOfDetSpatialMetric.cpp │ │ │ │ ├── SpacetimeDerivOfDetSpatialMetric.hpp │ │ │ │ ├── SpacetimeDerivOfNormOfShift.cpp │ │ │ │ ├── SpacetimeDerivOfNormOfShift.hpp │ │ │ │ ├── SpacetimeDerivativeOfSpacetimeMetric.cpp │ │ │ │ ├── SpacetimeDerivativeOfSpacetimeMetric.hpp │ │ │ │ ├── SpatialDerivOfLapse.cpp │ │ │ │ ├── SpatialDerivOfLapse.hpp │ │ │ │ ├── SpatialDerivOfShift.cpp │ │ │ │ ├── SpatialDerivOfShift.hpp │ │ │ │ ├── TimeDerivOfLapse.cpp │ │ │ │ ├── TimeDerivOfLapse.hpp │ │ │ │ ├── TimeDerivOfLowerShift.cpp │ │ │ │ ├── TimeDerivOfLowerShift.hpp │ │ │ │ ├── TimeDerivOfShift.cpp │ │ │ │ ├── TimeDerivOfShift.hpp │ │ │ │ ├── TimeDerivOfSpatialMetric.cpp │ │ │ │ ├── TimeDerivOfSpatialMetric.hpp │ │ │ │ ├── TimeDerivativeOfSpacetimeMetric.cpp │ │ │ │ └── TimeDerivativeOfSpacetimeMetric.hpp │ │ │ ├── GeodesicAcceleration.cpp │ │ │ ├── GeodesicAcceleration.hpp │ │ │ ├── GeodesicEquation.cpp │ │ │ ├── GeodesicEquation.hpp │ │ │ ├── InterfaceNullNormal.cpp │ │ │ ├── InterfaceNullNormal.hpp │ │ │ ├── InverseSpacetimeMetric.cpp │ │ │ ├── InverseSpacetimeMetric.hpp │ │ │ ├── KerrHorizon.cpp │ │ │ ├── KerrHorizon.hpp │ │ │ ├── KerrSchildCoords.cpp │ │ │ ├── KerrSchildCoords.hpp │ │ │ ├── Lapse.cpp │ │ │ ├── Lapse.hpp │ │ │ ├── ProjectionOperators.cpp │ │ │ ├── ProjectionOperators.hpp │ │ │ ├── Psi4.cpp │ │ │ ├── Psi4.hpp │ │ │ ├── Psi4Real.cpp │ │ │ ├── Psi4Real.hpp │ │ │ ├── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── __init__.py │ │ │ ├── QuadraticCurvatureScalars.cpp │ │ │ ├── QuadraticCurvatureScalars.hpp │ │ │ ├── Ricci.cpp │ │ │ ├── Ricci.hpp │ │ │ ├── Shift.cpp │ │ │ ├── Shift.hpp │ │ │ ├── SpacetimeDerivativeOfGothG.cpp │ │ │ ├── SpacetimeDerivativeOfGothG.hpp │ │ │ ├── SpacetimeMetric.cpp │ │ │ ├── SpacetimeMetric.hpp │ │ │ ├── SpacetimeNormalOneForm.cpp │ │ │ ├── SpacetimeNormalOneForm.hpp │ │ │ ├── SpacetimeNormalVector.cpp │ │ │ ├── SpacetimeNormalVector.hpp │ │ │ ├── SpatialMetric.cpp │ │ │ ├── SpatialMetric.hpp │ │ │ ├── Surfaces/ │ │ │ │ ├── AreaElement.cpp │ │ │ │ ├── AreaElement.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ComputeItems.hpp │ │ │ │ ├── Expansion.cpp │ │ │ │ ├── Expansion.hpp │ │ │ │ ├── ExtrinsicCurvature.cpp │ │ │ │ ├── ExtrinsicCurvature.hpp │ │ │ │ ├── GradUnitNormalOneForm.cpp │ │ │ │ ├── GradUnitNormalOneForm.hpp │ │ │ │ ├── InverseSurfaceMetric.cpp │ │ │ │ ├── InverseSurfaceMetric.hpp │ │ │ │ ├── Mass.cpp │ │ │ │ ├── Mass.hpp │ │ │ │ ├── Python/ │ │ │ │ │ ├── Bindings.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── __init__.py │ │ │ │ ├── RadialDistance.cpp │ │ │ │ ├── RadialDistance.hpp │ │ │ │ ├── RicciScalar.cpp │ │ │ │ ├── RicciScalar.hpp │ │ │ │ ├── Spin.cpp │ │ │ │ ├── Spin.hpp │ │ │ │ ├── SurfaceIntegralOfScalar.cpp │ │ │ │ ├── SurfaceIntegralOfScalar.hpp │ │ │ │ ├── SurfaceIntegralOfVector.cpp │ │ │ │ ├── SurfaceIntegralOfVector.hpp │ │ │ │ ├── Tags.hpp │ │ │ │ ├── TagsDeclarations.hpp │ │ │ │ ├── UnitNormalOneForm.cpp │ │ │ │ └── UnitNormalOneForm.hpp │ │ │ ├── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Conformal.hpp │ │ │ ├── Tags.hpp │ │ │ ├── TagsDeclarations.hpp │ │ │ ├── TimeDerivativeOfSpacetimeMetric.cpp │ │ │ ├── TimeDerivativeOfSpacetimeMetric.hpp │ │ │ ├── TimeDerivativeOfSpatialMetric.cpp │ │ │ ├── TimeDerivativeOfSpatialMetric.hpp │ │ │ ├── TortoiseCoordinates.cpp │ │ │ ├── TortoiseCoordinates.hpp │ │ │ ├── WeylElectric.cpp │ │ │ ├── WeylElectric.hpp │ │ │ ├── WeylMagnetic.cpp │ │ │ ├── WeylMagnetic.hpp │ │ │ ├── WeylPropagating.cpp │ │ │ ├── WeylPropagating.hpp │ │ │ ├── WeylTypeD1.cpp │ │ │ └── WeylTypeD1.hpp │ │ ├── Hydro/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ComovingMagneticField.cpp │ │ │ ├── ComovingMagneticField.hpp │ │ │ ├── EquationsOfState/ │ │ │ │ ├── Barotropic2D.cpp │ │ │ │ ├── Barotropic2D.hpp │ │ │ │ ├── Barotropic3D.cpp │ │ │ │ ├── Barotropic3D.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── DarkEnergyFluid.cpp │ │ │ │ ├── DarkEnergyFluid.hpp │ │ │ │ ├── Enthalpy.cpp │ │ │ │ ├── Enthalpy.hpp │ │ │ │ ├── EquationOfState.hpp │ │ │ │ ├── Equilibrium3D.cpp │ │ │ │ ├── Equilibrium3D.hpp │ │ │ │ ├── Factory.hpp │ │ │ │ ├── HybridEos.cpp │ │ │ │ ├── HybridEos.hpp │ │ │ │ ├── IdealFluid.cpp │ │ │ │ ├── IdealFluid.hpp │ │ │ │ ├── PiecewisePolytropicFluid.cpp │ │ │ │ ├── PiecewisePolytropicFluid.hpp │ │ │ │ ├── PolytropicFluid.cpp │ │ │ │ ├── PolytropicFluid.hpp │ │ │ │ ├── Python/ │ │ │ │ │ ├── Bindings.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Enthalpy.cpp │ │ │ │ │ ├── Enthalpy.hpp │ │ │ │ │ ├── EquationOfState.cpp │ │ │ │ │ ├── EquationOfState.hpp │ │ │ │ │ ├── PiecewisePolytropicFluid.cpp │ │ │ │ │ ├── PiecewisePolytropicFluid.hpp │ │ │ │ │ ├── PolytropicFluid.cpp │ │ │ │ │ ├── PolytropicFluid.hpp │ │ │ │ │ ├── Spectral.cpp │ │ │ │ │ ├── Spectral.hpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ │ ├── Spectral.cpp │ │ │ │ ├── Spectral.hpp │ │ │ │ ├── Tabulated3d.cpp │ │ │ │ └── Tabulated3d.hpp │ │ │ ├── InitialData/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── IrrotationalBns.cpp │ │ │ │ └── IrrotationalBns.hpp │ │ │ ├── InversePlasmaBeta.cpp │ │ │ ├── InversePlasmaBeta.hpp │ │ │ ├── LorentzFactor.cpp │ │ │ ├── LorentzFactor.hpp │ │ │ ├── LowerSpatialFourVelocity.cpp │ │ │ ├── LowerSpatialFourVelocity.hpp │ │ │ ├── MagneticFieldTreatment.cpp │ │ │ ├── MagneticFieldTreatment.hpp │ │ │ ├── MassFlux.cpp │ │ │ ├── MassFlux.hpp │ │ │ ├── MassWeightedFluidItems.cpp │ │ │ ├── MassWeightedFluidItems.hpp │ │ │ ├── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── __init__.py │ │ │ ├── QuadrupoleFormula.cpp │ │ │ ├── QuadrupoleFormula.hpp │ │ │ ├── SoundSpeedSquared.cpp │ │ │ ├── SoundSpeedSquared.hpp │ │ │ ├── SpecificEnthalpy.cpp │ │ │ ├── SpecificEnthalpy.hpp │ │ │ ├── StressEnergy.cpp │ │ │ ├── StressEnergy.hpp │ │ │ ├── Tags.hpp │ │ │ ├── TagsDeclarations.hpp │ │ │ ├── Temperature.hpp │ │ │ ├── TransportVelocity.cpp │ │ │ ├── TransportVelocity.hpp │ │ │ └── Units.hpp │ │ ├── InitialDataUtilities/ │ │ │ ├── AnalyticSolution.hpp │ │ │ ├── Background.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── InitialData.hpp │ │ │ ├── InitialGuess.hpp │ │ │ ├── NumericData.cpp │ │ │ ├── NumericData.hpp │ │ │ └── Tags/ │ │ │ ├── CMakeLists.txt │ │ │ └── InitialData.hpp │ │ ├── MathFunctions/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Factory.hpp │ │ │ ├── Gaussian.cpp │ │ │ ├── Gaussian.hpp │ │ │ ├── MathFunction.hpp │ │ │ ├── PowX.cpp │ │ │ ├── PowX.hpp │ │ │ ├── RegisterDerivedWithCharm.cpp │ │ │ ├── RegisterDerivedWithCharm.hpp │ │ │ ├── Sinusoid.cpp │ │ │ ├── Sinusoid.hpp │ │ │ ├── TensorProduct.cpp │ │ │ └── TensorProduct.hpp │ │ ├── Punctures/ │ │ │ ├── AdmIntegrals.cpp │ │ │ ├── AdmIntegrals.hpp │ │ │ ├── CMakeLists.txt │ │ │ └── Python/ │ │ │ ├── Bindings.cpp │ │ │ ├── CMakeLists.txt │ │ │ └── __init__.py │ │ ├── ScalarTensor/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ConstraintDampingTags.hpp │ │ │ ├── ConstraintGammas.hpp │ │ │ ├── RampUpFunction.cpp │ │ │ ├── RampUpFunction.hpp │ │ │ ├── ScalarCharge.cpp │ │ │ ├── ScalarCharge.hpp │ │ │ ├── ScalarGaussBonnet/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CouplingParameters.cpp │ │ │ │ ├── CouplingParameters.hpp │ │ │ │ ├── ScalarSource.cpp │ │ │ │ ├── ScalarSource.hpp │ │ │ │ └── Tags.hpp │ │ │ ├── ScalarSource.cpp │ │ │ ├── ScalarSource.hpp │ │ │ ├── SourceTags.hpp │ │ │ ├── StressEnergy.cpp │ │ │ ├── StressEnergy.hpp │ │ │ └── Xcts/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ScalarMomentum.cpp │ │ │ └── ScalarMomentum.hpp │ │ ├── SpecialRelativity/ │ │ │ ├── CMakeLists.txt │ │ │ ├── LorentzBoostMatrix.cpp │ │ │ └── LorentzBoostMatrix.hpp │ │ └── Xcts/ │ │ ├── AdmMass.cpp │ │ ├── AdmMass.hpp │ │ ├── AdmMomentum.cpp │ │ ├── AdmMomentum.hpp │ │ ├── CMakeLists.txt │ │ ├── CenterOfMass.cpp │ │ ├── CenterOfMass.hpp │ │ ├── ExtrinsicCurvature.cpp │ │ ├── ExtrinsicCurvature.hpp │ │ ├── LongitudinalOperator.cpp │ │ ├── LongitudinalOperator.hpp │ │ ├── SpacetimeQuantities.cpp │ │ └── SpacetimeQuantities.hpp │ ├── PythonBindings/ │ │ ├── BoundChecks.hpp │ │ ├── CMakeLists.txt │ │ ├── CharmCompatibility.cpp │ │ ├── FormalineCompatibility.cpp │ │ └── InfoAtLinkCompatibility.cpp │ ├── Time/ │ │ ├── Actions/ │ │ │ ├── CMakeLists.txt │ │ │ └── SelfStartActions.hpp │ │ ├── AdaptiveSteppingDiagnostics.cpp │ │ ├── AdaptiveSteppingDiagnostics.hpp │ │ ├── AdvanceTime.cpp │ │ ├── AdvanceTime.hpp │ │ ├── ApproximateTime.cpp │ │ ├── ApproximateTime.hpp │ │ ├── BoundaryHistory.hpp │ │ ├── BoundaryHistory.tpp │ │ ├── CMakeLists.txt │ │ ├── ChangeSlabSize/ │ │ │ ├── Action.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── ChangeSlabSize.hpp │ │ │ ├── Event.cpp │ │ │ ├── Event.hpp │ │ │ └── Tags.hpp │ │ ├── ChangeStepSize.hpp │ │ ├── ChangeTimeStepperOrder.hpp │ │ ├── ChangeTimeStepperOrder.tpp │ │ ├── ChooseLtsStepSize.cpp │ │ ├── ChooseLtsStepSize.hpp │ │ ├── CleanHistory.hpp │ │ ├── CleanHistory.tpp │ │ ├── EvolutionOrdering.hpp │ │ ├── History.cpp │ │ ├── History.hpp │ │ ├── LargestStepperError.cpp │ │ ├── LargestStepperError.hpp │ │ ├── OptionTags/ │ │ │ ├── CMakeLists.txt │ │ │ ├── InitialSlabSize.hpp │ │ │ ├── InitialTime.hpp │ │ │ ├── InitialTimeStep.hpp │ │ │ ├── LtsStepChoosers.hpp │ │ │ ├── MinimumTimeStep.hpp │ │ │ ├── TimeStepper.hpp │ │ │ └── VariableOrderAlgorithm.hpp │ │ ├── RecordTimeStepperData.hpp │ │ ├── RecordTimeStepperData.tpp │ │ ├── RequestsStepperErrorTolerances.hpp │ │ ├── SelfStart.cpp │ │ ├── SelfStart.hpp │ │ ├── Slab.cpp │ │ ├── Slab.hpp │ │ ├── SlabRoundingError.cpp │ │ ├── SlabRoundingError.hpp │ │ ├── StepChoosers/ │ │ │ ├── ByBlock.cpp │ │ │ ├── ByBlock.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Cfl.hpp │ │ │ ├── Constant.cpp │ │ │ ├── Constant.hpp │ │ │ ├── ElementSizeCfl.hpp │ │ │ ├── ErrorControl.hpp │ │ │ ├── Factory.hpp │ │ │ ├── FixedLtsRatio.cpp │ │ │ ├── FixedLtsRatio.hpp │ │ │ ├── LimitIncrease.cpp │ │ │ ├── LimitIncrease.hpp │ │ │ ├── Maximum.cpp │ │ │ ├── Maximum.hpp │ │ │ ├── PreventRapidIncrease.hpp │ │ │ ├── Random.cpp │ │ │ ├── Random.hpp │ │ │ ├── StepChooser.hpp │ │ │ ├── StepToTimes.cpp │ │ │ └── StepToTimes.hpp │ │ ├── StepperErrorEstimate.cpp │ │ ├── StepperErrorEstimate.hpp │ │ ├── StepperErrorTolerances.cpp │ │ ├── StepperErrorTolerances.hpp │ │ ├── Tags/ │ │ │ ├── AdaptiveSteppingDiagnostics.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── FixedLtsRatio.hpp │ │ │ ├── HistoryEvolvedVariables.hpp │ │ │ ├── LtsStepChoosers.hpp │ │ │ ├── MinimumTimeStep.hpp │ │ │ ├── StepNumberWithinSlab.hpp │ │ │ ├── StepperErrorEstimatesEnabled.hpp │ │ │ ├── StepperErrorTolerances.hpp │ │ │ ├── StepperErrorTolerancesCompute.cpp │ │ │ ├── StepperErrorTolerancesCompute.hpp │ │ │ ├── StepperErrors.hpp │ │ │ ├── Time.hpp │ │ │ ├── TimeAndPrevious.hpp │ │ │ ├── TimeStep.hpp │ │ │ ├── TimeStepId.hpp │ │ │ ├── TimeStepper.hpp │ │ │ └── VariableOrderAlgorithm.hpp │ │ ├── Time.cpp │ │ ├── Time.hpp │ │ ├── TimeSequence.cpp │ │ ├── TimeSequence.hpp │ │ ├── TimeStepId.cpp │ │ ├── TimeStepId.hpp │ │ ├── TimeStepRequest.cpp │ │ ├── TimeStepRequest.hpp │ │ ├── TimeStepRequestProcessor.cpp │ │ ├── TimeStepRequestProcessor.hpp │ │ ├── TimeSteppers/ │ │ │ ├── AdamsBashforth.cpp │ │ │ ├── AdamsBashforth.hpp │ │ │ ├── AdamsCoefficients.cpp │ │ │ ├── AdamsCoefficients.hpp │ │ │ ├── AdamsLts.cpp │ │ │ ├── AdamsLts.hpp │ │ │ ├── AdamsMoultonPc.cpp │ │ │ ├── AdamsMoultonPc.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── ClassicalRungeKutta4.cpp │ │ │ ├── ClassicalRungeKutta4.hpp │ │ │ ├── DormandPrince5.cpp │ │ │ ├── DormandPrince5.hpp │ │ │ ├── Factory.hpp │ │ │ ├── Heun2.cpp │ │ │ ├── Heun2.hpp │ │ │ ├── ImexRungeKutta.cpp │ │ │ ├── ImexRungeKutta.hpp │ │ │ ├── ImexTimeStepper.hpp │ │ │ ├── LtsTimeStepper.hpp │ │ │ ├── Rk3HesthavenSsp.cpp │ │ │ ├── Rk3HesthavenSsp.hpp │ │ │ ├── Rk3Kennedy.cpp │ │ │ ├── Rk3Kennedy.hpp │ │ │ ├── Rk3Owren.cpp │ │ │ ├── Rk3Owren.hpp │ │ │ ├── Rk3Pareschi.cpp │ │ │ ├── Rk3Pareschi.hpp │ │ │ ├── Rk4Kennedy.cpp │ │ │ ├── Rk4Kennedy.hpp │ │ │ ├── Rk4Owren.cpp │ │ │ ├── Rk4Owren.hpp │ │ │ ├── Rk5Owren.cpp │ │ │ ├── Rk5Owren.hpp │ │ │ ├── Rk5Tsitouras.cpp │ │ │ ├── Rk5Tsitouras.hpp │ │ │ ├── RungeKutta.cpp │ │ │ ├── RungeKutta.hpp │ │ │ ├── TimeStepper.cpp │ │ │ └── TimeStepper.hpp │ │ ├── Triggers/ │ │ │ ├── CMakeLists.txt │ │ │ ├── NearTimes.cpp │ │ │ ├── NearTimes.hpp │ │ │ ├── OnSubsteps.cpp │ │ │ ├── OnSubsteps.hpp │ │ │ ├── SlabCompares.cpp │ │ │ ├── SlabCompares.hpp │ │ │ ├── Slabs.cpp │ │ │ ├── Slabs.hpp │ │ │ ├── StepsWithinSlab.cpp │ │ │ ├── StepsWithinSlab.hpp │ │ │ ├── TimeCompares.cpp │ │ │ ├── TimeCompares.hpp │ │ │ ├── TimeTriggers.hpp │ │ │ ├── Times.cpp │ │ │ └── Times.hpp │ │ ├── UpdateU.hpp │ │ ├── UpdateU.tpp │ │ ├── VariableOrderAlgorithm.cpp │ │ └── VariableOrderAlgorithm.hpp │ ├── Utilities/ │ │ ├── Algorithm.hpp │ │ ├── Array.hpp │ │ ├── Autodiff/ │ │ │ ├── Autodiff.hpp │ │ │ └── CMakeLists.txt │ │ ├── Base64.cpp │ │ ├── Base64.hpp │ │ ├── Blas.cpp │ │ ├── Blas.hpp │ │ ├── BlazeExceptions.hpp │ │ ├── CMakeLists.txt │ │ ├── CachedFunction.hpp │ │ ├── CallWithDynamicType.hpp │ │ ├── CartesianProduct.hpp │ │ ├── CleanupRoutine.hpp │ │ ├── CloneUniquePtrs.hpp │ │ ├── ConstantExpressions.hpp │ │ ├── ContainerHelpers.hpp │ │ ├── ContainsAllocations.hpp │ │ ├── DereferenceWrapper.hpp │ │ ├── EqualWithinRoundoff.hpp │ │ ├── ErrorHandling/ │ │ │ ├── AbortWithErrorMessage.cpp │ │ │ ├── AbortWithErrorMessage.hpp │ │ │ ├── Assert.hpp │ │ │ ├── Breakpoint.cpp │ │ │ ├── Breakpoint.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CaptureForError.cpp │ │ │ ├── CaptureForError.hpp │ │ │ ├── Error.hpp │ │ │ ├── Exceptions.hpp │ │ │ ├── ExpectsAndEnsures.hpp │ │ │ ├── FloatingPointExceptions.cpp │ │ │ ├── FloatingPointExceptions.hpp │ │ │ ├── FormatStacktrace.cpp │ │ │ ├── FormatStacktrace.hpp │ │ │ ├── SegfaultHandler.cpp │ │ │ ├── SegfaultHandler.hpp │ │ │ ├── StaticAssert.hpp │ │ │ ├── Strerror.cpp │ │ │ ├── Strerror.hpp │ │ │ ├── StrerrorWrapper.c │ │ │ └── StrerrorWrapper.h │ │ ├── FileSystem.cpp │ │ ├── FileSystem.hpp │ │ ├── ForceInline.hpp │ │ ├── Formaline.cpp │ │ ├── Formaline.hpp │ │ ├── FractionUtilities.hpp │ │ ├── Functional.hpp │ │ ├── GenerateInstantiations.hpp │ │ ├── GetOutput.hpp │ │ ├── Gsl.hpp │ │ ├── Kokkos/ │ │ │ ├── CMakeLists.txt │ │ │ └── KokkosCore.hpp │ │ ├── Literals.hpp │ │ ├── MakeArray.hpp │ │ ├── MakeSignalingNan.hpp │ │ ├── MakeString.hpp │ │ ├── MakeVector.hpp │ │ ├── MakeWithValue.hpp │ │ ├── Math.hpp │ │ ├── MemoryHelpers.cpp │ │ ├── MemoryHelpers.hpp │ │ ├── NoSuchType.hpp │ │ ├── Numeric.hpp │ │ ├── OptimizerHacks.cpp │ │ ├── OptimizerHacks.hpp │ │ ├── OptionalHelpers.hpp │ │ ├── Overloader.hpp │ │ ├── PrettyType.cpp │ │ ├── PrettyType.hpp │ │ ├── PrintHelpers.hpp │ │ ├── ProtocolHelpers.hpp │ │ ├── Protocols/ │ │ │ ├── CMakeLists.txt │ │ │ └── StaticReturnApplyable.hpp │ │ ├── Rational.cpp │ │ ├── Rational.hpp │ │ ├── Registration.hpp │ │ ├── Requires.hpp │ │ ├── Serialization/ │ │ │ ├── CMakeLists.txt │ │ │ ├── CharmPupable.hpp │ │ │ ├── PupBoost.hpp │ │ │ ├── PupStlCpp11.hpp │ │ │ ├── PupStlCpp17.hpp │ │ │ ├── RegisterDerivedClassesWithCharm.hpp │ │ │ └── Serialize.hpp │ │ ├── SetNumberOfGridPoints.hpp │ │ ├── Simd/ │ │ │ ├── CMakeLists.txt │ │ │ └── Simd.hpp │ │ ├── SnakeCase.cpp │ │ ├── SnakeCase.hpp │ │ ├── Spherepack.hpp │ │ ├── SplitTuple.hpp │ │ ├── StaticCache.hpp │ │ ├── StdArrayHelpers.hpp │ │ ├── StdHelpers/ │ │ │ ├── Bit.hpp │ │ │ ├── CMakeLists.txt │ │ │ └── RetrieveUniquePtr.hpp │ │ ├── StdHelpers.hpp │ │ ├── StlBoilerplate.hpp │ │ ├── StlStreamDeclarations.hpp │ │ ├── System/ │ │ │ ├── Abort.cpp │ │ │ ├── Abort.hpp │ │ │ ├── AttachDebugger.cpp │ │ │ ├── AttachDebugger.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Exit.cpp │ │ │ ├── Exit.hpp │ │ │ ├── ParallelInfo.cpp │ │ │ ├── ParallelInfo.hpp │ │ │ ├── Prefetch.cpp │ │ │ ├── Prefetch.hpp │ │ │ └── System.hpp │ │ ├── TMPL.hpp │ │ ├── TmplDebugging.hpp │ │ ├── TmplDigraph.hpp │ │ ├── Tuple.hpp │ │ ├── TupleSlice.hpp │ │ ├── TypeTraits/ │ │ │ ├── ArraySize.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CanBeCopyConstructed.hpp │ │ │ ├── CreateGetStaticMemberVariableOrDefault.hpp │ │ │ ├── CreateGetTypeAliasOrDefault.hpp │ │ │ ├── CreateHasStaticMemberVariable.hpp │ │ │ ├── CreateHasTypeAlias.hpp │ │ │ ├── CreateIsCallable.hpp │ │ │ ├── FastPointerCast.hpp │ │ │ ├── FunctionInfo.hpp │ │ │ ├── GetFundamentalType.hpp │ │ │ ├── HasEquivalence.hpp │ │ │ ├── HasInequivalence.hpp │ │ │ ├── IsA.hpp │ │ │ ├── IsCallable.hpp │ │ │ ├── IsComplexOfFundamental.hpp │ │ │ ├── IsInteger.hpp │ │ │ ├── IsIterable.hpp │ │ │ ├── IsMaplike.hpp │ │ │ ├── IsStdArray.hpp │ │ │ ├── IsStdArrayOfSize.hpp │ │ │ ├── IsStreamable.hpp │ │ │ ├── RemoveReferenceWrapper.hpp │ │ │ └── TypeTraits.hpp │ │ ├── TypeTraits.hpp │ │ ├── UtcTime.cpp │ │ ├── UtcTime.hpp │ │ ├── VectorAlgebra.hpp │ │ ├── WrapText.cpp │ │ └── WrapText.hpp │ └── Visualization/ │ ├── CMakeLists.txt │ └── Python/ │ ├── CMakeLists.txt │ ├── ElementIdToParaview.py │ ├── GenerateTetrahedralConnectivity.py │ ├── GenerateXdmf.py │ ├── Plot.py │ ├── PlotAlongLine.py │ ├── PlotCce.py │ ├── PlotControlSystem.py │ ├── PlotDatFile.py │ ├── PlotEccentricityControl.py │ ├── PlotEllipticConvergence.py │ ├── PlotMemoryMonitors.py │ ├── PlotPowerMonitors.py │ ├── PlotSizeControl.py │ ├── PlotSlice.py │ ├── PlotTrajectories.py │ ├── ReadInputFile.py │ ├── Render1D.py │ ├── Render3D/ │ │ ├── Bbh.py │ │ ├── CMakeLists.txt │ │ ├── Clip.py │ │ ├── Domain.py │ │ └── __init__.py │ ├── __init__.py │ └── plots.mplstyle ├── support/ │ ├── CMakeLists.txt │ ├── Charm/ │ │ ├── v6.7.patch │ │ ├── v6.8.patch │ │ ├── v7.0.0.patch │ │ └── v7.0.1.patch │ ├── DevEnvironments/ │ │ └── spack.yaml │ ├── Environments/ │ │ ├── anvil_gcc.sh │ │ ├── caltech_hpc_gcc.sh │ │ ├── expanse_gcc.sh │ │ ├── frontera_gcc.sh │ │ ├── mbot.sh │ │ ├── ocean2.sh │ │ ├── ocean2_orca1.sh │ │ ├── ocean_gcc.sh │ │ ├── oscar.sh │ │ ├── perlmutter.sh │ │ ├── setup/ │ │ │ ├── anvil_gcc.sh │ │ │ ├── expanse_gcc.sh │ │ │ ├── frontera_gcc.sh │ │ │ └── mbot_install.sh │ │ ├── sonic.sh │ │ ├── urania.sh │ │ └── viper.sh │ ├── Machines/ │ │ ├── CaltechHpc.yaml │ │ ├── Mbot.yaml │ │ ├── Ocean2.yaml │ │ ├── Ocean2_orca1.yaml │ │ ├── Oscar.yaml │ │ ├── Perlmutter.yaml │ │ ├── Sonic.yaml │ │ ├── Urania.yaml │ │ └── Viper.yaml │ ├── Pipelines/ │ │ ├── Bbh/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ControlId.py │ │ │ ├── EccentricityControl.py │ │ │ ├── FindHorizon.py │ │ │ ├── InitialData.py │ │ │ ├── InitialData.yaml │ │ │ ├── Inspiral.py │ │ │ ├── Inspiral.yaml │ │ │ ├── PostprocessId.py │ │ │ ├── Ringdown.py │ │ │ ├── Ringdown.yaml │ │ │ └── __init__.py │ │ ├── Bns/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ComputeTrajectories.py │ │ │ └── __init__.py │ │ ├── CMakeLists.txt │ │ └── EccentricityControl/ │ │ ├── CMakeLists.txt │ │ ├── EccentricityControlParams.py │ │ ├── InitialOrbitalParameters.py │ │ └── __init__.py │ ├── Profiling/ │ │ └── ScoreP/ │ │ └── spectre.flt │ ├── Python/ │ │ ├── CMakeLists.txt │ │ ├── CheckSpecImport.py │ │ ├── CliExceptions.py │ │ ├── DirectoryStructure.py │ │ ├── Logging.py │ │ ├── Machines.py │ │ ├── Resubmit.py │ │ ├── RunNext.py │ │ ├── Schedule.py │ │ ├── Yaml.py │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── dev_requirements.txt │ │ ├── requirements.txt │ │ ├── shell-completion.bash │ │ ├── shell-completion.fish │ │ └── shell-completion.zsh │ ├── SubmitScripts/ │ │ ├── Anvil.sh │ │ ├── CaltechHpc.sh │ │ ├── Expanse.sh │ │ ├── Frontera.sh │ │ ├── Mbot.sh │ │ ├── Ocean2.sh │ │ ├── Ocean2_orca1.sh │ │ ├── Oscar.sh │ │ ├── Perlmutter.sh │ │ ├── Sonic.sh │ │ ├── SubmitTemplateBase.sh │ │ ├── Urania.sh │ │ └── Viper.sh │ └── TeXLive/ │ └── texlive.profile ├── tests/ │ ├── CMakeLists.txt │ ├── InputFiles/ │ │ ├── Burgers/ │ │ │ └── Step.yaml │ │ ├── Cce/ │ │ │ ├── AnalyticTestBouncingBlackHole.yaml │ │ │ ├── AnalyticTestGaugeWave.yaml │ │ │ ├── AnalyticTestLinearizedBondiSachs.yaml │ │ │ ├── AnalyticTestRobinsonTrautman.yaml │ │ │ ├── AnalyticTestRotatingSchwarzschild.yaml │ │ │ ├── AnalyticTestTeukolskyWave.yaml │ │ │ ├── AnalyticTestVolumeNewmanPenroseSpinCoefficients.yaml │ │ │ ├── AnalyticTestVolumeNewmanPenroseSpinCoefficientsRhoGammaMu.py │ │ │ ├── AnalyticTestVolumeUtils.py │ │ │ ├── AnalyticTestVolumeWeylPsi2.py │ │ │ ├── AnalyticTestVolumeWeylScalars.yaml │ │ │ ├── CharacteristicExtract.yaml │ │ │ └── KleinGordonCharacteristicExtract.yaml │ │ ├── CurvedScalarWave/ │ │ │ ├── PlaneWaveMinkowski1D.yaml │ │ │ ├── PlaneWaveMinkowski2D.yaml │ │ │ ├── PlaneWaveMinkowski3D.yaml │ │ │ └── WorldtubeKerrSchild.yaml │ │ ├── Elasticity/ │ │ │ ├── BentBeam.yaml │ │ │ ├── HalfSpaceMirror.yaml │ │ │ └── SingleCoatingMirror.yaml │ │ ├── ExampleExecutables/ │ │ │ ├── HelloWorldNoCharm.yaml │ │ │ ├── PiMonteCarlo.yaml │ │ │ ├── RandomAmr1D.yaml │ │ │ ├── RandomAmrKeepCoarseGrids1D.yaml │ │ │ └── SingletonHelloWorld.yaml │ │ ├── ExportCoordinates/ │ │ │ ├── Input1D.yaml │ │ │ ├── Input2D.yaml │ │ │ ├── Input3D.yaml │ │ │ └── InputTimeDependent3D.yaml │ │ ├── ExportEquationOfStateForRotNS/ │ │ │ └── ExportEosForRotNS.yaml │ │ ├── ForceFree/ │ │ │ └── FastWave.yaml │ │ ├── GeneralizedHarmonic/ │ │ │ ├── CylindricalBinaryBlackHole.yaml │ │ │ ├── GaugeWave1D.yaml │ │ │ ├── GaugeWave3D.yaml │ │ │ └── KerrSchild.yaml │ │ ├── GrMhd/ │ │ │ ├── GhValenciaDivClean/ │ │ │ │ ├── BinaryNeutronStar.yaml │ │ │ │ ├── CoreCollapseSupernova.yaml │ │ │ │ ├── EvolutionParameters.perl │ │ │ │ ├── GhMhdBondiMichel.yaml │ │ │ │ └── GhMhdTovStar.yaml │ │ │ └── ValenciaDivClean/ │ │ │ ├── BlastWave.yaml │ │ │ └── FishboneMoncriefDisk.yaml │ │ ├── NewtonianEuler/ │ │ │ ├── RiemannProblem1D.yaml │ │ │ ├── RiemannProblem2D.yaml │ │ │ └── RiemannProblem3D.yaml │ │ ├── Poisson/ │ │ │ ├── Lorentzian.yaml │ │ │ ├── ProductOfSinusoids1D.yaml │ │ │ ├── ProductOfSinusoids2D.yaml │ │ │ └── ProductOfSinusoids3D.yaml │ │ ├── PreprocessCceWorldtube/ │ │ │ ├── AdmFirstOrderDriverPreprocessCceWorldtube.yaml │ │ │ ├── AdmSecondOrderDriverPreprocessCceWorldtube.yaml │ │ │ └── PreprocessCceWorldtube.yaml │ │ ├── Punctures/ │ │ │ └── MultiplePunctures.yaml │ │ ├── RadiationTransport/ │ │ │ └── M1Grey/ │ │ │ └── ConstantM1.yaml │ │ ├── ScalarAdvection/ │ │ │ ├── Krivodonova1D.yaml │ │ │ ├── Kuzmin2D.yaml │ │ │ └── Sinusoid1D.yaml │ │ ├── ScalarTensor/ │ │ │ └── KerrSchildSphericalHarmonic.yaml │ │ ├── ScalarWave/ │ │ │ ├── PlaneWave1D.yaml │ │ │ ├── PlaneWave1DEventsAndTriggersExample.yaml │ │ │ ├── PlaneWave1DObserveExample.yaml │ │ │ ├── PlaneWave2D.overlay_0000.yaml │ │ │ ├── PlaneWave2D.yaml │ │ │ ├── PlaneWave3D.yaml │ │ │ └── PlaneWave3DCartoonSphere.yaml │ │ ├── SelfForce/ │ │ │ ├── GrCircularOrbit.yaml │ │ │ └── ScalarCircularOrbit.yaml │ │ └── Xcts/ │ │ ├── BinaryBlackHole.yaml │ │ ├── HeadOnBns.yaml │ │ ├── KerrSchild.yaml │ │ └── TovStar.yaml │ ├── Unit/ │ │ ├── ArchitectureVectorization/ │ │ │ └── CMakeLists.txt │ │ ├── CMakeLists.txt │ │ ├── ControlSystem/ │ │ │ ├── Actions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_GridCenters.cpp │ │ │ │ ├── Test_Initialization.cpp │ │ │ │ ├── Test_InitializeMeasurements.cpp │ │ │ │ └── Test_LimitTimeStep.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── ControlErrors/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ComovingCharSpeedDerivative.py │ │ │ │ ├── Test_ComovingCharSpeedDerivative.cpp │ │ │ │ ├── Test_Expansion.cpp │ │ │ │ ├── Test_GridCenters.cpp │ │ │ │ ├── Test_Rotation.cpp │ │ │ │ ├── Test_Shape.cpp │ │ │ │ ├── Test_SizeControlStates.cpp │ │ │ │ ├── Test_SizeError.cpp │ │ │ │ ├── Test_Skew.cpp │ │ │ │ ├── Test_StateHistory.cpp │ │ │ │ └── Test_Translation.cpp │ │ │ ├── Protocols/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_Protocols.cpp │ │ │ ├── Systems/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_Expansion.cpp │ │ │ │ ├── Test_GridCenters.cpp │ │ │ │ ├── Test_RotScaleTrans.cpp │ │ │ │ ├── Test_Rotation.cpp │ │ │ │ ├── Test_Shape.cpp │ │ │ │ ├── Test_Size.cpp │ │ │ │ ├── Test_Skew.cpp │ │ │ │ └── Test_Translation.cpp │ │ │ ├── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_FunctionsOfTimeInitialize.cpp │ │ │ │ ├── Test_FutureMeasurements.cpp │ │ │ │ └── Test_MeasurementTimescales.cpp │ │ │ ├── Test_Averager.cpp │ │ │ ├── Test_CleanFunctionsOfTime.cpp │ │ │ ├── Test_CombinedName.cpp │ │ │ ├── Test_Controller.cpp │ │ │ ├── Test_EventTriggerMetafunctions.cpp │ │ │ ├── Test_ExpirationTimes.cpp │ │ │ ├── Test_FutureMeasurements.cpp │ │ │ ├── Test_IsSize.cpp │ │ │ ├── Test_Measurements.cpp │ │ │ ├── Test_Metafunctions.cpp │ │ │ ├── Test_RunCallbacks.cpp │ │ │ ├── Test_Tags.cpp │ │ │ ├── Test_TimescaleTuner.cpp │ │ │ ├── Test_Trigger.cpp │ │ │ ├── Test_UpdateFunctionOfTime.cpp │ │ │ └── Test_WriteData.cpp │ │ ├── DataStructures/ │ │ │ ├── CMakeLists.txt │ │ │ ├── DataBox/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_DataBox.cpp │ │ │ │ ├── Test_DataBoxDocumentation.cpp │ │ │ │ ├── Test_DataBoxPrefixes.cpp │ │ │ │ ├── Test_MetavariablesTag.cpp │ │ │ │ ├── Test_ObservationBox.cpp │ │ │ │ ├── Test_PrefixHelpers.cpp │ │ │ │ ├── Test_Protocols.cpp │ │ │ │ ├── Test_TagName.cpp │ │ │ │ ├── Test_TagTraits.cpp │ │ │ │ ├── Test_TestHelpers.cpp │ │ │ │ └── Test_ValidateSelection.cpp │ │ │ ├── Tensor/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── EagerMath/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── CrossProduct.py │ │ │ │ │ ├── FrameTransform.py │ │ │ │ │ ├── Python/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_EagerMath.py │ │ │ │ │ ├── RaiseOrLowerIndex.py │ │ │ │ │ ├── Test_CartesianToSpherical.cpp │ │ │ │ │ ├── Test_CrossProduct.cpp │ │ │ │ │ ├── Test_Determinant.cpp │ │ │ │ │ ├── Test_DeterminantAndInverse.cpp │ │ │ │ │ ├── Test_DotProduct.cpp │ │ │ │ │ ├── Test_FrameTransform.cpp │ │ │ │ │ ├── Test_GramSchmidtOrthonormalize.cpp │ │ │ │ │ ├── Test_Magnitude.cpp │ │ │ │ │ ├── Test_Norms.cpp │ │ │ │ │ ├── Test_OrthonormalOneform.cpp │ │ │ │ │ ├── Test_OuterProduct.cpp │ │ │ │ │ ├── Test_RaiseOrLowerIndex.cpp │ │ │ │ │ ├── Test_Trace.cpp │ │ │ │ │ └── Trace.py │ │ │ │ ├── Expressions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_AddSubSymmetry.cpp │ │ │ │ │ ├── Test_AddSubtract.cpp │ │ │ │ │ ├── Test_Contract.cpp │ │ │ │ │ ├── Test_DataTypeSupport.cpp │ │ │ │ │ ├── Test_Divide.cpp │ │ │ │ │ ├── Test_Evaluate.cpp │ │ │ │ │ ├── Test_EvaluateComplex.cpp │ │ │ │ │ ├── Test_EvaluateRank3NonSymmetric.cpp │ │ │ │ │ ├── Test_EvaluateRank3Symmetric.cpp │ │ │ │ │ ├── Test_EvaluateRank4.cpp │ │ │ │ │ ├── Test_EvaluateSpatialAndTimeSpacetimeIndex.cpp │ │ │ │ │ ├── Test_EvaluateSpatialSpacetimeIndex.cpp │ │ │ │ │ ├── Test_EvaluateTimeIndex.cpp │ │ │ │ │ ├── Test_Examples.cpp │ │ │ │ │ ├── Test_MixedOperations.cpp │ │ │ │ │ ├── Test_Negate.cpp │ │ │ │ │ ├── Test_Product.cpp │ │ │ │ │ ├── Test_ProductHighRankIntermediate.cpp │ │ │ │ │ ├── Test_SpatialSpacetimeIndex.cpp │ │ │ │ │ ├── Test_SquareRoot.cpp │ │ │ │ │ ├── Test_TensorIndex.cpp │ │ │ │ │ ├── Test_TensorIndexTransformation.cpp │ │ │ │ │ └── Test_TimeIndex.cpp │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_Tensor.py │ │ │ │ ├── Test_CombineSpacetimeView.cpp │ │ │ │ ├── Test_ContractFirstNIndices.cpp │ │ │ │ ├── Test_Identity.cpp │ │ │ │ ├── Test_Metafunctions.cpp │ │ │ │ ├── Test_Slice.cpp │ │ │ │ ├── Test_Tensor.cpp │ │ │ │ └── Test_TensorKokkos.cpp │ │ │ ├── Test_ApplyMatrices.cpp │ │ │ ├── Test_BlazeInteroperability.cpp │ │ │ ├── Test_CachedTempBuffer.cpp │ │ │ ├── Test_ComplexDataVector.cpp │ │ │ ├── Test_ComplexDataVectorBinaryOperations.cpp │ │ │ ├── Test_ComplexDiagonalModalOperator.cpp │ │ │ ├── Test_ComplexModalVector.cpp │ │ │ ├── Test_ComplexModalVectorInhomogeneousOperations.cpp │ │ │ ├── Test_DataVector.cpp │ │ │ ├── Test_DataVector.py │ │ │ ├── Test_DataVectorBinaryOperations.cpp │ │ │ ├── Test_DiagonalModalOperator.cpp │ │ │ ├── Test_DynamicBuffer.cpp │ │ │ ├── Test_ExtractPoint.cpp │ │ │ ├── Test_FixedHashMap.cpp │ │ │ ├── Test_FloatingPointType.cpp │ │ │ ├── Test_IdPair.cpp │ │ │ ├── Test_Index.cpp │ │ │ ├── Test_IndexIterator.cpp │ │ │ ├── Test_LeviCivitaIterator.cpp │ │ │ ├── Test_LinkedMessageId.cpp │ │ │ ├── Test_LinkedMessageQueue.cpp │ │ │ ├── Test_MathWrapper.cpp │ │ │ ├── Test_Matrix.py │ │ │ ├── Test_ModalVector.cpp │ │ │ ├── Test_ModalVector.py │ │ │ ├── Test_ModalVectorInhomogeneousOperations.cpp │ │ │ ├── Test_MoreComplexDiagonalModalOperatorMath.cpp │ │ │ ├── Test_MoreDiagonalModalOperatorMath.cpp │ │ │ ├── Test_NonZeroStaticSizeVector.cpp │ │ │ ├── Test_SimpleSparseMatrix.cpp │ │ │ ├── Test_SliceIterator.cpp │ │ │ ├── Test_SliceTensorToVariables.cpp │ │ │ ├── Test_SliceVariables.cpp │ │ │ ├── Test_SparseMatrixFiller.cpp │ │ │ ├── Test_SpinWeighted.cpp │ │ │ ├── Test_StaticDeque.cpp │ │ │ ├── Test_StripeIterator.cpp │ │ │ ├── Test_TaggedContainers.cpp │ │ │ ├── Test_TaggedTuple.cpp │ │ │ ├── Test_TaggedVariant.cpp │ │ │ ├── Test_Tags.cpp │ │ │ ├── Test_TempBuffer.cpp │ │ │ ├── Test_Transpose.cpp │ │ │ ├── Test_Variables.cpp │ │ │ ├── Test_VectorImpl.cpp │ │ │ └── Test_VectorImplTestHelper.cpp │ │ ├── Domain/ │ │ │ ├── Amr/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_Flag.cpp │ │ │ │ ├── Test_Helpers.cpp │ │ │ │ ├── Test_Info.cpp │ │ │ │ ├── Test_NeighborsOfChild.cpp │ │ │ │ ├── Test_NeighborsOfParent.cpp │ │ │ │ ├── Test_NewNeighborIds.cpp │ │ │ │ ├── Test_Tags.cpp │ │ │ │ └── Test_UpdateAmrDecision.cpp │ │ │ ├── BoundaryConditions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_BoundaryCondition.cpp │ │ │ │ ├── Test_GenericBcs.cpp │ │ │ │ └── Test_GetBoundaryConditionsBase.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CoordinateMaps/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_Composition.py │ │ │ │ ├── Test_Affine.cpp │ │ │ │ ├── Test_BulgedCube.cpp │ │ │ │ ├── Test_Composition.cpp │ │ │ │ ├── Test_CoordinateMap.cpp │ │ │ │ ├── Test_CylindricalEndcap.cpp │ │ │ │ ├── Test_CylindricalFlatEndcap.cpp │ │ │ │ ├── Test_CylindricalFlatSide.cpp │ │ │ │ ├── Test_CylindricalSide.cpp │ │ │ │ ├── Test_DiscreteRotation.cpp │ │ │ │ ├── Test_Distribution.cpp │ │ │ │ ├── Test_EquatorialCompression.cpp │ │ │ │ ├── Test_Equiangular.cpp │ │ │ │ ├── Test_FlatOffsetSphericalWedge.cpp │ │ │ │ ├── Test_FlatOffsetWedge.cpp │ │ │ │ ├── Test_Frustum.cpp │ │ │ │ ├── Test_Identity.cpp │ │ │ │ ├── Test_Interval.cpp │ │ │ │ ├── Test_KerrHorizonConforming.cpp │ │ │ │ ├── Test_PolarToCartesian.cpp │ │ │ │ ├── Test_ProductMaps.cpp │ │ │ │ ├── Test_Rotation.cpp │ │ │ │ ├── Test_SpecialMobius.cpp │ │ │ │ ├── Test_SphericalToCartesianPfaffian.cpp │ │ │ │ ├── Test_Tags.cpp │ │ │ │ ├── Test_TimeDependentHelpers.cpp │ │ │ │ ├── Test_UniformCylindricalEndcap.cpp │ │ │ │ ├── Test_UniformCylindricalFlatEndcap.cpp │ │ │ │ ├── Test_UniformCylindricalSide.cpp │ │ │ │ ├── Test_Wedge2D.cpp │ │ │ │ ├── Test_Wedge3D.cpp │ │ │ │ └── TimeDependent/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ShapeMapTransitionFunctions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_SphereTransition.cpp │ │ │ │ │ └── Test_Wedge.cpp │ │ │ │ ├── Test_CubicScale.cpp │ │ │ │ ├── Test_ProductMaps.cpp │ │ │ │ ├── Test_RotScaleTrans.cpp │ │ │ │ ├── Test_Rotation.cpp │ │ │ │ ├── Test_RotationMatrixHelpers.cpp │ │ │ │ ├── Test_Shape.cpp │ │ │ │ ├── Test_Skew.cpp │ │ │ │ ├── Test_SphericalCompression.cpp │ │ │ │ └── Test_Translation.cpp │ │ │ ├── Creators/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_BinaryCompactObject.py │ │ │ │ │ ├── Test_Brick.py │ │ │ │ │ ├── Test_Cylinder.py │ │ │ │ │ ├── Test_Interval.py │ │ │ │ │ ├── Test_Rectangle.py │ │ │ │ │ └── Test_Sphere.py │ │ │ │ ├── Test_AlignedLattice.cpp │ │ │ │ ├── Test_AngularCylinder.cpp │ │ │ │ ├── Test_AngularDisk.cpp │ │ │ │ ├── Test_BinaryCompactObject.cpp │ │ │ │ ├── Test_Brick.cpp │ │ │ │ ├── Test_CartoonCylinder.cpp │ │ │ │ ├── Test_CartoonSphere1D.cpp │ │ │ │ ├── Test_CartoonSphere2D.cpp │ │ │ │ ├── Test_Cylinder.cpp │ │ │ │ ├── Test_CylindricalBinaryCompactObject.cpp │ │ │ │ ├── Test_Disk.cpp │ │ │ │ ├── Test_ExpandOverBlocks.cpp │ │ │ │ ├── Test_FrustalCloak.cpp │ │ │ │ ├── Test_Interval.cpp │ │ │ │ ├── Test_NonconformingSphericalShells.cpp │ │ │ │ ├── Test_Rectangle.cpp │ │ │ │ ├── Test_RotatedBricks.cpp │ │ │ │ ├── Test_RotatedIntervals.cpp │ │ │ │ ├── Test_RotatedRectangles.cpp │ │ │ │ ├── Test_Sphere.cpp │ │ │ │ ├── Test_SphericalShells.cpp │ │ │ │ ├── Test_Tags.cpp │ │ │ │ ├── TimeDependence/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_CubicScale.cpp │ │ │ │ │ ├── Test_None.cpp │ │ │ │ │ ├── Test_RotationAboutZAxis.cpp │ │ │ │ │ ├── Test_ScalingAndZRotation.cpp │ │ │ │ │ ├── Test_Shape.cpp │ │ │ │ │ ├── Test_SphericalCompression.cpp │ │ │ │ │ └── Test_UniformTranslation.cpp │ │ │ │ └── TimeDependentOptions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_BinaryCompactObject.py │ │ │ │ │ ├── Test_ExpansionMap.py │ │ │ │ │ ├── Test_GridCenters.py │ │ │ │ │ ├── Test_RotationMap.py │ │ │ │ │ ├── Test_ShapeMap.py │ │ │ │ │ ├── Test_SkewMap.py │ │ │ │ │ └── Test_TranslationMap.py │ │ │ │ ├── Test_BinaryCompactObject.cpp │ │ │ │ ├── Test_ExpansionMap.cpp │ │ │ │ ├── Test_FromVolumeFile.cpp │ │ │ │ ├── Test_GridCenters.cpp │ │ │ │ ├── Test_RotationMap.cpp │ │ │ │ ├── Test_ShapeMap.cpp │ │ │ │ ├── Test_Skew.cpp │ │ │ │ ├── Test_Sphere.cpp │ │ │ │ └── Test_TranslationMap.cpp │ │ │ ├── FunctionsOfTime/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── IntegratedFunctionOfTime.serializations │ │ │ │ ├── PiecewisePolynomial.serializations │ │ │ │ ├── QuaternionFunctionOfTime.serializations │ │ │ │ ├── Test_FixedSpeedCubic.cpp │ │ │ │ ├── Test_FunctionsOfTimeAreReady.cpp │ │ │ │ ├── Test_IntegratedFunctionOfTime.cpp │ │ │ │ ├── Test_OutputTimeBounds.cpp │ │ │ │ ├── Test_PiecewisePolynomial.cpp │ │ │ │ ├── Test_QuaternionFunctionOfTime.cpp │ │ │ │ ├── Test_QuaternionHelpers.cpp │ │ │ │ ├── Test_SettleToConstant.cpp │ │ │ │ ├── Test_SettleToConstantQuaternion.cpp │ │ │ │ ├── Test_Tags.cpp │ │ │ │ └── Test_ThreadsafeList.cpp │ │ │ ├── JacobianDiagnostic.py │ │ │ ├── NormalDotFlux.py │ │ │ ├── Python/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_BlockAndElementLogicalCoordinates.py │ │ │ │ ├── Test_Direction.py │ │ │ │ ├── Test_Domain.py │ │ │ │ ├── Test_ElementId.py │ │ │ │ ├── Test_ElementMap.py │ │ │ │ ├── Test_FunctionsOfTime.py │ │ │ │ ├── Test_JacobianDiagnostic.py │ │ │ │ ├── Test_RadiallyCompressedCoordinates.py │ │ │ │ ├── Test_SegmentId.py │ │ │ │ └── Test_StrahlkorperTransformations.py │ │ │ ├── Structure/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── OrientationMap1d.serializations │ │ │ │ ├── OrientationMap2d.serializations │ │ │ │ ├── OrientationMap3d.serializations │ │ │ │ ├── Test_BlockGroups.cpp │ │ │ │ ├── Test_BlockId.cpp │ │ │ │ ├── Test_BlockNeighbors.cpp │ │ │ │ ├── Test_ChildSize.cpp │ │ │ │ ├── Test_CreateInitialMesh.cpp │ │ │ │ ├── Test_Direction.cpp │ │ │ │ ├── Test_DirectionalId.cpp │ │ │ │ ├── Test_Element.cpp │ │ │ │ ├── Test_ElementId.cpp │ │ │ │ ├── Test_FaceType.cpp │ │ │ │ ├── Test_HasBoundary.cpp │ │ │ │ ├── Test_Hypercube.cpp │ │ │ │ ├── Test_IndexToSliceAt.cpp │ │ │ │ ├── Test_InitialElementIds.cpp │ │ │ │ ├── Test_NeighborIsConforming.cpp │ │ │ │ ├── Test_Neighbors.cpp │ │ │ │ ├── Test_ObjectLabel.cpp │ │ │ │ ├── Test_OrientationMap.cpp │ │ │ │ ├── Test_OrientationMapHelpers.cpp │ │ │ │ ├── Test_SegmentId.cpp │ │ │ │ ├── Test_Side.cpp │ │ │ │ ├── Test_Topology.cpp │ │ │ │ ├── Test_TrimMap.cpp │ │ │ │ └── Test_ZCurve.cpp │ │ │ ├── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_ElementDistribution.cpp │ │ │ │ ├── Test_Faces.cpp │ │ │ │ ├── Test_NeighborMesh.cpp │ │ │ │ └── Test_SurfaceJacobian.cpp │ │ │ ├── Test_AreaElement.cpp │ │ │ ├── Test_Block.cpp │ │ │ ├── Test_BlockAndElementLogicalCoordinates.cpp │ │ │ ├── Test_CoordinatesTag.cpp │ │ │ ├── Test_CoordsToDifferentFrame.cpp │ │ │ ├── Test_CreateInitialElement.cpp │ │ │ ├── Test_Domain.cpp │ │ │ ├── Test_DomainHelpers.cpp │ │ │ ├── Test_DomainTestHelpers.cpp │ │ │ ├── Test_ElementDistribution.cpp │ │ │ ├── Test_ElementMap.cpp │ │ │ ├── Test_ElementSearchTree.cpp │ │ │ ├── Test_ElementToBlockLogicalMap.cpp │ │ │ ├── Test_ExcisionSphere.cpp │ │ │ ├── Test_FaceNormal.cpp │ │ │ ├── Test_FlatLogicalMetric.cpp │ │ │ ├── Test_InterfaceHelpers.cpp │ │ │ ├── Test_InterfaceItems.cpp │ │ │ ├── Test_InterfaceLogicalCoordinates.cpp │ │ │ ├── Test_JacobianDiagnostic.cpp │ │ │ ├── Test_MinimumGridSpacing.cpp │ │ │ ├── Test_RadiallyCompressedCoordinates.cpp │ │ │ ├── Test_SizeOfElement.cpp │ │ │ ├── Test_StrahlkorperTransformations.cpp │ │ │ ├── Test_Tags.cpp │ │ │ ├── Test_TagsCharacteristicSpeeds.cpp │ │ │ └── Test_TagsTimeDependent.cpp │ │ ├── Elliptic/ │ │ │ ├── Actions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_InitializeAnalyticSolution.cpp │ │ │ │ ├── Test_InitializeBackgroundFields.cpp │ │ │ │ ├── Test_InitializeFields.cpp │ │ │ │ ├── Test_InitializeFixedSources.cpp │ │ │ │ └── Test_RunEventsAndTriggers.cpp │ │ │ ├── BoundaryConditions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Tags/ │ │ │ │ │ └── Test_BoundaryFields.cpp │ │ │ │ ├── Test_AnalyticSolution.cpp │ │ │ │ ├── Test_BoundaryCondition.cpp │ │ │ │ ├── Test_BoundaryConditionType.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── DiscontinuousGalerkin/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_InitializeDomain.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── SubdomainOperator/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_SubdomainOperator.cpp │ │ │ │ ├── Test_DgOperator.cpp │ │ │ │ ├── Test_LargeOuterRadius.cpp │ │ │ │ ├── Test_Penalty.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── Python/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_ReadH5.py │ │ │ ├── SubdomainPreconditioners/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_MinusLaplacian.cpp │ │ │ ├── Systems/ │ │ │ │ ├── BnsInitialData/ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── StarSurface.py │ │ │ │ │ │ └── Test_StarSurface.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Equations.py │ │ │ │ │ ├── Test_Equations.cpp │ │ │ │ │ └── Test_Tags.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Elasticity/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_InitializeConstitutiveRelation.cpp │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── LaserBeam.py │ │ │ │ │ │ ├── Test_LaserBeam.cpp │ │ │ │ │ │ └── Test_Zero.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Equations.py │ │ │ │ │ ├── Test_Equations.cpp │ │ │ │ │ └── Test_Tags.cpp │ │ │ │ ├── Poisson/ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Robin.py │ │ │ │ │ │ └── Test_Robin.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Equations.py │ │ │ │ │ ├── Test_Equations.cpp │ │ │ │ │ └── Test_Tags.cpp │ │ │ │ ├── Punctures/ │ │ │ │ │ ├── AmrCriteria/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_RefineAtPunctures.cpp │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Flatness.py │ │ │ │ │ │ └── Test_Flatness.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Equations.py │ │ │ │ │ ├── Test_Equations.cpp │ │ │ │ │ └── Test_Tags.cpp │ │ │ │ ├── ScalarGaussBonnet/ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_DoNothing.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Equations.py │ │ │ │ │ ├── Test_Equations.cpp │ │ │ │ │ └── Test_Tags.cpp │ │ │ │ ├── SelfForce/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── GeneralRelativity/ │ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ │ └── Test_InitializeEffectiveSource.cpp │ │ │ │ │ │ ├── AnalyticData/ │ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ │ └── Test_CircularOrbit.cpp │ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ │ ├── Test_Angular.cpp │ │ │ │ │ │ │ ├── Test_None.cpp │ │ │ │ │ │ │ └── Test_Sommerfeld.cpp │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_Tags.cpp │ │ │ │ │ └── Scalar/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_InitializeEffectiveSource.cpp │ │ │ │ │ ├── AmrCriteria/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_RefineAtPunctures.cpp │ │ │ │ │ ├── AnalyticData/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_CircularOrbit.cpp │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Test_None.cpp │ │ │ │ │ │ └── Test_Sommerfeld.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Events/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_ObserveSelfForce.cpp │ │ │ │ │ └── Test_Tags.cpp │ │ │ │ ├── Test_GetSourcesComputer.cpp │ │ │ │ └── Xcts/ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── ApparentHorizon.py │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Robin.py │ │ │ │ │ ├── Test_ApparentHorizon.cpp │ │ │ │ │ ├── Test_Flatness.cpp │ │ │ │ │ └── Test_Robin.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Equations.py │ │ │ │ ├── Events/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_ObserveAdmIntegrals.cpp │ │ │ │ ├── Test_Equations.cpp │ │ │ │ ├── Test_HydroQuantities.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── Test_Tags.cpp │ │ │ ├── Triggers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_EveryNIterations.cpp │ │ │ │ └── Test_HasConverged.cpp │ │ │ └── Utilities/ │ │ │ ├── CMakeLists.txt │ │ │ └── Test_ApplyAt.cpp │ │ ├── Evolution/ │ │ │ ├── Actions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_RunEventsAndDenseTriggers.cpp │ │ │ │ └── Test_RunEventsAndTriggers.cpp │ │ │ ├── Ader/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_Matrices.cpp │ │ │ ├── BoundaryConditions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_Type.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── DgSubcell/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── Test_Initialize.cpp │ │ │ │ │ ├── Test_ReconstructionCommunication.cpp │ │ │ │ │ ├── Test_SelectNumericalMethod.cpp │ │ │ │ │ ├── Test_TakeTimeStep.cpp │ │ │ │ │ ├── Test_TciAndRollback.cpp │ │ │ │ │ └── Test_TciAndSwitchToDg.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_ActiveGrid.cpp │ │ │ │ ├── Test_BackgroundGrVars.cpp │ │ │ │ ├── Test_CartesianFluxDivergence.cpp │ │ │ │ ├── Test_CellCenteredFlux.cpp │ │ │ │ ├── Test_CombineVolumeGhostData.cpp │ │ │ │ ├── Test_ComputeBoundaryTerms.cpp │ │ │ │ ├── Test_CorrectPackagedData.cpp │ │ │ │ ├── Test_DisableLts.cpp │ │ │ │ ├── Test_GetActiveTag.cpp │ │ │ │ ├── Test_GetTciDecision.cpp │ │ │ │ ├── Test_GhostData.cpp │ │ │ │ ├── Test_GhostZoneInverseJacobian.cpp │ │ │ │ ├── Test_GhostZoneLogicalCoordinates.cpp │ │ │ │ ├── Test_InitialTciData.cpp │ │ │ │ ├── Test_JacobianCompute.cpp │ │ │ │ ├── Test_Matrices.cpp │ │ │ │ ├── Test_Mesh.cpp │ │ │ │ ├── Test_MeshForGhostData.cpp │ │ │ │ ├── Test_NeighborRdmpAndVolumeData.cpp │ │ │ │ ├── Test_NeighborReconstructedFaceSolution.cpp │ │ │ │ ├── Test_NeighborTciDecision.cpp │ │ │ │ ├── Test_PerssonTci.cpp │ │ │ │ ├── Test_PrepareNeighborData.cpp │ │ │ │ ├── Test_Projection.cpp │ │ │ │ ├── Test_RdmpTci.cpp │ │ │ │ ├── Test_RdmpTciData.cpp │ │ │ │ ├── Test_ReceiveSubcellDataForDg.cpp │ │ │ │ ├── Test_Reconstruction.cpp │ │ │ │ ├── Test_ReconstructionMethod.cpp │ │ │ │ ├── Test_ReconstructionOrder.cpp │ │ │ │ ├── Test_SetInterpolators.cpp │ │ │ │ ├── Test_SliceData.cpp │ │ │ │ ├── Test_SliceTensor.cpp │ │ │ │ ├── Test_SliceVariable.cpp │ │ │ │ ├── Test_SubcellOptions.cpp │ │ │ │ ├── Test_Tags.cpp │ │ │ │ └── Test_TwoMeshRdmpTci.cpp │ │ │ ├── DiscontinuousGalerkin/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── Test_ApplyBoundaryCorrections.cpp │ │ │ │ │ ├── Test_BoundaryConditions.cpp │ │ │ │ │ ├── Test_ComputeTimeDerivative.cpp │ │ │ │ │ └── Test_NormalCovectorAndMagnitude.cpp │ │ │ │ ├── BoundaryCorrectionsHelper.py │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Initialization/ │ │ │ │ │ ├── Test_Mortars.cpp │ │ │ │ │ └── Test_QuadratureTag.cpp │ │ │ │ ├── Limiters/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_HwenoImpl.cpp │ │ │ │ │ ├── Test_Krivodonova.cpp │ │ │ │ │ ├── Test_LimiterActions.cpp │ │ │ │ │ ├── Test_LimiterActionsWithMinmod.cpp │ │ │ │ │ ├── Test_Minmod.cpp │ │ │ │ │ ├── Test_MinmodTci.cpp │ │ │ │ │ ├── Test_MinmodType.cpp │ │ │ │ │ ├── Test_SimpleWenoImpl.cpp │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ ├── Test_Weno.cpp │ │ │ │ │ ├── Test_WenoGridHelpers.cpp │ │ │ │ │ ├── Test_WenoHelpers.cpp │ │ │ │ │ ├── Test_WenoOscillationIndicator.cpp │ │ │ │ │ └── Test_WenoType.cpp │ │ │ │ ├── Messages/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_BoundaryMessage.cpp │ │ │ │ │ └── Test_InboxTags.cpp │ │ │ │ ├── Test_AtomicInboxBoundaryData.cpp │ │ │ │ ├── Test_BackgroundGrVars.cpp │ │ │ │ ├── Test_BoundaryCorrectionsHelper.cpp │ │ │ │ ├── Test_BoundaryData.cpp │ │ │ │ ├── Test_CleanMortarHistory.cpp │ │ │ │ ├── Test_InboxTags.cpp │ │ │ │ ├── Test_InterfaceDataPolicy.cpp │ │ │ │ ├── Test_InterpolatedBoundaryData.cpp │ │ │ │ ├── Test_MortarData.cpp │ │ │ │ ├── Test_MortarDataHolder.cpp │ │ │ │ ├── Test_MortarInfo.cpp │ │ │ │ ├── Test_MortarTags.cpp │ │ │ │ ├── Test_NormalVectorTags.cpp │ │ │ │ ├── Test_TimeSteppingPolicy.cpp │ │ │ │ └── Test_UsingSubcell.cpp │ │ │ ├── Imex/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_DoImplicitStep.cpp │ │ │ │ │ └── Test_RecordTimeStepperData.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Tags/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_ImplicitHistory.cpp │ │ │ │ │ ├── Test_Jacobian.cpp │ │ │ │ │ ├── Test_Mode.cpp │ │ │ │ │ ├── Test_SolveFailures.cpp │ │ │ │ │ └── Test_SolveTolerance.cpp │ │ │ │ ├── Test_CleanHistory.cpp │ │ │ │ ├── Test_GuessResult.cpp │ │ │ │ ├── Test_ImplicitDenseOutput.cpp │ │ │ │ ├── Test_Initialize.cpp │ │ │ │ ├── Test_Mode.cpp │ │ │ │ └── Test_SolveImplicitSector.cpp │ │ │ ├── Initialization/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_ConservativeSystem.cpp │ │ │ │ ├── Test_DgDomain.cpp │ │ │ │ ├── Test_Evolution.cpp │ │ │ │ ├── Test_NonconservativeSystem.cpp │ │ │ │ ├── Test_SetVariables.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── Particles/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── MonteCarlo/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_CellCrossingTime.cpp │ │ │ │ ├── Test_CellVolume.cpp │ │ │ │ ├── Test_CommunicationTags.cpp │ │ │ │ ├── Test_EmitPackets.cpp │ │ │ │ ├── Test_EvolvePackets.cpp │ │ │ │ ├── Test_FluidCouplingAction.cpp │ │ │ │ ├── Test_ImplicitMonteCarloCorrections.cpp │ │ │ │ ├── Test_InitializeAction.cpp │ │ │ │ ├── Test_InterpolateOpacities.cpp │ │ │ │ ├── Test_InverseJacobianInertialToFluid.cpp │ │ │ │ ├── Test_NeutrinoInteractionTable.cpp │ │ │ │ ├── Test_Packet.cpp │ │ │ │ ├── Test_Scattering.cpp │ │ │ │ ├── Test_SwapGrTags.cpp │ │ │ │ ├── Test_TakeTimeStep.cpp │ │ │ │ └── Test_TimeStepAction.cpp │ │ │ ├── Ringdown/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_ComputeRingdownShapeAndTranslationFoT.py │ │ │ │ └── Test_StrahlkorperCoefsAndCenters.cpp │ │ │ ├── Systems/ │ │ │ │ ├── Burgers/ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── DemandOutgoingCharSpeeds.py │ │ │ │ │ │ ├── Dirichlet.py │ │ │ │ │ │ ├── DirichletAnalytic.py │ │ │ │ │ │ ├── Test_DemandOutgoingCharSpeeds.cpp │ │ │ │ │ │ ├── Test_Dirichlet.cpp │ │ │ │ │ │ ├── Test_DirichletAnalytic.cpp │ │ │ │ │ │ └── Test_Periodic.cpp │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ ├── Hll.py │ │ │ │ │ │ ├── Rusanov.py │ │ │ │ │ │ ├── Test_Hll.cpp │ │ │ │ │ │ └── Test_Rusanov.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ │ ├── Linear.py │ │ │ │ │ │ ├── Test_BoundaryConditionGhostData.cpp │ │ │ │ │ │ ├── Test_MonotonisedCentral.cpp │ │ │ │ │ │ └── Test_Tag.cpp │ │ │ │ │ ├── Flux.py │ │ │ │ │ ├── Subcell/ │ │ │ │ │ │ ├── Test_ComputeFluxes.cpp │ │ │ │ │ │ ├── Test_GhostData.cpp │ │ │ │ │ │ ├── Test_NeighborPackagedData.cpp │ │ │ │ │ │ ├── Test_SetInitialRdmpData.cpp │ │ │ │ │ │ ├── Test_TciOnDgGrid.cpp │ │ │ │ │ │ ├── Test_TciOnFdGrid.cpp │ │ │ │ │ │ └── Test_TimeDerivative.cpp │ │ │ │ │ ├── Test_Characteristics.cpp │ │ │ │ │ ├── Test_Fluxes.cpp │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ └── Test_TimeDerivativeTerms.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Cce/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── ScriObserveInterpolated.py │ │ │ │ │ │ ├── Test_AnalyticBoundaryCommunication.cpp │ │ │ │ │ │ ├── Test_CalculateScriInputs.cpp │ │ │ │ │ │ ├── Test_CharacteristicEvolutionBondiCalculations.cpp │ │ │ │ │ │ ├── Test_FilterSwshVolumeQuantity.cpp │ │ │ │ │ │ ├── Test_GhBoundaryCommunication.cpp │ │ │ │ │ │ ├── Test_H5BoundaryCommunication.cpp │ │ │ │ │ │ ├── Test_InitializeCharacteristicEvolution.cpp │ │ │ │ │ │ ├── Test_InitializeFirstHypersurface.cpp │ │ │ │ │ │ ├── Test_InitializeKleinGordonCharacteristicEvolution.cpp │ │ │ │ │ │ ├── Test_InitializeKleinGordonFirstHypersurface.cpp │ │ │ │ │ │ ├── Test_InitializeKleinGordonWorldtubeBoundary.cpp │ │ │ │ │ │ ├── Test_InitializeWorldtubeBoundary.cpp │ │ │ │ │ │ ├── Test_InsertInterpolationScriData.cpp │ │ │ │ │ │ ├── Test_KleinGordonCceCalculations.cpp │ │ │ │ │ │ ├── Test_KleinGordonH5BoundaryCommunication.cpp │ │ │ │ │ │ ├── Test_Psi0Matching.cpp │ │ │ │ │ │ ├── Test_RequestBoundaryData.cpp │ │ │ │ │ │ ├── Test_RequestKleinGordonBoundaryData.cpp │ │ │ │ │ │ ├── Test_ScriObserveInterpolated.cpp │ │ │ │ │ │ ├── Test_SendGhVarsToCce.cpp │ │ │ │ │ │ ├── Test_TimeManagement.cpp │ │ │ │ │ │ ├── Test_UpdateGauge.cpp │ │ │ │ │ │ └── Test_WriteScriBondiQuantities.cpp │ │ │ │ │ ├── AnalyticSolutions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── GaugeWave.py │ │ │ │ │ │ ├── RotatingSchwarzschild.py │ │ │ │ │ │ ├── Test_BouncingBlackHole.cpp │ │ │ │ │ │ ├── Test_GaugeWave.cpp │ │ │ │ │ │ ├── Test_LinearizedBondiSachs.cpp │ │ │ │ │ │ ├── Test_RobinsonTrautman.cpp │ │ │ │ │ │ ├── Test_RotatingSchwarzschild.cpp │ │ │ │ │ │ ├── Test_TeukolskyWave.cpp │ │ │ │ │ │ └── TeukolskyWave.py │ │ │ │ │ ├── BoundaryData.py │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Equations.py │ │ │ │ │ ├── Events/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Test_ObserveFields.cpp │ │ │ │ │ │ └── Test_ObserveTimeStep.cpp │ │ │ │ │ ├── InterfaceManagers/ │ │ │ │ │ │ ├── Test_GhLocalTimeStepping.cpp │ │ │ │ │ │ └── Test_GhLockstep.cpp │ │ │ │ │ ├── NewmanPenrose.py │ │ │ │ │ ├── ScriPlusValues.py │ │ │ │ │ ├── Test_AnalyticBoundaryDataManager.cpp │ │ │ │ │ ├── Test_BoundaryData.cpp │ │ │ │ │ ├── Test_BoundaryDataTags.cpp │ │ │ │ │ ├── Test_DumpBondiSachsOnWorldtube.cpp │ │ │ │ │ ├── Test_Equations.cpp │ │ │ │ │ ├── Test_GaugeTransformBoundaryData.cpp │ │ │ │ │ ├── Test_InitializeCce.cpp │ │ │ │ │ ├── Test_KleinGordonWorldtubeData.cpp │ │ │ │ │ ├── Test_LinearOperators.cpp │ │ │ │ │ ├── Test_LinearSolve.cpp │ │ │ │ │ ├── Test_NewmanPenrose.cpp │ │ │ │ │ ├── Test_OptionTags.cpp │ │ │ │ │ ├── Test_PreSwshDerivatives.cpp │ │ │ │ │ ├── Test_PrecomputeCceDependencies.cpp │ │ │ │ │ ├── Test_ScriPlusInterpolationManager.cpp │ │ │ │ │ ├── Test_ScriPlusValues.cpp │ │ │ │ │ ├── Test_SwshDerivatives.cpp │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ └── Test_WorldtubeData.cpp │ │ │ │ ├── Ccz4/ │ │ │ │ │ ├── ATilde.py │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── Test_DirichletAnalytic.cpp │ │ │ │ │ │ └── Test_Sommerfeld.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Christoffel.py │ │ │ │ │ ├── DerivChristoffel.py │ │ │ │ │ ├── DerivLapse.py │ │ │ │ │ ├── DerivZ4Constraint.py │ │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ │ ├── Test_ApplyFilter.cpp │ │ │ │ │ │ ├── Test_BoundaryConditionGhostData.cpp │ │ │ │ │ │ ├── Test_Derivatives.cpp │ │ │ │ │ │ ├── Test_DummyReconstructor.cpp │ │ │ │ │ │ ├── Test_EnforceConstrainedEvolution.cpp │ │ │ │ │ │ ├── Test_Filter.cpp │ │ │ │ │ │ ├── Test_GhostData.cpp │ │ │ │ │ │ ├── Test_SoTimeDerivative.cpp │ │ │ │ │ │ └── Test_Tags.cpp │ │ │ │ │ ├── Ricci.py │ │ │ │ │ ├── RicciScalarPlusDivergenceZ4Constraint.py │ │ │ │ │ ├── Test_ATilde.cpp │ │ │ │ │ ├── Test_Ccz4WrappedGr.cpp │ │ │ │ │ ├── Test_Christoffel.cpp │ │ │ │ │ ├── Test_DerivChristoffel.cpp │ │ │ │ │ ├── Test_DerivLapse.cpp │ │ │ │ │ ├── Test_DerivZ4Constraint.cpp │ │ │ │ │ ├── Test_Ricci.cpp │ │ │ │ │ ├── Test_RicciScalarPlusDivergenceZ4Constraint.cpp │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ ├── Test_TempTags.cpp │ │ │ │ │ ├── Test_TimeDerivative.cpp │ │ │ │ │ ├── Test_Z4Constraint.cpp │ │ │ │ │ └── Z4Constraint.py │ │ │ │ ├── CurvedScalarWave/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ └── Test_SetInitialData.cpp │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── AnalyticConstant.py │ │ │ │ │ │ ├── ConstraintPreservingSphericalRadiation.py │ │ │ │ │ │ ├── DemandOutgoingCharSpeeds.py │ │ │ │ │ │ ├── Test_AnalyticConstant.cpp │ │ │ │ │ │ ├── Test_ConstraintPreservingSphericalRadiation.cpp │ │ │ │ │ │ ├── Test_DemandOutgoingCharSpeeds.cpp │ │ │ │ │ │ ├── Test_Worldtube.cpp │ │ │ │ │ │ ├── Worldtube.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ ├── Test_UpwindPenalty.cpp │ │ │ │ │ │ ├── UpwindPenalty.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Characteristics.py │ │ │ │ │ ├── Constraints.py │ │ │ │ │ ├── Fluxes.py │ │ │ │ │ ├── Test_ApplyTensorYlmFilter.cpp │ │ │ │ │ ├── Test_BackgroundSpacetime.cpp │ │ │ │ │ ├── Test_CalculateGrVars.cpp │ │ │ │ │ ├── Test_Characteristics.cpp │ │ │ │ │ ├── Test_Constraints.cpp │ │ │ │ │ ├── Test_InitializeConstraintDampingGammas.cpp │ │ │ │ │ ├── Test_InitializeEvolvedVariables.cpp │ │ │ │ │ ├── Test_PsiSquared.cpp │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ ├── Test_TimeDerivative.cpp │ │ │ │ │ ├── Worldtube/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── ElementActions/ │ │ │ │ │ │ │ ├── Test_InitializeConstraintGammas.cpp │ │ │ │ │ │ │ ├── Test_InitializeCurrentIteration.cpp │ │ │ │ │ │ │ ├── Test_Iterations.cpp │ │ │ │ │ │ │ ├── Test_ReceiveWorldtubeData.cpp │ │ │ │ │ │ │ └── Test_SendToWorldtube.cpp │ │ │ │ │ │ ├── SelfForce.py │ │ │ │ │ │ ├── SingletonActions/ │ │ │ │ │ │ │ ├── Test_ChangeSlabSize.cpp │ │ │ │ │ │ │ ├── Test_InitializeElementFacesGridCoordinates.cpp │ │ │ │ │ │ │ ├── Test_InitializeEvolvedVariables.cpp │ │ │ │ │ │ │ ├── Test_IterateAccelerationTerms.cpp │ │ │ │ │ │ │ ├── Test_ObserveWorldtubeSolution.cpp │ │ │ │ │ │ │ ├── Test_UpdateAcceleration.cpp │ │ │ │ │ │ │ ├── Test_UpdateFunctionsOfTime.cpp │ │ │ │ │ │ │ └── __init__.py │ │ │ │ │ │ ├── Test_AccelerationTerms.cpp │ │ │ │ │ │ ├── Test_KerrSchildDerivatives.cpp │ │ │ │ │ │ ├── Test_PunctureField.cpp │ │ │ │ │ │ ├── Test_PunctureInitialData.cpp │ │ │ │ │ │ ├── Test_RadiusFunctions.cpp │ │ │ │ │ │ ├── Test_SelfForce.cpp │ │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ │ └── Test_Triggers.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── ForceFree/ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── DemandOutgoingCharSpeeds.py │ │ │ │ │ │ ├── DirichletAnalytic.py │ │ │ │ │ │ ├── Test_DemandOutgoingCharSpeeds.cpp │ │ │ │ │ │ ├── Test_DirichletAnalytic.cpp │ │ │ │ │ │ └── Test_Periodic.cpp │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ ├── Rusanov.py │ │ │ │ │ │ └── Test_Rusanov.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ElectricCurrentDensity.py │ │ │ │ │ ├── ElectromagneticVariables.py │ │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ │ ├── Test_AdaptiveOrder.cpp │ │ │ │ │ │ ├── Test_MonotonisedCentral.cpp │ │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ │ └── Test_Wcns5z.cpp │ │ │ │ │ ├── Fluxes.py │ │ │ │ │ ├── MaskNeutronStarInterior.py │ │ │ │ │ ├── Sources.py │ │ │ │ │ ├── Subcell/ │ │ │ │ │ │ ├── Test_ComputeFluxes.cpp │ │ │ │ │ │ ├── Test_GhostData.cpp │ │ │ │ │ │ ├── Test_NeighborPackagedData.cpp │ │ │ │ │ │ ├── Test_SetInitialRdmpData.cpp │ │ │ │ │ │ ├── Test_TciOnDgGrid.cpp │ │ │ │ │ │ ├── Test_TciOnFdGrid.cpp │ │ │ │ │ │ └── Test_TciOptions.cpp │ │ │ │ │ ├── Test_Characteristics.cpp │ │ │ │ │ ├── Test_ElectricCurrentDensity.cpp │ │ │ │ │ ├── Test_ElectromagneticVariables.cpp │ │ │ │ │ ├── Test_Fluxes.cpp │ │ │ │ │ ├── Test_MaskNeutronStarInterior.cpp │ │ │ │ │ ├── Test_Sources.cpp │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ ├── Test_TimeDerivativeTerms.cpp │ │ │ │ │ └── TimeDerivative.py │ │ │ │ ├── GeneralizedHarmonic/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ └── Test_SetInitialData.cpp │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── Bjorhus.py │ │ │ │ │ │ ├── DemandOutgoingCharSpeeds.py │ │ │ │ │ │ ├── DirichletAnalytic.py │ │ │ │ │ │ ├── DirichletMinkowski.py │ │ │ │ │ │ ├── Test_Bjorhus.cpp │ │ │ │ │ │ ├── Test_BjorhusImpl.cpp │ │ │ │ │ │ ├── Test_DemandOutgoingCharSpeeds.cpp │ │ │ │ │ │ ├── Test_DirichletAnalytic.cpp │ │ │ │ │ │ ├── Test_DirichletMinkowski.cpp │ │ │ │ │ │ ├── Test_Periodic.cpp │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ ├── Test_AveragedUpwindPenalty.cpp │ │ │ │ │ │ ├── Test_UpwindPenalty.cpp │ │ │ │ │ │ └── UpwindPenalty.py │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Characteristics.py │ │ │ │ │ ├── Constraints.py │ │ │ │ │ ├── GaugeSourceFunctions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── DampedHarmonic.py │ │ │ │ │ │ ├── DampedWaveHelpers.py │ │ │ │ │ │ ├── HalfPiPhiTwoNormals.py │ │ │ │ │ │ ├── Test_AnalyticChristoffel.cpp │ │ │ │ │ │ ├── Test_DampedHarmonic.cpp │ │ │ │ │ │ ├── Test_DampedWaveHelpers.cpp │ │ │ │ │ │ ├── Test_HalfPiPhiTwoNormals.cpp │ │ │ │ │ │ ├── Test_Harmonic.cpp │ │ │ │ │ │ ├── Test_SetPiAndPhiFromConstraints.cpp │ │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Test_ApplyTensorYlmFilter.cpp │ │ │ │ │ ├── Test_BbhCheckpointAndExitIfCompletePhaseChange.cpp │ │ │ │ │ ├── Test_BbhCompletionCriteria.cpp │ │ │ │ │ ├── Test_BbhCompletionSingleton.cpp │ │ │ │ │ ├── Test_Characteristics.cpp │ │ │ │ │ ├── Test_Constraints.cpp │ │ │ │ │ ├── Test_DuDt.cpp │ │ │ │ │ ├── Test_DuDtTempTags.cpp │ │ │ │ │ ├── Test_Fluxes.cpp │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── GrMhd/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── GhValenciaDivClean/ │ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ │ └── Test_SetInitialData.cpp │ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ │ ├── Test_ConstraintPreservingFreeOutflow.cpp │ │ │ │ │ │ │ ├── Test_DirichletAnalytic.cpp │ │ │ │ │ │ │ └── Test_DirichletFreeOutflow.cpp │ │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ │ └── Test_ProductOfCorrections.cpp │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ │ │ ├── Test_BoundaryConditionGhostData.cpp │ │ │ │ │ │ │ ├── Test_Derivatives.cpp │ │ │ │ │ │ │ ├── Test_FillNeighborSpacetimeVariables.cpp │ │ │ │ │ │ │ ├── Test_FilterOptions.cpp │ │ │ │ │ │ │ ├── Test_Filters.cpp │ │ │ │ │ │ │ ├── Test_MonotonisedCentral.cpp │ │ │ │ │ │ │ ├── Test_PositivityPreservingAdaptiveOrder.cpp │ │ │ │ │ │ │ └── Test_Wcns5z.cpp │ │ │ │ │ │ ├── StressEnergy.py │ │ │ │ │ │ ├── Subcell/ │ │ │ │ │ │ │ ├── Test_FixConservativesAndComputePrims.cpp │ │ │ │ │ │ │ ├── Test_NeighborPackagedData.cpp │ │ │ │ │ │ │ ├── Test_PrimitiveGhostData.cpp │ │ │ │ │ │ │ ├── Test_PrimsAfterRollback.cpp │ │ │ │ │ │ │ ├── Test_ResizeAndComputePrimitives.cpp │ │ │ │ │ │ │ ├── Test_TimeDerivative.cpp │ │ │ │ │ │ │ └── Test_ZeroTimeDerivatives.cpp │ │ │ │ │ │ ├── Test_Characteristics.cpp │ │ │ │ │ │ ├── Test_Constraints.cpp │ │ │ │ │ │ ├── Test_SetPiAndPhiFromConstraints.cpp │ │ │ │ │ │ ├── Test_StressEnergy.cpp │ │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ │ └── Test_TimeDerivativeTerms.cpp │ │ │ │ │ ├── ValenciaDivClean/ │ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ │ └── Test_NumericInitialData.cpp │ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ │ ├── DemandOutgoingCharSpeeds.py │ │ │ │ │ │ │ ├── DirichletAnalytic.py │ │ │ │ │ │ │ ├── HydroFreeOutflow.py │ │ │ │ │ │ │ ├── Reflective.py │ │ │ │ │ │ │ ├── Test_DemandOutgoingCharSpeeds.cpp │ │ │ │ │ │ │ ├── Test_DirichletAnalytic.cpp │ │ │ │ │ │ │ ├── Test_HydroFreeOutflow.cpp │ │ │ │ │ │ │ ├── Test_Periodic.cpp │ │ │ │ │ │ │ ├── Test_Reflective.cpp │ │ │ │ │ │ │ └── __init__.py │ │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ │ ├── Hll.py │ │ │ │ │ │ │ ├── Rusanov.py │ │ │ │ │ │ │ ├── Test_Hll.cpp │ │ │ │ │ │ │ └── Test_Rusanov.cpp │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── CharacteristicSpeeds.py │ │ │ │ │ │ ├── ComovingMagneticFieldMagnitude.py │ │ │ │ │ │ ├── ConservativeFromPrimitive.py │ │ │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ │ │ ├── Test_BoundaryConditionGhostData.cpp │ │ │ │ │ │ │ ├── Test_MonotonicityPreserving5.cpp │ │ │ │ │ │ │ ├── Test_MonotonisedCentral.cpp │ │ │ │ │ │ │ ├── Test_PositivityPreservingAdaptiveOrder.cpp │ │ │ │ │ │ │ ├── Test_Tag.cpp │ │ │ │ │ │ │ └── Test_Wcns5z.cpp │ │ │ │ │ │ ├── Fluxes.py │ │ │ │ │ │ ├── Sources.py │ │ │ │ │ │ ├── Subcell/ │ │ │ │ │ │ │ ├── Test_ComputeFluxes.cpp │ │ │ │ │ │ │ ├── Test_FixConservativesAndComputePrims.cpp │ │ │ │ │ │ │ ├── Test_NeighborPackagedData.cpp │ │ │ │ │ │ │ ├── Test_PrimitiveGhostData.cpp │ │ │ │ │ │ │ ├── Test_PrimsAfterRollback.cpp │ │ │ │ │ │ │ ├── Test_ResizeAndComputePrimitives.cpp │ │ │ │ │ │ │ ├── Test_SetInitialRdmpData.cpp │ │ │ │ │ │ │ ├── Test_SwapGrTags.cpp │ │ │ │ │ │ │ ├── Test_TciOnDgGrid.cpp │ │ │ │ │ │ │ ├── Test_TciOnFdGrid.cpp │ │ │ │ │ │ │ ├── Test_TciOptions.cpp │ │ │ │ │ │ │ └── Test_TimeDerivative.cpp │ │ │ │ │ │ ├── Test_Characteristics.cpp │ │ │ │ │ │ ├── Test_ComovingMagneticFieldMagnitude.cpp │ │ │ │ │ │ ├── Test_ComputeFluxesFromPrimitives.cpp │ │ │ │ │ │ ├── Test_ConservativeFromPrimitive.cpp │ │ │ │ │ │ ├── Test_FixConservatives.cpp │ │ │ │ │ │ ├── Test_Flattener.cpp │ │ │ │ │ │ ├── Test_Fluxes.cpp │ │ │ │ │ │ ├── Test_PrimitiveFromConservative.cpp │ │ │ │ │ │ ├── Test_QuadrupoleFormula.cpp │ │ │ │ │ │ ├── Test_SetVariablesNeededFixingToFalse.cpp │ │ │ │ │ │ ├── Test_Sources.cpp │ │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ │ ├── Test_TimeDerivativeTerms.cpp │ │ │ │ │ │ ├── Test_ValenciaDivClean.cpp │ │ │ │ │ │ ├── TimeDerivative.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ └── __init__.py │ │ │ │ ├── NewtonianEuler/ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── DemandOutgoingCharSpeeds.py │ │ │ │ │ │ ├── DirichletAnalytic.py │ │ │ │ │ │ ├── Reflection.py │ │ │ │ │ │ ├── Test_DemandOutgoingCharSpeeds.cpp │ │ │ │ │ │ ├── Test_DirichletAnalytic.cpp │ │ │ │ │ │ ├── Test_Periodic.cpp │ │ │ │ │ │ ├── Test_Reflection.cpp │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ ├── Hll.py │ │ │ │ │ │ ├── Hllc.py │ │ │ │ │ │ ├── Rusanov.py │ │ │ │ │ │ ├── Test_Hll.cpp │ │ │ │ │ │ ├── Test_Hllc.cpp │ │ │ │ │ │ └── Test_Rusanov.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── CharacteristicSpeeds.py │ │ │ │ │ ├── ConservativeFromPrimitive.py │ │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ │ ├── Test_AoWeno.cpp │ │ │ │ │ │ ├── Test_MonotonisedCentral.cpp │ │ │ │ │ │ └── Test_Tag.cpp │ │ │ │ │ ├── Limiters/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Test_CharacteristicHelpers.cpp │ │ │ │ │ │ ├── Test_Flattener.cpp │ │ │ │ │ │ ├── Test_KxrcfTci.cpp │ │ │ │ │ │ ├── Test_Minmod.cpp │ │ │ │ │ │ ├── Test_VariablesToLimit.cpp │ │ │ │ │ │ └── Test_Weno.cpp │ │ │ │ │ ├── PrimitiveFromConservative.py │ │ │ │ │ ├── Sources/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── LaneEmdenGravitationalField.py │ │ │ │ │ │ ├── Test_LaneEmdenGravitationalField.cpp │ │ │ │ │ │ ├── Test_UniformAcceleration.cpp │ │ │ │ │ │ ├── Test_VortexPerturbation.cpp │ │ │ │ │ │ ├── UniformAcceleration.py │ │ │ │ │ │ ├── VortexPerturbation.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Subcell/ │ │ │ │ │ │ ├── Test_ComputeFluxes.cpp │ │ │ │ │ │ ├── Test_NeighborPackagedData.cpp │ │ │ │ │ │ ├── Test_PrimitiveGhostData.cpp │ │ │ │ │ │ ├── Test_PrimsAfterRollback.cpp │ │ │ │ │ │ ├── Test_ResizeAndComputePrimitives.cpp │ │ │ │ │ │ ├── Test_SetInitialRdmpData.cpp │ │ │ │ │ │ ├── Test_TciOnDgGrid.cpp │ │ │ │ │ │ ├── Test_TciOnFdGrid.cpp │ │ │ │ │ │ └── Test_TimeDerivative.cpp │ │ │ │ │ ├── Test_Characteristics.cpp │ │ │ │ │ ├── Test_ConservativeFromPrimitive.cpp │ │ │ │ │ ├── Test_Fluxes.cpp │ │ │ │ │ ├── Test_InternalEnergyDensity.cpp │ │ │ │ │ ├── Test_KineticEnergyDensity.cpp │ │ │ │ │ ├── Test_MachNumber.cpp │ │ │ │ │ ├── Test_PrimitiveFromConservative.cpp │ │ │ │ │ ├── Test_RamPressure.cpp │ │ │ │ │ ├── Test_SoundSpeedSquared.cpp │ │ │ │ │ ├── Test_SpecificKineticEnergy.cpp │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ ├── Test_TimeDerivativeTerms.cpp │ │ │ │ │ ├── TimeDerivative.py │ │ │ │ │ └── __init__.py │ │ │ │ ├── RadiationTransport/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── M1Grey/ │ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ │ ├── DirichletAnalytic.py │ │ │ │ │ │ │ ├── Test_DirichletAnalytic.cpp │ │ │ │ │ │ │ ├── Test_Periodic.cpp │ │ │ │ │ │ │ └── __init__.py │ │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ │ ├── Rusanov.py │ │ │ │ │ │ │ └── Test_Rusanov.cpp │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── ComputeM1HydroCouplingJacobian.py │ │ │ │ │ │ ├── Fluxes.py │ │ │ │ │ │ ├── M1HydroCoupling.py │ │ │ │ │ │ ├── Sources.py │ │ │ │ │ │ ├── Test_Actions.cpp │ │ │ │ │ │ ├── Test_Fluxes.cpp │ │ │ │ │ │ ├── Test_M1Closure.cpp │ │ │ │ │ │ ├── Test_M1HydroCoupling.cpp │ │ │ │ │ │ ├── Test_Sources.cpp │ │ │ │ │ │ ├── Test_System.cpp │ │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ │ ├── Test_TimeDerivativeTerms.cpp │ │ │ │ │ │ ├── TimeDerivative.py │ │ │ │ │ │ └── __init__.py │ │ │ │ │ └── __init__.py │ │ │ │ ├── ScalarAdvection/ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ └── Test_Periodic.cpp │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ ├── Rusanov.py │ │ │ │ │ │ └── Test_Rusanov.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ │ ├── Test_AoWeno.cpp │ │ │ │ │ │ ├── Test_MonotonisedCentral.cpp │ │ │ │ │ │ └── Test_Tag.cpp │ │ │ │ │ ├── Fluxes.py │ │ │ │ │ ├── Subcell/ │ │ │ │ │ │ ├── Test_ComputeFluxes.cpp │ │ │ │ │ │ ├── Test_GhostData.cpp │ │ │ │ │ │ ├── Test_NeighborPackagedData.cpp │ │ │ │ │ │ ├── Test_SetInitialRdmpData.cpp │ │ │ │ │ │ ├── Test_TciOnDgGrid.cpp │ │ │ │ │ │ ├── Test_TciOnFdGrid.cpp │ │ │ │ │ │ ├── Test_TciOptions.cpp │ │ │ │ │ │ ├── Test_TimeDerivative.cpp │ │ │ │ │ │ └── Test_VelocityAtFace.cpp │ │ │ │ │ ├── Test_Characteristics.cpp │ │ │ │ │ ├── Test_Fluxes.cpp │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ ├── Test_TimeDerivativeTerms.cpp │ │ │ │ │ ├── Test_VelocityField.cpp │ │ │ │ │ └── VelocityField.py │ │ │ │ ├── ScalarTensor/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ └── Test_SetInitialData.cpp │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── DemandOutgoingCharSpeeds.py │ │ │ │ │ │ ├── Test_ConstraintPreserving.cpp │ │ │ │ │ │ └── Test_DemandOutgoingCharSpeeds.cpp │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ └── Test_ProductOfCorrections.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_Characteristics.cpp │ │ │ │ │ ├── Test_Constraints.cpp │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ └── Test_TimeDerivative.cpp │ │ │ │ ├── ScalarWave/ │ │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ │ ├── ConstraintPreservingSphericalRadiation.py │ │ │ │ │ │ ├── DirichletAnalytic.py │ │ │ │ │ │ ├── SphericalRadiation.py │ │ │ │ │ │ ├── Test_ConstraintPreservingSphericalRadiation.cpp │ │ │ │ │ │ ├── Test_DirichletAnalytic.cpp │ │ │ │ │ │ ├── Test_Periodic.cpp │ │ │ │ │ │ └── Test_SphericalRadiation.cpp │ │ │ │ │ ├── BoundaryCorrections/ │ │ │ │ │ │ ├── Test_UpwindPenalty.cpp │ │ │ │ │ │ └── UpwindPenalty.py │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Characteristics.py │ │ │ │ │ ├── Constraints.py │ │ │ │ │ ├── EnergyDensity.py │ │ │ │ │ ├── MomentumDensity.py │ │ │ │ │ ├── Test_Characteristics.cpp │ │ │ │ │ ├── Test_Constraints.cpp │ │ │ │ │ ├── Test_EnergyDensity.cpp │ │ │ │ │ ├── Test_Equations.cpp │ │ │ │ │ ├── Test_MomentumDensity.cpp │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ └── Test_TimeDerivative.cpp │ │ │ │ └── __init__.py │ │ │ ├── Test_BoundaryCorrectionTags.cpp │ │ │ ├── Test_ComputeTags.cpp │ │ │ ├── Test_NumericInitialData.cpp │ │ │ ├── Test_Protocols.cpp │ │ │ ├── Test_Tags.cpp │ │ │ ├── Test_TagsDomain.cpp │ │ │ ├── Triggers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_SeparationLessThan.cpp │ │ │ ├── VariableFixing/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_Actions.cpp │ │ │ │ ├── Test_FixToAtmosphere.cpp │ │ │ │ ├── Test_LimitLorentzFactor.cpp │ │ │ │ ├── Test_ParameterizedDeleptonization.cpp │ │ │ │ └── Test_RadiallyFallingFloor.cpp │ │ │ └── __init__.py │ │ ├── Executables/ │ │ │ ├── CMakeLists.txt │ │ │ └── Test_PreprocessCceWorldtube.cpp │ │ ├── Framework/ │ │ │ ├── ActionTesting.hpp │ │ │ ├── CMakeLists.txt │ │ │ ├── CheckWithRandomValues.hpp │ │ │ ├── MockDistributedObject.hpp │ │ │ ├── MockRuntimeSystem.hpp │ │ │ ├── MockRuntimeSystemFreeFunctions.hpp │ │ │ ├── Pypp.hpp │ │ │ ├── PyppFundamentals.hpp │ │ │ ├── SetupLocalPythonEnvironment.cpp │ │ │ ├── SetupLocalPythonEnvironment.hpp │ │ │ ├── TestCreation.hpp │ │ │ ├── TestHelpers.hpp │ │ │ ├── TestingFramework.hpp │ │ │ └── Tests/ │ │ │ ├── CMakeLists.txt │ │ │ ├── PyppPyTests.py │ │ │ ├── Test_ActionTesting.cpp │ │ │ ├── Test_Pypp.cpp │ │ │ ├── Test_PyppAnalyticSolution.cpp │ │ │ ├── Test_PyppRandomValues.cpp │ │ │ ├── Test_TestCreation.cpp │ │ │ ├── Test_TestHelpers.cpp │ │ │ └── Test_TestingFramework.cpp │ │ ├── Helpers/ │ │ │ ├── CMakeLists.txt │ │ │ ├── ControlSystem/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Examples.hpp │ │ │ │ ├── SystemHelpers.hpp │ │ │ │ └── TestStructs.hpp │ │ │ ├── DataStructures/ │ │ │ │ ├── ApplyMatrix.cpp │ │ │ │ ├── ApplyMatrix.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CustomStaticSizeVector.hpp │ │ │ │ ├── DataBox/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Examples.hpp │ │ │ │ │ ├── TestHelpers.hpp │ │ │ │ │ └── TestTags.hpp │ │ │ │ ├── MakeRandomVectorInMagnitudeRange.hpp │ │ │ │ ├── MakeWithRandomValues.hpp │ │ │ │ ├── MathWrapper.hpp │ │ │ │ ├── MathWrapperDetail.cpp │ │ │ │ ├── MathWrapperDetail.hpp │ │ │ │ ├── RandomUnitNormal.cpp │ │ │ │ ├── RandomUnitNormal.hpp │ │ │ │ ├── Tensor/ │ │ │ │ │ └── Expressions/ │ │ │ │ │ ├── ComponentPlaceholder.hpp │ │ │ │ │ ├── EvaluateRank0.hpp │ │ │ │ │ ├── EvaluateRank1.hpp │ │ │ │ │ ├── EvaluateRank2.hpp │ │ │ │ │ ├── EvaluateRank3.hpp │ │ │ │ │ ├── EvaluateRank4.hpp │ │ │ │ │ ├── TensorIndexTransformationRank0.hpp │ │ │ │ │ ├── TensorIndexTransformationRank1.hpp │ │ │ │ │ ├── TensorIndexTransformationRank2.hpp │ │ │ │ │ ├── TensorIndexTransformationRank3.hpp │ │ │ │ │ ├── TensorIndexTransformationRank4.hpp │ │ │ │ │ ├── TensorIndexTransformationTimeIndex.hpp │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ ├── TestTags.hpp │ │ │ │ └── VectorImplTestHelper.hpp │ │ │ ├── Domain/ │ │ │ │ ├── Amr/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── NeighborFlagHelpers.cpp │ │ │ │ │ ├── NeighborFlagHelpers.hpp │ │ │ │ │ └── RegistrationHelpers.hpp │ │ │ │ ├── BoundaryConditions/ │ │ │ │ │ ├── BoundaryCondition.cpp │ │ │ │ │ ├── BoundaryCondition.hpp │ │ │ │ │ └── CMakeLists.txt │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CoordinateMaps/ │ │ │ │ │ └── TestMapHelpers.hpp │ │ │ │ ├── Creators/ │ │ │ │ │ ├── TestHelpers.hpp │ │ │ │ │ ├── TimeDependence/ │ │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ │ └── TimeDependent/ │ │ │ │ │ ├── TestHelpers.cpp │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ ├── DomainTestHelpers.cpp │ │ │ │ ├── DomainTestHelpers.hpp │ │ │ │ └── Structure/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── NeighborHelpers.cpp │ │ │ │ ├── NeighborHelpers.hpp │ │ │ │ ├── OrientationMapHelpers.cpp │ │ │ │ └── OrientationMapHelpers.hpp │ │ │ ├── Elliptic/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── DiscontinuousGalerkin/ │ │ │ │ │ └── NumericalFluxes/ │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ └── FirstOrderSystem.hpp │ │ │ ├── Evolution/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── DgSubcell/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ProjectionTestHelpers.cpp │ │ │ │ │ └── ProjectionTestHelpers.hpp │ │ │ │ ├── DiscontinuousGalerkin/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── ComputeTimeDerivativeImpl.hpp │ │ │ │ │ │ ├── ComputeTimeDerivativeImpl.tpp │ │ │ │ │ │ ├── InstantiateCons1d.cpp │ │ │ │ │ │ ├── InstantiateCons2d.cpp │ │ │ │ │ │ ├── InstantiateCons3d.cpp │ │ │ │ │ │ ├── InstantiateConsPrim1d.cpp │ │ │ │ │ │ ├── InstantiateConsPrim2d.cpp │ │ │ │ │ │ ├── InstantiateConsPrim3d.cpp │ │ │ │ │ │ ├── InstantiateMixed1d.cpp │ │ │ │ │ │ ├── InstantiateMixed2d.cpp │ │ │ │ │ │ ├── InstantiateMixed3d.cpp │ │ │ │ │ │ ├── InstantiateMixedPrim1d.cpp │ │ │ │ │ │ ├── InstantiateMixedPrim2d.cpp │ │ │ │ │ │ ├── InstantiateMixedPrim3d.cpp │ │ │ │ │ │ ├── InstantiateMixedPrimPrim1d.cpp │ │ │ │ │ │ ├── InstantiateMixedPrimPrim2d.cpp │ │ │ │ │ │ ├── InstantiateMixedPrimPrim3d.cpp │ │ │ │ │ │ ├── InstantiateNoncons1d.cpp │ │ │ │ │ │ ├── InstantiateNoncons2d.cpp │ │ │ │ │ │ ├── InstantiateNoncons3d.cpp │ │ │ │ │ │ ├── SystemType.cpp │ │ │ │ │ │ └── SystemType.hpp │ │ │ │ │ ├── BoundaryConditions.hpp │ │ │ │ │ ├── BoundaryCorrections.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Limiters/ │ │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ │ ├── NormalVectors.hpp │ │ │ │ │ └── Range.hpp │ │ │ │ ├── Imex/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DoImplicitStepInstantiate.cpp │ │ │ │ │ ├── DoImplicitStepSector.hpp │ │ │ │ │ └── TestSector.hpp │ │ │ │ └── Systems/ │ │ │ │ ├── Burgers/ │ │ │ │ │ └── FiniteDifference/ │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Cce/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ ├── CharacteristicInitialization.hpp │ │ │ │ │ │ └── WorldtubeBoundaryMocking.hpp │ │ │ │ │ ├── AnalyticSolutions/ │ │ │ │ │ │ ├── AnalyticDataHelpers.cpp │ │ │ │ │ │ ├── AnalyticDataHelpers.hpp │ │ │ │ │ │ └── CMakeLists.txt │ │ │ │ │ ├── BoundaryTestHelpers.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── CceComputationTestHelpers.cpp │ │ │ │ │ ├── CceComputationTestHelpers.hpp │ │ │ │ │ ├── KleinGordonBoundaryTestHelpers.cpp │ │ │ │ │ ├── KleinGordonBoundaryTestHelpers.hpp │ │ │ │ │ ├── VolumeTestHelpers.hpp │ │ │ │ │ └── WriteToWorldtubeH5.hpp │ │ │ │ ├── Ccz4/ │ │ │ │ │ └── PrimReconstructor.hpp │ │ │ │ ├── CurvedScalarWave/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── TestHelpers.cpp │ │ │ │ │ ├── TestHelpers.hpp │ │ │ │ │ └── Worldtube/ │ │ │ │ │ ├── TestHelpers.cpp │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ ├── ForceFree/ │ │ │ │ │ └── FiniteDifference/ │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ ├── GrMhd/ │ │ │ │ │ ├── GhValenciaDivClean/ │ │ │ │ │ │ └── FiniteDifference/ │ │ │ │ │ │ └── PrimReconstructor.hpp │ │ │ │ │ └── ValenciaDivClean/ │ │ │ │ │ └── FiniteDifference/ │ │ │ │ │ └── PrimReconstructor.hpp │ │ │ │ ├── NewtonianEuler/ │ │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ │ └── PrimReconstructor.hpp │ │ │ │ │ └── TimeDerivativeTerms.hpp │ │ │ │ └── ScalarAdvection/ │ │ │ │ └── FiniteDifference/ │ │ │ │ └── TestHelpers.hpp │ │ │ ├── IO/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Observers/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── MockH5.cpp │ │ │ │ │ ├── MockH5.hpp │ │ │ │ │ ├── MockWriteReductionDataRow.hpp │ │ │ │ │ └── ObserverHelpers.hpp │ │ │ │ ├── VolumeData.cpp │ │ │ │ └── VolumeData.hpp │ │ │ ├── NumericalAlgorithms/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── DiscontinuousGalerkin/ │ │ │ │ │ └── NumericalFluxes/ │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ ├── FiniteDifference/ │ │ │ │ │ ├── Exact.hpp │ │ │ │ │ ├── Python.hpp │ │ │ │ │ └── Roundoff.hpp │ │ │ │ ├── LinearSolver/ │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ ├── Spectral/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DiskTestFunctions.cpp │ │ │ │ │ ├── DiskTestFunctions.hpp │ │ │ │ │ ├── FourierTestFunctions.cpp │ │ │ │ │ ├── FourierTestFunctions.hpp │ │ │ │ │ ├── PolynomialTestFunctions.cpp │ │ │ │ │ └── PolynomialTestFunctions.hpp │ │ │ │ ├── SphericalHarmonics/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── StrahlkorperTestHelpers.cpp │ │ │ │ │ ├── StrahlkorperTestHelpers.hpp │ │ │ │ │ ├── Test_ApplyTensorYlmFilter.hpp │ │ │ │ │ ├── YlmTestFunctions.cpp │ │ │ │ │ └── YlmTestFunctions.hpp │ │ │ │ └── SpinWeightedSphericalHarmonics/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── SwshTestHelpers.cpp │ │ │ │ └── SwshTestHelpers.hpp │ │ │ ├── Parallel/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── RoundRobinArrayElements.hpp │ │ │ ├── ParallelAlgorithms/ │ │ │ │ ├── ApparentHorizonFinder/ │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Events/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── ObserveFields.hpp │ │ │ │ ├── EventsAndDenseTriggers/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── DenseTriggers/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── TestTrigger.cpp │ │ │ │ │ └── TestTrigger.hpp │ │ │ │ ├── Interpolation/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Examples.hpp │ │ │ │ │ ├── InterpolateOnElementTestHelpers.hpp │ │ │ │ │ └── InterpolationTargetTestHelpers.hpp │ │ │ │ ├── LinearSolver/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DistributedLinearSolverAlgorithmTestHelpers.cpp │ │ │ │ │ ├── DistributedLinearSolverAlgorithmTestHelpers.hpp │ │ │ │ │ ├── LinearSolverAlgorithmTestHelpers.hpp │ │ │ │ │ ├── Multigrid/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Helpers.hpp │ │ │ │ │ └── ResidualMonitorActionsTestHelpers.hpp │ │ │ │ └── NonlinearSolver/ │ │ │ │ ├── Algorithm.hpp │ │ │ │ └── CMakeLists.txt │ │ │ ├── PointwiseFunctions/ │ │ │ │ ├── AnalyticData/ │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ ├── AnalyticSolutions/ │ │ │ │ │ ├── Burgers/ │ │ │ │ │ │ └── CheckBurgersSolution.hpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── FirstOrderEllipticSolutionsTestHelpers.hpp │ │ │ │ │ ├── GeneralRelativity/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── CheckWrappedGrConsistency.hpp │ │ │ │ │ │ └── VerifyGrSolution.hpp │ │ │ │ │ ├── GrMhd/ │ │ │ │ │ │ └── VerifyGrMhdSolution.hpp │ │ │ │ │ ├── TestHelpers.hpp │ │ │ │ │ └── Xcts/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── VerifySolution.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ConstraintDamping/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ ├── GeneralRelativity/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Surfaces/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── TestHelpers.cpp │ │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ │ ├── TestHelpers.cpp │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ ├── Hydro/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── EquationsOfState/ │ │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ │ ├── TestHelpers.cpp │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ ├── MathFunctions/ │ │ │ │ │ └── TestHelpers.hpp │ │ │ │ └── PostNewtonian/ │ │ │ │ ├── BinaryTrajectories.cpp │ │ │ │ ├── BinaryTrajectories.hpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Python/ │ │ │ │ ├── Bindings.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── __init__.py │ │ │ ├── TestHelpers.hpp │ │ │ ├── Tests/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Domain/ │ │ │ │ │ ├── Amr/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_NeighborFlagHelpers.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Structure/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_NeighborHelpers.cpp │ │ │ │ │ └── Test_OrientationMapHelpers.cpp │ │ │ │ ├── IO/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Observers/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_MockH5.cpp │ │ │ │ │ └── Test_MockWriteReductionDataRow.cpp │ │ │ │ ├── PointwiseFunctions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── PostNewtonian/ │ │ │ │ │ ├── BinaryTrajectories.py │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_BinaryTrajectories.cpp │ │ │ │ │ └── Test_BinaryTrajectories.py │ │ │ │ ├── Test_MakeRandomVectorInMagnitudeRange.cpp │ │ │ │ ├── Test_MakeWithRandomValues.cpp │ │ │ │ └── Test_RandomUnitNormal.cpp │ │ │ ├── Time/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── TimeSteppers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ImexHelpers.cpp │ │ │ │ ├── ImexHelpers.hpp │ │ │ │ ├── LtsHelpers.cpp │ │ │ │ ├── LtsHelpers.hpp │ │ │ │ ├── RungeKutta.cpp │ │ │ │ ├── RungeKutta.hpp │ │ │ │ ├── TimeStepperTestUtils.cpp │ │ │ │ └── TimeStepperTestUtils.hpp │ │ │ └── Utilities/ │ │ │ ├── CMakeLists.txt │ │ │ └── Serialization/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Versioning.cpp │ │ │ └── Versioning.hpp │ │ ├── IO/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Exporter/ │ │ │ │ ├── BundledExporter/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_BundledExporter.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_InterpolateToPoints.py │ │ │ │ │ └── Test_SpacetimeInterpolator.py │ │ │ │ ├── Test_Exporter.cpp │ │ │ │ └── Test_SpacetimeInterpolator.cpp │ │ │ ├── External/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_InterpolateFromFuka.cpp │ │ │ ├── H5/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_CombineH5Dat.py │ │ │ │ │ ├── Test_DeleteSubfiles.py │ │ │ │ │ ├── Test_ExtendConnectivity.py │ │ │ │ │ ├── Test_ExtractDatFromH5.py │ │ │ │ │ ├── Test_ExtractInputSourceYamlFromH5.py │ │ │ │ │ ├── Test_FunctionsOfTimeFromVolume.py │ │ │ │ │ ├── Test_InterpolateToMesh.py │ │ │ │ │ ├── Test_IterElements.py │ │ │ │ │ ├── Test_ReadH5.py │ │ │ │ │ └── Test_TransformVolumeData.py │ │ │ │ ├── Test_Cce.cpp │ │ │ │ ├── Test_CheckH5PropertiesMatch.cpp │ │ │ │ ├── Test_CombineH5.cpp │ │ │ │ ├── Test_CombineH5.py │ │ │ │ ├── Test_Dat.cpp │ │ │ │ ├── Test_EosTable.cpp │ │ │ │ ├── Test_H5.cpp │ │ │ │ ├── Test_H5.py │ │ │ │ ├── Test_H5File.cpp │ │ │ │ ├── Test_OpenGroup.cpp │ │ │ │ ├── Test_StellarCollapseEos.cpp │ │ │ │ ├── Test_TensorData.cpp │ │ │ │ ├── Test_TensorData.py │ │ │ │ ├── Test_Version.cpp │ │ │ │ ├── Test_VolumeData.cpp │ │ │ │ └── Test_VolumeData.py │ │ │ ├── Importers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_Tags.cpp │ │ │ │ ├── Test_VolumeDataReaderActions.cpp │ │ │ │ ├── Test_VolumeDataReaderAlgorithm.cpp │ │ │ │ ├── Test_VolumeDataReaderAlgorithm.hpp │ │ │ │ ├── Test_VolumeDataReaderAlgorithm1D.yaml │ │ │ │ ├── Test_VolumeDataReaderAlgorithm2D.yaml │ │ │ │ └── Test_VolumeDataReaderAlgorithm3D.yaml │ │ │ ├── Logging/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_Tags.cpp │ │ │ │ └── Test_Verbosity.cpp │ │ │ ├── Observers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_GetLockPointer.cpp │ │ │ │ ├── Test_Initialize.cpp │ │ │ │ ├── Test_ObservationId.cpp │ │ │ │ ├── Test_ReductionObserver.cpp │ │ │ │ ├── Test_RegisterElements.cpp │ │ │ │ ├── Test_RegisterEvents.cpp │ │ │ │ ├── Test_RegisterSingleton.cpp │ │ │ │ ├── Test_Tags.cpp │ │ │ │ ├── Test_TypeOfObservation.cpp │ │ │ │ ├── Test_VolumeObserver.cpp │ │ │ │ └── Test_WriteSimpleData.cpp │ │ │ ├── Test_ComposeTable.cpp │ │ │ ├── Test_Connectivity.cpp │ │ │ ├── eos.parameters │ │ │ ├── eos.quantities │ │ │ └── eos.table │ │ ├── Informer/ │ │ │ ├── CMakeLists.txt │ │ │ └── Test_InfoAtCompile.py │ │ ├── NumericalAlgorithms/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Convergence/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_Criteria.cpp │ │ │ │ ├── Test_HasConverged.cpp │ │ │ │ ├── Test_Reason.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── DiscontinuousGalerkin/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Tags/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_Formulation.cpp │ │ │ │ ├── Test_ApplyMassMatrix.cpp │ │ │ │ ├── Test_Formulation.cpp │ │ │ │ ├── Test_HasReceivedFromAllMortars.cpp │ │ │ │ ├── Test_InterpolateFromBoundary.cpp │ │ │ │ ├── Test_LiftFlux.cpp │ │ │ │ ├── Test_LiftFromBoundary.cpp │ │ │ │ ├── Test_MetricIdentityJacobian.cpp │ │ │ │ ├── Test_MortarHelpers.cpp │ │ │ │ ├── Test_MortarInterpolator.cpp │ │ │ │ ├── Test_NormalDotFlux.cpp │ │ │ │ ├── Test_ProjectToBoundary.cpp │ │ │ │ ├── Test_SimpleBoundaryData.cpp │ │ │ │ ├── Test_SimpleMortarData.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── FiniteDifference/ │ │ │ │ ├── AoWeno53.py │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Minmod.py │ │ │ │ ├── MonotonicityPreserving5.py │ │ │ │ ├── MonotonisedCentral.py │ │ │ │ ├── PositivityPreservingAdaptiveOrder.py │ │ │ │ ├── Reconstruction.py │ │ │ │ ├── Test_AoWeno53.cpp │ │ │ │ ├── Test_DerivativeOrder.cpp │ │ │ │ ├── Test_FallbackReconstructorType.cpp │ │ │ │ ├── Test_Filter.cpp │ │ │ │ ├── Test_HighOrderFluxCorrection.cpp │ │ │ │ ├── Test_Minmod.cpp │ │ │ │ ├── Test_MonotonicityPreserving5.cpp │ │ │ │ ├── Test_MonotonisedCentral.cpp │ │ │ │ ├── Test_NeighborDataAsVariables.cpp │ │ │ │ ├── Test_NonUniform1D.cpp │ │ │ │ ├── Test_PartialDerivatives.cpp │ │ │ │ ├── Test_PositivityPreservingAdaptiveOrder.cpp │ │ │ │ ├── Test_SecondPartialDerivatives.cpp │ │ │ │ ├── Test_Unlimited.cpp │ │ │ │ ├── Test_Wcns5z.cpp │ │ │ │ ├── Wcns5z.py │ │ │ │ └── __init__.py │ │ │ ├── Integration/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_GslQuadAdaptive.cpp │ │ │ ├── Interpolation/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_BarycentricRational.py │ │ │ │ │ ├── Test_CubicSpline.py │ │ │ │ │ ├── Test_IrregularInterpolant.py │ │ │ │ │ └── Test_RegularGridInterpolant.py │ │ │ │ ├── Test_BarycentricRational.cpp │ │ │ │ ├── Test_CardinalInterpolator.cpp │ │ │ │ ├── Test_CubicSpline.cpp │ │ │ │ ├── Test_IrregularInterpolant.cpp │ │ │ │ ├── Test_LagrangePolynomial.cpp │ │ │ │ ├── Test_LinearLeastSquares.cpp │ │ │ │ ├── Test_LinearRegression.cpp │ │ │ │ ├── Test_MultiLinearSpanInterpolation.cpp │ │ │ │ ├── Test_PolynomialInterpolation.cpp │ │ │ │ ├── Test_PredictedZeroCrossing.cpp │ │ │ │ ├── Test_RegularGridInterpolant.cpp │ │ │ │ ├── Test_SendGhWorldtubeData.cpp │ │ │ │ ├── Test_SpanInterpolators.cpp │ │ │ │ └── Test_ZeroCrossingPredictor.cpp │ │ │ ├── LinearAlgebra/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_FindGeneralizedEigenvalues.cpp │ │ │ ├── LinearOperators/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_DefiniteIntegral.py │ │ │ │ │ ├── Test_PartialDerivatives.py │ │ │ │ │ └── Test_PowerMonitors.py │ │ │ │ ├── Test_CoefficientTransforms.cpp │ │ │ │ ├── Test_DefiniteIntegral.cpp │ │ │ │ ├── Test_Divergence.cpp │ │ │ │ ├── Test_Filtering.cpp │ │ │ │ ├── Test_IndefiniteIntegral.cpp │ │ │ │ ├── Test_Linearize.cpp │ │ │ │ ├── Test_MeanValue.cpp │ │ │ │ ├── Test_PartialDerivatives.cpp │ │ │ │ ├── Test_PowerMonitors.cpp │ │ │ │ └── Test_WeakDivergence.cpp │ │ │ ├── LinearSolver/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_BuildMatrix.cpp │ │ │ │ ├── Test_ExplicitInverse.cpp │ │ │ │ ├── Test_Gmres.cpp │ │ │ │ ├── Test_InnerProduct.cpp │ │ │ │ └── Test_Lapack.cpp │ │ │ ├── OdeIntegration/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_OdeIntegration.cpp │ │ │ ├── RootFinding/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_GslMultiRoot.cpp │ │ │ │ ├── Test_QuadraticEquation.cpp │ │ │ │ ├── Test_RootBracketing.cpp │ │ │ │ └── Test_TOMS748.cpp │ │ │ ├── Spectral/ │ │ │ │ ├── BasisFunctions/ │ │ │ │ │ ├── Test_Chebyshev.cpp │ │ │ │ │ ├── Test_Fourier.cpp │ │ │ │ │ ├── Test_Jacobi.cpp │ │ │ │ │ ├── Test_Legendre.cpp │ │ │ │ │ └── Test_Zernike.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_LogicalCoordinates.py │ │ │ │ │ ├── Test_Mesh.py │ │ │ │ │ └── Test_Spectral.py │ │ │ │ ├── Test_Basis.cpp │ │ │ │ ├── Test_BasisFunctionNormalizationSquare.cpp │ │ │ │ ├── Test_Cartoon.cpp │ │ │ │ ├── Test_ChebyshevGauss.cpp │ │ │ │ ├── Test_ChebyshevGaussLobatto.cpp │ │ │ │ ├── Test_Clenshaw.cpp │ │ │ │ ├── Test_CollocationPointsAndWeights.cpp │ │ │ │ ├── Test_DifferentiationMatrix.cpp │ │ │ │ ├── Test_Filtering.cpp │ │ │ │ ├── Test_FiniteDifference.cpp │ │ │ │ ├── Test_IndefiniteIntegral.cpp │ │ │ │ ├── Test_IntegrationMatrix.cpp │ │ │ │ ├── Test_InterpolationMatrix.cpp │ │ │ │ ├── Test_InterpolationWeights.cpp │ │ │ │ ├── Test_Legendre.cpp │ │ │ │ ├── Test_LegendreGauss.cpp │ │ │ │ ├── Test_LegendreGaussLobatto.cpp │ │ │ │ ├── Test_LinearFilterMatrix.cpp │ │ │ │ ├── Test_LogicalCoordinates.cpp │ │ │ │ ├── Test_Mesh.cpp │ │ │ │ ├── Test_ModalToNodalMatrix.cpp │ │ │ │ ├── Test_NodalToModalMatrix.cpp │ │ │ │ ├── Test_Parity.cpp │ │ │ │ ├── Test_ParityFromSymmetry.cpp │ │ │ │ ├── Test_Projection.cpp │ │ │ │ ├── Test_Quadrature.cpp │ │ │ │ ├── Test_QuadratureWeights.cpp │ │ │ │ ├── Test_SegmentSize.cpp │ │ │ │ ├── Test_Spectral.cpp │ │ │ │ └── Test_ZernikeGaussRadauUpper.cpp │ │ │ ├── SphericalHarmonics/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── IO/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_FillYlmLegendAndData.cpp │ │ │ │ │ ├── Test_ReadSurfaceYlm.cpp │ │ │ │ │ └── Test_StrahlkorperCoordsToTextFile.cpp │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_Spherepack.py │ │ │ │ │ └── Test_Strahlkorper.py │ │ │ │ ├── Test_AngularOrdering.cpp │ │ │ │ ├── Test_ChangeCenterOfStrahlkorper.cpp │ │ │ │ ├── Test_RealSphericalHarmonics.cpp │ │ │ │ ├── Test_Spherepack.cpp │ │ │ │ ├── Test_SpherepackIterator.cpp │ │ │ │ ├── Test_Strahlkorper.cpp │ │ │ │ ├── Test_StrahlkorperDataBox.cpp │ │ │ │ ├── Test_StrahlkorperFunctions.cpp │ │ │ │ ├── Test_Tags.cpp │ │ │ │ ├── Test_TensorYlmCartToSphere.cpp │ │ │ │ ├── Test_TensorYlmFilter.cpp │ │ │ │ ├── Test_TensorYlmSphereToCart.cpp │ │ │ │ ├── Test_WignerThreeJ.cpp │ │ │ │ └── Test_YlmToStf.cpp │ │ │ └── SpinWeightedSphericalHarmonics/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Test_ComplexDataView.cpp │ │ │ ├── Test_SwshCoefficients.cpp │ │ │ ├── Test_SwshCollocation.cpp │ │ │ ├── Test_SwshDerivatives.cpp │ │ │ ├── Test_SwshFiltering.cpp │ │ │ ├── Test_SwshInterpolation.cpp │ │ │ ├── Test_SwshTags.cpp │ │ │ ├── Test_SwshTestHelpers.cpp │ │ │ └── Test_SwshTransform.cpp │ │ ├── Options/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Test_Auto.cpp │ │ │ ├── Test_Comparator.cpp │ │ │ ├── Test_CustomTypeConstruction.cpp │ │ │ ├── Test_Factory.cpp │ │ │ ├── Test_FactoryHelpers.cpp │ │ │ ├── Test_Options.cpp │ │ │ └── Test_StdComplex.cpp │ │ ├── Parallel/ │ │ │ ├── ArrayCollection/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_IsDgElementArrayMember.cpp │ │ │ │ ├── Test_IsDgElementCollection.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── PhaseControl/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_CheckpointAndExitAfterWallclock.cpp │ │ │ │ ├── Test_ExecutePhaseChange.cpp │ │ │ │ ├── Test_PhaseChange.cpp │ │ │ │ ├── Test_PhaseControlTags.cpp │ │ │ │ └── Test_VisitAndReturn.cpp │ │ │ ├── Printf/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_Printf.cpp │ │ │ ├── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_ArrayIndex.cpp │ │ │ │ ├── Test_InputSource.cpp │ │ │ │ └── Test_Section.cpp │ │ │ ├── Test_AlgorithmCore.cpp │ │ │ ├── Test_AlgorithmGlobalCache.cpp │ │ │ ├── Test_AlgorithmGlobalCache.yaml │ │ │ ├── Test_AlgorithmLocalSyncAction.cpp │ │ │ ├── Test_AlgorithmMessages.cpp │ │ │ ├── Test_AlgorithmNestedApply1.cpp │ │ │ ├── Test_AlgorithmNestedApply2.cpp │ │ │ ├── Test_AlgorithmNodelock.cpp │ │ │ ├── Test_AlgorithmParallel.cpp │ │ │ ├── Test_AlgorithmParallel.yaml │ │ │ ├── Test_AlgorithmPhaseControl.hpp │ │ │ ├── Test_AlgorithmPhaseControlNodegroup.cpp │ │ │ ├── Test_AlgorithmPhaseControlNodegroup.yaml │ │ │ ├── Test_AlgorithmPhaseControlSingleton.cpp │ │ │ ├── Test_AlgorithmPhaseControlSingleton.yaml │ │ │ ├── Test_AlgorithmReduction.cpp │ │ │ ├── Test_ArrayComponentId.cpp │ │ │ ├── Test_Callback.cpp │ │ │ ├── Test_CheckpointRestart.cpp │ │ │ ├── Test_DetectHangArray.cpp │ │ │ ├── Test_DomainDiagnosticInfo.cpp │ │ │ ├── Test_DynamicInsertion.cpp │ │ │ ├── Test_DynamicInsertionState.cpp │ │ │ ├── Test_DynamicInsertionState.yaml │ │ │ ├── Test_ExitCode.cpp │ │ │ ├── Test_FifoCache.cpp │ │ │ ├── Test_GlobalCache.ci │ │ │ ├── Test_GlobalCache.cpp │ │ │ ├── Test_GlobalCache.hpp │ │ │ ├── Test_GlobalCacheDataBox.cpp │ │ │ ├── Test_InboxInserters.cpp │ │ │ ├── Test_InitializationTag.cpp │ │ │ ├── Test_MemoryMonitor.cpp │ │ │ ├── Test_MultiReaderSpinlock.cpp │ │ │ ├── Test_NodeLock.cpp │ │ │ ├── Test_OutputInbox.cpp │ │ │ ├── Test_Parallel.cpp │ │ │ ├── Test_ParallelComponentHelpers.cpp │ │ │ ├── Test_Phase.cpp │ │ │ ├── Test_PhaseChangeMain.cpp │ │ │ ├── Test_ResourceInfo.cpp │ │ │ ├── Test_SectionReductions.cpp │ │ │ ├── Test_StaticSpscQueue.cpp │ │ │ └── Test_TypeTraits.cpp │ │ ├── ParallelAlgorithms/ │ │ │ ├── Actions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_AddComputeTags.cpp │ │ │ │ ├── Test_AddSimpleTags.cpp │ │ │ │ ├── Test_Goto.cpp │ │ │ │ ├── Test_InitializeItems.cpp │ │ │ │ ├── Test_MutateApply.cpp │ │ │ │ ├── Test_RandomizeVariables.cpp │ │ │ │ ├── Test_SetData.cpp │ │ │ │ ├── Test_TerminatePhase.cpp │ │ │ │ └── Test_UpdateMessageQueue.cpp │ │ │ ├── Amr/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── Test_AdjustDomain.cpp │ │ │ │ │ ├── Test_CollectDataFromChildren.cpp │ │ │ │ │ ├── Test_CreateChild.cpp │ │ │ │ │ ├── Test_CreateParent.cpp │ │ │ │ │ ├── Test_EvaluateRefinementCriteria.cpp │ │ │ │ │ ├── Test_Initialize.cpp │ │ │ │ │ ├── Test_InitializeChild.cpp │ │ │ │ │ ├── Test_InitializeParent.cpp │ │ │ │ │ ├── Test_SendDataToChildren.cpp │ │ │ │ │ └── Test_UpdateAmrDecision.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Criteria/ │ │ │ │ │ ├── Test_Constraints.cpp │ │ │ │ │ ├── Test_Criterion.cpp │ │ │ │ │ ├── Test_DriveToTarget.cpp │ │ │ │ │ ├── Test_IncreaseResolution.cpp │ │ │ │ │ ├── Test_Loehner.cpp │ │ │ │ │ ├── Test_Persson.cpp │ │ │ │ │ ├── Test_Random.cpp │ │ │ │ │ ├── Test_TruncationError.cpp │ │ │ │ │ └── Test_Type.cpp │ │ │ │ ├── Events/ │ │ │ │ │ ├── Test_ObserveAmrCriteria.cpp │ │ │ │ │ └── Test_RefineMesh.cpp │ │ │ │ ├── Policies/ │ │ │ │ │ ├── Test_EnforcePolicies.cpp │ │ │ │ │ ├── Test_Isotropy.cpp │ │ │ │ │ ├── Test_Limits.cpp │ │ │ │ │ └── Test_Policies.cpp │ │ │ │ ├── Projectors/ │ │ │ │ │ ├── Test_CopyFromCreatorOrLeaveAsIs.cpp │ │ │ │ │ ├── Test_DefaultInitialize.cpp │ │ │ │ │ ├── Test_Mesh.cpp │ │ │ │ │ ├── Test_Tensors.cpp │ │ │ │ │ └── Test_Variables.cpp │ │ │ │ ├── Test_Protocols.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── ApparentHorizonFinder/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Callbacks/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_FailedHorizonFind.cpp │ │ │ │ │ ├── Test_InvokeCallbacks.cpp │ │ │ │ │ ├── Test_ObserveCenters.cpp │ │ │ │ │ ├── Test_ObserveFieldsAndTimeSeriesOnHorizon.cpp │ │ │ │ │ └── Test_SendDependencyToObserverWriter.cpp │ │ │ │ ├── Criteria/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_Criterion.cpp │ │ │ │ │ ├── Test_IncreaseResolution.cpp │ │ │ │ │ ├── Test_Residual.cpp │ │ │ │ │ └── Test_Shape.cpp │ │ │ │ ├── Events/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_FindApparentHorizon.cpp │ │ │ │ │ └── Test_FindCommonHorizon.cpp │ │ │ │ ├── Protocols/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_Protocols.cpp │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_FastFlow.py │ │ │ │ ├── Test_CleanUp.cpp │ │ │ │ ├── Test_ComputeCoords.cpp │ │ │ │ ├── Test_ComputeVarsToInterpolateToTarget.cpp │ │ │ │ ├── Test_CurrentTime.cpp │ │ │ │ ├── Test_Destination.cpp │ │ │ │ ├── Test_FastFlow.cpp │ │ │ │ ├── Test_FindApparentHorizon.cpp │ │ │ │ ├── Test_Initialization.cpp │ │ │ │ ├── Test_InterpolateVolumeVars.cpp │ │ │ │ ├── Test_OptionTags.cpp │ │ │ │ ├── Test_Storage.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── Events/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_Completion.cpp │ │ │ │ ├── Test_ErrorIfDataTooBig.cpp │ │ │ │ ├── Test_ObserveAdaptiveSteppingDiagnostics.cpp │ │ │ │ ├── Test_ObserveAtExtremum.cpp │ │ │ │ ├── Test_ObserveFields.cpp │ │ │ │ ├── Test_ObserveNorms.cpp │ │ │ │ ├── Test_ObserveTimeStep.cpp │ │ │ │ ├── Test_ObserveTimeStepVolume.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── EventsAndDenseTriggers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── DenseTriggers/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_Filter.cpp │ │ │ │ │ ├── Test_Or.cpp │ │ │ │ │ └── Test_Times.cpp │ │ │ │ ├── Test_EventsAndDenseTriggers.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── EventsAndTriggers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_EventsAndTriggers.cpp │ │ │ │ ├── Test_RunEventsOnFailure.cpp │ │ │ │ ├── Test_Tags.cpp │ │ │ │ └── Test_WhenToCheck.cpp │ │ │ ├── Initialization/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_MutateAssign.cpp │ │ │ ├── Interpolation/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_ComputeExcisionBoundaryVolumeQuantities.cpp │ │ │ │ ├── Test_ElementReceiveInterpPoints.cpp │ │ │ │ ├── Test_InitializeInterpolationTarget.cpp │ │ │ │ ├── Test_InterpolateWithoutInterpComponent.cpp │ │ │ │ ├── Test_InterpolationTargetKerrHorizon.cpp │ │ │ │ ├── Test_InterpolationTargetLineSegment.cpp │ │ │ │ ├── Test_InterpolationTargetSpecifiedPoints.cpp │ │ │ │ ├── Test_InterpolationTargetSphere.cpp │ │ │ │ ├── Test_InterpolationTargetVarsFromElement.cpp │ │ │ │ ├── Test_InterpolationTargetWedgeSectionTorus.cpp │ │ │ │ ├── Test_ObserveLineSegment.cpp │ │ │ │ ├── Test_ObserveTimeSeriesAndSurfaceData.cpp │ │ │ │ ├── Test_Protocols.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── LinearSolver/ │ │ │ │ ├── Actions/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_BuildMatrix.cpp │ │ │ │ │ ├── Test_BuildMatrix.yaml │ │ │ │ │ └── Test_MakeIdentityIfSkipped.cpp │ │ │ │ ├── AsynchronousSolvers/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_ElementActions.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ConjugateGradient/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_ConjugateGradientAlgorithm.cpp │ │ │ │ │ ├── Test_ConjugateGradientAlgorithm.yaml │ │ │ │ │ ├── Test_DistributedConjugateGradientAlgorithm.cpp │ │ │ │ │ ├── Test_DistributedConjugateGradientAlgorithm.yaml │ │ │ │ │ ├── Test_ElementActions.cpp │ │ │ │ │ └── Test_ResidualMonitorActions.cpp │ │ │ │ ├── Gmres/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_ComplexGmresAlgorithm.cpp │ │ │ │ │ ├── Test_ComplexGmresAlgorithm.yaml │ │ │ │ │ ├── Test_DistributedGmresAlgorithm.cpp │ │ │ │ │ ├── Test_DistributedGmresAlgorithm.yaml │ │ │ │ │ ├── Test_DistributedGmresPreconditionedAlgorithm.cpp │ │ │ │ │ ├── Test_DistributedGmresPreconditionedAlgorithm.yaml │ │ │ │ │ ├── Test_ElementActions.cpp │ │ │ │ │ ├── Test_GmresAlgorithm.cpp │ │ │ │ │ ├── Test_GmresAlgorithm.yaml │ │ │ │ │ ├── Test_GmresPreconditionedAlgorithm.cpp │ │ │ │ │ ├── Test_GmresPreconditionedAlgorithm.yaml │ │ │ │ │ └── Test_ResidualMonitorActions.cpp │ │ │ │ ├── Multigrid/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_RestrictFields.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_Hierarchy.cpp │ │ │ │ │ ├── Test_MultigridAlgorithm.cpp │ │ │ │ │ ├── Test_MultigridAlgorithm.yaml │ │ │ │ │ ├── Test_MultigridAlgorithmMassive.yaml │ │ │ │ │ ├── Test_MultigridPreconditionedGmresAlgorithm.cpp │ │ │ │ │ ├── Test_MultigridPreconditionedGmresAlgorithm.yaml │ │ │ │ │ └── Test_Tags.cpp │ │ │ │ ├── Richardson/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_DistributedRichardsonAlgorithm.cpp │ │ │ │ │ ├── Test_DistributedRichardsonAlgorithm.yaml │ │ │ │ │ ├── Test_RichardsonAlgorithm.cpp │ │ │ │ │ ├── Test_RichardsonAlgorithm.yaml │ │ │ │ │ └── Test_Tags.cpp │ │ │ │ ├── Schwarz/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Test_CommunicateOverlapFields.cpp │ │ │ │ │ │ └── Test_ResetSubdomainSolver.cpp │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_ComputeTags.cpp │ │ │ │ │ ├── Test_ElementCenteredSubdomainData.cpp │ │ │ │ │ ├── Test_OverlapHelpers.cpp │ │ │ │ │ ├── Test_SchwarzAlgorithm.cpp │ │ │ │ │ ├── Test_SchwarzAlgorithm.yaml │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ └── Test_Weighting.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── NonlinearSolver/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── NewtonRaphson/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_LineSearch.cpp │ │ │ │ │ ├── Test_NewtonRaphsonAlgorithm.cpp │ │ │ │ │ └── Test_NewtonRaphsonAlgorithm.yaml │ │ │ │ └── Test_Tags.cpp │ │ │ ├── RayTracer/ │ │ │ │ ├── BackgroundSpacetimes/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_NumericData.cpp │ │ │ │ │ └── Test_WrappedGr.cpp │ │ │ │ └── CMakeLists.txt │ │ │ └── SurfaceFinder/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Test_FindRadialSurface.py │ │ │ └── Test_SurfaceFinder.cpp │ │ ├── PointwiseFunctions/ │ │ │ ├── AnalyticData/ │ │ │ │ ├── Burgers/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Sinusoid.py │ │ │ │ │ ├── Test_Sinusoid.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── CurvedWaveEquation/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── PureSphericalHarmonic.py │ │ │ │ │ ├── Test_PureSphericalHarmonic.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── ForceFree/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── FfeBreakdown.py │ │ │ │ │ ├── MagnetosphericWald.py │ │ │ │ │ ├── RotatingDipole.py │ │ │ │ │ ├── Test_FfeBreakdown.cpp │ │ │ │ │ ├── Test_MagnetosphericWald.cpp │ │ │ │ │ ├── Test_RotatingDipole.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── GeneralRelativity/ │ │ │ │ │ ├── BrillLindquist.py │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_BrillLindquist.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── GrMhd/ │ │ │ │ │ ├── BlastWave.py │ │ │ │ │ ├── BondiHoyleAccretion.py │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── InitialMagneticFields/ │ │ │ │ │ │ ├── Poloidal.py │ │ │ │ │ │ ├── Test_Poloidal.cpp │ │ │ │ │ │ ├── Test_Toroidal.cpp │ │ │ │ │ │ └── Toroidal.py │ │ │ │ │ ├── KhInstability.py │ │ │ │ │ ├── MagneticFieldLoop.py │ │ │ │ │ ├── MagneticRotor.py │ │ │ │ │ ├── MagnetizedFmDisk.py │ │ │ │ │ ├── OrszagTangVortex.py │ │ │ │ │ ├── RiemannProblem.py │ │ │ │ │ ├── SlabJet.py │ │ │ │ │ ├── Test_BlastWave.cpp │ │ │ │ │ ├── Test_BondiHoyleAccretion.cpp │ │ │ │ │ ├── Test_CcsnCollapse.cpp │ │ │ │ │ ├── Test_FukaInitialData.cpp │ │ │ │ │ ├── Test_KhInstability.cpp │ │ │ │ │ ├── Test_MagneticFieldLoop.cpp │ │ │ │ │ ├── Test_MagneticRotor.cpp │ │ │ │ │ ├── Test_MagnetizedFmDisk.cpp │ │ │ │ │ ├── Test_MagnetizedTovStar.cpp │ │ │ │ │ ├── Test_OrszagTangVortex.cpp │ │ │ │ │ ├── Test_PolarMagnetizedFmDisk.cpp │ │ │ │ │ ├── Test_RiemannProblem.cpp │ │ │ │ │ ├── Test_SlabJet.cpp │ │ │ │ │ ├── Test_SphericalTorus.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── NewtonianEuler/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── KhInstability.py │ │ │ │ │ ├── ShuOsherTube.py │ │ │ │ │ ├── SodExplosion.py │ │ │ │ │ ├── Test_KhInstability.cpp │ │ │ │ │ ├── Test_ShuOsherTube.cpp │ │ │ │ │ └── Test_SodExplosion.cpp │ │ │ │ ├── Punctures/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── MultiplePunctures.py │ │ │ │ │ └── Test_MultiplePunctures.cpp │ │ │ │ ├── RadiationTransport/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── M1Grey/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── HomogeneousSphere.py │ │ │ │ │ └── Test_HomogeneousSphere.cpp │ │ │ │ ├── ScalarTensor/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── KerrSphericalHarmonic.py │ │ │ │ │ └── Test_KerrSphericalHarmonic.cpp │ │ │ │ ├── Test_AnalyticData.cpp │ │ │ │ ├── Xcts/ │ │ │ │ │ ├── Binary.py │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_Binary.cpp │ │ │ │ └── __init__.py │ │ │ ├── AnalyticSolutions/ │ │ │ │ ├── Burgers/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_Bump.cpp │ │ │ │ │ ├── Test_Linear.cpp │ │ │ │ │ └── Test_Step.cpp │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Elasticity/ │ │ │ │ │ ├── BentBeam.py │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── HalfSpaceMirror.py │ │ │ │ │ ├── Test_BentBeam.cpp │ │ │ │ │ ├── Test_HalfSpaceMirror.cpp │ │ │ │ │ ├── Test_Zero.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── ForceFree/ │ │ │ │ │ ├── AlfvenWave.py │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ExactWald.py │ │ │ │ │ ├── FastWave.py │ │ │ │ │ ├── Test_AlfvenWave.cpp │ │ │ │ │ ├── Test_ExactWald.cpp │ │ │ │ │ ├── Test_FastWave.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── GeneralRelativity/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── GaugeWave.py │ │ │ │ │ ├── KerrHorizon.py │ │ │ │ │ ├── Minkowski.py │ │ │ │ │ ├── Python/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_Bindings.py │ │ │ │ │ ├── Test_GaugePlaneWave.cpp │ │ │ │ │ ├── Test_GaugeWave.cpp │ │ │ │ │ ├── Test_HarmonicSchwarzschild.cpp │ │ │ │ │ ├── Test_KerrSchild.cpp │ │ │ │ │ ├── Test_Minkowski.cpp │ │ │ │ │ ├── Test_SphericalKerrSchild.cpp │ │ │ │ │ ├── Test_TeukolskyWave.cpp │ │ │ │ │ ├── Test_TrumpetSchwarzschild.cpp │ │ │ │ │ ├── Test_WrappedGr.cpp │ │ │ │ │ ├── TeukolskyWave.py │ │ │ │ │ ├── TrumpetSchwarzschild.py │ │ │ │ │ └── __init__.py │ │ │ │ ├── GhGrMhd/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_InstantiateWrappedGr.cpp │ │ │ │ ├── GhRelativisticEuler/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_InstantiateWrappedGr.cpp │ │ │ │ ├── GrMhd/ │ │ │ │ │ ├── AlfvenWave.py │ │ │ │ │ ├── BondiMichel.py │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── KomissarovShock.py │ │ │ │ │ ├── SmoothFlow.py │ │ │ │ │ ├── Test_AlfvenWave.cpp │ │ │ │ │ ├── Test_BondiMichel.cpp │ │ │ │ │ ├── Test_KomissarovShock.cpp │ │ │ │ │ ├── Test_SmoothFlow.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── Hydro/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── SmoothFlow.py │ │ │ │ │ ├── Test_SmoothFlow.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── NewtonianEuler/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── IsentropicVortex.py │ │ │ │ │ ├── LaneEmdenStar.py │ │ │ │ │ ├── RiemannProblem.py │ │ │ │ │ ├── Test_IsentropicVortex.cpp │ │ │ │ │ ├── Test_LaneEmdenStar.cpp │ │ │ │ │ ├── Test_RiemannProblem.cpp │ │ │ │ │ ├── Test_SmoothFlow.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── Poisson/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Gaussian.py │ │ │ │ │ ├── Lorentzian.py │ │ │ │ │ ├── Moustache.py │ │ │ │ │ ├── ProductOfSinusoids.py │ │ │ │ │ ├── Test_Lorentzian.cpp │ │ │ │ │ ├── Test_MathFunction.cpp │ │ │ │ │ ├── Test_Moustache.cpp │ │ │ │ │ ├── Test_ProductOfSinusoids.cpp │ │ │ │ │ └── Test_Zero.cpp │ │ │ │ ├── Punctures/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_Flatness.cpp │ │ │ │ ├── RadiationTransport/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── M1Grey/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── ConstantM1.py │ │ │ │ │ │ ├── Test_ConstantM1.cpp │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── MonteCarlo/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_HomogeneousSphere.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── RelativisticEuler/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── FishboneMoncriefDisk.py │ │ │ │ │ ├── Python/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ └── Test_Tov.py │ │ │ │ │ ├── Test_FishboneMoncriefDisk.cpp │ │ │ │ │ ├── Test_RotatingStar.cpp │ │ │ │ │ ├── Test_SmoothFlow.cpp │ │ │ │ │ ├── Test_Tov.cpp │ │ │ │ │ ├── Test_TovStar.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── ScalarAdvection/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Krivodonova.py │ │ │ │ │ ├── Kuzmin.py │ │ │ │ │ ├── Sinusoid.py │ │ │ │ │ ├── Test_Krivodonova.cpp │ │ │ │ │ ├── Test_Kuzmin.cpp │ │ │ │ │ ├── Test_Sinusoid.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── Test_AnalyticSolution.cpp │ │ │ │ ├── Test_Tags.cpp │ │ │ │ ├── WaveEquation/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_PlaneWave.cpp │ │ │ │ │ ├── Test_RegularSphericalWave.cpp │ │ │ │ │ └── Test_SemidiscretizedDg.cpp │ │ │ │ ├── Xcts/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ConstantDensityStar.py │ │ │ │ │ ├── SchwarzschildIsotropic.py │ │ │ │ │ ├── SchwarzschildKerrSchildIsotropic.py │ │ │ │ │ ├── SchwarzschildMaximalIsotropic.py │ │ │ │ │ ├── SchwarzschildPainleveGullstrand.py │ │ │ │ │ ├── Test_ConstantDensityStar.cpp │ │ │ │ │ ├── Test_Flatness.cpp │ │ │ │ │ ├── Test_HarmonicSchwarzschild.cpp │ │ │ │ │ ├── Test_Kerr.cpp │ │ │ │ │ ├── Test_RotatingStar.cpp │ │ │ │ │ ├── Test_Schwarzschild.cpp │ │ │ │ │ ├── Test_SphericalKerr.cpp │ │ │ │ │ └── Test_TovStar.cpp │ │ │ │ └── __init__.py │ │ │ ├── CMakeLists.txt │ │ │ ├── ConstraintDamping/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Python/ │ │ │ │ │ ├── Constant.py │ │ │ │ │ ├── ConstraintDampingHelpers.py │ │ │ │ │ ├── GaussianPlusConstant.py │ │ │ │ │ ├── TimeDependentTripleGaussian.py │ │ │ │ │ └── TimeDependentTripleGaussianObjectCenters.py │ │ │ │ ├── Test_Constant.cpp │ │ │ │ ├── Test_GaussianPlusConstant.cpp │ │ │ │ └── Test_TimeDependentTripleGaussian.cpp │ │ │ ├── Elasticity/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ConstitutiveRelations/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── CubicCrystal.py │ │ │ │ │ ├── IsotropicHomogeneous.py │ │ │ │ │ ├── Test_CubicCrystal.cpp │ │ │ │ │ ├── Test_IsotropicHomogeneous.cpp │ │ │ │ │ ├── Test_Tags.cpp │ │ │ │ │ └── __init__.py │ │ │ │ ├── PotentialEnergy.py │ │ │ │ ├── Strain.py │ │ │ │ ├── Test_PotentialEnergy.cpp │ │ │ │ ├── Test_Strain.cpp │ │ │ │ └── __init__.py │ │ │ ├── GeneralRelativity/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Christoffel.py │ │ │ │ ├── ComputeGhQuantities.py │ │ │ │ ├── ComputeSpacetimeQuantities.py │ │ │ │ ├── GeodesicEquation.py │ │ │ │ ├── InterfaceNullNormal.py │ │ │ │ ├── KerrSchildCoords.py │ │ │ │ ├── ProjectionOperators.py │ │ │ │ ├── Psi4.py │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_Bindings.py │ │ │ │ │ └── Test_GhBindings.py │ │ │ │ ├── Ricci.py │ │ │ │ ├── RicciScalar.py │ │ │ │ ├── SpacetimeDerivativeOfGothG.py │ │ │ │ ├── Surfaces/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_ComputeItems.cpp │ │ │ │ │ ├── Test_GrSurfaces.cpp │ │ │ │ │ └── Test_Tags.cpp │ │ │ │ ├── Test_Christoffel.cpp │ │ │ │ ├── Test_ComputeGhQuantities.cpp │ │ │ │ ├── Test_ComputeSpacetimeQuantities.cpp │ │ │ │ ├── Test_CurvatureScalarComputeTags.cpp │ │ │ │ ├── Test_CurvatureScalars.cpp │ │ │ │ ├── Test_GeodesicAcceleration.cpp │ │ │ │ ├── Test_GeodesicEquation.cpp │ │ │ │ ├── Test_InterfaceNullNormal.cpp │ │ │ │ ├── Test_KerrHorizon.cpp │ │ │ │ ├── Test_KerrSchildCoords.cpp │ │ │ │ ├── Test_ProjectionOperators.cpp │ │ │ │ ├── Test_Psi4.cpp │ │ │ │ ├── Test_Ricci.cpp │ │ │ │ ├── Test_SpacetimeDerivativeOfGothG.cpp │ │ │ │ ├── Test_Tags.cpp │ │ │ │ ├── Test_TortoiseCoordinates.cpp │ │ │ │ ├── Test_WeylElectric.cpp │ │ │ │ ├── Test_WeylMagnetic.cpp │ │ │ │ ├── Test_WeylPropagating.cpp │ │ │ │ ├── Test_WeylTypeD1.cpp │ │ │ │ ├── TortoiseCoordinates.py │ │ │ │ ├── WeylElectric.py │ │ │ │ ├── WeylElectricScalar.py │ │ │ │ ├── WeylMagnetic.py │ │ │ │ ├── WeylMagneticScalar.py │ │ │ │ ├── WeylPropagating.py │ │ │ │ ├── WeylTypeD1.py │ │ │ │ ├── WeylTypeD1Scalar.py │ │ │ │ └── __init__.py │ │ │ ├── Hydro/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ComovingMagneticField.py │ │ │ │ ├── EquationsOfState/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── DarkEnergyFluid.py │ │ │ │ │ ├── HybridEos.py │ │ │ │ │ ├── IdealFluid.py │ │ │ │ │ ├── PiecewisePolytropicFluid.py │ │ │ │ │ ├── PolytropicFluid.py │ │ │ │ │ ├── Python/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── Test_Enthalpy.py │ │ │ │ │ │ ├── Test_PiecewisePolytropicFluid.py │ │ │ │ │ │ ├── Test_PolytropicFluid.py │ │ │ │ │ │ └── Test_Spectral.py │ │ │ │ │ ├── Test_Barotropic2D.cpp │ │ │ │ │ ├── Test_Barotropic3D.cpp │ │ │ │ │ ├── Test_DarkEnergyFluid.cpp │ │ │ │ │ ├── Test_Enthalpy.cpp │ │ │ │ │ ├── Test_Equilibrium3D.cpp │ │ │ │ │ ├── Test_HybridEos.cpp │ │ │ │ │ ├── Test_IdealFluid.cpp │ │ │ │ │ ├── Test_PiecewisePolytropicFluid.cpp │ │ │ │ │ ├── Test_PolytropicFluid.cpp │ │ │ │ │ ├── Test_SpectralEoS.cpp │ │ │ │ │ └── Test_Tabulated3D.cpp │ │ │ │ ├── InitialData/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── IrrotationalBns.py │ │ │ │ │ └── Test_IrrotationalBns.cpp │ │ │ │ ├── InversePlasmaBeta.py │ │ │ │ ├── LorentzFactor.py │ │ │ │ ├── MassFlux.py │ │ │ │ ├── MassWeightedFluidItems.py │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── ComovingMagneticField.py │ │ │ │ │ ├── LorentzFactor.py │ │ │ │ │ ├── MassFlux.py │ │ │ │ │ ├── MassWeightedFluidItems.py │ │ │ │ │ ├── SoundSpeedSquared.py │ │ │ │ │ ├── SpecificEnthalpy.py │ │ │ │ │ └── Test_StressEnergy.py │ │ │ │ ├── QuadrupoleFormula.py │ │ │ │ ├── SpecificEnthalpy.py │ │ │ │ ├── Test_ComovingMagneticField.cpp │ │ │ │ ├── Test_InversePlasmaBeta.cpp │ │ │ │ ├── Test_LorentzFactor.cpp │ │ │ │ ├── Test_MagneticFieldTreatment.cpp │ │ │ │ ├── Test_MassFlux.cpp │ │ │ │ ├── Test_MassWeightedFluidItems.cpp │ │ │ │ ├── Test_QuadrupoleFormula.cpp │ │ │ │ ├── Test_SoundSpeedSquared.cpp │ │ │ │ ├── Test_SpecificEnthalpy.cpp │ │ │ │ ├── Test_StressEnergy.cpp │ │ │ │ ├── Test_Tags.cpp │ │ │ │ ├── Test_Temperature.cpp │ │ │ │ ├── Test_TestHelpers.cpp │ │ │ │ ├── Test_TransportVelocity.cpp │ │ │ │ └── TransportVelocity.py │ │ │ ├── InitialDataUtilities/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Tags/ │ │ │ │ │ └── Test_InitialData.cpp │ │ │ │ └── Test_NumericData.cpp │ │ │ ├── MathFunctions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Python/ │ │ │ │ │ ├── Gaussian.py │ │ │ │ │ ├── PowX.py │ │ │ │ │ └── Sinusoid.py │ │ │ │ ├── Test_Gaussian.cpp │ │ │ │ ├── Test_PowX.cpp │ │ │ │ ├── Test_Sinusoid.cpp │ │ │ │ └── Test_TensorProduct.cpp │ │ │ ├── Punctures/ │ │ │ │ ├── AdmIntegrals.py │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Python/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ └── Test_Bindings.py │ │ │ │ └── Test_AdmIntegrals.cpp │ │ │ ├── ScalarTensor/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── RampUpFunction.py │ │ │ │ ├── ScalarCharge.py │ │ │ │ ├── ScalarGaussBonnet/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── Test_CouplingParameters.cpp │ │ │ │ │ ├── Test_ScalarSource.cpp │ │ │ │ │ └── Test_Tags.cpp │ │ │ │ ├── Sources.py │ │ │ │ ├── StressEnergy.py │ │ │ │ ├── Test_ConstraintDampingTags.cpp │ │ │ │ ├── Test_ConstraintGammas.cpp │ │ │ │ ├── Test_RampUpFunction.cpp │ │ │ │ ├── Test_ScalarCharge.cpp │ │ │ │ ├── Test_ScalarSource.cpp │ │ │ │ ├── Test_SourceTags.cpp │ │ │ │ ├── Test_StressEnergy.cpp │ │ │ │ └── Xcts/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ScalarMomentum.py │ │ │ │ └── Test_ScalarMomentum.cpp │ │ │ ├── SpecialRelativity/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── LorentzBoostMatrix.py │ │ │ │ └── Test_LorentzBoostMatrix.cpp │ │ │ ├── Xcts/ │ │ │ │ ├── AdmLinearMomentum.py │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── ExtrinsicCurvature.py │ │ │ │ ├── LongitudinalOperator.py │ │ │ │ ├── SpacetimeQuantities.py │ │ │ │ ├── Test_AdmMass.cpp │ │ │ │ ├── Test_AdmMomentum.cpp │ │ │ │ ├── Test_CenterOfMass.cpp │ │ │ │ ├── Test_ExtrinsicCurvature.cpp │ │ │ │ ├── Test_LongitudinalOperator.cpp │ │ │ │ ├── Test_SpacetimeQuantities.cpp │ │ │ │ └── __init__.py │ │ │ └── __init__.py │ │ ├── TestMain.cpp │ │ ├── TestMainCharm.ci │ │ ├── TestMainCharm.cpp │ │ ├── TestMainCharm.hpp │ │ ├── Time/ │ │ │ ├── Actions/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_SelfStartActions.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── ChangeSlabSize/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_Action.cpp │ │ │ │ ├── Test_ChangeSlabSize.cpp │ │ │ │ └── Test_Tags.cpp │ │ │ ├── OptionTags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_InitialSlabSize.cpp │ │ │ │ ├── Test_InitialTime.cpp │ │ │ │ ├── Test_InitialTimeStep.cpp │ │ │ │ ├── Test_LtsStepChoosers.cpp │ │ │ │ ├── Test_MinimumTimeStep.cpp │ │ │ │ ├── Test_TimeStepper.cpp │ │ │ │ └── Test_VariableOrderAlgorithm.cpp │ │ │ ├── StepChoosers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_ByBlock.cpp │ │ │ │ ├── Test_Cfl.cpp │ │ │ │ ├── Test_Constant.cpp │ │ │ │ ├── Test_ElementSizeCfl.cpp │ │ │ │ ├── Test_ErrorControl.cpp │ │ │ │ ├── Test_FixedLtsRatio.cpp │ │ │ │ ├── Test_LimitIncrease.cpp │ │ │ │ ├── Test_Maximum.cpp │ │ │ │ ├── Test_PreventRapidIncrease.cpp │ │ │ │ ├── Test_Random.cpp │ │ │ │ └── Test_StepToTimes.cpp │ │ │ ├── Tags/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_AdaptiveSteppingDiagnostics.cpp │ │ │ │ ├── Test_FixedLtsRatio.cpp │ │ │ │ ├── Test_HistoryEvolvedVariables.cpp │ │ │ │ ├── Test_LtsStepChoosers.cpp │ │ │ │ ├── Test_MinimumTimeStep.cpp │ │ │ │ ├── Test_StepNumberWithinSlab.cpp │ │ │ │ ├── Test_StepperErrorEstimatesEnabled.cpp │ │ │ │ ├── Test_StepperErrorTolerances.cpp │ │ │ │ ├── Test_StepperErrorTolerancesCompute.cpp │ │ │ │ ├── Test_StepperErrors.cpp │ │ │ │ ├── Test_Time.cpp │ │ │ │ ├── Test_TimeAndPrevious.cpp │ │ │ │ ├── Test_TimeStep.cpp │ │ │ │ ├── Test_TimeStepId.cpp │ │ │ │ ├── Test_TimeStepper.cpp │ │ │ │ └── Test_VariableOrderAlgorithm.cpp │ │ │ ├── Test_AdaptiveSteppingDiagnostics.cpp │ │ │ ├── Test_AdvanceTime.cpp │ │ │ ├── Test_ApproximateTime.cpp │ │ │ ├── Test_BoundaryHistory.cpp │ │ │ ├── Test_ChangeStepSize.cpp │ │ │ ├── Test_ChangeTimeStepperOrder.cpp │ │ │ ├── Test_ChooseLtsStepSize.cpp │ │ │ ├── Test_CleanHistory.cpp │ │ │ ├── Test_EvolutionOrdering.cpp │ │ │ ├── Test_History.cpp │ │ │ ├── Test_LargestStepperError.cpp │ │ │ ├── Test_RecordTimeStepperData.cpp │ │ │ ├── Test_SelfStart.cpp │ │ │ ├── Test_Slab.cpp │ │ │ ├── Test_SlabRoundingError.cpp │ │ │ ├── Test_StepperErrorTolerances.cpp │ │ │ ├── Test_Time.cpp │ │ │ ├── Test_TimeSequence.cpp │ │ │ ├── Test_TimeStepId.cpp │ │ │ ├── Test_TimeStepRequest.cpp │ │ │ ├── Test_TimeStepRequestProcessor.cpp │ │ │ ├── Test_UpdateU.cpp │ │ │ ├── TimeSteppers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_AdamsBashforth.cpp │ │ │ │ ├── Test_AdamsCoefficients.cpp │ │ │ │ ├── Test_AdamsLts.cpp │ │ │ │ ├── Test_AdamsMoultonPc.cpp │ │ │ │ ├── Test_ClassicalRungeKutta4.cpp │ │ │ │ ├── Test_DormandPrince5.cpp │ │ │ │ ├── Test_Factory.cpp │ │ │ │ ├── Test_Heun2.cpp │ │ │ │ ├── Test_Rk3HesthavenSsp.cpp │ │ │ │ ├── Test_Rk3Kennedy.cpp │ │ │ │ ├── Test_Rk3Owren.cpp │ │ │ │ ├── Test_Rk3Pareschi.cpp │ │ │ │ ├── Test_Rk4Kennedy.cpp │ │ │ │ ├── Test_Rk4Owren.cpp │ │ │ │ ├── Test_Rk5Owren.cpp │ │ │ │ └── Test_Rk5Tsitouras.cpp │ │ │ └── Triggers/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Test_NearTimes.cpp │ │ │ ├── Test_SlabCompares.cpp │ │ │ ├── Test_Slabs.cpp │ │ │ ├── Test_StepsWithinSlab.cpp │ │ │ ├── Test_TimeCompares.cpp │ │ │ └── Test_Times.cpp │ │ ├── Utilities/ │ │ │ ├── Autodiff/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_Autodiff.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── ErrorHandling/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_AbortWithErrorMessage.cpp │ │ │ │ ├── Test_AssertAndError.cpp │ │ │ │ ├── Test_CaptureForError.cpp │ │ │ │ ├── Test_Error.cpp │ │ │ │ ├── Test_FloatingPointExceptions.cpp │ │ │ │ ├── Test_SegfaultHandler.cpp │ │ │ │ └── Test_Strerror.cpp │ │ │ ├── Kokkos/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── TestKernel.cpp │ │ │ │ ├── TestKernel.hpp │ │ │ │ └── Test_Kokkos.cpp │ │ │ ├── Protocols/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_StaticReturnApplyable.cpp │ │ │ ├── Serialization/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_PupBoost.cpp │ │ │ │ ├── Test_PupStlCpp11.cpp │ │ │ │ ├── Test_PupStlCpp17.cpp │ │ │ │ ├── Test_RegisterDerivedClassesWithCharm.cpp │ │ │ │ └── Test_Serialize.cpp │ │ │ ├── StdHelpers/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_RetrieveUniquePtr.cpp │ │ │ ├── System/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── Test_Prefetch.cpp │ │ │ ├── Test_Algorithm.cpp │ │ │ ├── Test_Array.cpp │ │ │ ├── Test_Base64.cpp │ │ │ ├── Test_Blas.cpp │ │ │ ├── Test_Blas.hpp │ │ │ ├── Test_CachedFunction.cpp │ │ │ ├── Test_CallWithDynamicType.cpp │ │ │ ├── Test_CartesianProduct.cpp │ │ │ ├── Test_CleanupRoutine.cpp │ │ │ ├── Test_CloneUniquePtrs.cpp │ │ │ ├── Test_ConstantExpressions.cpp │ │ │ ├── Test_ContainerHelpers.cpp │ │ │ ├── Test_DereferenceWrapper.cpp │ │ │ ├── Test_EqualWithinRoundoff.cpp │ │ │ ├── Test_FileSystem.cpp │ │ │ ├── Test_Formaline.cpp │ │ │ ├── Test_FractionUtilities.cpp │ │ │ ├── Test_Functional.cpp │ │ │ ├── Test_GetOutput.cpp │ │ │ ├── Test_Gsl.cpp │ │ │ ├── Test_MakeArray.cpp │ │ │ ├── Test_MakeSignalingNan.cpp │ │ │ ├── Test_MakeString.cpp │ │ │ ├── Test_MakeVector.cpp │ │ │ ├── Test_MakeWithValue.cpp │ │ │ ├── Test_Math.cpp │ │ │ ├── Test_MemoryHelpers.cpp │ │ │ ├── Test_Numeric.cpp │ │ │ ├── Test_OptionalHelpers.cpp │ │ │ ├── Test_Overloader.cpp │ │ │ ├── Test_ParallelInfo.cpp │ │ │ ├── Test_PrettyType.cpp │ │ │ ├── Test_PrintHelpers.cpp │ │ │ ├── Test_ProtocolHelpers.cpp │ │ │ ├── Test_Rational.cpp │ │ │ ├── Test_Registration.cpp │ │ │ ├── Test_Requires.cpp │ │ │ ├── Test_SetNumberOfGridPoints.cpp │ │ │ ├── Test_SnakeCase.cpp │ │ │ ├── Test_SplitTuple.cpp │ │ │ ├── Test_StaticCache.cpp │ │ │ ├── Test_StdArrayHelpers.cpp │ │ │ ├── Test_StdHelpers.cpp │ │ │ ├── Test_StlBoilerplate.cpp │ │ │ ├── Test_TMPL.cpp │ │ │ ├── Test_TMPLDocumentation.cpp │ │ │ ├── Test_Tuple.cpp │ │ │ ├── Test_TupleSlice.cpp │ │ │ ├── Test_VectorAlgebra.cpp │ │ │ ├── Test_WrapText.cpp │ │ │ └── TypeTraits/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Test_ArraySize.cpp │ │ │ ├── Test_CanBeCopyConstructed.cpp │ │ │ ├── Test_CreateGetStaticMemberVariableOrDefault.cpp │ │ │ ├── Test_CreateGetTypeAliasOrDefault.cpp │ │ │ ├── Test_CreateHasStaticMemberVariable.cpp │ │ │ ├── Test_CreateHasTypeAlias.cpp │ │ │ ├── Test_CreateIsCallable.cpp │ │ │ ├── Test_FastPointerCast.cpp │ │ │ ├── Test_FunctionInfo.cpp │ │ │ ├── Test_GetFundamentalType.cpp │ │ │ ├── Test_HasEquivalence.cpp │ │ │ ├── Test_HasInequivalence.cpp │ │ │ ├── Test_IsA.cpp │ │ │ ├── Test_IsCallable.cpp │ │ │ ├── Test_IsComplexOfFundamental.cpp │ │ │ ├── Test_IsInteger.cpp │ │ │ ├── Test_IsIterable.cpp │ │ │ ├── Test_IsMaplike.cpp │ │ │ ├── Test_IsStdArray.cpp │ │ │ ├── Test_IsStdArrayOfSize.cpp │ │ │ ├── Test_IsStreamable.cpp │ │ │ └── Test_RemoveReferenceWrapper.cpp │ │ └── Visualization/ │ │ ├── CMakeLists.txt │ │ └── Python/ │ │ ├── CMakeLists.txt │ │ ├── Render3D/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Test_Clip.py │ │ │ └── Test_Domain.py │ │ ├── Test_ElementIdToParaview.py │ │ ├── Test_GenerateTetrahedralConnectivity.py │ │ ├── Test_GenerateXdmf.py │ │ ├── Test_PlotAlongLine.py │ │ ├── Test_PlotCce.py │ │ ├── Test_PlotControlSystem.py │ │ ├── Test_PlotDatFile.py │ │ ├── Test_PlotEccentricityControl.py │ │ ├── Test_PlotEllipticConvergence.py │ │ ├── Test_PlotMemoryMonitors.py │ │ ├── Test_PlotPowerMonitors.py │ │ ├── Test_PlotSizeControl.py │ │ ├── Test_PlotSlice.py │ │ ├── Test_PlotTrajectories.py │ │ ├── Test_ReadInputFile.py │ │ ├── Test_Render1D.py │ │ └── teststyle.mplstyle │ ├── __init__.py │ ├── support/ │ │ ├── CMakeLists.txt │ │ ├── Pipelines/ │ │ │ ├── Bbh/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Test_EccentricityControl.py │ │ │ │ ├── Test_FindHorizon.py │ │ │ │ ├── Test_InitialData.py │ │ │ │ ├── Test_Inspiral.py │ │ │ │ ├── Test_PostprocessId.py │ │ │ │ └── Test_Ringdown.py │ │ │ ├── CMakeLists.txt │ │ │ └── EccentricityControl/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Test_EccentricityControlParams.py │ │ │ └── Test_InitialOrbitalParameters.py │ │ └── Python/ │ │ ├── CMakeLists.txt │ │ ├── Test_DirectoryStructure.py │ │ ├── Test_Machines.py │ │ ├── Test_Main.py │ │ ├── Test_RunNext.py │ │ └── Test_Schedule.py │ └── tools/ │ ├── CMakeLists.txt │ ├── Test_CharmSimplifyTraces.py │ ├── Test_CleanOutput.py │ ├── Test_CompileReleaseNotes.py │ ├── Test_Status.py │ ├── Test_ValidateInputFile.py │ └── __init__.py └── tools/ ├── CMakeLists.txt ├── CharmModulePatches/ │ └── src/ │ ├── Evolution/ │ │ └── DiscontinuousGalerkin/ │ │ └── Messages/ │ │ ├── BoundaryMessage_v7.0.0.decl.h.patch │ │ ├── BoundaryMessage_v7.0.1.decl.h.patch │ │ └── BoundaryMessage_v8.0.0.decl.h.patch │ └── Parallel/ │ └── Algorithms/ │ ├── AlgorithmArray_v7.0.0.decl.h.patch │ ├── AlgorithmArray_v7.0.0.def.h.patch │ ├── AlgorithmArray_v7.0.1.decl.h.patch │ ├── AlgorithmArray_v7.0.1.def.h.patch │ ├── AlgorithmArray_v8.0.0.decl.h.patch │ ├── AlgorithmArray_v8.0.0.def.h.patch │ ├── AlgorithmSingleton_v7.0.0.def.h.patch │ ├── AlgorithmSingleton_v7.0.1.def.h.patch │ └── AlgorithmSingleton_v8.0.0.def.h.patch ├── CharmSimplifyTraces.py ├── CharmTraceReplacements.json ├── CheckCommits.sh ├── CheckFiles.sh ├── CheckMetadata.py ├── CheckOutputFiles.py ├── ClangTidyAll.sh ├── ClangTidyHash.sh ├── CleanOutput.py ├── CompileReleaseNotes.py ├── FileTestDefs.sh ├── Formaline.sh ├── Hooks/ │ ├── CheckFileSize.py │ └── pre-commit.sh ├── ResignCommits.sh ├── SpectrePch.hpp ├── SpectrePrettyPrinters.py ├── Status/ │ ├── CMakeLists.txt │ ├── Dashboard.py │ ├── ExecutableStatus/ │ │ ├── CMakeLists.txt │ │ ├── CharacteristicExtract.py │ │ ├── EvolveGhBinaryBlackHole.py │ │ ├── EvolveGhSingleBlackHole.py │ │ ├── ExecutableStatus.py │ │ ├── SolveXcts.py │ │ └── __init__.py │ ├── Status.py │ └── __init__.py ├── SuppressionsCppCheck.txt ├── ValidateInputFile.py ├── WrapExecutableLinker.sh ├── WrapLibraryLinker.sh ├── __init__.py ├── latex2dox.py ├── llvm-gcov.sh ├── patch_charm_modules.sh └── pr-docs ================================================ FILE CONTENTS ================================================ ================================================ FILE: .clang-format ================================================ --- # We'll use defaults from the Google style. # See http://clang.llvm.org/docs/ClangFormat.html for help. # # We include the full configuration to avoid changes with our code # formatting when there are changes added in clang-format or changes # in Google's style Language: Cpp # BasedOnStyle: Google AccessModifierOffset: -1 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false AlignEscapedNewlines: Left AlignOperands: true AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: All AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: true AlwaysBreakTemplateDeclarations: true BinPackArguments: true BinPackParameters: true BraceWrapping: AfterClass: false AfterControlStatement: false AfterEnum: false AfterFunction: false AfterNamespace: false AfterObjCDeclaration: false AfterStruct: false AfterUnion: false BeforeCatch: false BeforeElse: false IndentBraces: false SplitEmptyFunction: true SplitEmptyRecord: true SplitEmptyNamespace: true BreakBeforeBinaryOperators: None BreakBeforeBraces: Attach BreakBeforeInheritanceComma: false BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeColon BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true ColumnLimit: 80 CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DisableFormat: false ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true ForEachMacros: - foreach - Q_FOREACH - BOOST_FOREACH IncludeCategories: - Regex: '^<.*' Priority: 1 - Regex: '.*' Priority: 2 IncludeIsMainRegex: '([-_](test|unittest))?$' IndentCaseLabels: true IndentWidth: 2 IndentWrappedFunctionNames: false JavaScriptQuotes: Leave JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: false MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 NamespaceIndentation: None ObjCBlockIndentWidth: 2 ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: false PenaltyBreakAssignment: 2 PenaltyBreakBeforeFirstCallParameter: 1 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 ReflowComments: true SortIncludes: true SortUsingDeclarations: true SpaceAfterCStyleCast: false SpaceAfterTemplateKeyword: true SpaceBeforeAssignmentOperators: true SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 2 SpacesInAngles: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false Standard: Auto TabWidth: 8 UseTab: Never AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false PointerAlignment: Left DerivePointerAlignment: false ... ================================================ FILE: .clang-tidy ================================================ # Define the checks we want to use and remove with comments as to why. # # Here is a list of the quirks with clang-tidy file format: # - no apostrophes in the comments # - every comment line in the checks must end with a comma # - every line in the checks must start at the beginning of the line Checks: '*, -abseil-*, -altera-*, -android-*, -bugprone-easily-swappable-parameters, -bugprone-exception-escape, # complains about Catch macros having infinite loops, -bugprone-infinite-loop, # false positive: Catch2 CHECK(a == b) expands to Decomposer() <= a == b, # which triggers the chained comparison check on macro-generated code., -bugprone-chained-comparison, -bugprone-macro-parentheses, # useless as it triggers on calls to value() which already do a check, # and is too aggressive as it requires the check to be immediately before the # access. -bugprone-unchecked-optional-access, # Official justification is not public, unofficial justification has nothing, # specific to iterators and is basically "never create mutable temporaries",, # which is against standard practice everywhere else., -cert-dcl21-cpp, # many static variables we use do not throw and if they do we, # want to terminate anyway, -cert-err58-cpp, -cert-msc51-cpp, -cert-msc32-c, # checks for incorrectly implemented self-assignment, # checks. However, it is broken., -cert-oop54-cpp, -cppcoreguidelines-avoid-c-arrays, -cppcoreguidelines-avoid-do-while, # too many inconvenient positives for us to deal with, -cppcoreguidelines-avoid-magic-numbers, # false positives, -cppcoreguidelines-c-copy-assignment-signature, # sometimes macros are the right answer., -cppcoreguidelines-macro-usage, # public and protected member variables are fine, -cppcoreguidelines-non-private-member-variables-in-classes, # We do not use gsl::owner, -cppcoreguidelines-owning-memory, -fuchsia-*, # defaulting virtual functions in CoordinateMap, -google-default-arguments, # Documented as redundant with -Wold-style-cast. Has more false positives., -google-readability-casting, # specifying int32_t and int64_t instead of just int, -google-runtime-int, # redundant with other checks, -hicpp-*, # We use pragma once instead of include guards, -llvm-header-guard, # Makes code less portable because some implementation-defined STL, # types can be pointers or not. Same as, # readability-qualified-auto below, -llvm-qualified-auto, # We are not developing LLVM libc, -llvmlibc-*, # anonymous namespaces are the idiomatic C++ way to restrict visibility;, # conflicts with misc-use-anonymous-namespace which prefers anonymous namespaces., -llvm-prefer-static-over-anonymous-namespace, # Triggers when "l" is used because it is "too similar" to "I", -misc-confusable-identifiers, # thinks constexpr variables in header files cause ODR violations, -misc-definitions-in-headers, # Insufficiently configurable, does not handle system headers well, -misc-include-cleaner, # false positives, -misc-noexcept-move-constructor, -misc-non-private-member-variables-in-classes, # false positives, -misc-unconventional-assign-operator, -modernize-raw-string-literal, # should be used, but requires possibly a lot of code changes that, # we do not have the resources for, -modernize-use-nodiscard, # this wants everything to use trailing return type syntax, which, # is silly., -modernize-use-trailing-return-type, -performance-noexcept-move-constructor, # complains about decltype(auto), -readability-const-return-type, # style choice, discussed in issue #145, -readability-else-after-return, -llvm-else-after-return, # flagged code that is not very complex, -readability-function-cognitive-complexity, # We have lots of "x", "p", & "os" variable names, -readability-identifier-length, -readability-magic-numbers, -misc-confusable-identifiers # Same as llvm-qualified-auto above., -readability-qualified-auto, # Access specifiers can be useful to structure code, -readability-redundant-access-specifiers, # We can have two of: methods are static when possible, static, # methods are not called through instances, and methods of, # calling, e.g., x.size(), are consistent across classes. We, # choose to lose this one., -readability-static-accessed-through-instance, # we are okay with lower case, -readability-uppercase-literal-suffix,' CheckOptions: - key: cppcoreguidelines-avoid-do-while.IgnoreMacros value: true - key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions value: true - key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor value: true - key: performance-move-const-arg.CheckTriviallyCopyableMove value: false # The fix for this is not supported by GCC 9. - key: modernize-loop-convert.UseCxx20ReverseRanges value: false WarningsAsErrors: '*' # It is unclear if the header filter actually works or how to use it so # just include all headers HeaderFilterRegex: '' FormatStyle: none ================================================ FILE: .claude/hooks/PostFormat.sh ================================================ #!/usr/bin/env bash # Distributed under the MIT License. # See LICENSE.txt for details. # Claude Code PostToolUse hook: auto-format files after Edit/Write. # # - C++ (.cpp, .hpp, .tpp): # Edit -> git-clang-format -f (diff-only formatting) # Write -> clang-format -i (whole-file formatting) # - Python (.py): # black -q && isort -q (single-file formatting) # Returns the path to the best available git-clang-format binary. # Prefers the unversioned `git-clang-format`, then falls back to the # highest-versioned `git-clang-format-N` found in PATH. find_git_clang_format() { if command -v git-clang-format &>/dev/null; then echo "git-clang-format" return fi local best_ver=0 best_bin="" IFS=: read -ra dirs <<< "$PATH" for dir in "${dirs[@]}"; do for bin in "$dir"/git-clang-format-*; do [[ -x "$bin" ]] || continue local ver="${bin##*-}" [[ "$ver" =~ ^[0-9]+$ ]] || continue (( ver > best_ver )) && { best_ver=$ver; best_bin=$bin; } done done echo "$best_bin" } INPUT=$(cat) FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty') TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty') if [[ -z "$FILE" || ! -f "$FILE" ]]; then exit 0 fi case "$FILE" in *.cpp|*.hpp|*.tpp) if [[ "$TOOL" == "Write" ]]; then clang-format -i "$FILE" 2>/dev/null else gcf=$(find_git_clang_format) if [[ -n "$gcf" ]]; then "$gcf" -f -- "$FILE" 2>/dev/null else clang-format -i "$FILE" 2>/dev/null fi fi ;; *.py) black -q "$FILE" 2>/dev/null isort -q "$FILE" 2>/dev/null ;; esac exit 0 ================================================ FILE: .claude/rules/CMake.md ================================================ --- triggers: - glob: "**/CMakeLists.txt" --- - Files listed in spectre_target_sources() and spectre_target_headers() must be in alphabetical order (case-insensitive). When adding or removing entries, maintain the sorted order. - Use ${LIBRARY} variable in CMake target calls, not hardcoded library names. ================================================ FILE: .claude/rules/Cxx.md ================================================ --- triggers: - glob: "**/*.{hpp,cpp,tpp}" --- # SpECTRE Code Rules Reference ## Banned Patterns - `#include ` -> `Parallel/Printf/Printf.hpp` with `Parallel::printf` - `#include ` -> `#include ` - `std::enable_if` -> C++20 `requires` clause - `||` `&&` `!` (logical operators) -> `or` `and` `not` (C++ alternative tokens). Note: `!=` is fine. - `.ckLocal()` -> `Parallel::local(proxy)` - `.ckLocalBranch()` -> `Parallel::local_branch(proxy)` - `return Py_None;` -> `Py_RETURN_NONE` - `TEST_CASE(` -> `SPECTRE_TEST_CASE(` - `Approx(` in tests -> `approx` from `Framework/TestingFramework.hpp` - `namespace _details` / `namespace details` -> `_detail` / `detail` - `boost::optional` / `boost/optional.hpp` -> `std::optional` - `mutable` member variables -> avoid (race conditions in parallel); discuss with core devs - `struct TD;` / `class TD;` -> remove (debug artifacts) - `Ls` as abbreviation -> use `List` - `int` for container sizes/indices -> `size_t` - `noexcept` -> don't add unless overriding a signature that requires it ## Prefer-Library Patterns When you see manual loops over Tensor indices, suggest the existing utility: - Dot product -> `DataStructures/Tensor/EagerMath/DotProduct.hpp` - Cross product -> `EagerMath/CrossProduct.hpp` - Trace -> `EagerMath/Trace.hpp` - Determinant -> `EagerMath/Determinant.hpp` or `DeterminantAndInverse.hpp` - Magnitude/norm -> `EagerMath/Magnitude.hpp` or `Norms.hpp` - Outer product -> `EagerMath/OuterProduct.hpp` - Raise/lower index -> `EagerMath/RaiseOrLowerIndex.hpp` - Gram-Schmidt -> `EagerMath/GramSchmidtOrthonormalize.hpp` - Frame transform -> `EagerMath/FrameTransform.hpp` - Cartesian<->Spherical -> `EagerMath/CartesianToSpherical.hpp` If you spot a tensor loop not covered above, grep `src/DataStructures/Tensor/EagerMath/` and `src/NumericalAlgorithms/` for an existing utility before suggesting the author write their own. Encourage use of tensor expressions `src/DataStructures/Tensor/Expressions/`. For general relativity, generalized harmonic, CCZ4, apparent horizons, and GRMHD, many manipulations like shift from spacetime metric, lapse from spacetime metric, derivative of shift, etc. are implemented as functions in `src/PointwiseFunctions/GeneralRelativity` or `src/PointwiseFunctions/Hydro`. ## Style Rules - **Naming**: CamelCase for classes, template params, files, dirs. snake_case for functions, variables. SCREAMING_SNAKE_CASE for macros. Trailing `_` on private members. Unused params: `/*name*/`. - **Names**: Use full, descriptive names (e.g., `block_id` not `blk_id`). - **Almost always `auto`** except expression templates (e.g. `DataVector`) - **Braces on all loops and if/else** (no braceless one-liners) - **Return by value** preferred. Mutable out-params: `gsl::not_null` (listed first in arg list). - **`std::move`** into members from by-value constructor parameters - **`get(tensor)`** when indices are compile-time known - **Explicit double literals**: `2.0` or `2.`, never bare `2` in floating-point context - **`#pragma once`** for header guards (not `#ifndef`) - **`override`** keyword on all virtual overrides - **`const`** on all immutable objects - **No top-level `const` on value parameters in declarations**: In `.hpp` forward declarations, don't mark value parameters (including pointer-by-value) as `const`. `const` is fine in the corresponding definition. Example: `void foo(int x, double* ptr);` (declaration) vs `void foo(const int x, double* const ptr) { ... }` (definition). - **Templates**: prefer definitions in `.cpp` with explicit instantiations (`GENERATE_EXPLICIT_INSTANTIATIONS`) - **Internal namespaces**: `LibraryOrFile_detail` (e.g. `Tensor_detail`) - **Macros**: avoid if possible; use `constexpr` or templates. Macro vars: add suffix to avoid collisions. - **Error messages**: descriptive, include runtime values. Bad: "Size mismatch". Good: "The number of grid points in matrix 'F' (N) != determinant grid points (M)." - **Header order**: (1) TestingFramework.hpp + blank (tests), (2) corresponding .hpp + blank (.cpp files), (3) STL/external `<>` alphabetical, (4) blank, (5) SpECTRE `""` alphabetical - **Doxygen**: required for all public API in `.hpp`. Use `///` or `/*!`. NO doxygen in `.cpp`. Use `\f$...\f$` for inline math, `align` env (not `eqnarray`) for multi-line. Blank doxygen line before/after out-of-line equations. - **CMake lists**: alphabetical. Use `${LIBRARY}` variable, not hardcoded names. ## Test Requirements - Files: `tests/Unit//Test_.cpp` - Include order: `"Framework/TestingFramework.hpp"`, blank line, system/external includes, blank line, spectre includes. - All helper classes/functions in anonymous `namespace {}` - Test macro: `SPECTRE_TEST_CASE("Unit.Category.Name", "[Unit][Category]")` - Floating-point: `CHECK_ITERABLE_APPROX` (not `Approx`) - Completion: < 5 seconds (prefer < 0.5s) - Random values: `MAKE_GENERATOR(gen)`, test 10^4 times for tolerance - Error tests: `CHECK_THROWS_WITH` inside `#ifdef SPECTRE_DEBUG` - Pointwise functions: test with analytic solution AND random-value comparison via `pypp::check_with_random_values()` - Use metamorphic tests: like `sin^2(x)+cos^2(x)=1` or that a spacetime vector in general relativity that should be null is actually null. I.e, test identities. - Name tests after the component and behavior (e.g., `Test_ApparentHorizonFinder`). - Prefer a single `SPECTRE_TEST_CASE` that calls several anonymous-namespace helper functions over many small `SPECTRE_TEST_CASE`s. - Increase test timeouts sparingly. If necessary, use `// [[TimeOut, SECONDS]]` on the line before `SPECTRE_TEST_CASE`. Default timeout is 2 seconds. ================================================ FILE: .claude/settings.json ================================================ { "permissions": { "allow": [ "Skill(spectre-fix-ci)", "Skill(spectre-fix-issue)", "Skill(spectre-fix-pr)", "Skill(spectre-review)" ] }, "hooks": { "PostToolUse": [ { "matcher": "Edit|Update|Write", "hooks": [ { "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/PostFormat.sh" } ] } ] } } ================================================ FILE: .claude/skills/spectre-fix-ci/SKILL.md ================================================ --- name: spectre-fix-ci description: > Fetch and analyze a failed GitHub Actions job log. When viewing a job in GitHub Actions, the job ID is the last number in the URL, e.g. in "runs/24319442407/job/71002790711" the job ID is "71002790711". allowed-tools: ["Bash"] argument-hint: "JOB_ID [--owner OWNER]" user-invocable: true model-invocable: false --- Read and follow instructions in file `$(git rev-parse --show-toplevel)/.skills/spectre-fix-ci/SKILL.md` ================================================ FILE: .claude/skills/spectre-fix-issue/SKILL.md ================================================ --- name: spectre-fix-issue description: > Fetch a GitHub issue by number. Trigger when the user references a GitHub issue (e.g. "fix issue #1727", "work on #1727"). allowed-tools: ["Bash", "Read"] argument-hint: "ISSUE_NUMBER [--repo OWNER/REPO] [--full]" --- Read and follow instructions in file `$(git rev-parse --show-toplevel)/.skills/spectre-fix-issue/SKILL.md` ================================================ FILE: .claude/skills/spectre-fix-pr/SKILL.md ================================================ --- name: spectre-fix-pr description: > Fetch PR review comments. Trigger when users reference a PR (e.g. "address comments on PR #1234", "work on PR #1234 reviews"). allowed-tools: ["Bash", "Read"] argument-hint: "PR_NUMBER [--repo OWNER/REPO]" --- Read and follow instructions in file `$(git rev-parse --show-toplevel)/.skills/spectre-fix-pr/SKILL.md` ================================================ FILE: .claude/skills/spectre-review/SKILL.md ================================================ --- name: spectre-review description: SpECTRE code review (PR or local commits) argument-hint: "[PR#] [clang-tidy] [coverage]" allowed-tools: ["Bash", "Read", "Grep", "Glob", "Agent", "AskUserQuestion", "TaskCreate", "TaskUpdate", "TaskList"] disable-model-invocation: true --- Read and follow instructions in file `$(git rev-parse --show-toplevel)/.skills/spectre-review/SKILL.md` ================================================ FILE: .codecov.yaml ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Disable PR comments comment: false coverage: status: # Check that PRs increase overall coverage project: default: target: auto # Account for random-value tests sometimes taking different code paths threshold: 0.3% # Check that PRs are fully tested patch: default: target: 100% ================================================ FILE: .devcontainer/cmake-kits.json ================================================ [ { "name": "Default", "compilers": { "C": "clang", "CXX": "clang++", "Fortran": "gfortran" }, "cmakeSettings": { "BUILD_SHARED_LIBS": "ON", "MEMORY_ALLOCATOR": "SYSTEM" }, "preferredGenerator": { "name": "Unix Makefiles" } } ] ================================================ FILE: .devcontainer/devcontainer.json ================================================ { "name": "SpECTRE development environment", "image": "sxscollaboration/spectre:dev", "workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind,consistency=delegated", "workspaceFolder": "${localWorkspaceFolder}", "customizations": { "vscode": { "extensions": [ "eamodio.gitlens", "foxundermoon.shell-format", "github.vscode-pull-request-github", "gruntfuggly.format-modified", "ms-python.black-formatter", "ms-python.python", "ms-vscode.cmake-tools", "ms-vscode.cpptools", "ms-vsliveshare.vsliveshare", "redhat.vscode-yaml", "stkb.rewrap", "streetsidesoftware.code-spell-checker", "twxs.cmake" ], "settings": { "cmake.buildDirectory": "${localWorkspaceFolder}/build-${buildKit}-${buildType}", "editor.rulers": [80], "editor.wordWrap": "off", "editor.formatOnSave": false, "editor.formatOnPaste": true, "editor.formatOnType": true, "python.pythonPath": "/usr/bin/python3", "[python]": { "editor.defaultFormatter": "ms-python.black-formatter" } } } }, "remoteEnv": { "SPECTRE_HOME": "${localWorkspaceFolder}" }, "postCreateCommand": "git config --global --add safe.directory ${localWorkspaceFolder} && mkdir -p /root/.local/share/CMakeTools && cp ${localWorkspaceFolder}/.devcontainer/cmake-kits.json /root/.local/share/CMakeTools/cmake-tools-kits.json" } ================================================ FILE: .dockerignore ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Build directories # Ignore build dirs named similarly to the example in the installation notes; # in general arbitrary names are possible and cannot all be ignored. This will # keep the size of the context down and prevent errors in the demo image where # we create our own `build` directory in the container build* containers/Dockerfile.buildenv ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ # Bug reports: ### Expected behavior: ### Current behavior: ### Environment: Add as an attachment `$SPECTRE_BUILD_DIR/BuildInfo.txt` or add its contents here. # Feature request: ### Component: - [ ] Code - [ ] Documentation - [ ] Build system - [ ] Continuous integration ### Desired feature: - [ ] Detail 1 - [ ] Detail 2 - [ ] Detail 3 ### Detailed discussion: ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ## Proposed changes ### Upgrade instructions ### Code review checklist - [ ] The code is documented and the documentation renders correctly. Run `make doc` to generate the documentation locally into `BUILD_DIR/docs/html`. Then open `index.html`. - [ ] The code follows the stylistic and code quality guidelines listed in the [code review guide](https://spectre-code.org/code_review_guide.html). - [ ] The PR lists upgrade instructions and is labeled `bugfix` or `new feature` if appropriate. - [ ] If a coding agent is used, have one of "Co-Authored-By: Claude Sonnet 4.6 ", "Co-Authored-by: Codex ", or "Co-Authored-By: GitHub Copilot CLI " as the last line of the commit, depending on the agent. ### Further comments ================================================ FILE: .github/actions/parse-compiler/action.yaml ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. name: Parse compiler description: | Parse the compiler name and version from the input and set the environment variables CC, CXX, FC, COMPILER_ID, and COMPILER_VERSION. For nvcc, it sets CC, CXX, and FC to the host compilers (gcc, g++, gfortran). inputs: compiler: description: Compiler to parse, e.g. 'gcc-10' required: true runs: using: "composite" steps: - run: | if [[ ${{ inputs.compiler }} =~ (gcc|clang|nvcc)-([0-9\.\-]+) ]]; then COMPILER_ID=${BASH_REMATCH[1]} COMPILER_VERSION=${BASH_REMATCH[2]} if [[ $COMPILER_ID = gcc ]]; then CC=gcc-${COMPILER_VERSION}; CXX=g++-${COMPILER_VERSION}; FC=gfortran-${COMPILER_VERSION}; elif [[ $COMPILER_ID = clang ]]; then CC=clang-${COMPILER_VERSION}; CXX=clang++-${COMPILER_VERSION}; FC=gfortran-11; elif [[ $COMPILER_ID = nvcc ]]; then # Set host compilers CC=gcc; CXX=g++; FC=gfortran-11; fi fi echo "CC=$CC" >> $GITHUB_ENV echo "CXX=$CXX" >> $GITHUB_ENV echo "FC=$FC" >> $GITHUB_ENV echo "COMPILER_ID=$COMPILER_ID" >> $GITHUB_ENV echo "COMPILER_VERSION=$COMPILER_VERSION" >> $GITHUB_ENV shell: bash ================================================ FILE: .github/problem_matchers/ClangTidy.json ================================================ { "problemMatcher": [ { "owner": "clang-tidy", "pattern": [ { "regexp": "^(?:\\x1b\\[[\\d;]+m)*(.+):(\\d+):(\\d+):\\s(?:\\x1b\\[[\\d;]+m)*(error):\\s(?:\\x1b\\[[\\d;]+m)*(.+)\\s\\[(.+)\\](?:\\x1b\\[[\\d;]+m)*$", "file": 1, "line": 2, "column": 3, "severity": 4, "message": 5, "code": 6 } ] } ] } ================================================ FILE: .github/scripts/Release.py ================================================ #!/usr/bin/env python # Distributed under the MIT License. # See LICENSE.txt for details. import datetime import difflib import logging import operator import os import pathlib import re import tempfile import textwrap import urllib from typing import List import git import pybtex.database import requests import uplink import yaml from cffconvert.citation import Citation from pybtex.backends.plaintext import Backend as PlaintextBackend from pybtex.style.formatting.plain import Style as PlainStyle logger = logging.getLogger(__name__) VERSION_PATTERN = r"(\d{4})\.(\d{2})\.(\d{2})(\.\d+)?" PUBLICATION_DATE_PATTERN = r"\d{4}-\d{2}-\d{2}" DOI_PATTERN = r"10\.\d{4,9}/zenodo\.\d+" ZENODO_ID_PATTERN = r"\d+" def report_check_only(msg: str): logger.info(f"CHECK ONLY: {msg}") def new_version_id_from_response(response): """Retrieves the ID of the new version draft from the API response The "New version" action of the Zenodo API returns the ID of the created version draft in the 'links' section, as documented [here](https://developers.zenodo.org/#new-version). This function parses the ID out of the link. """ new_version_url = response.json()["links"]["latest_draft"] return int( pathlib.PurePosixPath( urllib.parse.urlparse(new_version_url).path ).parts[-1] ) def raise_for_status(response): try: response.raise_for_status() except requests.exceptions.HTTPError as err: if response.status_code >= 400 and response.status_code < 500: raise requests.exceptions.HTTPError( yaml.safe_dump(response.json(), allow_unicode=True) ) from err else: raise return response @uplink.response_handler(raise_for_status) class Zenodo(uplink.Consumer): """Abstraction of the [Zenodo API](https://developers.zenodo.org)""" @uplink.returns.json @uplink.get("deposit/depositions/{id}") def get_deposition(self, id: uplink.Path): """Retrieves a deposition by ID.""" pass @uplink.returns.json @uplink.get("records/{id}") def get_record(self, id: uplink.Path): """Retrieves a published record by ID.""" pass @uplink.returns.json( key=("metadata", "relations", "version", 0, "is_last"), type=bool, ) @uplink.get("records/{id}") def is_latest_version(self, record_id: uplink.Path(name="id")): """Checks whether the record is the latest version.""" pass @uplink.response_handler(new_version_id_from_response) @uplink.post("deposit/depositions/{id}/actions/newversion") def new_version(self, latest_version_id: uplink.Path(name="id")): """Invoke the "New version" action on a deposition. Returns: The ID of the new version. """ pass @uplink.returns.json @uplink.post("deposit/depositions/{id}/actions/publish") def publish(self, id: uplink.Path): """Invoke the "Publish" action on a deposition.""" pass @uplink.json @uplink.returns.json @uplink.put("deposit/depositions/{id}") def update_deposition(self, id: uplink.Path, **body: uplink.Body): """Update the deposition with the metadata""" pass @uplink.returns.json @uplink.put("files/{bucket_id}/{filename}") def upload_file( self, bucket_id: uplink.Path, filename: uplink.Path, file: uplink.Body ): """Uploads a file to the bucket.""" pass @uplink.response_handler(raise_for_status) class Github(uplink.Consumer): """Abstraction of the [GitHub REST API](https://docs.github.com/en/rest)""" # This endpoint is not currently implemented in PyGithub, so we wrap it # here manually @uplink.headers({"Content-Type": "text/x-markdown"}) @uplink.response_handler(operator.attrgetter("text")) @uplink.post("markdown/raw") def render_markdown_raw(self, text: uplink.Body): """Render Markdown in plain format like a README.md file on GitHub""" pass @uplink.returns.json @uplink.get("repos/{user}/{repo}/releases/tags/{tag}") def get_release_by_tag( self, user: uplink.Path, repo: uplink.Path, tag: uplink.Path ): pass @uplink.returns.json @uplink.get("repos/{user}/{repo}/releases/{release_id}/assets") def get_assets( self, user: uplink.Path, repo: uplink.Path, release_id: uplink.Path ): pass def to_plaintext_reference( bib_entry: pybtex.database.Entry, style=PlainStyle(), backend=PlaintextBackend(), ) -> str: # pybtex doesn't support 'software' bibtex types for some reason: # https://bitbucket.org/pybtex-devs/pybtex/issues/157/support-for-software-and-patent-entries-in if bib_entry.type == "software": bib_entry.type = "misc" return style.format_entry(label=bib_entry.key, entry=bib_entry).text.render( backend ) def collect_zenodo_metadata( metadata: dict, references: List[pybtex.database.Entry], github: Github ) -> dict: """Produces the metadata that we send to Zenodo Args: metadata: The project metadata read from the YAML file. This is the main source of information for this function. references: List of references resolved from 'metadata["References"]'. They will be formatted and sent to Zenodo. github: The GitHub API client. We use it to render the description to HTML in a way that's consistent with GitHub's rendering. Returns: Metadata in the format that the Zenodo API expects. """ # Generate the DOI author list from the authors in the project metadata zenodo_creators = [] for author_tier in ["Core", "Developers", "Contributors"]: for author in metadata["Authors"][author_tier]["List"]: zenodo_creator = dict(name=author["Name"]) if "Orcid" in author: zenodo_creator["orcid"] = author["Orcid"] if "Affiliations" in author and len(author["Affiliations"]) > 0: zenodo_creator["affiliation"] = " and ".join( author["Affiliations"] ) zenodo_creators.append(zenodo_creator) # Render the description to HTML rendered_description = github.render_markdown_raw(metadata["Description"]) # Format references as plain text for Zenodo formatted_references = [ to_plaintext_reference(entry) for entry in references ] # Construct Zenodo metadata return dict( title=metadata["Name"], version=metadata["Version"], publication_date=metadata["PublicationDate"].isoformat(), doi=metadata["Doi"], description=rendered_description, creators=zenodo_creators, related_identifiers=[ dict( identifier=metadata["Homepage"], relation="isDocumentedBy", scheme="url", resource_type="publication-softwaredocumentation", ), dict( identifier=("https://github.com/" + metadata["GitHub"]), relation="isSupplementTo", scheme="url", resource_type="software", ), ], language="eng", communities=[dict(identifier="sxs")], keywords=metadata["Keywords"], license=metadata["License"], upload_type="software", access_right="open", references=formatted_references, ) def to_cff_person(person: pybtex.database.Person) -> dict: """BibTeX to CFF conversion for person objects. The format is defined here: https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#definitionsperson """ # Map BibTeX to CFF fields name_fields = { "last": "family-names", "bibtex_first": "given-names", "prelast": "name-particle", "lineage": "name-suffix", } result = { cff_field: " ".join(person.get_part(bibtex_field)) for bibtex_field, cff_field in name_fields.items() if person.get_part(bibtex_field) } # Use CFF "entity" format if BibTex has no first & last names if list(result.keys()) == ["family-names"]: return {"name": result["family-names"]} return result def to_cff_reference(bib_entry: pybtex.database.Entry) -> dict: """BibTeX to CFF conversion for references. The format is defined here: https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#definitionsreference """ def _cff_transform(cff_field, bib_value): if cff_field == "type": if bib_value == "inproceedings": return "article" elif bib_value == "incollection": return "article" elif cff_field == "publisher": return {"name": bib_value} elif cff_field == "month": try: return int(bib_value) except ValueError: return { "jan": 1, "feb": 2, "mar": 3, "apr": 4, "may": 5, "jun": 6, "jul": 7, "aug": 8, "sep": 9, "oct": 10, "nov": 11, "dec": 12, }[bib_value[:3].lower()] return bib_value cff_reference = { "type": _cff_transform(cff_field="type", bib_value=bib_entry.type), "authors": [ to_cff_person(person) for person in bib_entry.persons["author"] ], } # Map BibTeX to CFF fields. This is just a subset of the most relevant # fields. fields = { "doi": "doi", "edition": "edition", "isbn": "isbn", "license": "license", "month": "month", "number": "number", "pages": "pages", "publisher": "publisher", "title": "title", "url": "url", "version": "version", "volume": "volume", "year": "year", "booktitle": "collection-title", } for bibtex_field, value in bib_entry.fields.items(): bibtex_field = bibtex_field.lower() if bibtex_field in fields: cff_field = fields[bibtex_field] cff_reference[cff_field] = _cff_transform( cff_field=cff_field, bib_value=value ) return cff_reference def collect_citation_metadata( metadata: dict, references: List[pybtex.database.Entry] ) -> dict: """Produces the data stored in the CITATION.cff file Args: metadata: The project metadata read from the YAML file. This is the main source of information for this function. references: List of references resolved from 'metadata["References"]'. They will be converted to CFF. Returns: Citation data in the [Citation File Format](https://github.com/citation-file-format/citation-file-format) """ # Author list citation_authors = [] for author_tier in ["Core", "Developers", "Contributors"]: for author in metadata["Authors"][author_tier]["List"]: family_names, given_names = author["Name"].split(", ") citation_author = { "family-names": family_names, "given-names": given_names, } if "Orcid" in author: citation_author["orcid"] = ( "https://orcid.org/" + author["Orcid"] ) if "Affiliations" in author and len(author["Affiliations"]) > 0: citation_author["affiliation"] = " and ".join( author["Affiliations"] ) citation_authors.append(citation_author) # References in CITATION.cff format citation_references = [to_cff_reference(entry) for entry in references] return { "cff-version": "1.2.0", "message": ( "Please cite SpECTRE in any publications that make use of its code" " or data. Cite the latest version that you use in your" " publication. The citation for this version is listed below." ), "title": metadata["Name"], "url": metadata["Homepage"], "repository-code": "https://github.com/" + metadata["GitHub"], "version": metadata["Version"], "date-released": metadata["PublicationDate"], "doi": metadata["Doi"], "authors": citation_authors, "keywords": metadata["Keywords"], "license": metadata["License"], "references": citation_references, } def build_bibtex_entry(metadata: dict): """Builds a BibTeX entry that we suggest people cite in publications Args: metadata: The project metadata read from the YAML file Returns: A pybtex.database.Entry. Use the `to_string` member function to convert to a string in BibTeX, YAML or other formats. """ # We truncate the author list in the BibTeX entry after 'Developers', # because not all journals are happy with printing an excessively long # author list, e.g. Phys. Rev. wants at most 15 authors. By truncating the # author list here, the user who copies the BibTeX entry doesn't have to # make the decision where to truncate. authors = [ pybtex.database.Person(author["Name"]) for author in ( metadata["Authors"]["Core"]["List"] + metadata["Authors"]["Developers"]["List"] ) ] + [pybtex.database.Person("others")] entry = pybtex.database.Entry( "software", persons=dict(author=authors), fields=dict( title=( r"\texttt{" + metadata["Name"] + " v" + metadata["Version"] + "}" ), # The 'version' field is not used by revtex4-2, so we also put the # version in the title version=metadata["Version"], publisher="Zenodo", doi=metadata["Doi"], url=metadata["Homepage"], howpublished=( r"\href{https://doi.org/" + metadata["Doi"] + "}{" + metadata["Doi"] + "}" ), license=metadata["License"], year=str(metadata["PublicationDate"].year), month=str(metadata["PublicationDate"].month), ), ) entry.key = "spectrecode" return entry def prepare( metadata: dict, version_name: str, metadata_file: str, citation_file: str, bib_file: str, references_file: str, readme_file: str, zenodo: Zenodo, github: Github, update_only: bool, check_only: bool, ): # Validate new version name match_version_name = re.match(VERSION_PATTERN + "$", version_name) if not match_version_name: raise ValueError( f"Version name '{version_name}' doesn't match " f"pattern '{VERSION_PATTERN}'." ) publication_date = datetime.date( year=int(match_version_name.group(1)), month=int(match_version_name.group(2)), day=int(match_version_name.group(3)), ) if update_only: # Don't try to create a new version draft on Zenodo but update the # existing one. We assume that the metadata in the repository already # point to the existing version draft on Zenodo that we want to update. # This is the case when the user has run this script without the # `--update-only` option before and has thus created the new version # draft on Zenodo, and is now running it again with the `--update-only` # option to push updated metadata to the draft. new_version_id = metadata["ZenodoId"] else: # Zenodo doesn't have a draft for the new version yet, or the metadata # in the repository is not yet updated. Either way, we use the ID from # the metadata to obtain the latest version on Zenodo and create a new # draft. Zenodo doesn't create another draft if one already exists, but # just returns it. latest_version_id = metadata["ZenodoId"] try: assert zenodo.is_latest_version(record_id=latest_version_id), ( "The latest Zenodo version ID in the repository is" f" {latest_version_id}, but Zenodo reports it is not the latest" " version." ) except requests.exceptions.HTTPError as err: raise requests.exceptions.HTTPError( f"No published record with ID {latest_version_id} found on " "Zenodo. Use the '--update-only' flag if you're re-running " "the script over a repository that already has an unpublished " "new version ID inserted into Metadata.yaml." ) from err logger.info(f"The latest Zenodo version ID is {latest_version_id}.") # Reserve a DOI by creating a new version on Zenodo. It will remain a # draft until we publish it in the `publish` subprogram. if check_only: report_check_only( "Would create new version on Zenodo with " f"ID {latest_version_id}." ) new_version_id = latest_version_id else: new_version_id = zenodo.new_version( latest_version_id=latest_version_id ) new_version_draft = zenodo.get_deposition(id=new_version_id) new_version_doi = new_version_draft["metadata"]["prereserve_doi"]["doi"] assert new_version_doi, ( "Zenodo did not return a reserved DOI for the new version draft. " "You may want to visit {} to reserve one, save the draft and re-run " "this script with the '--update-only' flag." ).format(new_version_draft["links"]["html"]) logger.info( "The new version draft on Zenodo has " f"ID {new_version_id} and DOI {new_version_doi}." ) # Insert the new version information into the metadata file. We have to # resort to regex-replacements because pyyaml doesn't support # format-preserving round-trips. def replace_in_yaml(content, key, value, validate_value_pattern): content, num_subs = re.subn( r"^{}: {}$".format(key, validate_value_pattern), r"{}: {}".format(key, value), content, flags=re.MULTILINE, ) if num_subs == 0: match = re.search( r"^{}: (.*)$".format(key), content, flags=re.MULTILINE ) if match: raise ValueError( f"The value of '{key}' in the file '{metadata_file}' " f"does not match the pattern '{validate_value_pattern}': " f"{match.group(1)}" ) else: raise ValueError( f"Could not find '{key}' in root of file '{metadata_file}'." ) elif num_subs > 1: raise ValueError( f"Found more than one '{key}' in file '{metadata_file}'." ) return content with open(metadata_file, "r" if check_only else "r+") as open_metadata_file: content_original = open_metadata_file.read() content_new = replace_in_yaml( content_original, "Version", version_name, VERSION_PATTERN ) content_new = replace_in_yaml( content_new, "PublicationDate", publication_date.isoformat(), PUBLICATION_DATE_PATTERN, ) content_new = replace_in_yaml( content_new, "Doi", new_version_doi, DOI_PATTERN ) content_new = replace_in_yaml( content_new, "ZenodoId", new_version_id, ZENODO_ID_PATTERN ) content_diff = "\n".join( difflib.context_diff( content_original.split("\n"), content_new.split("\n"), lineterm="", fromfile=metadata_file, tofile=metadata_file, ) ) if check_only: report_check_only(f"Would apply diff:\n{content_diff}") else: logger.debug(f"Applying diff:\n{content_diff}") open_metadata_file.seek(0) open_metadata_file.write(content_new) open_metadata_file.truncate() logger.info(f"Inserted new version info into '{metadata_file}'.") # Also update the the metadata dict to make sure we don't accidentally use # the old values somewhere metadata["Version"] = version_name metadata["PublicationDate"] = publication_date metadata["Doi"] = new_version_doi metadata["ZenodoId"] = new_version_id def write_file_or_check(filename, content_new): with open(filename, "r" if check_only else "r+") as open_file: content_original = open_file.read() content_diff = "\n".join( difflib.context_diff( content_original.split("\n"), content_new.split("\n"), lineterm="", fromfile=filename, tofile=filename, ) ) if check_only: report_check_only(f"Would apply diff:\n{content_diff}") else: logger.debug(f"Applying diff:\n{content_diff}") open_file.seek(0) open_file.write(content_new) open_file.truncate() # Write the CITATION.cff file reference_keys = metadata["References"]["List"] all_references = pybtex.database.parse_file(references_file) references = [all_references.entries[key] for key in reference_keys] citation_data = collect_citation_metadata(metadata, references) citation_file_content = """# Distributed under the MIT License. # See LICENSE.txt for details. # This file is automatically generated. It will be overwritten at every # release. See .github/scripts/Release.py for details. """ citation_file_content += yaml.safe_dump(citation_data, allow_unicode=True) write_file_or_check(citation_file, citation_file_content) # Validate the CFF file Citation(citation_file_content, src=citation_file).validate() # Get the BibTeX entry and write to file bibtex_entry = build_bibtex_entry(metadata) bib_file_content = bibtex_entry.to_string( "bibtex", # LaTeX-encode special characters, instead of writing unicode symbols encoding="ASCII", ) # Fix an issue with encoded accents (a space in the author list is # recognized as delimiter between names) bib_file_content = bib_file_content.replace(r"\c c", r"\c{c}") # Wrap long lines in BibTeX output bib_file_content = "\n".join( [textwrap.fill(line, width=80) for line in bib_file_content.split("\n")] ) write_file_or_check(bib_file, bib_file_content) # Insert the new version information into the README def replace_badge_in_readme(content, key, image_url, link_url): content, num_subs = re.subn( r"\[!\[{}\]\(.*\)\]\(.*\)".format(key), r"[![{}]({})]({})".format(key, image_url, link_url), content, flags=re.MULTILINE, ) assert ( num_subs > 0 ), f"Could not find badge '{key}' in file '{readme_file}'." return content def replace_doi_in_readme(content, doi, doi_url): content, num_subs = re.subn( r"DOI: \[{}\]\(.*\)".format(DOI_PATTERN), r"DOI: [{}]({})".format(doi, doi_url), content, flags=re.MULTILINE, ) assert ( num_subs > 0 ), "Could not find DOI (matching '{}') with link in file '{}'.".format( DOI_PATTERN, readme_file ) return content def replace_link_in_readme(content, link_text, link_url): content, num_subs = re.subn( r"\[{}\]\(.*\)".format(link_text), r"[{}]({})".format(link_text, link_url), content, flags=re.MULTILINE, ) assert num_subs > 0, ( f"Could not find link with text '{link_text}' in " f"file '{readme_file}'." ) return content def replace_bibtex_entry_in_readme(content, bibtex_entry): bibtex_entry_string = bib_file_content # Work around an issue with escaping LaTeX commands bibtex_entry_string = bibtex_entry_string.replace("\\", "\\\\") FENCE_PATTERN = "" content, num_subs = re.subn( (FENCE_PATTERN + "(.*)" + FENCE_PATTERN), ( FENCE_PATTERN + "\n```bib\n" + bibtex_entry_string.strip() + "\n```\n" + FENCE_PATTERN ), content, flags=re.DOTALL, ) assert ( num_subs > 0 ), f"Could not find a BibTeX entry in file '{readme_file}'." return content with open(readme_file, "r" if check_only else "r+") as open_readme_file: content_original = open_readme_file.read() content = replace_badge_in_readme( content_original, "release", f"https://img.shields.io/badge/release-v{version_name}-informational", "https://github.com/{}/releases/tag/v{}".format( metadata["GitHub"], version_name ), ) content = replace_badge_in_readme( content, "DOI", f"https://zenodo.org/badge/doi/{new_version_doi}.svg", f"https://doi.org/{new_version_doi}", ) content = replace_doi_in_readme( content, new_version_doi, f"https://doi.org/{new_version_doi}" ) # We don't currently link to the Zenodo BibTeX entry because it isn't # very good. Instead, we generate our own. content = replace_bibtex_entry_in_readme(content, bibtex_entry) content_diff = "\n".join( difflib.context_diff( content_original.split("\n"), content.split("\n"), lineterm="", fromfile=readme_file, tofile=readme_file, ) ) if check_only: report_check_only(f"Would apply diff:\n{content_diff}") else: logger.debug(f"Applying diff:\n{content_diff}") open_readme_file.seek(0) open_readme_file.write(content) open_readme_file.truncate() # Upload the updated metadata to Zenodo zenodo_metadata = collect_zenodo_metadata(metadata, references, github) logger.debug( "The metadata we'll send to Zenodo are:\n{}".format( yaml.safe_dump(zenodo_metadata, allow_unicode=True) ) ) if check_only: report_check_only("Would upload metadata to Zenodo.") else: zenodo.update_deposition(id=new_version_id, metadata=zenodo_metadata) logger.debug( ( "New Zenodo version draft is now prepared. You can edit " "it here:\n{}" ).format(new_version_draft["links"]["html"]) ) def publish( metadata: dict, zenodo: Zenodo, github: Github, auto_publish: bool, check_only: bool, ): version_name = metadata["Version"] new_version_id = metadata["ZenodoId"] # Retrieve the Zenodo deposition for the version draft that we have # prepared before new_version_draft = zenodo.get_deposition(id=new_version_id) # Retrieve the file "bucket" ID for uploading data bucket_id = pathlib.PurePosixPath( urllib.parse.urlparse(new_version_draft["links"]["bucket"]).path ).parts[-1] # Retrieve the URL of the GitHub release archive that we want to upload # to Zenodo gh_user, gh_repo = metadata["GitHub"].split("/") # Alternatively we could use the release ID that GitHub's # 'actions/create-release' returns to retrieve the release gh_release = github.get_release_by_tag( user=gh_user, repo=gh_repo, tag="v" + version_name ) logger.debug( "The release on GitHub is:\n{}".format( yaml.safe_dump(gh_release, allow_unicode=True) ) ) zipball_url = gh_release["zipball_url"] # Stream the release archive to Zenodo. # We keep the file name for the archive on Zenodo the same for each # release so we can just overwrite it. Note that the _unpacked_ directory # name contains the version as expected, since the unpacked directory name # is determined by the GitHub release. archive_filename = gh_repo + ".zip" if check_only: report_check_only( f"Would stream release zipball '{zipball_url}' as " f"filename '{archive_filename}' to bucket '{bucket_id}'." ) else: # Download the zipball from GitHub, then upload to Zenodo. # Note: Something like this should also work to stream the file # directly from GitHub to Zenodo without temporarily saving it, but # Zenodo doesn't currently document their new "bucket" file API so it # is difficult to debug: # with requests.get(zipball_url, stream=True) as zipball_stream: # zipball_stream.raise_for_status() # uploaded_file = zenodo.upload_file(bucket_id=bucket_id, # file=zipball_stream, # filename=archive_filename) zipball_download = requests.get(zipball_url, stream=True) with tempfile.TemporaryFile() as open_tmp_file: for chunk in zipball_download.iter_content(): open_tmp_file.write(chunk) open_tmp_file.seek(0) uploaded_file = zenodo.upload_file( bucket_id=bucket_id, file=open_tmp_file, filename=archive_filename, ) logger.debug( "Release archive upload complete:\n{}".format( yaml.safe_dump(uploaded_file, allow_unicode=True) ) ) # Publish! if auto_publish: if check_only: report_check_only( f"Would publish Zenodo record {new_version_id} now!" ) else: published_record = zenodo.publish(id=new_version_id) logger.debug( "Zenodo record published:\n{}".format( yaml.safe_dump(published_record, allow_unicode=True) ) ) logger.info( ( "Zenodo record is now public! Here's the link to the " "record:\n{}" ).format(published_record["links"]["record_html"]) ) else: logger.info( ( "Release is ready to be published on Zenodo. Go to this " "website, make sure everything looks fine and then hit the " "'Publish' button:\n{}" ).format(new_version_draft["links"]["html"]) ) if __name__ == "__main__": # Always work with the repository that contains this file repo = git.Repo(__file__, search_parent_directories=True) import argparse parser = argparse.ArgumentParser( description=( "Prepare the repository and publish releases on Zenodo as part of" " the automatic versioning procedure. This script is not intended" " to be run outside of GitHub actions. The 'prepare' subprogram" " reserves a DOI on Zenodo and inserts it into the repository" " along with the new version name. Once the release archive has" " been created, the 'publish'subprogram uploads it to Zenodo." f" Repository: {repo.working_dir}." ) ) parent_parser = argparse.ArgumentParser(add_help=False) parent_parser.add_argument( "--zenodo-token", required=True, help=( "Zenodo access token. Refer to the Zenodo documentation " "for instructions on creating a personal access token." ), ) parent_parser.add_argument( "--zenodo-sandbox", action="store_true", help="Use the Zenodo sandbox instead of the public version of Zenodo", ) parent_parser.add_argument( "--github-token", required=False, help=( "Access token for GitHub queries. Refer to the GitHub documentation" " for instructions on creating a personal access token." ), ) parent_parser.add_argument( "-v", "--verbose", action="count", default=0, help="Verbosity (-v, -vv, ...)", ) parent_parser.add_argument( "--check-only", action="store_true", help=( "Dry mode, only check that all files are consistent. Nothing is" " edited or uploaded to Zenodo. Used in CI tests to make sure" " changes to the repository remain compatible with this script." ), ) subparsers = parser.add_subparsers() parser_prepare = subparsers.add_parser("prepare", parents=[parent_parser]) parser_prepare.set_defaults(subprogram=prepare) parser_prepare.add_argument( "--update-only", action="store_true", help=( "Only update an existing version draft on Zenodo, not creating a " "new one. Use this flag if the metadata in the repository already " "reference the new version draft on Zenodo." ), ) parser_prepare.add_argument( "--version-name", required=False, help=( "The name of the new version. Will be inserted into the " "'--metadata-file'. Required unless '--check-only'." ), ) parser_publish = subparsers.add_parser("publish", parents=[parent_parser]) parser_publish.set_defaults(subprogram=publish) parser_publish.add_argument( "--auto-publish", action="store_true", help=( "Publish the Zenodo record once it's ready. " "WARNING: Published records cannot be deleted and editing is " "limited. Omit this argument to print out the link to the " "prepared draft on Zenodo so you can do a manual sanity-check " "before publishing it." ), ) args = parser.parse_args() # Set the log level logging.basicConfig(level=logging.WARNING - args.verbose * 10) logging.getLogger("pykwalify").setLevel(logging.CRITICAL) del args.verbose # Load the project metadata metadata_file = os.path.join(repo.working_dir, "Metadata.yaml") args.metadata = yaml.safe_load(open(metadata_file, "r")) if args.subprogram == prepare: args.metadata_file = metadata_file # Make passing a version name optional in check-only mode if args.subprogram == prepare: assert args.check_only or args.version_name, ( "The '--version-name' argument is required unless you run in " "'--check-only' mode." ) if args.check_only and not args.version_name: args.version_name = args.metadata["Version"] # Locate project files if args.subprogram == prepare: args.readme_file = os.path.join(repo.working_dir, "README.md") args.citation_file = os.path.join(repo.working_dir, "CITATION.cff") args.bib_file = os.path.join(repo.working_dir, "citation.bib") args.references_file = os.path.join( repo.working_dir, args.metadata["References"]["BibliographyFile"] ) # Configure the Zenodo API client args.zenodo = Zenodo( base_url=( "https://sandbox.zenodo.org/api/" if args.zenodo_sandbox else "https://zenodo.org/api/" ), auth=uplink.auth.BearerToken(args.zenodo_token), ) del args.zenodo_sandbox del args.zenodo_token # Configure the GitHub API client args.github = Github( base_url="https://api.github.com/", auth=( uplink.auth.BearerToken(args.github_token) if args.github_token else None ), ) del args.github_token # Dispatch to the selected subprogram subprogram = args.subprogram del args.subprogram subprogram(**vars(args)) ================================================ FILE: .github/scripts/requirements-release.txt ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Required Python packages for the release workflow GitPython~=3.1.11 pybtex~=0.24.0 PyGithub~=1.53 PyYAML~=5.3.1 tqdm~=4.55.1 uplink==0.9.7 cffconvert==2.0.0 ================================================ FILE: .github/workflows/BuildDockerContainer.yaml ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # This workflow can be run manually on any branch to build and push our Docker # containers. # # We build containers that run both an AMD64/x86-64 and on ARM64. We used to use # a cross-compilation approach with Docker's buildx support, but this can be # quite fragile since cross-compilation is notoriously difficult. While buildx # used an emulator, QEMU, this is still found to be quite fragile with difficult # to diagnose segmentation faults and other errors. To get around this we use # the GitHub Actions ARM64 runners to build the ARM image and the x86-64 runners # to build that image. Then, once both images are pushed to Dockerhub, we create # what Docker calls a "manifest", which is essentially a file that tells Docker # which image to download depending on what it wants. This means for ARM64 it # will automatically download the ARM64 container and similar for # x86-64. The net result is extremely similar to the cross-compilation approach # but since the builds are always native, it is simpler. name: Build Docker container on: workflow_dispatch: inputs: image_name: description: > Image name to push to DockerHub required: true default: 'sxscollaboration/spectre' build_arm: type: boolean description: > Build ARM container in addition to x86_64 default: true jobs: build: name: Build (${{ matrix.arch }}) runs-on: ${{ matrix.runner }} # This environment can be protected to require manual approval before # deployment. On forks where you set your own secrets for authentication # with DockerHub you can choose not to protect this environment. environment: deploy-containers strategy: fail-fast: true # Dynamically set the matrix based on the build_arm input. GitHub Actions # expressions lack a ternary operator, so we use short-circuit evaluation: # condition && value_if_true || value_if_false # fromJSON() then parses the resulting JSON string into an array for # `include`. The multi-line ${{ }} works because YAML folds unquoted # scalars into a single line before the expression is evaluated. # Docs: # https://docs.github.com/en/actions/reference/workflows-and-actions/expressions # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#expanding-or-adding-matrix-configurations matrix: include: ${{ fromJSON(inputs.build_arm && '[{"arch":"amd64","runner":"ubuntu-latest"}, {"arch":"arm64","runner":"ubuntu-24.04-arm"}]' || '[{"arch":"amd64","runner":"ubuntu-latest"}]') }} steps: - name: Checkout repository uses: actions/checkout@v5 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Login to DockerHub uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} # We could also push containers to GitHub instead of DockerHub # - name: Login to GitHub container registry # uses: docker/login-action@v3 # with: # registry: ghcr.io # username: ${{ github.actor }} # password: ${{ secrets.GITHUB_TOKEN }} - name: Build dev container uses: docker/build-push-action@v7 with: push: true context: . file: "./containers/Dockerfile.buildenv" target: dev tags: ${{ inputs.image_name }}:dev-${{ matrix.arch }} platforms: linux/${{ matrix.arch }} build-args: | PARALLEL_MAKE_ARG=-j4 UBUNTU_VERSION=22.04 # The 18.04 container only supports amd64 - name: Build dev1804 container if: ${{ matrix.arch == 'amd64' }} uses: docker/build-push-action@v7 with: push: true context: . file: "./containers/Dockerfile.buildenv" target: dev tags: ${{ inputs.image_name }}:dev1804 platforms: linux/amd64 build-args: | PARALLEL_MAKE_ARG=-j4 UBUNTU_VERSION=18.04 create_manifest: name: Create multi-arch manifest needs: build runs-on: ubuntu-latest environment: deploy-containers steps: - name: Login to DockerHub uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Create dev manifest run: | SOURCES="${{ inputs.image_name }}:dev-amd64" if [ "${{ inputs.build_arm }}" = "true" ]; then SOURCES="$SOURCES ${{ inputs.image_name }}:dev-arm64" fi docker buildx imagetools create \ --tag ${{ inputs.image_name }}:dev $SOURCES - name: Inspect manifest run: > docker buildx imagetools inspect ${{ inputs.image_name }}:dev run_tests: name: Test uses: ./.github/workflows/Tests.yaml needs: create_manifest secrets: inherit with: container: ${{ inputs.image_name }}:dev ================================================ FILE: .github/workflows/ClobberCache.yaml ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Dump a large file into the cache to force GitHub to clobber it. name: Clobber Cache on: workflow_dispatch: jobs: clobber_cache: name: Clobber Cache runs-on: ubuntu-latest strategy: fail-fast: false steps: # Configure the clobber cache - name: Restore cache uses: actions/cache@v4 with: path: cache key: "clobber-cache" restore-keys: | clobber-cache # Generate the random file to clobber the cache. # Note that the file size must be updated as GitHub expands the cache # size limits. - name: Clobber cache run: > mkdir -p cache cd ./cache rm -rf ./* head -c 9900MB /dev/urandom > clobber.txt ================================================ FILE: .github/workflows/DemoContainer.yaml ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. name: Deploy containers on: workflow_dispatch: inputs: image_name: description: Image name to push to DockerHub default: 'sxscollaboration/spectre' build_arm: type: boolean description: Build ARM container in addition to x86_64 default: true workflow_call: inputs: image_name: type: string description: Image name to push to DockerHub default: 'sxscollaboration/spectre' build_arm: type: boolean description: Build ARM container in addition to x86_64 default: true secrets: DOCKERHUB_USERNAME: required: true DOCKERHUB_TOKEN: required: true jobs: build: name: Build (${{ matrix.arch }}) runs-on: ${{ matrix.runner }} environment: deploy-containers strategy: fail-fast: true matrix: include: ${{ fromJSON(inputs.build_arm && '[{"arch":"amd64","runner":"ubuntu-latest"}, {"arch":"arm64","runner":"ubuntu-24.04-arm"}]' || '[{"arch":"amd64","runner":"ubuntu-latest"}]') }} steps: - name: Checkout repository uses: actions/checkout@v5 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Login to DockerHub uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push deploy container uses: docker/build-push-action@v7 with: push: true context: . file: "./containers/Dockerfile.buildenv" target: deploy tags: ${{ inputs.image_name }}:deploy-${{ matrix.arch }} platforms: linux/${{ matrix.arch }} build-args: PARALLEL_MAKE_ARG=-j4 - name: Build and push demo container uses: docker/build-push-action@v5 with: push: true context: . file: "./containers/Dockerfile.buildenv" target: demo tags: ${{ inputs.image_name }}:demo-${{ matrix.arch }} platforms: linux/${{ matrix.arch }} build-args: PARALLEL_MAKE_ARG=-j4 create_manifests: name: Create multi-arch manifests needs: build runs-on: ubuntu-latest environment: deploy-containers steps: - name: Login to DockerHub uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Create deploy manifest run: | SOURCES="${{ inputs.image_name }}:deploy-amd64" if [ "${{ inputs.build_arm }}" = "true" ]; then SOURCES="$SOURCES ${{ inputs.image_name }}:deploy-arm64" fi docker buildx imagetools create \ --tag ${{ inputs.image_name }}:deploy \ --tag ${{ inputs.image_name }}:latest \ $SOURCES - name: Create demo manifest run: | SOURCES="${{ inputs.image_name }}:demo-amd64" if [ "${{ inputs.build_arm }}" = "true" ]; then SOURCES="$SOURCES ${{ inputs.image_name }}:demo-arm64" fi docker buildx imagetools create \ --tag ${{ inputs.image_name }}:demo $SOURCES - name: Inspect manifests run: | docker buildx imagetools inspect ${{ inputs.image_name }}:deploy docker buildx imagetools inspect ${{ inputs.image_name }}:demo ================================================ FILE: .github/workflows/DeployStaticExecutables.yaml ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. name: Deploy static executables on: release: types: [published] workflow_dispatch: inputs: tag_name: type: string required: true description: The name of the release tag jobs: deploy_static_execs: name: Deploy static executables and libraries runs-on: ubuntu-latest env: RELEASE_TAG_NAME: ${{ inputs.tag_name || github.event.release.tag_name }} steps: - name: Checkout repository uses: actions/checkout@v5 # Build static executables in a Docker container with an older version # of Ubuntu so that the glibc is compatible with most Linux distros. - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Build static executables uses: docker/build-push-action@v7 with: push: false context: . file: "./containers/Dockerfile.buildenv" target: deploy_static_execs_and_libs tags: sxs-collaboration/spectre:deploy_static_execs_and_libs platforms: linux/amd64 load: true build-args: | UBUNTU_VERSION=18.04 PARALLEL_MAKE_ARG=-j4 - name: Run Docker container run: > docker run --name static-execs sxs-collaboration/spectre:deploy_static_execs_and_libs - name: Install python dependencies run: > pip3 install numpy h5py gdown - name: Download extra data to include for CCE run: | gdown \ "https://drive.google.com/uc?id=1CmgLLfuLod8stc13EtmjHUvBoIgSVD-Y" gdown \ "https://drive.google.com/uc?id=1mN1oFQ7UcB1wsiXw9dphwAprQqufLia0" gdown \ "https://drive.google.com/uc?id=1yYMM4PVUec9pIjKTxI4aCpo0Umqconr8" - name: Copy CCE executables from the container run: > mkdir CceExecutables; mkdir ./CceExecutables/PreprocessCceWorldtube; mkdir ./CceExecutables/Tests; cp ./tests/InputFiles/Cce/CharacteristicExtract.yaml ./CceExecutables/CharacteristicExtract.yaml cp ./tests/InputFiles/PreprocessCceWorldtube/PreprocessCceWorldtube.yaml ./CceExecutables/PreprocessCceWorldtube/PreprocessCceWorldtube.yaml cp ./tests/InputFiles/PreprocessCceWorldtube/AdmFirstOrderDriverPreprocessCceWorldtube.yaml ./CceExecutables/PreprocessCceWorldtube/AdmFirstOrderDriverPreprocessCceWorldtube.yaml cp ./tests/InputFiles/PreprocessCceWorldtube/AdmSecondOrderDriverPreprocessCceWorldtube.yaml ./CceExecutables/PreprocessCceWorldtube/AdmSecondOrderDriverPreprocessCceWorldtube.yaml docker cp static-execs:/work/spectre/build/bin/CharacteristicExtract ./CceExecutables/ docker cp static-execs:/work/spectre/build/bin/PreprocessCceWorldtube ./CceExecutables/PreprocessCceWorldtube/ docker cp static-execs:/work/spectre/build/bin/WriteCceWorldtubeCoordsToFile ./CceExecutables/PreprocessCceWorldtube/ - name: Test CCE executable outside of container run: | mv BondiSachsCceR0200.h5 ./CceExecutables/Tests/ mv CheckCceOutput.py ./CceExecutables/Tests/ mv CharacteristicExtractReduction_Expected.h5 \ ./CceExecutables/Tests/ sed -i 's/CceR0257/Tests\/BondiSachsCceR0200/g' \ ./CceExecutables/CharacteristicExtract.yaml cd ./CceExecutables/ ./CharacteristicExtract \ --input-file ./CharacteristicExtract.yaml python ./Tests/CheckCceOutput.py rm CharacteristicExtractReduction.h5 cd ../ - name: Create CCE executables release asset # Note: We use xz compression since it's much better than gzip, even # though it's a decent bit slower. Specifically, xz is two thirds the # size of gzip. run: | tar cJf CceExecutables.tar.xz CceExecutables - name: Upload to release uses: softprops/action-gh-release@v3 with: tag_name: ${{ env.RELEASE_TAG_NAME }} fail_on_unmatched_files: true files: | CceExecutables.tar.xz ================================================ FILE: .github/workflows/NewContributors.yaml ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Add new contributors when their first PR was merged name: New contributors on: pull_request_target: branches: [develop] types: [closed] jobs: new_contributors: if: github.event.pull_request.merged == true name: Notify runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - name: Check PR author is new id: check_pr_author shell: python run: | import yaml def all_authors(): authors = yaml.safe_load(open('Metadata.yaml', 'r'))['Authors'] for tier in ['Core', 'Developers', 'Contributors']: for author in authors[tier]['List']: yield author['GitHub'] pr_author = '${{ github.event.pull_request.user.login }}' if pr_author not in all_authors(): print('::set-output name=is_new::true') - name: Comment on PR if: steps.check_pr_author.outputs.is_new uses: peter-evans/create-or-update-comment@v5 with: issue-number: ${{ github.event.pull_request.number }} body: > # Newlines are line breaks, body renders as GitHub markdown @${{ github.event.pull_request.user.login }} looks like this is your first contribution to SpECTRE. Welcome! 🎉 Your contribution is much appreciated, and we invite you to add your name to the author list: 1. Edit the [`Metadata.yaml`](https://github.com/${{ github.event.pull_request.user.login }}/spectre/blob/develop/Metadata.yaml) file in the repository. 2. Add an entry to the list in `Authors.Contributors` with your name, affiliation, etc. Note that the list is ordered alphabetically by last name. 3. Commit the change on a new branch and open a pull request with the change. Once the pull request is merged, your name will appear on the [SpECTRE DOI on Zenodo](https://doi.org/10.5281/zenodo.4290404) with the next public release. ================================================ FILE: .github/workflows/PostRelease.yaml ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Automations that run on published releases name: Post release on: release: types: [published] workflow_dispatch: inputs: tag_name: description: 'Tag name of the release' required: true jobs: add_spack_version: name: Add version to Spack # Checksum the new release and send a PR to Spack that adds the new version. # The 'sxs-bot' GitHub account is the author of the commit and the PR. # - This job requires a repository secret named `GH_TOKEN_SXSBOT_SPACK` that # has write access to the `sxs-bot/spack` repository. runs-on: ubuntu-latest env: RELEASE_TAG_NAME: ${{ inputs.tag_name || github.event.release.tag_name }} steps: - name: Download Spack uses: actions/checkout@v5 with: repository: spack/spack fetch-depth: 0 token: ${{ secrets.GH_TOKEN_SXSBOT_SPACK }} - name: Add spack-python to path run: | echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH - name: Checksum new version # Download and checksum the release tarball, and add a line to Spack's # `spectre/package.py`` file with the new version. # # The package file defines versions in lines like this: # # version('develop', branch='develop') # version('2022.01.03', sha256='872a0d1...') # ... # # The `spack.util.format.get_version_lines` function returns a string # with lines like this for the new version(s), including the correct # indentation. Therefore, we insert the new lines into the file right # below the 'develop' version. shell: spack-python {0} run: | import spack.spec import spack.stage import spack.repo import spack.util.format import os # The tag name includes the 'v' prefix release_name = '${{ env.RELEASE_TAG_NAME }}'[1:] # Get the URL for the release tarball. The # 'github.event.release.tarball_url' points to a slightly different # 'https://api.github.com/...' URL, which has a different checksum # than the tarball listed on the GitHub release page and used by # Spack. pkg_cls = spack.repo.PATH.get_pkg_class('spectre') pkg = pkg_cls(spack.spec.Spec('spectre')) release_url = pkg.url_for_version(release_name) url_dict = { release_name: release_url, } version_hashes = spack.stage.get_checksums_for_versions( url_dict, pkg.name, fetch_options=pkg.fetch_options, ) version_lines = spack.util.format.get_version_lines( version_hashes, url_dict ) package_file = os.path.join(pkg.package_dir, 'package.py') with open(package_file, 'r') as open_package_file: package_file_lines = open_package_file.readlines() with open(package_file, 'w') as open_package_file: for line in package_file_lines: open_package_file.write(line) if line.strip().startswith('version("develop"'): open_package_file.write(version_lines + "\n") - name: Fix code formatting run: | spack style --fix `git diff --name-only` # Formatting can also be fixed later by Spack maintainers in the PR, so # it's fine if it fails here for some reason continue-on-error: true - name: Print diff run: | git diff - name: Send pull request to Spack uses: peter-evans/create-pull-request@v8 with: token: ${{ secrets.GH_TOKEN_SXSBOT_SPACK }} commit-message: "spectre: add ${{ env.RELEASE_TAG_NAME }}" committer: "sxs-bot " branch: "spectre-${{ env.RELEASE_TAG_NAME }}" delete-branch: true push-to-fork: sxs-bot/spack title: "spectre: add ${{ env.RELEASE_TAG_NAME }}" body: "" # Build and push the `demo` container to DockerHub on releases. This is # because the `demo` container has pre-built executables that we want to keep # up to date. docker: uses: ./.github/workflows/DemoContainer.yaml secrets: inherit ================================================ FILE: .github/workflows/Spack.yaml ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Installation test with the Spack package manager name: Spack on: # Could run this on a schedule once Spack is stable enough to not break every # week. # schedule: # - cron: '0 0 * * 1' # every Monday morning workflow_dispatch: concurrency: group: spack cancel-in-progress: true jobs: spack_install: name: Install strategy: matrix: host: [ubuntu-latest, macos-latest] compiler: [gcc, llvm, apple-clang] exclude: - host: ubuntu-latest compiler: apple-clang version: # A non-exhaustive set of versions to test, e.g., versions listed in # published papers. - 'develop' - '2021.12.15' fail-fast: false runs-on: ${{ matrix.host }} env: # This is the configuration ("spec") that we'll install with Spack # - Build a subset of executables, and Python bindings # - Disable debug symbols to fit in the memory of the GitHub Actions VM # - Select the 'multicore' backend for Charm++, since we're running on a # single node. # - Select HDF5 without MPI to avoid compiling MPI. SPECTRE_SPEC: >- # Line breaks are spaces, no trailing newline spectre@${{ matrix.version }} executables=SolvePoisson1D +python ~debug_symbols ^${{ matrix.compiler }} ^charmpp backend=multicore ^hdf5~mpi SPACK_COLOR: always steps: - name: Install compiler if: matrix.host == 'macos-latest' && matrix.compiler == 'llvm' run: | brew install llvm echo "$(brew --prefix llvm)/bin" >> $GITHUB_PATH - name: Install Spack run: | git clone -c feature.manyFiles=true --depth=1 \ https://github.com/spack/spack.git echo $PWD/spack/bin >> $GITHUB_PATH - name: Configure Spack run: | spack debug report spack compiler find spack compiler info ${{ matrix.compiler }} spack external find - name: Print packages to install run: | spack spec -I ${SPECTRE_SPEC} - name: Install SpECTRE run: | spack install --show-log-on-error ${SPECTRE_SPEC} ================================================ FILE: .github/workflows/Tests.yaml ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Continuous integration tests that pull requests are required to pass. This # workflow can also be dispatched manually to tag and release versions. name: Tests # Set any defaults for the runs below. # - use bash as the default shell since this is almost certainly what # is always expected. We use regular expressions in a few places # that rely on bash. defaults: run: shell: bash # Note that by default the jobs only run on the base repository, testing pull # requests and merge commits. Enable GitHub Actions in your fork's repository # settings to also run the tests on every push to one of your branches. on: # We run all jobs when pull requests are opened, commits are pushed, or pull # requests are re-opened after being closed. # The jobs triggered by this event run on the base repository of the pull # request, so they have access to its caches. pull_request: # We run those jobs that require no information about a pull request (e.g. # unit tests) also on `push` events. This setup tests merge commits into # `develop` and also builds up caches on `develop` that can be re-used by PRs. # It also runs the jobs on forks if they have GitHub Actions enabled. push: branches-ignore: - gh-pages # Allow running the workflow manually to run tests and optionally release a # version on success (see the dev guide on "Automatic versioning") workflow_dispatch: inputs: release_version: description: > Enter a version name YYYY.MM.DD[.TWEAK] to create a release on success required: false default: '' timezone: description: > Timezone used for validating the version name. The release must be approved by the end of the day in the specified timezone. See /usr/share/zoneinfo for a list of possible values. required: false default: 'America/Los_Angeles' clear_ccache: description: > Enter 'yes' without quotes to clear ccache before running required: false default: '' container: description: > Container to use for builds required: false default: 'sxscollaboration/spectre:dev' # Allow running this workflow as a job in another workflow. This is used to # test a new Docker container before publishing it. workflow_call: inputs: container: description: > Container to use for builds required: false type: string default: 'sxscollaboration/spectre:dev' # Cancel all other queued or in-progress runs of this workflow when it is # scheduled, so repeated pushes to a branch or a PR don't block CI. Repeated # pushes to 'develop' and 'release' are not canceled, so every merge commit is # tested. concurrency: group: ${{ github.ref }} cancel-in-progress: ${{ github.ref != 'refs/heads/develop' && github.ref != 'refs/heads/release' }} jobs: # Make sure no commits are prefixed with `fixup` or similar keywords. See # `tools/CheckCommits.sh` for details. check_commits: name: Commits # Only run on pull requests since we don't check _all_ commits, but only # those that came after the PR's base ref. if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v5 with: fetch-depth: 0 - name: Check commits # `CheckCommits.sh` tests against the local `develop` branch, so that's # where we fetch the pull-request's base-branch to. Typically, it is # the upstream `sxs-collaboration/spectre/develop` branch. run: > cd $GITHUB_WORKSPACE git remote add upstream https://github.com/${{ github.repository }}.git git remote -v git fetch upstream ${{ github.base_ref }}:develop ./tools/CheckCommits.sh # - Run simple textual checks over files in the repository, e.g. checking for # a license, line length limits etc. See `tools/CheckFiles.sh` for details. # - Run format checker for python to make sure the code is formatted correctly # - Check the metadata are consistent check_files_and_formatting: name: Files and formatting runs-on: ubuntu-latest container: image: ${{ inputs.container || 'sxscollaboration/spectre:dev' }} steps: - name: Checkout repository uses: actions/checkout@v5 with: fetch-depth: 0 # Work around https://github.com/actions/checkout/issues/760 - name: Trust checkout run: | git config --global --add safe.directory $GITHUB_WORKSPACE # The action above checks out the `github.ref` by default, which points to # the merge commit with the target branch for pull-request events. For # this job we check out the pull-request HEAD instead. It makes # git-related issues easier to debug because the state matches the local # repository. It also prevents releases that happened since the # pull-request branch was last rebased from disrupting tests that involve # the latest release tag. - name: Checkout pull-request HEAD if: github.event_name == 'pull_request' run: | git checkout ${{ github.event.pull_request.head.sha }} # Some tests involve release tags, which may not have been pushed to # forks. Fetching them here. - name: Fetch upstream tags on forks if: github.repository != 'sxs-collaboration/spectre' run: | git fetch --tags https://github.com/sxs-collaboration/spectre - name: Install Python dependencies run: | pip3 install -r .github/scripts/requirements-release.txt pip3 install -r support/Python/dev_requirements.txt - name: Test tools run: | python3 -m unittest discover -p 'Test_CompileReleaseNotes.py' \ tests.tools -v - name: Check Python formatting run: | cd $GITHUB_WORKSPACE echo "Using 'black' to check Python formatting..." black --check --extend-exclude '/external/' . echo "Using 'isort' to check Python formatting..." isort --check-only --extend-skip external . - name: Test script run: | cd $GITHUB_WORKSPACE ./tools/CheckFiles.sh --test - name: Check files run: | cd $GITHUB_WORKSPACE ./tools/CheckFiles.sh - name: Check metadata run: | python3 tools/CheckMetadata.py - name: Check the metadata is consistent with the releases # No need to check this on forks. They would need to set a Zenodo token # for this test. Also disable on PRs because they don't have access to # the repo's secrets. if: > github.repository == 'sxs-collaboration/spectre' && github.event_name != 'pull_request' run: | python3 .github/scripts/Release.py prepare -vv --check-only \ --zenodo-token ${{ secrets.ZENODO_READONLY_TOKEN }} \ --github-token ${{ secrets.GITHUB_TOKEN }} python3 .github/scripts/Release.py publish -vv --check-only \ --zenodo-token ${{ secrets.ZENODO_READONLY_TOKEN }} \ --github-token ${{ secrets.GITHUB_TOKEN }} \ --auto-publish - name: Check release notes run: | python3 tools/CompileReleaseNotes.py -vv -o release_notes.md \ --github-token ${{ secrets.GITHUB_TOKEN }} - name: Upload release notes uses: actions/upload-artifact@v7 with: name: release-notes path: release_notes.md # GitHub doesn't display artifacts until the workflow has completed, so we # print the release notes here to be able to review them before approving # a release - name: Print release notes run: | cat release_notes.md # Lint with clang-tidy. We check only code that changed relative to the # nearest common ancestor commit with `sxs-collaboration/spectre/develop`. clang_tidy: name: Clang-tidy if: > (github.event_name == 'pull_request' && github.repository == 'sxs-collaboration/spectre' && github.base_ref == 'develop') || github.ref != 'refs/heads/develop' runs-on: ubuntu-latest container: image: ${{ inputs.container || 'sxscollaboration/spectre:dev' }} strategy: matrix: build_type: [Debug, Release] steps: - name: Checkout repository uses: actions/checkout@v5 with: fetch-depth: 0 # Work around https://github.com/actions/checkout/issues/760 - name: Trust checkout run: | git config --global --add safe.directory $GITHUB_WORKSPACE # Some cpp20 features aren't supported until clang-tidy-16. See: # https://stackoverflow.com/questions/46114214/lambda-implicit-capture-fails-with-variable-declared-from-structured-binding#comment135007519_46115028 # The clang-tidy-diff tool doesn't report exit codes until version # 18.1.0, so we grab the version that does: # https://github.com/llvm/llvm-project/commit/4294bca5e4f6e6e8cfdbd9fbe8751c5e5415fd47 - name: Install clang-tidy-16 run: | apt-get update -y apt-get remove -y clang-tidy clang-tidy-14 apt-get install -y clang-tidy-16 ln -s /usr/bin/clang-tidy-16 /usr/bin/clang-tidy wget https://raw.githubusercontent.com/llvm/llvm-project/4294bca5e4f6e6e8cfdbd9fbe8751c5e5415fd47/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py chmod +x clang-tidy-diff.py mv clang-tidy-diff.py /usr/bin/clang-tidy-diff.py ln -s /usr/bin/clang-tidy-diff.py /usr/bin/clang-tidy-diff - name: Configure annotations # Has to be accessible outside the container, see issue: # https://github.com/actions/toolkit/issues/305 run: | cp .github/problem_matchers/ClangTidy.json "$HOME/" echo "::add-matcher::$HOME/ClangTidy.json" - name: Fetch sxs-collaboration/spectre/develop run: > cd $GITHUB_WORKSPACE git remote add upstream https://github.com/sxs-collaboration/spectre.git git remote -v git fetch upstream develop - name: Configure with cmake run: > mkdir build && cd build cmake -D CMAKE_C_COMPILER=clang-14 -D CMAKE_CXX_COMPILER=clang++-14 -D CMAKE_Fortran_COMPILER=gfortran -D CHARM_ROOT=${CHARM_ROOT} -D CMAKE_BUILD_TYPE=${{ matrix.build_type }} -D OVERRIDE_ARCH=x86-64 -D USE_CCACHE=OFF -D USE_PCH=OFF -D DEBUG_SYMBOLS=OFF -D BUILD_PYTHON_BINDINGS=ON -D SPECTRE_AUTODIFF=ON -D SPECTRE_FETCH_MISSING_DEPS=ON $GITHUB_WORKSPACE make -j4 module_All Libsharp-external - name: Check clang-tidy run: > UPSTREAM_HASH=$(git merge-base HEAD upstream/develop) echo "Running clang-tidy relative to: $UPSTREAM_HASH\n" git diff -U0 $UPSTREAM_HASH | clang-tidy-diff -path build -p1 -use-color -j4 \ -extra-arg=-I/usr/include/hdf5/serial \ -extra-arg=-I$GITHUB_WORKSPACE/build/_deps/autodiff-src # Build the documentation and check for problems, then upload as a workflow # artifact and deploy to gh-pages. doc_check: name: Documentation needs: check_files_and_formatting runs-on: ubuntu-latest container: image: ${{ inputs.container || 'sxscollaboration/spectre:dev' }} env: CCACHE_DIR: /work/ccache CCACHE_READONLY: 1 CCACHE_COMPILERCHECK: content CCACHE_BASEDIR: $GITHUB_WORKSPACE steps: - name: Checkout repository uses: actions/checkout@v5 # Work around https://github.com/actions/checkout/issues/760 - name: Trust checkout run: | git config --global --add safe.directory $GITHUB_WORKSPACE # These can be installed directly in the Docker container instead - name: Install Python dependencies run: | python3 -m pip install -r support/Python/dev_requirements.txt - name: Download release notes uses: actions/download-artifact@v8 id: release-notes with: name: release-notes path: /work - name: Append release notes to changelog # The sed command escapes @ symbols at beginning of words (GitHub # usernames) so they aren't interpreted as Doxygen commands run: | echo "" >> docs/Changelog.md cat /work/release_notes.md | sed 's/\(\B\@\)/\\\1/g' \ >> docs/Changelog.md - name: Restore ccache uses: actions/cache/restore@v5 id: restore-ccache env: CACHE_KEY_PREFIX: ccache-gcc-11-Debug-pch-ON with: path: /work/ccache key: "${{ env.CACHE_KEY_PREFIX }}-${{ github.run_id }}" restore-keys: | ${{ env.CACHE_KEY_PREFIX }}- # - Make sure to use the same build configuration as the unit tests from # which we restore the ccache. # - Set `BUILD_TESTING=OFF` to test a CMake configuration with tests # turned off. - name: Configure with cmake run: > mkdir build && cd build cmake -D CMAKE_C_COMPILER=gcc-11 -D CMAKE_CXX_COMPILER=g++-11 -D CMAKE_Fortran_COMPILER=gfortran-11 -D CMAKE_CXX_FLAGS="-Werror" -D OVERRIDE_ARCH=x86-64 -D CHARM_ROOT=${CHARM_ROOT} -D CMAKE_BUILD_TYPE=Debug -D SPECTRE_DEBUG_Og=ON -D DEBUG_SYMBOLS=OFF -D USE_PCH=ON -D USE_XSIMD=ON -D USE_CCACHE=ON -D ENABLE_OPENMP=ON -D BUILD_PYTHON_BINDINGS=ON -D BUILD_SHARED_LIBS=ON -D MEMORY_ALLOCATOR=SYSTEM -D BUILD_DOCS=ON -D BUILD_TESTING=OFF -D SPECTRE_AUTODIFF=ON -D SPECTRE_FETCH_MISSING_DEPS=ON $GITHUB_WORKSPACE - name: Check documentation working-directory: build run: | make doc-check # Re-build with coverage information on pushes to develop for deployment # to gh-pages. - name: Build documentation with coverage if: github.event_name == 'push' && github.ref == 'refs/heads/develop' working-directory: build run: | make doc-coverage - name: Build Python docs working-directory: build run: | make py-docs -j4 # Upload as an artifact to make available to deployment and to PRs - name: Prepare for upload working-directory: build run: | tar -cf docs-html.tar --directory docs/html . - name: Upload documentation uses: actions/upload-artifact@v7 with: name: docs-html path: build/docs-html.tar # Deploy to gh-pages on pushes to develop # See docs: https://github.com/actions/deploy-pages docs-deploy: name: Deploy documentation if: github.event_name == 'push' && github.ref == 'refs/heads/develop' needs: doc_check runs-on: ubuntu-latest permissions: pages: write id-token: write environment: name: github-pages url: ${{ steps.deploy.outputs.page_url }} steps: - uses: actions/deploy-pages@v5 id: deploy with: artifact_name: docs-html # Build all test executables and run unit tests on a variety of compiler # configurations. unit_tests: name: Unit tests runs-on: ubuntu-latest timeout-minutes: 345 strategy: fail-fast: false matrix: # We have a sparse clang test configuration to reduce the amount of # GitHub cache space we use. GCC being the production compiler on # supercomputers means we need to thoroughly test it. compiler: - gcc-10 - gcc-11 - gcc-13 build_type: [Debug, Release] include: # Generate code coverage report for a single build # Note: currently disabled because it exceeds the available disk space # - compiler: gcc-9 # build_type: Debug # COVERAGE: ON # TEST_TIMEOUT_FACTOR: 3 # This configuration seems to run consistently slower than newer gcc # or clang builds, so we increase the test timeout a bit - compiler: gcc-10 build_type: Debug TEST_TIMEOUT_FACTOR: 2 # Test 3D rendering with ParaView # Note: currently disabled because of some unknown upstream issue # test_3d_rendering: ON # Need Python version consistent with ParaView PYTHON_VERSION: "3.9" # Test with Kokkos enabled but without CUDA - compiler: gcc-10 build_type: Release KOKKOS: ON # Disable FMA optimizations to avoid this issue: # https://github.com/sxs-collaboration/spectre/issues/5145 EXTRA_CXX_FLAGS: "-mno-fma" # Don't modify the gcc-11 Debug build so its cache can be reused for # the documentation build # - compiler: gcc-11 # build_type: Debug # Test with Python 3.8 so that we retain backwards compatibility. We # keep track of Python versions on supercomputers in this issue: # https://github.com/sxs-collaboration/spectre/issues/442 - compiler: gcc-11 build_type: Release PYTHON_VERSION: "3.8" # Disable building executable for this build for now because it # exceeds the available memory. See issue: # https://github.com/sxs-collaboration/spectre/issues/5472 test_executables: OFF # Test building with static libraries. Do so with clang in release # mode because these builds use up little disk space compared to GCC # builds or clang Debug builds - compiler: clang-13 build_type: Release BUILD_SHARED_LIBS: OFF use_xsimd: ON MEMORY_ALLOCATOR: JEMALLOC # Add a test without PCH to the build matrix, which only builds core # libraries. Building all the tests without the PCH takes very long # and the most we would catch is a missing include of something that's # in the PCH. # Use this test also to build and test all input files with "normal" # or higher priority. The other configurations only test input files # with "high" priority to reduce the total build time. - compiler: clang-13 build_type: Debug use_pch: OFF unit_tests: OFF input_file_tests_min_priority: "normal" # Test with ASAN - compiler: clang-14 build_type: Debug # When building with ASAN we also need python bindings to be # disabled because otherwise we get link errors. See issue: # https://github.com/sxs-collaboration/spectre/issues/1890 # So we are also using this build to test building without Python # bindings enabled. ASAN: ON BUILD_PYTHON_BINDINGS: OFF MEMORY_ALLOCATOR: JEMALLOC TEST_TIMEOUT_FACTOR: 2 - compiler: clang-14 build_type: Release # Test compatibility with oldest supported CMake version CMAKE_VERSION: "3.18.2" # Use an MPI version of Charm CHARM_ROOT: /work/charm_7_0_0/mpi-linux-x86_64-smp-clang # MPI running tests is a bit slower than multicore TEST_TIMEOUT_FACTOR: 3 # If MPI should be tested USE_MPI: ON # Test `install` target with clang in Release mode because it uses # little disk space install: ON # Test compiling with nvcc and CUDA - compiler: nvcc-12-6 SPECTRE_AUTODIFF: OFF CUDA: ON KOKKOS: ON # Compile for NVIDIA Ampere architecture. Can't run this on # GitHub-hosted runners because they don't have the GPU hardware, # but we can test the compilation. KOKKOS_ARCH: "AMPERE80" # Compile in Release mode to speed up the build build_type: Release # Build with static libs because Kokkos CUDA doesn't support shared # libs BUILD_SHARED_LIBS: OFF # Build only a subset of the code because compiling the full code is # too slow and exceeds the available memory. We should extend this # to the full code once we have a better solution for the memory # issue. See 'Test nvcc support' step below. unit_tests: OFF test_executables: OFF # Enable PlaneWave3D.yaml input file test input_file_tests_min_priority: "normal" # Disable pybindings until they support nvcc BUILD_PYTHON_BINDINGS: OFF # Disable warnings as nvcc emits a lot of them from system headers ENABLE_WARNINGS: OFF container: image: ${{ inputs.container || 'sxscollaboration/spectre:dev' }} env: # We make sure to use a fixed absolute path for the ccache directory CCACHE_DIR: /work/ccache # Use a separate temp directory to conserve cache space on GitHub CCACHE_TEMPDIR: /work/ccache-tmp # Control the max cache size. We evict unused entries in a step below to # make sure that each build only uses what it need of this max size. CCACHE_MAXSIZE: "2G" # Control the compression level. The ccache docs recommend at most level # 5 to avoid slowing down compilation. CCACHE_COMPRESS: 1 CCACHE_COMPRESSLEVEL: 5 # We hash the content of the compiler rather than the location and mtime # to make sure the cache works across the different machines CCACHE_COMPILERCHECK: content # Rewrite absolute paths starting with this base dir to relative paths # before hashing. This is needed to reuse the cache for the formaline # test below, which builds in a different directory. CCACHE_BASEDIR: $GITHUB_WORKSPACE # These vars are to allow running charm with MPI as root inside the # container which arises from using the "--privileged" flag just below. OMPI_ALLOW_RUN_AS_ROOT: 1 OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1 # The number of cores to run on. This is given at: # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories NUMBER_OF_CORES: 4 # See https://lists.cs.illinois.edu/lists/arc/charm/2018-10/msg00011.html # for why we need this options: --privileged steps: - name: Record start time id: start run: | echo "time=$(date +%s)" >> "$GITHUB_OUTPUT" - name: Checkout repository uses: actions/checkout@v5 # Work around https://github.com/actions/checkout/issues/760 - name: Trust checkout run: | git config --global --add safe.directory $GITHUB_WORKSPACE - uses: ./.github/actions/parse-compiler with: compiler: ${{ matrix.compiler }} # Install the selected compiler. We don't bundle all of them in the # container because they take up a lot of space. - name: Install compiler run: | add-apt-repository ppa:ubuntu-toolchain-r/test apt-get update -y if [[ $COMPILER_ID = gcc ]]; then apt-get install -y $CC $CXX $FC elif [[ $COMPILER_ID = clang ]]; then apt-get install -y $CC $FC elif [[ $COMPILER_ID = nvcc ]]; then # Install CUDA wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb dpkg -i cuda-keyring_1.1-1_all.deb apt-get update -y apt-get install -y cuda-nvcc-${COMPILER_VERSION} \ build-essential libc6-dev pkg-config echo "/usr/local/cuda-${COMPILER_VERSION/-/.}/bin" >> $GITHUB_PATH fi - name: Install Kokkos if: matrix.KOKKOS == 'ON' working-directory: /work run: | KOKKOS_VERSION=4.4.00 wget -O kokkos.tar.gz "https://github.com/kokkos/kokkos/releases/download/${KOKKOS_VERSION}/kokkos-${KOKKOS_VERSION}.tar.gz" tar -xzf kokkos.tar.gz && mv kokkos-* kokkos && cd kokkos mkdir build && cd build cmake .. \ -D CMAKE_BUILD_TYPE=${{ matrix.build_type }} \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D Kokkos_ENABLE_SERIAL=ON \ -D Kokkos_ENABLE_OPENMP=ON \ -D Kokkos_ENABLE_CUDA=${{ matrix.CUDA || 'OFF' }} \ -D Kokkos_ARCH_${{ matrix.KOKKOS_ARCH || 'X86_64' }}=ON \ -D Kokkos_ENABLE_CUDA_CONSTEXPR=ON \ -D Kokkos_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE=ON \ -D CMAKE_POSITION_INDEPENDENT_CODE=ON make -j ${NUMBER_OF_CORES} install cd ../../ && rm -rf kokkos.tar.gz kokkos # Use Kokkos compiler wrapper for nvcc if [[ $COMPILER_ID = nvcc ]]; then echo "CXX=/usr/local/bin/nvcc_wrapper" >> $GITHUB_ENV fi # Install specific CMake version if requested - name: Install CMake version if: matrix.CMAKE_VERSION working-directory: /work run: | CMAKE_VERSION=${{ matrix.CMAKE_VERSION }} wget -O cmake-install.sh "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-x86_64.sh" sh cmake-install.sh --prefix=/usr --skip-license rm cmake-install.sh - name: Install Python version if: matrix.PYTHON_VERSION run: | add-apt-repository ppa:deadsnakes/ppa apt install -y python${{ matrix.PYTHON_VERSION }}-dev \ python${{ matrix.PYTHON_VERSION }}-venv \ python${{ matrix.PYTHON_VERSION }}-distutils update-alternatives --install /usr/bin/python3 python3 \ /usr/bin/python${{ matrix.PYTHON_VERSION }} 1 - name: Install Python dependencies if: matrix.PYTHON_VERSION run: | python${{ matrix.PYTHON_VERSION }} -m pip install \ -r support/Python/requirements.txt \ -r support/Python/dev_requirements.txt python${{ matrix.PYTHON_VERSION }} -m pip list -v - name: Install ParaView if: matrix.test_3d_rendering == 'ON' working-directory: /work # Can't just `apt-get install python3-paraview` because we need the # headless build of ParaView. So we download a binary from paraview.org # (which is built for a specific Python version unfortunately). run: | apt-get install -y libglvnd-dev # Needed to find 'libglapi.so' wget -O paraview.tar.gz --no-check-certificate "https://www.paraview.org/paraview-downloads/download.php?submit=Download&version=v5.10&type=binary&os=Linux&downloadFile=ParaView-5.10.1-osmesa-MPI-Linux-Python3.9-x86_64.tar.gz" tar -xzf paraview.tar.gz rm paraview.tar.gz mv ParaView-* /opt/paraview echo "/opt/paraview/bin" >> $GITHUB_PATH # Make 'paraview' Python package available PYTHONPATH=/opt/paraview/lib/python3.9/site-packages:$PYTHONPATH # Give system-installed Python packages priority over ParaView's PYTHONPATH=$pythonLocation/lib/python3.9/site-packages:$PYTHONPATH echo "PYTHONPATH=$PYTHONPATH" >> $GITHUB_ENV - name: Install MPI and Charm++ if: matrix.USE_MPI == 'ON' working-directory: /work run: | apt-get install -y libopenmpi-dev cd /work/charm_7_0_0 && ./build charm++ mpi-linux-x86_64-smp clang \ -j ${NUMBER_OF_CORES} -g0 -O1 --build-shared --with-production # Assign a unique cache key for every run. # - We will save the cache using this unique key, but only on the develop # branch. This way we regularly update the cache without filling up the # storage space with caches from other branches. # - To restore the most recent cache we provide a partially-matched # "restore key". - name: Restore ccache uses: actions/cache/restore@v5 id: restore-ccache env: CACHE_KEY_PREFIX: "ccache-${{ matrix.compiler }}-\ ${{ matrix.build_type }}-pch-${{ matrix.use_pch || 'ON' }}" with: path: /work/ccache key: "${{ env.CACHE_KEY_PREFIX }}-${{ github.run_id }}" restore-keys: | ${{ env.CACHE_KEY_PREFIX }}- - name: Configure ccache # Print the ccache configuration and reset statistics run: | ccache -pz - name: Clear ccache # Clear ccache if requested if: > github.event_name == 'workflow_dispatch' && github.event.inputs.clear_ccache == 'yes' run: | ccache -C - name: Configure build with cmake # Notes on the build configuration: # - We don't need debug symbols during CI, so we turn them off to reduce # memory usage. # - We run unit tests with the following compiler flags: # -Werror: Treat warnings as error. # -march=x86-64: Make sure we are building on a consistent # architecture so caching works. This is necessary because GitHub may # run the job on different hardware. run: > mkdir build && cd build ENABLE_WARNINGS=${{ matrix.ENABLE_WARNINGS }} WERROR="${{ matrix.WERROR != 'OFF' && '-Werror' || '' }}" CXX_FLAGS="${WERROR} ${{ matrix.EXTRA_CXX_FLAGS }}" PYTHON_VERSION=${{ matrix.PYTHON_VERSION }} BUILD_PYTHON_BINDINGS=${{ matrix.BUILD_PYTHON_BINDINGS }} BUILD_SHARED_LIBS=${{ matrix.BUILD_SHARED_LIBS }} KOKKOS=${{ matrix.KOKKOS }} MATRIX_CHARM_ROOT=${{ matrix.CHARM_ROOT }} ASAN=${{ matrix.ASAN }} MEMORY_ALLOCATOR=${{ matrix.MEMORY_ALLOCATOR }} UBSAN_UNDEFINED=${{ matrix.UBSAN_UNDEFINED }} UBSAN_INTEGER=${{ matrix.UBSAN_INTEGER }} USE_PCH=${{ matrix.use_pch }} USE_XSIMD=${{ matrix.use_xsimd }} COVERAGE=${{ matrix.COVERAGE }} TEST_TIMEOUT_FACTOR=${{ matrix.TEST_TIMEOUT_FACTOR }} INPUT_FILE_MIN_PRIO=${{ matrix.input_file_tests_min_priority }} SPECTRE_AUTODIFF=${{ matrix.SPECTRE_AUTODIFF }} cmake --version cmake -D CMAKE_C_COMPILER=${CC} -D CMAKE_CXX_COMPILER=${CXX} -D CMAKE_Fortran_COMPILER=${FC} -D Python_EXECUTABLE=/usr/bin/python${PYTHON_VERSION:-'3'} -D CMAKE_CXX_FLAGS="${CXX_FLAGS}" -D OVERRIDE_ARCH=x86-64 -D ENABLE_WARNINGS=${ENABLE_WARNINGS:-'ON'} -D CHARM_ROOT=${MATRIX_CHARM_ROOT:-$CHARM_ROOT} -D CMAKE_BUILD_TYPE=${{ matrix.build_type }} -D SPECTRE_DEBUG_Og=ON -D DEBUG_SYMBOLS=OFF -D BACKTRACE_LIB=/usr/local/lib/libbacktrace.a -D BACKTRACE_HEADER_DIR=/usr/local/include -D UNIT_TESTS_IN_TEST_EXECUTABLES=OFF -D SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY=${INPUT_FILE_MIN_PRIO:-'high'} -D STRIP_SYMBOLS=ON -D STUB_EXECUTABLE_OBJECT_FILES=ON -D STUB_LIBRARY_OBJECT_FILES=ON -D USE_PCH=${USE_PCH:-'ON'} -D USE_XSIMD=${USE_XSIMD:-'ON'} -D USE_CCACHE=ON -D ENABLE_OPENMP=ON -D SPECTRE_KOKKOS=${KOKKOS:-'OFF'} -D COVERAGE=${COVERAGE:-'OFF'} -D BUILD_PYTHON_BINDINGS=${BUILD_PYTHON_BINDINGS:-'ON'} -D BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-'ON'} -D ASAN=${ASAN:-'OFF'} -D UBSAN_UNDEFINED=${UBSAN_UNDEFINED:-'OFF'} -D UBSAN_INTEGER=${UBSAN_INTEGER:-'OFF'} -D MEMORY_ALLOCATOR=${MEMORY_ALLOCATOR:-'SYSTEM'} -D SPECTRE_UNIT_TEST_TIMEOUT_FACTOR=${TEST_TIMEOUT_FACTOR:-'1'} -D SPECTRE_INPUT_FILE_TEST_TIMEOUT_FACTOR=${TEST_TIMEOUT_FACTOR:-'1'} -D SPECTRE_PYTHON_TEST_TIMEOUT_FACTOR=${TEST_TIMEOUT_FACTOR:-'1'} -D CMAKE_INSTALL_PREFIX=/work/spectre_install -D BUILD_DOCS=OFF -D SPECTRE_AUTODIFF=${SPECTRE_AUTODIFF:-'ON'} -D SPECTRE_FETCH_MISSING_DEPS=ON --warn-uninitialized $GITHUB_WORKSPACE 2>&1 | tee CMakeOutput.txt 2>&1 - name: Check for CMake warnings working-directory: build run: | ! grep -A 6 "CMake Warning" ./CMakeOutput.txt - name: Build unit tests if: matrix.unit_tests != 'OFF' working-directory: build run: | make -j${NUMBER_OF_CORES} unit-tests - name: Run unit tests if: matrix.unit_tests != 'OFF' && matrix.COVERAGE != 'ON' working-directory: build run: | # We get occasional random timeouts, repeat tests to see if # it is a random timeout or systematic. # # We run ctest -L unit before build test-executables to make # sure that all the unit tests are actually built by the # unit-tests target. ctest -j${NUMBER_OF_CORES} -L unit \ --output-on-failure --repeat after-timeout:3 - name: Run unit tests with coverage reporting if: matrix.COVERAGE == 'ON' working-directory: build run: | make unit-test-coverage rm -r docs/html/unit-test-coverage - name: Upload coverage report to codecov.io if: matrix.COVERAGE == 'ON' uses: codecov/codecov-action@v4 with: files: build/tmp/coverage.info token: ${{ secrets.CODECOV_TOKEN }} # Display the job as failed if upload fails (defaults to false for # some reason) fail_ci_if_error: true # We currently don't require codecov in our guidelines, so don't fail # the CI build if codecov fails to upload continue-on-error: true # Test only a few unit tests with nvcc for now because compiling the full # suite is too slow and exceed the available memory. We should extend this # to the full suite once we have a better solution for the memory issue. - name: Test nvcc support if: matrix.CUDA == 'ON' working-directory: build run: | make -j${NUMBER_OF_CORES} \ Test_DataStructures \ Test_Tensor \ Test_Kokkos \ Test_Spectral \ Test_Utilities \ EvolveScalarWave3D # Can't run these tests on GitHub-hosted runners because they don't # have GPU hardware. # ./bin/Test_DataStructures # ./bin/Test_Tensor # ./bin/Test_Kokkos # ./bin/Test_Spectral # ./bin/Test_Utilities # ctest -R PlaneWave3D.yaml --output-on-failure # Avoid running out of disk space by cleaning up the build directory - name: Clean up unit tests working-directory: build run: | pwd ls | xargs du -sh du -sh . rm -f bin/Test_* # Build the executables in a single thread to reduce memory usage # sufficiently so they compile on the GitHub-hosted runners - name: Build executables if: matrix.COVERAGE != 'ON' && matrix.test_executables != 'OFF' working-directory: build run: | make test-executables - name: Build Benchmark executable if: matrix.build_type == 'Release' working-directory: build run: | make -j${NUMBER_OF_CORES} Benchmark # Delete unused cache entries before uploading the cache - name: Clean up ccache if: github.ref == 'refs/heads/develop' run: | now=$(date +%s) job_duration=$((now - ${{ steps.start.outputs.time }})) ccache --evict-older-than "${job_duration}s" # Save the cache after everything has been built. Also save on failure or # on cancellation (`always()`) because a partial cache is better than no # cache. - name: Save ccache if: always() && github.ref == 'refs/heads/develop' uses: actions/cache/save@v5 with: path: /work/ccache key: ${{ steps.restore-ccache.outputs.cache-primary-key }} - name: Print size of build directory working-directory: build run: | pwd ls | xargs du -sh du -sh . - name: Diagnose ccache run: | ccache -s - name: Run non-unit tests if: matrix.COVERAGE != 'ON' && matrix.test_executables != 'OFF' working-directory: build run: | # We get occasional random timeouts, repeat tests to see if # it is a random timeout or systematic # # Only use 2 cores because these tests run more slowly. ctest -j2 -LE unit --output-on-failure \ --repeat after-timeout:3 - name: Install if: matrix.install == 'ON' working-directory: build # Make sure the `install` target runs without error. We could add some # basic smoke tests here to make sure the installation worked. run: | make install - name: Print size of install directory if: matrix.install == 'ON' working-directory: /work/spectre_install # Remove files post-install to reduce disk space for later on. run: | pwd ls | xargs du -sh du -sh . rm -r ./* - name: Test formaline tar can be built # - We only run the formaline tests in debug mode to reduce total build # time in CI. We don't run them with ASAN because then we run out of # disk space. # - We do run for all compilers, though, because formaline injects data # at the linking stage, which means we are somewhat tied to the # compiler version. # - We make sure to use the same compiler flags as the full build above # so ccache is able to speed up the build. if: > matrix.build_type == 'Debug' && matrix.ASAN != 'ON' && matrix.test_executables != 'OFF' working-directory: build run: > make EvolveBurgers -j${NUMBER_OF_CORES} if [ ! -f ./bin/EvolveBurgers ]; then echo "Could not find the executable EvolveBurgers"; echo "which we use for testing formaline"; exit 1 fi # We disable ASAN's leak sanitizer because Charm++ has false # positives that would cause the build to fail. We disable # leak sanitizer for the ctest runs inside CMake anyway. ASAN_OPTIONS=detect_leaks=0 ./bin/EvolveBurgers --dump-source-tree-as spectre_src --dump-only mkdir spectre_src; mv spectre_src.tar.gz spectre_src; cd spectre_src; tar xf spectre_src.tar.gz; mkdir build-formaline; cd build-formaline ENABLE_WARNINGS=${{ matrix.ENABLE_WARNINGS }} WERROR="${{ matrix.WERROR != 'OFF' && '-Werror' || '' }}" CXX_FLAGS="${WERROR} ${{ matrix.EXTRA_CXX_FLAGS }}" PYTHON_VERSION=${{ matrix.PYTHON_VERSION }} BUILD_PYTHON_BINDINGS=${{ matrix.BUILD_PYTHON_BINDINGS }} MATRIX_CHARM_ROOT=${{ matrix.CHARM_ROOT }} MEMORY_ALLOCATOR=${{ matrix.MEMORY_ALLOCATOR }}; USE_PCH=${{ matrix.use_pch }}; USE_XSIMD=${{ matrix.use_xsimd }} cmake -D CMAKE_C_COMPILER=${CC} -D CMAKE_CXX_COMPILER=${CXX} -D CMAKE_Fortran_COMPILER=${FC} -D Python_EXECUTABLE=/usr/bin/python${PYTHON_VERSION:-'3'} -D CMAKE_CXX_FLAGS="${CXX_FLAGS}" -D OVERRIDE_ARCH=x86-64 -D ENABLE_WARNINGS=${ENABLE_WARNINGS:-'ON'} -D BUILD_SHARED_LIBS=ON -D CHARM_ROOT=${MATRIX_CHARM_ROOT:-$CHARM_ROOT} -D CMAKE_BUILD_TYPE=${{ matrix.build_type }} -D SPECTRE_DEBUG_Og=ON -D DEBUG_SYMBOLS=OFF -D UNIT_TESTS_IN_TEST_EXECUTABLES=OFF -D STRIP_SYMBOLS=ON -D STUB_EXECUTABLE_OBJECT_FILES=ON -D STUB_LIBRARY_OBJECT_FILES=ON -D USE_PCH=${USE_PCH:-'ON'} -D USE_XSIMD=${USE_XSIMD:-'ON'} -D USE_CCACHE=ON -D BUILD_PYTHON_BINDINGS=${BUILD_PYTHON_BINDINGS:-'ON'} -D MEMORY_ALLOCATOR=${MEMORY_ALLOCATOR:-'SYSTEM'} -D BUILD_DOCS=OFF -D SPECTRE_AUTODIFF=ON -D SPECTRE_FETCH_MISSING_DEPS=ON .. make EvolveBurgers -j${NUMBER_OF_CORES} # Run on multiple cores to run both the "parse" and "execute" tests # simultaneously. ctest -j${NUMBER_OF_CORES} -R InputFiles.Burgers.Step.yaml --output-on-failure cd .. && rm -r build-formaline - name: Test bundled exporter if: matrix.ASAN != 'ON' && matrix.CUDA != 'ON' working-directory: build run: | make -j${NUMBER_OF_CORES} BundledExporter mkdir build-test-exporter && cd build-test-exporter cmake -D SPECTRE_ROOT=$GITHUB_WORKSPACE/build \ $GITHUB_WORKSPACE/tests/Unit/IO/Exporter/BundledExporter make -j${NUMBER_OF_CORES} ./TestSpectreExporter \ $GITHUB_WORKSPACE/tests/Unit/Visualization/Python/VolTestData0.h5 \ element_data 0 Psi 0 0 0 -0.07059806932542323 cd .. && rm -r build-test-exporter - name: Diagnose ccache run: | ccache -s # Build all test executables and run unit tests on macOS unit_tests_macos: name: Unit tests on macOS timeout-minutes: 345 strategy: fail-fast: false matrix: os: - macos-15-intel - macos-15 runs-on: ${{ matrix.os }} env: # We install some low-level dependencies with Homebrew. They get picked up # by `spack external find`. SPECTRE_BREW_DEPS: >- # Line breaks are spaces, no trailing newline autoconf automake boost catch2 ccache cmake gsl hdf5 openblas yaml-cpp xsimd # We install these packages with Spack and cache them. The full specs are # listed below. This list is only needed to create the cache. SPECTRE_SPACK_DEPS: blaze charmpp libxsmm CCACHE_DIR: $HOME/ccache CCACHE_TEMPDIR: $HOME/ccache-tmp CCACHE_MAXSIZE: "2G" CCACHE_COMPRESS: 1 CCACHE_COMPRESSLEVEL: 5 CCACHE_COMPILERCHECK: content SPACK_SKIP_MODULES: true SPACK_COLOR: always NUM_CORES: ${{ matrix.NUM_CORES }} steps: - name: Record start time id: start run: | echo "time=$(date +%s)" >> "$GITHUB_OUTPUT" - name: Get CPU cores id: get_cores run: | CORES=$(sysctl -n hw.ncpu) echo "NUM_CORES=$CORES" >> $GITHUB_ENV echo "Detect $CORES cores" - name: Checkout repository uses: actions/checkout@v5 - uses: actions/setup-python@v6 with: python-version: '3.12' - name: Install Homebrew dependencies # uninstall cmake to avoid conflict between brew taps run: | brew uninstall cmake brew install $SPECTRE_BREW_DEPS # We install the remaining dependencies with Spack and cache them. # See the `unit_tests` job above for details on the cache configuration. - name: Restore dependency cache uses: actions/cache/restore@v5 id: restore-dependencies env: CACHE_KEY_PREFIX: "dependencies-${{ matrix.os }}" with: path: ~/dependencies key: "${{ env.CACHE_KEY_PREFIX }}-${{ github.run_id }}" restore-keys: | ${{ env.CACHE_KEY_PREFIX }}- - name: Install Spack # Pin a specific version of Spack to avoid breaking CI builds when # Spack changes. run: | cd $HOME git clone -c feature.manyFiles=true \ https://github.com/spack/spack.git cd spack git checkout 7d1de58378fa210b7db887964fcc17187a504ad8 - name: Configure Spack # - To avoid re-building packages that are already installed by Homebrew # we let Spack find them. # - Add the dependency cache as binary mirror. run: | source $HOME/spack/share/spack/setup-env.sh spack debug report spack compiler find && spack compiler list spack external find spack config get packages spack mirror add dependencies file://$HOME/dependencies/spack # Install the remaining dependencies from source with Spack. We install # them in an environment that we can activate later. After building the # dependencies from source we cache them as compressed tarballs. - name: Install Spack dependencies run: | source $HOME/spack/share/spack/setup-env.sh spack env create spectre spack env activate spectre spack add blaze@3.8.2 ~blas ~lapack smp=none # Support installing charm 7.0.0 with CMake 4.0 export CMAKE_POLICY_VERSION_MINIMUM=3.5 spack add charmpp@7.0.0 +shared backend=multicore build-target=charm++ # Use main branch until spack has 2.0 release spack add libxsmm@main spack concretize --reuse spack install --no-check-signature spack find -v - name: Update dependency cache if: github.ref == 'refs/heads/develop' run: | source $HOME/spack/share/spack/setup-env.sh # Clear existing buildcache so we don't accumulate old versions of # packages in the cache rm -rf $HOME/dependencies spack buildcache create -uf dependencies $SPECTRE_SPACK_DEPS # Allow the buildcache creation to fail without failing the job, since # it sometimes runs out of memory continue-on-error: true - name: Save dependency cache if: github.ref == 'refs/heads/develop' uses: actions/cache/save@v5 with: path: ~/dependencies key: ${{ steps.restore-dependencies.outputs.cache-primary-key }} # Install remaining pure Python dependencies with pip because the Spack # package index can be incomplete (it can't mirror all of pip) - name: Install Python dependencies run: | source $HOME/spack/share/spack/setup-env.sh spack env activate spectre pip install -r support/Python/requirements.txt # Replace the ccache directory that building the dependencies may have # generated with the cached ccache directory. - name: Clear ccache from dependencies run: | ccache --clear rm -rf $CCACHE_DIR mkdir -p $CCACHE_DIR - name: Restore ccache uses: actions/cache/restore@v5 id: restore-ccache env: CACHE_KEY_PREFIX: "ccache-${{ matrix.os }}" with: path: ~/ccache key: "${{ env.CACHE_KEY_PREFIX }}-${{ github.run_id }}" restore-keys: | ${{ env.CACHE_KEY_PREFIX }}- - name: Configure ccache run: | ccache -pz - name: Clear ccache # Clear ccache if requested if: > github.event_name == 'workflow_dispatch' && github.event.inputs.clear_ccache == 'yes' run: | ccache -C # Configure, build and run tests. See the `unit_tests` job above for # details. # - We increase the timeout for tests because the GitHub-hosted macOS VMs # appear to be quite slow. - name: Configure build with cmake run: | source $HOME/spack/share/spack/setup-env.sh spack env activate spectre mkdir build && cd build cmake \ -D CMAKE_C_COMPILER=clang \ -D CMAKE_CXX_COMPILER=clang++ \ -D CMAKE_Fortran_COMPILER=gfortran-14 \ -D CMAKE_CXX_FLAGS="-Werror" \ -D BUILD_SHARED_LIBS=ON \ -D BUILD_PYTHON_BINDINGS=ON \ -D MEMORY_ALLOCATOR=SYSTEM \ -D CHARM_ROOT=$(spack location --install-dir charmpp) \ -D BLAS_ROOT=$(brew --prefix openblas) \ -D LAPACK_ROOT=$(brew --prefix openblas) \ -D CMAKE_BUILD_TYPE=Debug \ -D SPECTRE_DEBUG_Og=ON \ -D DEBUG_SYMBOLS=OFF \ -D UNIT_TESTS_IN_TEST_EXECUTABLES=OFF \ -D STUB_EXECUTABLE_OBJECT_FILES=ON \ -D STUB_LIBRARY_OBJECT_FILES=ON \ -D USE_PCH=ON \ -D USE_CCACHE=ON \ -D SPECTRE_TEST_TIMEOUT_FACTOR=10 \ -D CMAKE_INSTALL_PREFIX=../install \ -D BUILD_DOCS=OFF \ -D CMAKE_OSX_SYSROOT=macosx \ $GITHUB_WORKSPACE - name: Build unit tests working-directory: build run: | make -j${NUM_CORES} unit-tests - name: Build executables working-directory: build run: | make test-executables - name: Clean up ccache if: github.ref == 'refs/heads/develop' run: | now=$(date +%s) job_duration=$((now - ${{ steps.start.outputs.time }})) ccache --evict-older-than "${job_duration}s" - name: Save ccache if: always() && github.ref == 'refs/heads/develop' uses: actions/cache/save@v5 with: path: ~/ccache key: ${{ steps.restore-ccache.outputs.cache-primary-key }} - name: Print size of build directory working-directory: build run: | ls | xargs du -sh du -sh . - name: Diagnose ccache run: | ccache -s - name: Run unit tests working-directory: build run: | ctest -E TestingFramework.Abort -j${NUM_CORES} \ --repeat after-timeout:3 --output-on-failure - name: Install working-directory: build run: | make install - name: Print size of install directory working-directory: install run: | ls | xargs du -sh du -sh . rm -r ./* # Release a new version on manual events when requested and the tests pass. # Only enable this on the `sxs-collaboration/spectre` repository (not on # forks). release_version: name: Release version # Running in a protected environment that provides the necessary secrets environment: release runs-on: ubuntu-latest if: > github.repository == 'sxs-collaboration/spectre' && github.ref == 'refs/heads/develop' && github.event_name == 'workflow_dispatch' && github.event.inputs.release_version != '' needs: - check_files_and_formatting - doc_check - unit_tests env: TZ: ${{ github.event.inputs.timezone }} steps: - uses: actions/checkout@v5 with: fetch-depth: 0 # Using a personal access token with admin privileges here so this # action can push to protected branches. Note that this also means # that the pushes can trigger additional workflows (GitHub only # prevents pushes with the default GITHUB_TOKEN from triggering # additional workflows). # # Note: sxs-bot has the personal access token configured. # # GitHub has 2 forms of personal access tokens. # For Fine-Grained Access: # "Only selected repositories" # - Contents: Access: Read and write # - Deployments: Access: Read and write # # For Tokens (classic): # repo: (off) # public_repo: on # Everything else is off. token: ${{ secrets.GH_TOKEN_RELEASE }} - uses: actions/setup-python@v6 with: python-version: '3.8' - name: Install Python dependencies run: | pip3 install -r .github/scripts/requirements-release.txt # We use the current date as tag name, unless a tag name was specified # as input to the `workflow_dispatch` event - name: Determine release version id: get_version run: | INPUT_RELEASE_VERSION=${{ github.event.inputs.release_version }} RELEASE_VERSION=${INPUT_RELEASE_VERSION:-$(date +'%Y.%m.%d')} echo "Release version is: ${RELEASE_VERSION}" echo "RELEASE_VERSION=$RELEASE_VERSION" >> $GITHUB_ENV - name: Validate release version run: | VERSION_PATTERN="^([0-9]{4})\.([0-9]{2})\.([0-9]{2})(\.[0-9]+)?$" if [[ $RELEASE_VERSION =~ $VERSION_PATTERN ]]; then if [ $(date +'%Y') != ${BASH_REMATCH[1]} ] || [ $(date +'%m') != ${BASH_REMATCH[2]} ] || [ $(date +'%d') != ${BASH_REMATCH[3]} ]; then TODAY=$(date +'%Y.%m.%d') echo "'$RELEASE_VERSION' doesn't match current date '$TODAY'" exit 1 fi else echo "'$RELEASE_VERSION' doesn't match '$VERSION_PATTERN'" exit 1 fi if [ $(git tag -l "v$RELEASE_VERSION") ]; then echo "Tag 'v$RELEASE_VERSION' already exists" exit 1 fi if [ $(git rev-parse HEAD) == $(git rev-parse origin/release) ]; then echo "Nothing changed since last release $(git describe release)." exit 1 fi - name: Reserve Zenodo DOI and prepare repository run: | python3 .github/scripts/Release.py prepare -vv \ --version $RELEASE_VERSION \ --zenodo-token ${{ secrets.ZENODO_READWRITE_TOKEN }} \ --github-token ${{ secrets.GITHUB_TOKEN }} git diff - name: Download release notes uses: actions/download-artifact@v8 id: release-notes with: name: release-notes path: ~/release-notes # Push a commit tagged with the new version to `develop` and `release`. # The push will trigger the workflow again because we're using a personal # access token. The triggered workflow will build and deploy the # documentation so we don't need to do that here. - name: Commit and push run: | git config user.name sxs-bot git config user.email sxs-bot@black-holes.org git commit -a -m "Prepare release $RELEASE_VERSION" git show HEAD git status git tag -a v$RELEASE_VERSION -m "Release $RELEASE_VERSION" HEAD git push origin HEAD:develop git push origin HEAD:release git push origin v$RELEASE_VERSION - name: Create release on GitHub uses: softprops/action-gh-release@v2 with: token: ${{ secrets.GH_TOKEN_RELEASE }} tag_name: v${{ env.RELEASE_VERSION }} name: Release ${{ env.RELEASE_VERSION }} body_path: >- ${{ steps.release-notes.outputs.download-path }}/release_notes.md # Publish the Zenodo record. Once published, the record can't be deleted # anymore and editing is limited. - name: Publish to Zenodo run: | python3 .github/scripts/Release.py publish -vv \ --zenodo-token ${{ secrets.ZENODO_PUBLISH_TOKEN }} \ --github-token ${{ secrets.GITHUB_TOKEN }} \ --auto-publish arch_datastructures_tests: name: Archs runs-on: ubuntu-latest strategy: fail-fast: false matrix: compiler: - gcc-10 - gcc-11 - clang-13 - clang-14 include: - sde_arch: ("-nhm;nehalem" "-snb;sandybridge" "-hsw;haswell" "-skl;skylake" "-icx;icelake-server") compiler: gcc-10 - sde_arch: ("-nhm;nehalem" "-snb;sandybridge" "-hsw;haswell" "-skl;skylake" "-icx;icelake-server") compiler: gcc-11 - sde_arch: ("-nhm;nehalem" "-snb;sandybridge" "-hsw;haswell" "-skl;skylake" "-icx;icelake-server") compiler: clang-13 - sde_arch: ("-nhm;nehalem" "-snb;sandybridge" "-hsw;haswell" "-skl;skylake" "-icx;icelake-server" "-tgl;tigerlake") compiler: clang-14 container: image: ${{ inputs.container || 'sxscollaboration/spectre:dev' }} env: # See the unit test job for the reasons for these configuration choices CXXFLAGS: "-Werror" steps: - name: Checkout repository uses: actions/checkout@v5 # Work around https://github.com/actions/checkout/issues/760 - name: Trust checkout run: | git config --global --add safe.directory $GITHUB_WORKSPACE - uses: ./.github/actions/parse-compiler with: compiler: ${{ matrix.compiler }} - name: Install compiler run: | apt-get update -y apt-get install --reinstall ca-certificates if [[ $COMPILER_ID = gcc ]]; then apt-get install -y $CC $CXX $FC else apt-get install -y $CC $FC fi - name: Install Intel SDE working-directory: /work run: | wget -O sde-external.tar.xz https://downloadmirror.intel.com/913594/sde-external-10.7.0-2026-02-18-lin.tar.xz tar -xJf sde-external.tar.xz mv sde-external-* sde rm sde-* - name: Configure, build, and run tests working-directory: /work # Notes on the build configuration: # - We don't need debug symbols during CI, so we turn them off to reduce # memory usage. run: > ARCH_PARAM_LIST=${{ matrix.sde_arch }} for ARCH_PARAM in ${ARCH_PARAM_LIST[@]}; do OVERRIDE_ARCH=`echo ${ARCH_PARAM} | cut -d";" -f2` SDE_FLAG=`echo ${ARCH_PARAM} | cut -d";" -f1` echo "CMake arch flag: $OVERRIDE_ARCH" echo "Intel SDE arch flag: $SDE_FLAG" cd /work BUILD_DIR=build$OVERRIDE_ARCH mkdir $BUILD_DIR && cd $BUILD_DIR cmake\ -D CMAKE_C_COMPILER=${CC}\ -D CMAKE_CXX_COMPILER=${CXX}\ -D CMAKE_Fortran_COMPILER=${FC}\ -D CMAKE_CXX_FLAGS="${CXXFLAGS}"\ -D OVERRIDE_ARCH=${OVERRIDE_ARCH}\ -D CHARM_ROOT=${CHARM_ROOT}\ -D CMAKE_BUILD_TYPE=Debug\ -D SPECTRE_DEBUG_Og=ON\ -D DEBUG_SYMBOLS=OFF\ -D STRIP_SYMBOLS=ON\ -D STUB_EXECUTABLE_OBJECT_FILES=ON\ -D STUB_LIBRARY_OBJECT_FILES=ON\ -D USE_PCH=ON\ -D USE_CCACHE=ON\ -D BUILD_DOCS=OFF\ -D SPECTRE_AUTODIFF=ON\ -D SPECTRE_FETCH_MISSING_DEPS=ON\ $GITHUB_WORKSPACE make -j4 TestArchitectureVectorization /work/sde/sde ${SDE_FLAG}\ -- ./bin/TestArchitectureVectorization [Unit] done shell: bash ================================================ FILE: .gitignore ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Build directories # Ignore build dirs named similarly to the example in the installation notes; # in general arbitrary names are possible and cannot all be ignored. /build* # Editor configurations .vscode compile_commands.json .idea CMakeUserPresets.json # Spack /support/spack/ .spack-env /support/DevEnvironments/spack.lock # Python environments # These are conventional locations where people may install Python packages # related to the project. They are mentioned in the Python docs: # https://docs.python.org/3/library/venv.html /.venv /env # Temporary files *~ *.swp \#*\# .\#* .DS_Store .dir-locals.el .cquery_cached_index .ycm_extra_conf.py .clangd .cache .projectile-cache.eld # TeX products *.aux *.log *.toc *.bbl *.bbg *.blg *.out *.bak docs/auto # Python related files *.pyc .ipynb_checkpoints # charm++ runtime files charmrun.* # Observer output *.xmf *.h5 # Ignore deploy SSH keys and other TravisCI related files .travis/deploy_key coverage.info # ClangFormat git hook file .clang_format_diff.patch # CTags, ETags and GNU Global Tags files GPATH GRTAGS GTAGS TAGS tags # Keep Tags/ directories on case-insensitive file systems !Tags/ # AI/LLM Agent/CLI tools AGENTS.md .aider* CLAUDE.md .claude/settings.local.json CLAUDE.local.md ================================================ FILE: .skills/scripts/FetchCiLog.py ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. """Fetch a failed GitHub Actions job log and extract failure context. Retrieves the job summary and full log via the gh CLI, locates failure lines, and prints a context window around each failure for the LLM. """ import argparse import re import subprocess import sys FAILURE_PATTERNS = [ re.compile(r"FAILED:"), re.compile(r"\berror:"), re.compile(r"The following tests FAILED"), re.compile(r"##\[error\]"), re.compile(r"Process completed with exit code"), re.compile(r"\*\*\*Failed"), ] # Patterns where only context *after* the failure line is useful # (e.g. CTest's "***Failed" line is followed by the test output) AFTER_ONLY_PATTERNS = {r"\*\*\*Failed"} # Timestamp prefix on every GH Actions log line TIMESTAMP_RE = re.compile(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z\s?") def fetch_job_summary(job_id, owner, repo): """Fetch the job summary via 'gh run view --job'.""" cmd = [ "gh", "run", "view", "--job", str(job_id), "-R", f"{owner}/{repo}", ] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: print( f"Warning: could not fetch job summary: {result.stderr.strip()}", file=sys.stderr, ) return None return result.stdout def fetch_job_log(job_id, owner, repo): """Fetch the full job log via the GitHub API.""" cmd = [ "gh", "api", f"repos/{owner}/{repo}/actions/jobs/{job_id}/logs", ] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: print(f"Error fetching log: {result.stderr.strip()}", file=sys.stderr) sys.exit(1) return result.stdout def strip_timestamps(lines): """Remove GH Actions timestamp prefixes from each line.""" return [TIMESTAMP_RE.sub("", line) for line in lines] def find_failure_lines(lines): """Return sorted list of (line_index, after_only) tuples. ``after_only`` is True when the matched pattern only needs context after the failure line (e.g. CTest's ``***Failed`` output). """ hits = {} for i, line in enumerate(lines): for pattern in FAILURE_PATTERNS: if pattern.search(line): after_only = pattern.pattern in AFTER_ONLY_PATTERNS hits[i] = after_only break return hits def merge_windows(hits, context, total_lines): """Merge overlapping [start, end] windows around each hit. ``hits`` is a dict {line_index: after_only}. For after-only hits the window starts at the hit line itself (no before-context). """ if not hits: return [] windows = [] for hit in sorted(hits): after_only = hits[hit] start = hit if after_only else max(0, hit - context) end = min(total_lines - 1, hit + context) if windows and start <= windows[-1][1] + 1: windows[-1] = (windows[-1][0], end, windows[-1][2] | {hit}) else: windows.append((start, end, {hit})) return windows def print_window(lines, start, end, failure_indices): """Print a window of lines with line numbers, marking failures.""" for i in range(start, end + 1): marker = ">>>" if i in failure_indices else " " print(f"{marker} {i + 1:>6d} | {lines[i]}") def main(): parser = argparse.ArgumentParser( description=( "Fetch a failed GitHub Actions job log and extract failure context." ) ) parser.add_argument("job_id", help="GitHub Actions job ID") parser.add_argument( "--owner", default="sxs-collaboration", help="Repository owner (default: sxs-collaboration)", ) parser.add_argument( "--repo", default="spectre", help="Repository name (default: spectre)", ) parser.add_argument( "--context", type=int, default=50, help="Number of lines before and after each failure (default: 50)", ) args = parser.parse_args() # -- Job summary -- summary = fetch_job_summary(args.job_id, args.owner, args.repo) if summary: print("=" * 60) print("JOB SUMMARY") print("=" * 60) print(summary.rstrip()) print() # -- Fetch and process log -- raw_log = fetch_job_log(args.job_id, args.owner, args.repo) raw_lines = raw_log.splitlines() lines = strip_timestamps(raw_lines) hits = find_failure_lines(lines) if not hits: print("No failure patterns found in the log.") print(f"Total log lines: {len(lines)}") sys.exit(1) windows = merge_windows(hits, args.context, len(lines)) num_hits = len(hits) print("=" * 60) print(f"FAILURE LOG (job {args.job_id}, {args.owner}/{args.repo})") print( f" {num_hits} failure line(s) found, {len(windows)} context window(s)" ) print(f" Total log lines: {len(lines)}") print("=" * 60) for idx, (start, end, failure_indices) in enumerate(windows): print() print( f"--- Window {idx + 1}/{len(windows)} " f"(lines {start + 1}-{end + 1}) ---" ) print_window(lines, start, end, failure_indices) print() print("=" * 60) print("END OF FAILURE CONTEXT") print("=" * 60) if __name__ == "__main__": main() ================================================ FILE: .skills/scripts/FetchIssue.py ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. """Fetch a GitHub issue and print it in a structured format for Claude. If the issue is a random test failure (title contains 'random failure in' and the body/comments contain MAKE_GENERATOR seed lines), a compact [RANDOM_FAILURE] format is emitted instead of the full issue text. """ import argparse import json import re import subprocess import sys def is_random_failure(title, all_text): """Return True if this looks like a MAKE_GENERATOR random failure issue.""" if "random failure in" not in title.lower(): return False return bool(re.search(r"Seed is:\s*\d+\s+from", all_text)) def extract_make_generator_seeds(all_text): """Parse 'Seed is: N from path:line' entries, returning {path:line: [seeds]}. CI logs often wrap long paths at '/' boundaries, so we strip timestamps and collapse continuation lines before matching. """ # Strip CI log timestamps (e.g. "2023-09-11T19:44:29.1292895Z ") text = re.sub(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z\s*", "", all_text) # Collapse lines where a path wraps after a '/' text = re.sub(r"/\s*\n\s*", "/", text) pattern = r"Seed is:\s*(\d+)\s+from\s+(.*?\.[hct]pp:\d+)" matches = re.findall(pattern, text) grouped = {} for seed, raw_path in matches: # Canonicalize: keep only the part after tests/Unit/ m = re.search(r"tests/Unit/(.*)", raw_path) canonical = m.group(1) if m else raw_path grouped.setdefault(canonical, []) if seed not in grouped[canonical]: grouped[canonical].append(seed) return grouped def extract_test_name(title): """Extract the test name from a 'Random failure in TEST' title.""" m = re.search(r"[Rr]andom\s+[Ff]ailure\s+in\s+(\S+)", title) return m.group(1) if m else title def main(): parser = argparse.ArgumentParser( description="Fetch a GitHub issue via gh CLI" ) parser.add_argument("issue_number", help="Issue number (e.g. 1727)") parser.add_argument( "--repo", default=None, help="Repository in owner/repo form (default: current repo)", ) parser.add_argument( "--full", action="store_true", help="Always print full issue text, bypassing random-failure detection", ) args = parser.parse_args() cmd = [ "gh", "issue", "view", str(args.issue_number), "--json", ( "number,title,state,author,assignees," "createdAt,labels,url,body,comments" ), ] if args.repo: cmd.extend(["--repo", args.repo]) result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: print(f"Error: {result.stderr.strip()}", file=sys.stderr) sys.exit(1) data = json.loads(result.stdout) title = data.get("title", "") body = data.get("body", "") or "" comments = data.get("comments", []) all_text = body + "\n" + "\n".join((c.get("body") or "") for c in comments) # --- Random failure detection --- if not args.full and is_random_failure(title, all_text): seeds = extract_make_generator_seeds(all_text) test_name = extract_test_name(title) print("[RANDOM_FAILURE]") print(f"Issue #{data['number']}: {title}") print(f"URL: {data.get('url', '')}") print(f"Test: {test_name}") print() print("Seeds by location (paths relative to tests/Unit/):") for path_line, seed_list in seeds.items(): print(f" {path_line} -> {', '.join(seed_list)}") sys.exit(0) # --- Normal issue output --- author = (data.get("author") or {}).get("login", "ghost") labels = ", ".join(lbl["name"] for lbl in data.get("labels", [])) assignees = ", ".join(a["login"] for a in data.get("assignees", [])) print(f"Issue #{data['number']}: {data['title']}") print(f"URL: {data.get('url', '')}") print(f"State: {data['state']}") print(f"Author: {author}") print(f"Created: {data['createdAt']}") if assignees: print(f"Assigned: {assignees}") if labels: print(f"Labels: {labels}") print() print((data.get("body") or "").strip()) for comment in comments: comment_author = (comment.get("author") or {}).get("login", "ghost") print() print("---") print(f"Comment by: {comment_author} at {comment['createdAt']}") print((comment.get("body") or "").strip()) if __name__ == "__main__": main() ================================================ FILE: .skills/scripts/FetchPrComments.py ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. """Fetch PR review data and print it in a structured format for Claude.""" import argparse import json import subprocess import sys def run_gh_command(cmd): """Run a gh CLI command and return parsed JSON, or exit on error.""" result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: print(f"Error: {result.stderr.strip()}", file=sys.stderr) sys.exit(1) return json.loads(result.stdout) def fetch_pr_metadata(pr_number, repo=None): """Fetch PR metadata, comments, reviews, and files via gh pr view.""" cmd = [ "gh", "pr", "view", str(pr_number), "--json", ( "number,title,state,author,baseRefName,headRefName," "body,comments,reviews,files,url,createdAt,reviewDecision" ), ] if repo: cmd.extend(["--repo", repo]) return run_gh_command(cmd) def fetch_review_threads(pr_number, repo=None): """Fetch review threads with resolution status via GraphQL API.""" if repo: owner, name = repo.split("/", 1) else: detect_cmd = ["gh", "repo", "view", "--json", "owner,name"] repo_data = run_gh_command(detect_cmd) owner = repo_data["owner"]["login"] name = repo_data["name"] query = """query { repository(owner:"%s", name:"%s") { pullRequest(number:%d) { reviewThreads(first:100) { totalCount pageInfo { hasNextPage } nodes { isResolved isOutdated path line originalLine startLine originalStartLine subjectType comments(first:50) { nodes { body author { login } path diffHunk line originalLine startLine originalStartLine createdAt } } } } } } }""" % (owner, name, int(pr_number)) cmd = ["gh", "api", "graphql", "-f", f"query={query}"] data = run_gh_command(cmd) threads_data = ( data.get("data", {}) .get("repository", {}) .get("pullRequest", {}) .get("reviewThreads", {}) ) if threads_data.get("pageInfo", {}).get("hasNextPage"): print( ( "WARNING: PR has more than 100 review threads. " "Only the first 100 are shown." ), file=sys.stderr, ) return threads_data.get("nodes", []) def print_pr_header(data): """Print PR metadata header.""" author = (data.get("author") or {}).get("login", "ghost") print(f"PR #{data['number']}: {data['title']}") print(f"URL: {data.get('url', '')}") print(f"State: {data['state']}") print(f"Author: {author}") print(f"Created: {data['createdAt']}") print(f"Base <- Head: {data['baseRefName']} <- {data['headRefName']}") print(f"Review decision: {data.get('reviewDecision', 'NONE')}") def print_changed_files(files): """Print changed files list with addition/deletion counts.""" print() print("=" * 60) print("CHANGED FILES") print("=" * 60) for f in files: print(f" +{f['additions']:-4d} -{f['deletions']:-4d} {f['path']}") total_add = sum(f["additions"] for f in files) total_del = sum(f["deletions"] for f in files) print(f" {'':>10} ({len(files)} files, +{total_add} -{total_del} total)") def print_pr_body(body): """Print PR description.""" body = (body or "").strip() if body: print() print("=" * 60) print("PR DESCRIPTION") print("=" * 60) print(body) def print_top_level_comments(comments): """Print top-level PR conversation comments.""" if not comments: return print() print("=" * 60) print(f"TOP-LEVEL COMMENTS ({len(comments)})") print("=" * 60) for c in comments: author = (c.get("author") or {}).get("login", "ghost") print() print(f"--- Comment by {author} at {c['createdAt']} ---") print((c.get("body") or "").strip()) def print_review_summaries(reviews): """Print review summaries (APPROVED, CHANGES_REQUESTED, etc.).""" summaries = [r for r in reviews if (r.get("body") or "").strip()] if not summaries: return print() print("=" * 60) print(f"REVIEW SUMMARIES ({len(summaries)})") print("=" * 60) for r in summaries: author = (r.get("author") or {}).get("login", "ghost") state = r.get("state", "COMMENTED") print() print(f"--- [{state}] Review by {author} at {r['submittedAt']} ---") print((r.get("body") or "").strip()) def print_review_threads(threads): """Print inline review threads grouped by resolution status.""" if not threads: print() print("=" * 60) print("INLINE REVIEW THREADS") print("=" * 60) print(" (none)") return unresolved = [t for t in threads if not t["isResolved"]] resolved = [t for t in threads if t["isResolved"]] print() print("=" * 60) print( "INLINE REVIEW THREADS " f"({len(unresolved)} unresolved, {len(resolved)} resolved)" ) print("=" * 60) for label, group in [("UNRESOLVED", unresolved), ("RESOLVED", resolved)]: if not group: continue print() print(f"--- {label} THREADS ---") for i, thread in enumerate(group, 1): status_tags = [] if thread["isResolved"]: status_tags.append("[RESOLVED]") else: status_tags.append("[UNRESOLVED]") if thread["isOutdated"]: status_tags.append("[OUTDATED]") path = thread.get("path", "unknown") line = thread.get("line") or thread.get("originalLine") line_info = f":{line}" if line else "" print() print(f" Thread {i}: {' '.join(status_tags)} {path}{line_info}") comments = thread.get("comments", {}).get("nodes", []) for j, c in enumerate(comments): author = (c.get("author") or {}).get("login", "ghost") print(f" [{author} at {c['createdAt']}]") diff_hunk = c.get("diffHunk", "") if diff_hunk and j == 0: for hunk_line in diff_hunk.split("\n"): print(f" {hunk_line}") body = (c.get("body") or "").strip() if body: for body_line in body.split("\n"): print(f" {body_line}") def main(): parser = argparse.ArgumentParser( description="Fetch PR review data via gh CLI and GraphQL" ) parser.add_argument("pr_number", help="Pull request number (e.g. 1234)") parser.add_argument( "--repo", default=None, help="Repository in owner/repo form (default: current repo)", ) args = parser.parse_args() pr_data = fetch_pr_metadata(args.pr_number, args.repo) threads = fetch_review_threads(args.pr_number, args.repo) print_pr_header(pr_data) print_changed_files(pr_data.get("files", [])) print_pr_body(pr_data.get("body")) print_top_level_comments(pr_data.get("comments", [])) print_review_summaries(pr_data.get("reviews", [])) print_review_threads(threads) if __name__ == "__main__": main() ================================================ FILE: .skills/spectre-fix-ci/SKILL.md ================================================ Run the fetch script to retrieve and analyze the CI job log: ``` python3 \ "$(git rev-parse --show-toplevel)/.skills/scripts/FetchCiLog.py" \ [--owner OWNER] [--context LINES] ``` - Extract the job ID from the user's message (required). - Pass `--owner OWNER` if the user specifies an owner (default is `sxs-collaboration`). - `--context` defaults to 50 lines before and after each failure. After the script returns: 1. **Summarize the failure**: which step failed, which test(s) failed, and what the error was. 2. **Identify source locations**: find file paths and line numbers in the error output that point to the failing code. 3. **Suggest next steps**: propose a fix or further investigation. If the context window seems too narrow to understand the failure, re-run with `--context 150` for more surrounding lines. ================================================ FILE: .skills/spectre-fix-issue/RANDOM_FAILURE.md ================================================ # Fixing a Random Test Failure You have a random test failure issue. The script output above contains the test name and a list of `file:line` locations with their failing seeds. Random failures are almost always caused by a **numerical bug in the source code**, not by overly tight test tolerances. Your job is to find and fix the source-level bug. Increasing a test tolerance is a last resort, gated behind mandatory investigation. ## 1. Background `MAKE_GENERATOR(gen)` (defined in `tests/Unit/Framework/TestHelpers.hpp`) creates a `std::mt19937` with a random seed. `MAKE_GENERATOR(gen, SEED)` uses the provided constant instead, making the test deterministic. On failure, prints `Seed is: N from file:line` so the failure can be replayed. ### Seeding a test file When the `file:line` points to a test file (not `CheckWithRandomValues.hpp`): open the file at the indicated line (line numbers may have shifted -- search nearby for `MAKE_GENERATOR`) and change `MAKE_GENERATOR(gen);` to `MAKE_GENERATOR(gen, SEED);` using the first seed listed for that location. ### Seeding CheckWithRandomValues When the `file:line` points to `Framework/CheckWithRandomValues.hpp`: `check_with_random_values()` accepts `epsilon` and `seed` parameters. Find the calling test's `check_with_random_values` invocation and pass the failing seed as the last argument. For example, if the original call is: ```cpp pypp::check_with_random_values<1>( &Foo::bar, klass, "Module", "function", {{{-10.0, 10.0}}}, member_vars, used_for_size); ``` add `epsilon` (default is `1.0e-12`) and the seed: ```cpp pypp::check_with_random_values<1>( &Foo::bar, klass, "Module", "function", {{{-10.0, 10.0}}}, member_vars, used_for_size, 1.0e-12, FAILING_SEED); ``` ## 2. Reproduce the Failure For each `file:line` + seed entry from the script output: 1. **Set the seed** per Section 1 above. 2. **Find the build target**: ``` cd build && ctest --show-only=json-v1 -R "TEST_NAME" ``` Parse the JSON output for the binary path (first element of `"command"`). 3. **Build**: `ninja -C build ` 4. **Run**: `build/bin/ "TEST_NAME"` 5. **If the test does NOT fail**: STOP and report to the user that the failure cannot be reproduced (code may have changed since the issue was filed). ## 3. Investigate the Root Cause (REQUIRED) This is the most important section. You MUST complete this investigation before considering any tolerance change. ### 3a. Trace the call chain 1. Read the error output to identify the **exact failing comparison** -- which values were compared, what the expected vs. actual values were, and what the discrepancy is. 2. Identify which **function under test** produces the incorrect value. 3. **Read the source code** of that function. Trace through its arithmetic step by step. Identify the specific operation (e.g., "the subtraction on line 438 of Wedge.cpp") that amplifies floating-point error. 4. If the function calls other functions, trace into those as well. Follow the data flow until you reach the arithmetic that is numerically unstable. You MUST identify a specific line and operation in the source code. "The computation accumulates floating-point error" is not sufficient -- you need to say *where* and *why*. ### 3b. Numerical patterns checklist Search the source code in the call chain for these common floating-point pitfalls. For each pattern found, attempt the listed fix: - **Catastrophic cancellation**: subtraction of nearly-equal values (`a - b` where `a ~ b`). Fix: rearrange the algebra to avoid the subtraction, use compensated forms, or factor out common terms. - **Division by near-zero**: a denominator that approaches zero for certain inputs (e.g., near coordinate boundaries, poles, or special points). Fix: reformulate to multiply instead of divide, combine fractions to cancel the small denominator, or restructure the expression analytically. - **`atan` instead of `atan2`**: `atan(y/x)` loses quadrant information and divides by near-zero when `x ~ 0`. Fix: replace with `atan2(y, x)`. - **Missing precision-preserving library functions**: `log(1+x)` loses precision when `x ~ 0`; `exp(x)-1` loses precision when `x ~ 0`; `sqrt(x*x + y*y)` can overflow for large values. Fix: use `log1p(x)`, `expm1(x)`, and `hypot(x, y)`. - **Naive summation of many terms**: summing a long list of floating-point numbers accumulates round-off. Fix: use Kahan (compensated) summation, or sort terms by magnitude before summing. - **Unstable polynomial evaluation**: monomial form (`a*x^3 + b*x^2 + c*x + d`) accumulates error for large `x`. Fix: use Horner's method (`((a*x + b)*x + c)*x + d`). - **Numerically unstable quadratic formula**: the standard formula `(-b +/- sqrt(b^2 - 4ac)) / 2a` loses precision when `b^2 >> 4ac` due to catastrophic cancellation in the numerator. Fix: use the numerically stable form (compute one root via the standard formula, the other via `c / (a * first_root)`). - **Accumulation of terms with widely varying magnitudes**: adding a tiny correction to a large value drops the correction entirely. Fix: reorder operations so values of similar magnitude are combined first, or use compensated summation. ### 3c. Attempt a source-level fix Based on the pattern(s) you identified in 3a and 3b: 1. **Implement a fix in the source code** (not the test). For example: rearrange an expression to avoid cancellation, replace a division with a multiplication, switch `atan` to `atan2`, etc. 2. **Build and run with the failing seed** to verify the fix resolves the failure. 3. If the fix works, skip Section 4 entirely and go to Section 5 (Verify). 4. If the fix does not fully resolve the issue, document what you tried and why it was insufficient, then continue investigating. Only proceed to Section 4 after exhausting source-level options. ## 4. LAST RESORT -- Tolerance Adjustment **MANDATORY GATE -- you may NOT adjust any tolerance until ALL of the following are true:** 1. You have identified the full call chain from the test to the failing arithmetic operation. 2. You have named the specific source-code operation (file, line, expression) that produces the numerical error. 3. You have attempted at least one source-level fix and can explain why it did not work. 4. You have confirmed the error is inherent to the algorithm in double precision and cannot be eliminated by rearranging the arithmetic. **If you cannot satisfy all four conditions, go back to Section 3.** ### Adjusting tolerance in a test file - `Approx custom_approx = Approx::custom().epsilon(TOL).scale(1.0);` - For scalars: `CHECK(expected == custom_approx(computed));` - For iterables: `CHECK_ITERABLE_CUSTOM_APPROX(expected, computed, custom_approx);` - Start with `1.0e-14` and multiply by 10 until the test passes. Keep the tolerance as small as possible. ### Adjusting tolerance in CheckWithRandomValues Adjust the `epsilon` parameter in the `check_with_random_values` call. Start at `1.0e-12` and multiply by 10. Keep as small as possible. ### Required documentation Add a C++ comment next to the tolerance change explaining: - What source-level operation causes the error - Why a source-level fix is not feasible - What magnitude of error is expected ## 5. Verify 1. **Remove the explicit seed** so the generator returns to `MAKE_GENERATOR(gen);` (or remove the seed argument from `check_with_random_values`). 2. **Run**: `ctest --repeat-until-fail 1000 -R "TEST_NAME"` in the build directory. 3. If any iterations fail, return to Section 3 and investigate the new failure. Repeat until all 1000 iterations pass. ## 6. Report Summary After all `file:line` entries are resolved, report: - Every file and line changed - For **source-level fixes**: what the numerical issue was and how it was fixed - For **tolerance adjustments**: the root cause, why a source fix wasn't feasible, and the new tolerance value ## Important Notes - The build directory is `build/` under the repository root. - Do NOT modify global `approx` in `tests/Unit/Framework/TestingFramework.hpp`. - Always remove explicit seeds before committing -- the seed is only for reproducing the failure, not for the final code. - If multiple distinct test files have seeds, investigate each independently. ================================================ FILE: .skills/spectre-fix-issue/SKILL.md ================================================ Run the fetch script to retrieve the issue title, body, and comments: ``` python3 \ "$(git rev-parse --show-toplevel)/.skills/scripts/FetchIssue.py" \ [--repo owner/repo] [--full] ``` - Extract the issue number from the user's message. - Pass `--repo owner/repo` if the user specifies a repo or says "upstream" (for SpECTRE, upstream is `sxs-collaboration/spectre`). - Pass `--full` if the user explicitly asks for the full/unshortened issue text (e.g. "show me the full issue", "don't shorten it", "skip random failure handling"). Do NOT pass `--full` by default. **If the output starts with `[RANDOM_FAILURE]`**: Read and follow the instructions in `$(git rev-parse --show-toplevel)/.skills/spectre-fix-issue/RANDOM_FAILURE.md` using the seed data from the script output. Mention to the user that they can ask for the full issue text if they need it. **Otherwise**: Summarize the issue, then proceed with the user's request. ================================================ FILE: .skills/spectre-fix-pr/SKILL.md ================================================ Run the fetch script to retrieve PR metadata, review comments, and changed files: ``` python3 \ "$(git rev-parse --show-toplevel)/.skills/scripts/FetchPrComments.py" \ [--repo owner/repo] ``` - Extract the PR number from the user's message. - Pass `--repo owner/repo` if the user specifies a repo or says "upstream" (for SpECTRE, upstream is `sxs-collaboration/spectre`). After fetching the PR data: 1. **Summarize the review** before starting work: list the total number of threads, how many are unresolved, and the files affected. 2. **Prioritize UNRESOLVED threads** -- these are the comments that still need to be addressed. Start with unresolved, non-outdated threads first. 3. **Group by file** -- work through comments file-by-file rather than jumping around, since multiple threads often apply to the same file. 4. **Use the diff hunk context** -- each inline comment includes the surrounding diff hunk so you can understand exactly what code the reviewer is referring to. 5. **Check OUTDATED threads** -- these refer to code that has since changed. Verify whether the concern still applies before making changes. 6. **Skip resolved threads** unless the user specifically asks about them. ================================================ FILE: .skills/spectre-review/SKILL.md ================================================ # SpECTRE Code Review **Arguments**: $ARGUMENTS **Current branch**: !`git branch --show-current` Perform a thorough code review of SpECTRE changes. Follow every step below precisely. The full SpECTRE code rules reference (provide to review agents): !`tail -n +5 .claude/rules/Cxx.md` ## Step 1: Parse Arguments & Acquire Diff Parse `$ARGUMENTS`: - **Number present** (e.g. `1234`): PR mode. Fetch with: `gh pr diff --repo sxs-collaboration/spectre` and `gh pr view --repo sxs-collaboration/spectre --json title,body,headRefName,baseRefName` - **No number**: Local mode. Use `git diff develop...HEAD` for committed changes, plus `git diff` and `git diff --cached` for uncommitted changes. If no diff, fall back to `git diff HEAD~1`. - **"clang-tidy" present**: Enable the clang-tidy step. - **"coverage" present**: Enable the targeted code coverage step. Save the diff. Extract the list of changed files categorized by type (C++ `.cpp/.hpp/.tpp`, Python `.py`, CMake `CMakeLists.txt`, other). Create a task list tracking all review steps. ## Step 2: Formatting Checks (run in parallel) ### C++ (clang-format) For each changed C++ file: 1. Parse diff hunk headers (`@@ +START,COUNT @@`) to get changed line ranges 2. Expand each range by +/-4 lines (clamped to file bounds) 3. Run: `clang-format -style=file --lines=START:END [--lines=...] FILEPATH` 4. Diff against original. Collect any formatting differences. ### Python (black + isort) For each changed `.py` file (excluding `external/`): ``` black --check --diff FILEPATH isort --check-only --diff FILEPATH ``` ## Step 3: CI Pre-Checks on Changed Files (run in parallel) Check each changed file for issues that SpECTRE CI (`tools/FileTestDefs.sh`, `tools/CheckFiles.sh`) will flag. Only check lines/patterns introduced in the diff, not pre-existing issues. **All files**: lines >80 chars (excluding URLs, NOLINT, #include, \snippet, \image, \link, import); missing MIT license header; no final newline; tabs; trailing whitespace; carriage returns **C++ files (.cpp/.hpp/.tpp)**: - Missing `#pragma once` in headers - `#include ` -> use `Parallel/Printf/Printf.hpp` - `#include ` -> use `` - `std::enable_if` -> use `requires` - `namespace _details` -> use `_detail` - `struct TD;` / `class TD;` (debug artifacts) - `.ckLocal()` -> `Parallel::local()` - `.ckLocalBranch()` -> `Parallel::local_branch()` - `return Py_None;` -> `Py_RETURN_NONE` - Text after `/*!` on same line - `Ls` abbreviation -> use `List` - Doxygen (`///` or `/*!`) in `.cpp` files (only use `//` comments in cpp) - Top-level `const` on value parameters in function declarations (`.hpp`) -> remove `const` from the declaration (keep in definition) - TODO/FIXME comments (not allowed) **Test files**: - `TEST_CASE` instead of `SPECTRE_TEST_CASE` - `Approx(` instead of `approx` **CMake**: New C++ files in a directory must be listed in that directory's CMakeLists.txt; removed files must be removed; entries should be alphabetical. **LLM Comments**: Identify comments that seem like notes from a coding agent during its thinking process. ### Include Order (C++ files in diff) Verify: 1. (Tests) `"Framework/TestingFramework.hpp"` first, then blank line 2. (`.cpp` with `.hpp`) Corresponding `.hpp`, then blank line 3. STL/external `` alphabetical 4. Blank line 5. SpECTRE `"headers"` alphabetical ### Commit Messages (local mode only) Check no commit starts with (case-insensitive): fixup, wip, fixme, deleteme, rebaseme, testing, rebase. ## Step 4: Code Review (2 Parallel Agents) Launch 2 parallel agents. Provide each with the full diff and the SpECTRE code rules reference shown above. ### Agent A: Style, Patterns & Idioms Instructions for the agent: - Check the diff against every rule in **Banned Patterns** and **Style Rules** - Check for **Prefer-Library Patterns** (manual tensor loops that should use EagerMath) - When you spot a suspicious pattern NOT in the checklist (e.g., a manual matrix operation, a loop that looks like it reimplements an existing utility), use `grep -r` in `src/DataStructures/Tensor/EagerMath/`, `src/DataStructures/`, `src/NumericalAlgorithms/`, or `src/Utilities/` to find an existing utility - Only flag issues in lines that the diff introduces (not pre-existing code) - For each finding: `file:line`, severity (`critical`/`important`/`suggestion`), explanation ### Agent B: Bugs, Logic, Tests & Documentation Instructions for the agent: - Read each changed file in full (not just the diff) to understand surrounding context - Look for: logic errors, off-by-one, uninitialized variables, NaN handling, race conditions, incorrect template instantiations, virtual inheritance issues (most-derived must init virtual bases) - Check that new/changed public API in `.hpp` files has Doxygen documentation - Check that new source files have corresponding tests (`src/Foo/Bar.hpp` -> `tests/Unit/Foo/Test_Bar.cpp`) - Check that new `.cpp`/`.hpp` files are listed in their `CMakeLists.txt` - Only flag issues introduced by the diff - For each finding: `file:line`, severity, explanation - Check for potentially problematic floating point math like: - Catastrophic cancellation: subtraction of nearly-equal values (`a - b` where `a ~ b`). - Division by near-zero: a denominator that approaches zero for certain inputs (e.g., near coordinate boundaries, poles, or special points). - Naive summation of many terms: summing a long list of floating-point numbers accumulates round-off. - Unstable polynomial evaluation: monomial form (`a*x^3 + b*x^2 + c*x + d`), instead use Horner's method, `evaluate_polynomial()` from `src/Utilities/Math.hpp` - Numerically unstable quadratic formula: the standard formula `(-b +/- sqrt(b^2 - 4ac)) / 2a` loses precision. - Accumulation of terms with widely varying magnitudes: adding a tiny correction to a large value drops the correction entirely. - Make sure the code always uses `atan2` instead of `atan`, `log1p(x)` instead of `log(1+x)`, `expm1(x)` instead of `exp(x)-1`, `hypot(x,y)` instead of `sqrt(x*x+y*y)`. ## Step 5: clang-tidy (if requested, run in parallel) If "clang-tidy" was in arguments: 1. Check for `build/compile_commands.json`. If missing, report that clang-tidy requires a configured build directory and skip. 2. For each changed `.cpp` file: `clang-tidy -p build/ FILEPATH 2>&1` 3. Filter output to only warnings on lines in the diff. ## Step 6: Code Coverage (if requested, run in parallel) If "coverage" was in arguments: Read `references/coverage-steps.md` and follow those instructions exactly. ## Step 7: Self-Review Prune Combine all findings from steps 2-6. Review each finding and REMOVE only clear non-issues: - False positives (pattern match that isn't the actual flagged issue) - Pre-existing issues not introduced by this diff - Issues suppressed by `// NOLINT(...)` comments - Exact duplicates between agents or between agents and formatting/CI checks Assign each remaining finding a confidence score (0-100). Remove findings below 50. Keep all findings scoring 50 or above -- err on the side of including borderline issues rather than missing real ones. ## Step 8: Lightweight Model Critique Spawn an agent using the cheapest available model (Claude Code: `haiku`; Codex: `gpt-5.4-mini`). Provide it with: - The SpECTRE code rules reference (from Step 1) - The list of pruned findings (with scores) - A summary of what the diff does Ask the critique agent to: 1. Score each finding 0-100 for "is this a real, actionable issue?" 2. Flag any remaining false positives with reasoning 3. Note if important issues seem to be missing 4. Return scores and feedback After receiving the critique agent's feedback: - Remove findings scored < 40 - Downgrade severity (e.g., important -> suggestion) for findings scored 40-60 - Consider adding issues the critique agent suggested (verify them first) ## Step 9: Final Report Read `references/report-template.md` and present the report in that format. ================================================ FILE: .skills/spectre-review/references/coverage-steps.md ================================================ # Code Coverage Steps These instructions are followed by the orchestrator when "coverage" was in the review arguments. Execute all sub-steps below exactly as written. ### 6a. Check out PR branch (PR mode only) Coverage must be measured against the actual PR code, not the current working tree. Before building or running any tests: 1. Record the current branch and stash any uncommitted changes so they can be restored afterwards: ```bash ORIGINAL_BRANCH=$(git branch --show-current) STASH_RESULT=$(git stash push --include-untracked -m "coverage-stash" 2>&1) STASHED=$([[ "$STASH_RESULT" == *"Saved"* ]] && echo yes || echo no) ``` 2. Attempt to check out the PR branch using the GitHub CLI: ```bash gh pr checkout --repo sxs-collaboration/spectre 2>&1 ``` If that fails (e.g. SSH key / remote mismatch), fall back to: ```bash git fetch upstream pull//head:pr- 2>&1 git checkout pr- 2>&1 ``` 3. **Handle checkout conflicts explicitly.** If checkout fails with any error (e.g. "Your local changes to the following files would be overwritten", "untracked working tree files would be overwritten by checkout", or "Please commit your changes or stash them"), do NOT attempt to force-checkout. Instead, abort coverage and report clearly: > "Coverage analysis skipped: checking out PR branch '' failed > because the following local files conflict with the PR: > > Please resolve the conflict manually (commit, stash, or delete those files) > and re-run the review with 'coverage'." Then restore the original branch and pop the stash (step 5) and skip all remaining coverage steps. 4. Verify the checkout succeeded by comparing HEAD to the expected PR commit: ```bash git log --oneline -1 gh pr view --repo sxs-collaboration/spectre \ --json headRefOid -q .headRefOid ``` The two commit hashes should match (or the local log should show the PR branch name). If they differ, report: "Coverage skipped: checkout succeeded but HEAD does not match PR head — local branch may be stale." 5. **Restore step (must run after all coverage steps, or on any failure after this point):** at the end of Step 6f, restore the original working state: ```bash git checkout "$ORIGINAL_BRANCH" [[ "$STASHED" == "yes" ]] && git stash pop ``` ### 6b. Prerequisites & Build Verification 1. Check `build/compile_commands.json` exists. If missing, skip with: "Coverage requires a configured build directory." 2. Check `build/CMakeCache.txt` for `COVERAGE:BOOL=ON`. If not found, skip with: "Build not compiled with -DCOVERAGE=ON. Rebuild with `cmake -DCOVERAGE=ON ..` to enable coverage." 3. Check `lcov` is available. 4. **Verify the gcov wrapper is functional.** For Clang builds, `build/llvm-gcov.sh` may contain `LLVM_COV_BIN-NOTFOUND` if `llvm-cov` was not found at CMake configure time. Check: ```bash grep "NOTFOUND" build/llvm-gcov.sh ``` If found, locate the correct binary and fix the wrapper in-place: ```bash LLVM_VER=$(clang++ --version | grep -oP '\d+' | head -1) LLVM_COV=$(which llvm-cov-${LLVM_VER} 2>/dev/null || which llvm-cov) printf '#!/bin/bash\nexec %s gcov "$@"\n' "$LLVM_COV" > build/llvm-gcov.sh chmod +x build/llvm-gcov.sh ``` 5. Determine the gcov tool and **always use its absolute path** to avoid lcov failing with "No such file or directory" when it resolves relative paths from a different working directory: - Clang: `GCOV=$(realpath build/llvm-gcov.sh)` - GNU: `GCOV=$(which gcov)` 6. **Verify objects are instrumented.** Pick one `.o` file for a changed source and check it has coverage symbols: ```bash nm 2>/dev/null | grep -c "__llvm_gcov_ctr\|__gcov_" ``` If the count is 0, objects were compiled before coverage was enabled — rebuild the relevant test targets: ```bash cmake --build build --target -- -j$(nproc) ``` Re-check instrumentation after the rebuild. If still 0, skip coverage with: "Objects lack coverage instrumentation even after rebuild. Check that the build was configured with -DCOVERAGE=ON before compiling." ### 6c. Map changed files to test targets For each changed C++ file under `src/`: 1. Find the corresponding test directory: `src/A/B/C.hpp` -> `tests/Unit/A/B/` 2. Walk up directories reading `CMakeLists.txt` files for `set(LIBRARY "Test_...")` to find the test binary name. Test naming is NOT a simple transform (e.g., `Test_DomainCreators`, `Test_EllipticDG`, `Test_DgSubcell`), so CMakeLists.txt parsing is required. 3. Verify each binary exists in `build/bin/`. If not, build it: `cmake --build build --target -- -j$(nproc)` 4. If >5 unique test targets, ask the user before proceeding. ### 6d. Run tests and capture coverage For each test target (using `$GCOV` absolute path from Step 6b): ```bash lcov --gcov-tool $GCOV --directory build/ --zerocounters build/bin/ lcov --gcov-tool $GCOV --capture --rc lcov_branch_coverage=0 \ --directory build/ --output-file /tmp/coverage_.info ``` After the lcov capture, verify `.gcda` files were actually produced: ```bash find build/ -name "*.gcda" | grep -q . ``` If no `.gcda` files are found, report: > "No coverage data files (.gcda) generated. Possible causes: (1) objects were > not compiled with --coverage (rebuild required after confirming > -DCOVERAGE=ON), (2) test binary exited before writing data, (3) build > directory path mismatch between compile and run." Then skip remaining coverage steps (but still run Step 6f to restore the branch). ### 6e. Filter to changed lines only 1. Merge .info files: `lcov --add-tracefile ... --output-file /tmp/coverage_merged.info` 2. Extract only changed source files: `lcov --extract /tmp/coverage_merged.info '' ... -o /tmp/coverage_filtered.info` 3. Parse `DA:,` entries from the filtered .info file 4. Cross-reference with diff hunk headers: only report lines that are both NEW in the diff AND have execution_count == 0. **Use new-file line numbers from the diff** — after checking out the PR branch these match the files on disk exactly. Do not use base-branch line numbers, which are offset from the PR. 5. Group uncovered lines into contiguous ranges ### 6f. Cleanup Remove temporary .info files to avoid polluting subsequent builds: ```bash rm -f /tmp/coverage_*.info /tmp/coverage_merged.info /tmp/coverage_filtered.info ``` Then restore the original branch and unstash local changes (PR mode only): ```bash git checkout "$ORIGINAL_BRANCH" [[ "$STASHED" == "yes" ]] && git stash pop ``` ================================================ FILE: .skills/spectre-review/references/report-template.md ================================================ # Final Report Template Present a clean report in the format below. Be brief and specific. No emojis. Link to files and lines. ``` ### SpECTRE Code Review **Reviewing**: [PR #N: title | local changes on branch `name`] **Files changed**: N (X C++, Y Python, Z CMake) #### Formatting [clang-format / black / isort changes, or "No formatting issues."] #### Critical Issues N. **Description** `file:line` Explanation and suggested fix. #### Important Issues N. **Description** `file:line` Explanation. #### Suggestions N. **Description** `file:line` Explanation. #### CI Pre-Check Warnings [Issues that CI will flag, or "None."] [If clang-tidy ran:] #### clang-tidy [Findings or "No issues."] [If coverage ran:] #### Code Coverage (changed lines) [Uncovered changed lines per file, or "All changed lines are covered by tests."] [Files with no test target: "Coverage not checked: file1.cpp, file2.hpp (no test target found)"] ``` If no issues at all: "No issues found. Checked style, patterns, bugs, formatting, and CI compliance." ================================================ FILE: CITATION.cff ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # This file is automatically generated. It will be overwritten at every # release. See .github/scripts/Release.py for details. authors: - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Deppe given-names: Nils orcid: https://orcid.org/0000-0003-4557-4115 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Throwe given-names: William orcid: https://orcid.org/0000-0001-5059-4378 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Kidder given-names: Lawrence E. orcid: https://orcid.org/0000-0001-5392-7342 - affiliation: Max Planck Institute for Gravitational Physics (Albert Einstein Institute), Am Mühlenberg 1, Potsdam 14476, Germany family-names: Vu given-names: Nils L. orcid: https://orcid.org/0000-0002-5767-3949 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Nelli given-names: Kyle C. orcid: https://orcid.org/0000-0003-2426-8768 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Armaza given-names: Cristóbal orcid: https://orcid.org/0000-0002-1791-0743 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Bonilla given-names: Marceline S. orcid: https://orcid.org/0000-0003-4502-528X - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Hébert given-names: François orcid: https://orcid.org/0000-0001-9009-6955 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Kim given-names: Yoonsoo orcid: https://orcid.org/0000-0002-4305-6026 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Kumar given-names: Prayush orcid: https://orcid.org/0000-0001-5523-4603 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Lovelace given-names: Geoffrey orcid: https://orcid.org/0000-0002-7084-1070 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Macedo given-names: Alexandra orcid: https://orcid.org/0009-0001-7671-6377 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Moxon given-names: Jordan orcid: https://orcid.org/0000-0001-9891-8677 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: O'Shea given-names: Eamonn - affiliation: Max Planck Institute for Gravitational Physics (Albert Einstein Institute), Am Mühlenberg 1, Potsdam 14476, Germany family-names: Pfeiffer given-names: Harald P. orcid: https://orcid.org/0000-0001-9288-519X - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Scheel given-names: Mark A. orcid: https://orcid.org/0000-0001-6656-9134 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA and Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Teukolsky given-names: Saul A. orcid: https://orcid.org/0000-0001-9765-4526 - affiliation: Max Planck Institute for Gravitational Physics (Albert Einstein Institute), Am Mühlenberg 1, Potsdam 14476, Germany family-names: Wittek given-names: Nikolas A. orcid: https://orcid.org/0000-0001-8575-5450 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Anantpurkar given-names: Isha orcid: https://orcid.org/0000-0002-5814-4109 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Anderson given-names: Carter orcid: https://orcid.org/0009-0009-0359-6763 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Boyle given-names: Michael orcid: https://orcid.org/0000-0002-5075-5116 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Carpenter given-names: Alexander orcid: https://orcid.org/0000-0002-9183-8006 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Ceja given-names: Andrea orcid: https://orcid.org/0000-0002-1681-7299 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Chaudhary given-names: Himanshu orcid: https://orcid.org/0000-0002-4101-0534 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Corso given-names: Nicholas orcid: https://orcid.org/0000-0002-0088-2563 - affiliation: Max Planck Institute for Gravitational Physics (Albert Einstein Institute), Am Mühlenberg 1, Potsdam 14476, Germany family-names: Dittmer given-names: Clemens orcid: https://orcid.org/0009-0007-3833-9252 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Fayyazuddin Ljungberg given-names: Nora orcid: https://orcid.org/0000-0002-7074-4545 - affiliation: Department of Physics & Astronomy, University of New Hampshire, 9 Library Way, Durham NH 03824, USA family-names: Foucart given-names: Francois orcid: https://orcid.org/0000-0003-4617-4738 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Ghadiri given-names: Noora orcid: https://orcid.org/0000-0001-9162-4449 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Giesler given-names: Matthew orcid: https://orcid.org/0000-0003-2300-893X - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Guo given-names: Jason S. - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Habib given-names: Sarah orcid: https://orcid.org/0000-0002-4725-4978 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Huang given-names: Chenhang orcid: https://orcid.org/0000-0003-2617-1011 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Iozzo given-names: Dante A. B. orcid: https://orcid.org/0000-0002-7244-1900 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Jones given-names: Ken Z. orcid: https://orcid.org/0009-0003-1034-0498 - affiliation: Max Planck Institute for Gravitational Physics (Albert Einstein Institute), Am Mühlenberg 1, Potsdam 14476, Germany family-names: Lara given-names: Guillermo orcid: https://orcid.org/0000-0001-9461-6292 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Legred given-names: Isaac orcid: https://orcid.org/0000-0002-9523-9617 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Li given-names: Dongjun orcid: https://orcid.org/0000-0002-1962-680X - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Ma given-names: Sizheng orcid: https://orcid.org/0000-0002-4645-453X - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Melchor given-names: Denyz orcid: https://orcid.org/0000-0002-7854-1953 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA and Department of Physics and Astronomy, Oberlin College, Oberlin, Ohio 44074, USA family-names: Mendes given-names: Iago orcid: https://orcid.org/0009-0007-9845-8448 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Morales given-names: Marlo orcid: https://orcid.org/0000-0002-0593-4318 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Most given-names: Elias R. orcid: https://orcid.org/0000-0002-0491-1210 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Murphy given-names: Michael orcid: https://orcid.org/0000-0003-3865-3034 - affiliation: Max Planck Institute for Gravitational Physics (Albert Einstein Institute), Am Mühlenberg 1, Potsdam 14476, Germany family-names: Nee given-names: Peter James orcid: https://orcid.org/0000-0002-2362-5420 - affiliation: Max Planck Institute for Gravitational Physics (Albert Einstein Institute), Am Mühlenberg 1, Potsdam 14476, Germany family-names: Nishimura given-names: Nami orcid: https://orcid.org/0009-0002-4398-9130 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Osorio given-names: Alejandro orcid: https://orcid.org/0009-0000-5024-0086 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Pajkos given-names: Michael A. orcid: https://orcid.org/0000-0002-4983-4589 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Pannone given-names: Kyle orcid: https://orcid.org/0009-0005-8607-2113 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Pineda given-names: Jose Maria orcid: https://orcid.org/0009-0007-6694-8434 - affiliation: International Centre for Theoretical Sciences - Tata Institute of Fundamental Research (ICTS-TIFR), Survey No. 151, Shivakote, Hesaraghatta Hobli, Bengaluru - 560 089, Karnataka, India. family-names: Prasad given-names: Vaishak orcid: https://orcid.org/0000-0001-6712-2457 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Ramirez given-names: Teresita orcid: https://orcid.org/0000-0003-0994-115X - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Ring given-names: Noah orcid: https://orcid.org/0000-0001-6510-4300 - affiliation: CFisUC, Department of Physics, University of Coimbra, 3004-516 Coimbra, Portugal family-names: Rüter given-names: Hannes R. orcid: https://orcid.org/0000-0002-3442-5360 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Sanchez given-names: Jennifer orcid: https://orcid.org/0000-0002-5335-4924 - affiliation: Department of Physics and Astronomy, University of Mississippi, University, Mississippi 38677, USA family-names: Stein given-names: Leo C. orcid: https://orcid.org/0000-0001-7559-9597 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Tellez given-names: Daniel orcid: https://orcid.org/0009-0008-7784-2528 - affiliation: Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA family-names: Thomas given-names: Sierra orcid: https://orcid.org/0000-0003-3574-2090 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Tommasini given-names: Vittoria orcid: https://orcid.org/0009-0001-4440-9751 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA and I. Physikalisches Institut, Universität zu Köln, Zülpicher Straße 77, 50937, Köln, Germany family-names: Vieira given-names: Daniel orcid: https://orcid.org/0000-0001-8019-0390 - affiliation: Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA family-names: Wang given-names: Xiyue orcid: https://orcid.org/0009-0006-3331-0832 - affiliation: Max Planck Institute for Gravitational Physics (Albert Einstein Institute), Am Mühlenberg 1, Potsdam 14476, Germany family-names: Wlodarczyk given-names: Tom orcid: https://orcid.org/0000-0003-0005-348X - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Wu given-names: David orcid: https://orcid.org/0000-0002-5287-4389 - affiliation: Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA family-names: Yoo given-names: Jooheon orcid: https://orcid.org/0000-0002-3251-0924 cff-version: 1.2.0 date-released: 2026-04-01 doi: 10.5281/zenodo.19373346 keywords: - Software - Astrophysics - General Relativity - Numerical Relativity - Multiphysics - Gravitational Waves - Discontinuous Galerkin - Finite Difference - Finite Volume license: MIT message: Please cite SpECTRE in any publications that make use of its code or data. Cite the latest version that you use in your publication. The citation for this version is listed below. references: - authors: - family-names: Iglberger given-names: Klaus - family-names: Hager given-names: Georg - family-names: Treibig given-names: Jan - family-names: Rüde given-names: Ulrich collection-title: 2012 International Conference on High Performance Computing \& Simulation (HPCS) doi: 10.1109/HPCSim.2012.6266939 pages: 367-373 title: High performance smart expression template math libraries type: article year: '2012' - authors: - family-names: Iglberger given-names: Klaus - family-names: Hager given-names: Georg - family-names: Treibig given-names: Jan - family-names: R\"{u}de given-names: Ulrich doi: 10.1137/110830125 number: '2' pages: C42-C69 title: 'Expression Templates Revisited: A Performance Analysis of Current Methodologies' type: article url: https://doi.org/10.1137/110830125 volume: '34' year: '2012' - authors: - family-names: Kale given-names: Laxmikant - family-names: Acun given-names: Bilge - family-names: Bak given-names: Seonmyeong - family-names: Becker given-names: Aaron - family-names: Bhandarkar given-names: Milind - family-names: Bhat given-names: Nitin - family-names: Bhatele given-names: Abhinav - family-names: Bohm given-names: Eric - family-names: Bordage given-names: Cyril - family-names: Brunner given-names: Robert - family-names: Buch given-names: Ronak - family-names: Chakravorty given-names: Sayantan - family-names: Chandrasekar given-names: Kavitha - family-names: Choi given-names: Jaemin - family-names: Denardo given-names: Michael - family-names: DeSouza given-names: Jayant - family-names: Diener given-names: Matthias - family-names: Dokania given-names: Harshit - family-names: Dooley given-names: Isaac - family-names: Fenton given-names: Wayne - family-names: Galvez given-names: Juan - family-names: Gioachin given-names: Fillipo - family-names: Gupta given-names: Abhishek - family-names: Gupta given-names: Gagan - family-names: Gupta given-names: Manish - family-names: Gursoy given-names: Attila - family-names: Harsh given-names: Vipul - family-names: Hu given-names: Fang - family-names: Huang given-names: Chao - family-names: Jagathesan given-names: Narain - family-names: Jain given-names: Nikhil - family-names: Jetley given-names: Pritish - family-names: Jindal given-names: Prateek - family-names: Kanakagiri given-names: Raghavendra - family-names: Koenig given-names: Greg - family-names: Krishnan given-names: Sanjeev - family-names: Kumar given-names: Sameer - family-names: Kunzman given-names: David - family-names: Lang given-names: Michael - family-names: Langer given-names: Akhil - family-names: Lawlor given-names: Orion - family-names: Wai Lee given-names: Chee - family-names: Lifflander given-names: Jonathan - family-names: Mahesh given-names: Karthik - family-names: Mendes given-names: Celso - family-names: Menon given-names: Harshitha - family-names: Mei given-names: Chao - family-names: Meneses given-names: Esteban - family-names: Mikida given-names: Eric - family-names: Miller given-names: Phil - family-names: Mokos given-names: Ryan - family-names: Narayanan given-names: Venkatasubrahmanian - family-names: Ni given-names: Xiang - family-names: Nomura given-names: Kevin - family-names: Paranjpye given-names: Sameer - family-names: Ramachandran given-names: Parthasarathy - family-names: Ramkumar given-names: Balkrishna - family-names: Ramos given-names: Evan - family-names: Robson given-names: Michael - family-names: Saboo given-names: Neelam - family-names: Saletore given-names: Vikram - family-names: Sarood given-names: Osman - family-names: Senthil given-names: Karthik - family-names: Shah given-names: Nimish - family-names: Shu given-names: Wennie - family-names: B. Sinha given-names: Amitabh - family-names: Sun given-names: Yanhua - family-names: Sura given-names: Zehra - family-names: Totoni given-names: Ehsan - family-names: Varadarajan given-names: Krishnan - family-names: Venkataraman given-names: Ramprasad - family-names: Wang given-names: Jackie - family-names: Wesolowski given-names: Lukasz - family-names: White given-names: Sam - family-names: Wilmarth given-names: Terry - family-names: Wright given-names: Jeff - family-names: Yelon given-names: Joshua - family-names: Zheng given-names: Gengbin doi: 10.5281/zenodo.3370873 month: 8 title: '{The Charm++ Parallel Programming System}' type: software url: https://charm.cs.illinois.edu year: '2019' - authors: - family-names: Kale given-names: Laxmikant - family-names: Acun given-names: Bilge - family-names: Bak given-names: Seonmyeong - family-names: Becker given-names: Aaron - family-names: Bhandarkar given-names: Milind - family-names: Bhat given-names: Nitin - family-names: Bhatele given-names: Abhinav - family-names: Bohm given-names: Eric - family-names: Bordage given-names: Cyril - family-names: Brunner given-names: Robert - family-names: Buch given-names: Ronak - family-names: Chakravorty given-names: Sayantan - family-names: Chandrasekar given-names: Kavitha - family-names: Choi given-names: Jaemin - family-names: Denardo given-names: Michael - family-names: DeSouza given-names: Jayant - family-names: Diener given-names: Matthias - family-names: Dokania given-names: Harshit - family-names: Dooley given-names: Isaac - family-names: Fenton given-names: Wayne - family-names: Fink given-names: Zane - family-names: Galvez given-names: Juan - family-names: Ghosh given-names: Pathikrit - family-names: Gioachin given-names: Fillipo - family-names: Gupta given-names: Abhishek - family-names: Gupta given-names: Gagan - family-names: Gupta given-names: Manish - family-names: Gursoy given-names: Attila - family-names: Harsh given-names: Vipul - family-names: Hu given-names: Fang - family-names: Huang given-names: Chao - family-names: Jagathesan given-names: Narain - family-names: Jain given-names: Nikhil - family-names: Jetley given-names: Pritish - family-names: Jindal given-names: Prateek - family-names: Kanakagiri given-names: Raghavendra - family-names: Koenig given-names: Greg - family-names: Krishnan given-names: Sanjeev - family-names: Kumar given-names: Sameer - family-names: Kunzman given-names: David - family-names: Lang given-names: Michael - family-names: Langer given-names: Akhil - family-names: Lawlor given-names: Orion - family-names: Lee given-names: Chee Wai - family-names: Lifflander given-names: Jonathan - family-names: Mahesh given-names: Karthik - family-names: Mendes given-names: Celso - family-names: Menon given-names: Harshitha - family-names: Mei given-names: Chao - family-names: Meneses given-names: Esteban - family-names: Mikida given-names: Eric - family-names: Miller given-names: Phil - family-names: Mokos given-names: Ryan - family-names: Narayanan given-names: Venkatasubrahmanian - family-names: Ni given-names: Xiang - family-names: Nomura given-names: Kevin - family-names: Paranjpye given-names: Sameer - family-names: Ramachandran given-names: Parthasarathy - family-names: Ramkumar given-names: Balkrishna - family-names: Ramos given-names: Evan - family-names: Robson given-names: Michael - family-names: Saboo given-names: Neelam - family-names: Saletore given-names: Vikram - family-names: Sarood given-names: Osman - family-names: Senthil given-names: Karthik - family-names: Shah given-names: Nimish - family-names: Shu given-names: Wennie - family-names: Sinha given-names: Amitabh B. - family-names: Sun given-names: Yanhua - family-names: Sura given-names: Zehra - family-names: Szaday given-names: Justin - family-names: Totoni given-names: Ehsan - family-names: Varadarajan given-names: Krishnan - family-names: Venkataraman given-names: Ramprasad - family-names: Wang given-names: Jackie - family-names: Wesolowski given-names: Lukasz - family-names: White given-names: Sam - family-names: Wilmarth given-names: Terry - family-names: Wright given-names: Jeff - family-names: Yelon given-names: Joshua - family-names: Zheng given-names: Gengbin doi: 10.5281/zenodo.5597907 month: 10 publisher: name: Zenodo title: '{UIUC-PPL}/charm: {Charm++} version 7.0.0' type: software url: https://doi.org/10.5281/zenodo.5597907 version: v7.0.0 year: '2021' - authors: - family-names: Kale given-names: Laxmikant V - family-names: Krishnan given-names: Sanjeev collection-title: Parallel programming using C++ pages: 175--213 publisher: name: The MIT Press title: 'Charm++: Parallel programming with message-driven objects' type: article year: '1996' - authors: - family-names: Galassi given-names: M. - name: others edition: '3' isbn: '9780954612078' publisher: name: Network Theory Ltd. title: '{GNU} Scientific Library Reference Manual' type: book year: '2009' - authors: - name: '{The HDF Group}' title: '{Hierarchical Data Format, version 5}' type: software year: 1997-2023 - authors: - family-names: '{Reinecke}' given-names: M. - family-names: '{Seljebotn}' given-names: D. S. doi: 10.1051/0004-6361/201321494 month: 6 pages: A112 title: '{Libsharp - spherical harmonic transforms revisited}' type: article volume: '554' year: '2013' - authors: - family-names: Heinecke given-names: Alexander - family-names: Henry given-names: Greg - family-names: Hutchinson given-names: Maxwell - family-names: Pabst given-names: Hans collection-title: Proceedings of the International Conference for High Performance Computing, Networking, Storage and Analysis isbn: '9781467388153' pages: 1-11 publisher: name: IEEE Press title: '{LIBXSMM}: {Accelerating} Small Matrix Multiplications by Runtime Code Generation' type: article year: '2016' - authors: - family-names: Hunter given-names: J. D. doi: 10.1109/MCSE.2007.55 number: '3' pages: 90--95 publisher: name: IEEE COMPUTER SOC title: 'Matplotlib: A 2D graphics environment' type: article volume: '9' year: '2007' - authors: - family-names: Caswell given-names: Thomas A - family-names: Droettboom given-names: Michael - family-names: Lee given-names: Antony - family-names: Hunter given-names: John - family-names: Firing given-names: Eric - family-names: Andrade given-names: Elliott Sales name-particle: de - family-names: Hoffmann given-names: Tim - family-names: Stansby given-names: David - family-names: Klymak given-names: Jody - family-names: Varoquaux given-names: Nelle - family-names: Nielsen given-names: Jens Hedegaard - family-names: Root given-names: Benjamin - family-names: May given-names: Ryan - family-names: Elson given-names: Phil - family-names: Dale given-names: Darren - family-names: Lee given-names: Jae-Joon - family-names: Seppänen given-names: Jouni K. - family-names: McDougall given-names: Damon - family-names: Straw given-names: Andrew - family-names: Hobson given-names: Paul - family-names: Gohlke given-names: Christoph - family-names: Yu given-names: Tony S - family-names: Ma given-names: Eric - family-names: Vincent given-names: Adrien F. - family-names: Silvester given-names: Steven - family-names: Moad given-names: Charlie - family-names: Kniazev given-names: Nikita - name: hannah - family-names: Ernest given-names: Elan - family-names: Ivanov given-names: Paul doi: 10.5281/zenodo.3948793 month: 7 publisher: name: Zenodo title: 'matplotlib/matplotlib: {REL:} v3.3.0' type: software url: https://doi.org/10.5281/zenodo.3948793 version: v3.3.0 year: '2020' - authors: - family-names: Harris given-names: Charles R. - family-names: Millman given-names: K. Jarrod - family-names: Walt given-names: St{\'{e}}fan J. name-particle: van der - family-names: Gommers given-names: Ralf - family-names: Virtanen given-names: Pauli - family-names: Cournapeau given-names: David - family-names: Wieser given-names: Eric - family-names: Taylor given-names: Julian - family-names: Berg given-names: Sebastian - family-names: Smith given-names: Nathaniel J. - family-names: Kern given-names: Robert - family-names: Picus given-names: Matti - family-names: Hoyer given-names: Stephan - family-names: Kerkwijk given-names: Marten H. name-particle: van - family-names: Brett given-names: Matthew - family-names: Haldane given-names: Allan - family-names: R{\'{i}}o given-names: Jaime Fern{\'{a}}ndez name-particle: del - family-names: Wiebe given-names: Mark - family-names: Peterson given-names: Pearu - family-names: G{\'{e}}rard-Marchant given-names: Pierre - family-names: Sheppard given-names: Kevin - family-names: Reddy given-names: Tyler - family-names: Weckesser given-names: Warren - family-names: Abbasi given-names: Hameer - family-names: Gohlke given-names: Christoph - family-names: Oliphant given-names: Travis E. doi: 10.1038/s41586-020-2649-2 month: 9 number: '7825' pages: 357--362 publisher: name: Springer Science and Business Media {LLC} title: Array programming with {NumPy} type: article url: https://doi.org/10.1038/s41586-020-2649-2 volume: '585' year: '2020' - authors: - family-names: Ayachit given-names: Utkarsh isbn: '1930934300' publisher: name: Kitware, Inc. title: 'The ParaView Guide: A Parallel Visualization Application' type: book year: '2015' - authors: - family-names: Ahrens given-names: J. - family-names: Geveci given-names: Berk - family-names: Law given-names: C. isbn: '9780123875822' publisher: name: Elsevier title: '{ParaView}: {An} end-user tool for large-data visualization' type: book year: '2005' - authors: - family-names: Jakob given-names: Wenzel - family-names: Rhinelander given-names: Jason - family-names: Moldovan given-names: Dean title: pybind11 -- Seamless operability between C++11 and Python type: software year: '2017' - authors: - family-names: Beder given-names: Jesse - family-names: Woehlke given-names: Matthew - family-names: Breitbart given-names: Jens - family-names: Wolchok given-names: Scott - family-names: Hackimov given-names: Azamat H. - family-names: Snape given-names: Jamie - family-names: Hamlet given-names: Oliver - family-names: Novotny given-names: Paul - family-names: Tambre given-names: Raul - family-names: Reinhold given-names: Stefan - family-names: Vaucher given-names: Alain - family-names: Zaitsev given-names: Alexander - family-names: Anokhin given-names: Alexander - family-names: Karatarakis given-names: Alexander - family-names: Maloney given-names: Andy - family-names: Polukhin given-names: Antony - family-names: Brandenburg given-names: Craig M. - family-names: Ibanez given-names: Dan - family-names: Gladkikh given-names: Denis - family-names: Eich given-names: Florian - family-names: Dumont given-names: Guillaume - family-names: Trigg given-names: Haydn - family-names: King given-names: Jim - family-names: Frederico given-names: Joel - family-names: Hamilton given-names: Jonathan - family-names: Langley given-names: Joseph - family-names: Hämäläinen given-names: Lassi - family-names: Blair given-names: Matt - family-names: Duggan given-names: Michael Welsh - family-names: Wang given-names: Olli - family-names: Stotko given-names: Patrick - family-names: Levine given-names: Peter - family-names: Bena given-names: Petr - family-names: Cordoba given-names: Rodrigo Hernandez - family-names: Schmidt given-names: Ryan - family-names: Gottlieb given-names: Simon Gene - family-names: Prilmeier given-names: Franz - family-names: Zhang given-names: Tanki - family-names: Ishi given-names: Tatsuyuki - family-names: Lyngmo given-names: Ted - family-names: Mataré given-names: Victor - family-names: Konečný given-names: Michael - name: USDOE doi: 10.11578/dc.20220817.13 month: 9 title: yaml-cpp type: software url: https://www.osti.gov/biblio/1881863 year: '2009' repository-code: https://github.com/sxs-collaboration/spectre title: SpECTRE url: https://spectre-code.org version: 2026.04.01 ================================================ FILE: CMakeLists.txt ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. cmake_minimum_required(VERSION 3.18.0) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") # Create a new (or overwrite existing) info file at start of configuration file(WRITE "${CMAKE_BINARY_DIR}/BuildInfo.txt" "") # Determine the project version and other metadata include(SpectreLoadMetadata) # Set up the project. Notes: # - Fortran is needed for SPHEREPACK project(${SPECTRE_NAME} VERSION ${SPECTRE_VERSION} LANGUAGES CXX C Fortran) # Unset the CMake-defined version variable because it strips zeros from the # version components, e.g. 2020.12.07 becomes 2020.12.7 unset(${SPECTRE_NAME}_VERSION) # Also unset the version-component variables because they have no meaning in # our versioning scheme unset(${SPECTRE_NAME}_VERSION_MAJOR) unset(${SPECTRE_NAME}_VERSION_MINOR) unset(${SPECTRE_NAME}_VERSION_PATCH) # Policies # The `cmake_minimum_required` above sets policies to `NEW` that are compatible # with the given minimum cmake version. Here we overwrite policies that we # have back-ported in our cmake code. # - We use test names with '.' characters in them if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.19) cmake_policy(SET CMP0110 NEW) endif () # - We allow both uppercase and case-preserved hints in `find_package` calls, so # `PACKAGENAME_ROOT` and `PackageName_ROOT` are both searched in # `FindPackageName.cmake` (NEW behavior). The OLD behavior was to search only # `PackageName_ROOT` (before CMake v3.27). We have backported the NEW behavior # by adding the uppercase name explicitly to the list of hints. if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.27) cmake_policy(SET CMP0144 NEW) endif() # - The `NEW` behavior of `DOWNLOAD_EXTRACT_TIMESTAMP` is recommended. if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) cmake_policy(SET CMP0135 NEW) endif() # - We allow CMake 3.30 and above to load Boost's CMake config file that is # installed alongside Boost. Before, CMake provided its own FindBoost module. if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.30) cmake_policy(SET CMP0167 NEW) endif () # FetchContent can be used to download and build some dependencies. We can # consider turning this on by default later. option(SPECTRE_FETCH_MISSING_DEPS "Download missing dependencies" OFF) # - Mark FetchContent as 'SYSTEM' to suppress warnings. # Supported since CMake version 3.25. if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.25) set(SPECTRE_FETCHCONTENT_BASE_ARGS SYSTEM) else() set(SPECTRE_FETCHCONTENT_BASE_ARGS "") endif() # Define standard installation directories include(GNUInstallDirs) # Disable `make install` depending on `make all` since we want to control what # we install more closely. With this setting, and targets marked as `OPTIONAL`, # only targets that were built will be installed. set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY ON) set(CMAKE_VERBOSE_MAKEFILE OFF) include(SpectreGetGitHash) include(SpectreSetSiteName) # We need Python in the build system and throughout the code. Setting it up # early so we can rely on a consistent Python version in the build system. option(ENABLE_PYTHON "Enable Python" ON) if (ENABLE_PYTHON) find_package(Python 3.8 REQUIRED) # Define the location of Python code in the build directory. Unit tests etc. can # add this location to their `PYTHONPATH`. set(SPECTRE_PYTHON_PREFIX_PARENT "${CMAKE_BINARY_DIR}/bin/python") get_filename_component( SPECTRE_PYTHON_PREFIX_PARENT "${SPECTRE_PYTHON_PREFIX_PARENT}" ABSOLUTE) set(SPECTRE_PYTHON_SITE_PACKAGES "${CMAKE_BINARY_DIR}/lib/\ python${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}/site-packages") set(PYTHONPATH "${SPECTRE_PYTHON_PREFIX_PARENT}:\ ${SPECTRE_PYTHON_SITE_PACKAGES}") if(DEFINED ENV{PYTHONPATH}) set(PYTHONPATH "${PYTHONPATH}:$ENV{PYTHONPATH}") endif() message(STATUS "PYTHONPATH: ${PYTHONPATH}") include(BootstrapPyDeps) else() # We still need minimal Python for linking purpose. find_package(Python REQUIRED) endif() option(BUILD_DOCS "Enable building documentation" ON) option( DOCS_ONLY "Skip all initialization not required for rendering documentation" OFF ) if (BUILD_DOCS AND DOCS_ONLY) include(SetupDoxygen) return() endif() option(USE_PCH "Use precompiled headers" ON) include(SpectreInitializeVariables) include(CheckCompilerVersion) include(ProhibitInSourceBuild) include(SpectreSetupFlagsTarget) include(SetupFortran) include(SetupNinjaColors) include(SetOutputDirectory) include(SpectreAddInterfaceLibraryHeaders) include(SpectreTargetHeaders) include(SpectreTargetSources) include(SetupFormaline) include(SetupGitHooks) include(SetupLicenseInfo) include(SetBuildType) include(SetupPic) include(SetupLinkTimeOptimization) include(SetCxxStandard) include(StripSymbols) # We need Boost for InfoAtLink include(SetupBoost) include(SetupInformer) include(SetupCCache) include(SetupCharm) include(EnableWarnings) include(SetupGoldOrLldLinker) # In order to use certain code analysis tools like clang-tidy and cppcheck the # compile commands need to be accessible. CMake can write these to a # "compile_commands.json" file. set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include(SetupLIBCXX) include(SetupSpectreInlining) include(SetupCxxFlags) include(SetupProfiling) include(SetupSanitizers) include(SetupListTargets) include(AddSpectreExecutable) include(CheckBrokenArray0) # Blaze depends on both Blas and Lapack, since LIBXSMM is a Blas # alternative we set it up early too. Finally, Blaze uses the GSL # blas headers, so we need to set that up before Blaze as well. include(SetupBlas) include(SetupLapack) include(SetupLIBXSMM) include(SetupGsl) include(SetupAutodiff) include(SetupBlaze) include(SetupFuka) include(SetupGoogleBenchmark) include(SetupHdf5) include(SetupAllocator) include(SetupPapi) include(SetupPybind11) include(SetupSpec) include(SetupStl) include(SetupXsimd) include(SetupYamlCpp) include(SetupOpenMP) include(SetupParaView) add_subdirectory(external) include(SetupKokkos) include(SetupLIBCXXCharm) # The precompiled header must be setup after all libraries have been found if (USE_PCH) include(SetupPch) endif() # All special targets and configs that need to be applied to *all* # executables must be added at once in the 'UpdateAddExecutables' file. # This is because of what is likely a bug in CMake where if a function is # overridden multiple times (using the _function_name(...) method) then some # versions of CMake (at least 3.13.2) segfault. include(UpdateAddExecutables) # The ClangFormat, clang-tidy, Doxygen, and CodeCov are intentionally # after the PCH setup because that way they are able to change their # dependencies on the PCH if necessary. include(SetupClangFormat) include(SetupClangTidy) if(BUILD_DOCS) include(SetupDoxygen) include(SetupSphinx) endif() include(CodeCoverageDetection) include(SpectreAddLibraries) include(SpectreSetupTesting) if(BUILD_TESTING) include(SetupCatch) include(SetupPypp) include(SpectreAddTestLibs) include(SpectreAddCatchTests) include(AddInputFileTests) include(AddStandaloneTests) endif() include(SpectreSetupPythonPackage) # Set global include directory for all targets include_directories(${CMAKE_SOURCE_DIR}/src) # Charm++ generated headers are created in the build directory # (by `add_charm_module`) include_directories(SYSTEM ${CMAKE_BINARY_DIR}/src) add_subdirectory(src) add_subdirectory(support) if(BUILD_TESTING) add_subdirectory(tests) endif() add_subdirectory(tools) include(PrintUsefulCMakeInfo) include(SpectreCheckDependencies) ================================================ FILE: LICENSE.txt ================================================ ============================================================================== SpECTRE Release License ============================================================================== Copyright 2017 - 2026 Simulating eXtreme Spacetimes Collaboration Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Metadata.yaml ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. Name: SpECTRE License: MIT Homepage: https://spectre-code.org GitHub: sxs-collaboration/spectre Version: 2026.04.01 PublicationDate: 2026-04-01 Doi: 10.5281/zenodo.19373346 ZenodoId: 19373346 Description: | SpECTRE is an open-source code for multi-scale, multi-physics problems in astrophysics and gravitational physics. In the future, we hope that it can be applied to problems across discipline boundaries in fluid dynamics, geoscience, plasma physics, nuclear physics, and engineering. It runs at petascale and is designed for future exascale computers. SpECTRE is being developed in support of our collaborative Simulating eXtreme Spacetimes (SXS) research program into the multi-messenger astrophysics of neutron star mergers, core-collapse supernovae, and gamma-ray bursts. Keywords: - Software - Astrophysics - General Relativity - Numerical Relativity - Multiphysics - Gravitational Waves - Discontinuous Galerkin - Finite Difference - Finite Volume Affiliations: - &aei Max Planck Institute for Gravitational Physics (Albert Einstein Institute), Am Mühlenberg 1, Potsdam 14476, Germany - &caltech Theoretical Astrophysics, Walter Burke Institute for Theoretical Physics, California Institute of Technology, Pasadena, CA 91125, USA - &cornell Cornell Center for Astrophysics and Planetary Science, Cornell University, Ithaca, New York 14853, USA - &coimbra CFisUC, Department of Physics, University of Coimbra, 3004-516 Coimbra, Portugal - &fullerton Nicholas and Lee Begovich Center for Gravitational-Wave Physics and Astronomy, California State University, Fullerton, Fullerton, California 92831, USA - &icts International Centre for Theoretical Sciences - Tata Institute of Fundamental Research (ICTS-TIFR), Survey No. 151, Shivakote, Hesaraghatta Hobli, Bengaluru - 560 089, Karnataka, India. - &new_hampshire Department of Physics & Astronomy, University of New Hampshire, 9 Library Way, Durham NH 03824, USA - &koln I. Physikalisches Institut, Universität zu Köln, Zülpicher Straße 77, 50937, Köln, Germany - &umiss Department of Physics and Astronomy, University of Mississippi, University, Mississippi 38677, USA - &oberlin Department of Physics and Astronomy, Oberlin College, Oberlin, Ohio 44074, USA Authors: Description: | We maintain three tiers of authors for the code as a whole: Core, Developers and Contributors. The full author list for the SpECTRE DOI is built by concatenating all authors in the order they are listed here. The primary goal of this author list is to recognize infrastructure work that does not or cannot have any science papers and results associated with it. Through authorship on the SpECTRE DOI such work gains recognition that holds value in academia. Authorship on the SpECTRE DOI does not directly entitle a person for authorship rights on other publications. Authorship rights on publications related to SpECTRE are governed by our publication policy (see `docs/PublicationPolicy.md`). Note that the placement of authors in these tiers is inherently a subjective topic since we are forced to compare different projects people work on. Nevertheless, having guidelines and some way of promoting healthy and constructive discussions is vital for ensuring the collaborative aspect of the code is healthy. Core: Description: | For the time a Developer serves as Core developer they take on some project-management responsibilities, such as initiating and signing off on code reviews, maintaining compatibility with third-party libraries, maintaining the CI/CD infrastructure and overseeing the code as a whole. Guidelines on becoming a Core developer: - Have at least 4-5 major infrastructure contributions, each taking roughly 4-5 weeks of full-time work for an existing Core developer. - Seek out PRs to review and volunteer when calls for a reviewer are made. - Reach out to any of the existing Core developers and express your interest in taking on the responsibilities that come with this role. The Core developers will discuss the request and either appoint you to Core developer or provide you with feedback on what they think remains to be done. Note that most people will not end up in the Core developer list since a lot of work will lead to science results and authorship on science papers, which pay dividends for the work. Supervising students and postdocs does not count towards Core developer status. Guidelines on stepping down as Core developer: - After a Core developer leaves the project they will remain in this tier for at least two years. At that point the Core developers will discuss if the person should be moved to the Developer tier. - A Core developer can step down from the Core developer role at any time. The author list order is decided by the Core developers. List: - Name: Deppe, Nils Orcid: 0000-0003-4557-4115 Affiliations: [*caltech] GitHub: nilsdeppe - Name: Throwe, William Orcid: 0000-0001-5059-4378 Affiliations: [*cornell] GitHub: wthrowe - Name: Kidder, Lawrence E. Orcid: 0000-0001-5392-7342 Affiliations: [*cornell] GitHub: kidder - Name: Vu, Nils L. Orcid: 0000-0002-5767-3949 Affiliations: [*aei] GitHub: nilsvu - Name: Nelli, Kyle C. Orcid: 0000-0003-2426-8768 Affiliations: [*caltech] GitHub: knelli2 Developers: Description: | Developers have contributed major features to SpECTRE and remain in this list indefinitely unless they wish to be removed. Guidelines on becoming a Developer: - Do some code review, does not need to be self-initiated. - Somewhere around 40 commits and 10k-15k lines of code should trigger a discussion among the Core developers to move someone from Contributors to Developers. These are guidelines and being above or below these arbitrary cutoffs does not automatically include or exclude you. E.g. someone doing complicated low-level code will likely become a Developer with far fewer lines of code contributed. - Anyone supervising a Core developer or two Developers may be considered for Developer status. Whether to be placed as Developer or Contributor will depend on how active the supervision is. If most of the supervision is coming from the Core developers then Contributor status is appropriate. This will be discussed with the person supervising the Core developer and/or Developers. This author list is ordered by last name. List: - Name: Armaza, Cristóbal Orcid: 0000-0002-1791-0743 Affiliations: [*cornell] GitHub: carmaza - Name: Bonilla, Marceline S. Orcid: 0000-0003-4502-528X Affiliations: [*fullerton] GitHub: mar-celine - Name: Hébert, François Orcid: 0000-0001-9009-6955 Affiliations: [*caltech] GitHub: fmahebert - Name: Kim, Yoonsoo Orcid: 0000-0002-4305-6026 Affiliations: [*caltech] GitHub: yoonso0-0 - Name: Kumar, Prayush Orcid: 0000-0001-5523-4603 Affiliations: [*cornell] GitHub: prayush - Name: Lovelace, Geoffrey Orcid: 0000-0002-7084-1070 Affiliations: [*fullerton] GitHub: geoffrey4444 - Name: Macedo, Alexandra Orcid: 0009-0001-7671-6377 Affiliations: [*fullerton] GitHub: macedo22 - Name: Moxon, Jordan Orcid: 0000-0001-9891-8677 Affiliations: [*caltech] GitHub: moxcodes - Name: O'Shea, Eamonn Affiliations: [*cornell] GitHub: osheamonn - Name: Pfeiffer, Harald P. Orcid: 0000-0001-9288-519X Affiliations: [*aei] GitHub: haraldp271 - Name: Scheel, Mark A. Orcid: 0000-0001-6656-9134 Affiliations: [*caltech] GitHub: markscheel - Name: Teukolsky, Saul A. Orcid: 0000-0001-9765-4526 Affiliations: [*caltech, *cornell] GitHub: teukolsky - Name: Wittek, Nikolas A. Orcid: 0000-0001-8575-5450 Affiliations: [*aei] GitHub: nikwit Contributors: Description: | Anyone who has contributed to SpECTRE will be added to this list and remain a Contributor indefinitely unless they wish to be removed. Guidelines on becoming a Contributor: - See our guidelines in `docs/CONTRIBUTING.md` for information on how to get involved with SpECTRE development. - Having any PR merged qualifies for this list. If multiple people worked on the PR together, e.g. several undergraduate students contributing to a single PR, all persons involved will become a Contributor. - Supervising a project that results in a merged PR qualifies for this list. The supervision must be active, i.e. not primarily done by the Core developers. - Having an idea for a contribution does not count towards any contributor status. There must be active supervision of the person(s) implementing the idea, such as advice on debugging, how to best implement the idea, etc. The supervision is what will be counted for contributor status. Generally, a paper is written where the person who came up with the idea is a co-author, which is how credit is given for the idea. An example is suggesting "We should try reconstruction scheme X" without continued guidance throughout the implementation process would not be counted for contributor status. This author list is ordered by last name. List: - Name: Anantpurkar, Isha Orcid: 0000-0002-5814-4109 Affiliations: [*cornell] GitHub: isha1810 - Name: Anderson, Carter Orcid: 0009-0009-0359-6763 Affiliations: [*caltech] GitHub: ctrandrsn - Name: Boyle, Michael Orcid: 0000-0002-5075-5116 Affiliations: [*cornell] GitHub: moble - Name: Carpenter, Alexander Orcid: 0000-0002-9183-8006 Affiliations: [*fullerton] GitHub: AlexCarpenter46 - Name: Ceja, Andrea Orcid: 0000-0002-1681-7299 Affiliations: [*fullerton] GitHub: acifajkya - Name: Chaudhary, Himanshu Orcid: 0000-0002-4101-0534 Affiliations: [*caltech] GitHub: GitHimanshuc - Name: Corso, Nicholas Orcid: 0000-0002-0088-2563 Affiliations: [*cornell] GitHub: ncorsobh - Name: Dittmer, Clemens Orcid: 0009-0007-3833-9252 Affiliations: [*aei] GitHub: clemensdittmer - Name: Fayyazuddin Ljungberg, Nora Orcid: 0000-0002-7074-4545 Affiliations: [*cornell] GitHub: norafl - Name: Foucart, Francois Orcid: 0000-0003-4617-4738 Affiliations: [*new_hampshire] GitHub: ffoucart - Name: Ghadiri, Noora Orcid: 0000-0001-9162-4449 Affiliations: [*fullerton] GitHub: noora-gn - Name: Giesler, Matthew Orcid: 0000-0003-2300-893X Affiliations: [*cornell] GitHub: mgiesler - Name: Guo, Jason S. Affiliations: [*cornell] GitHub: erfz - Name: Habib, Sarah Orcid: 0000-0002-4725-4978 Affiliations: [*caltech] GitHub: shabibti - Name: Huang, Chenhang Orcid: 0000-0003-2617-1011 Affiliations: [*cornell] GitHub: hen-w - Name: Iozzo, Dante A. B. Orcid: 0000-0002-7244-1900 Affiliations: [*cornell] GitHub: "10220" - Name: Jones, Ken Z. Orcid: 0009-0003-1034-0498 Affiliations: [*fullerton] GitHub: "kenzenjones" - Name: Lara, Guillermo Orcid: 0000-0001-9461-6292 Affiliations: [*aei] GitHub: guilara - Name: Legred, Isaac Orcid: 0000-0002-9523-9617 Affiliations: [*caltech] GitHub: isaaclegred - Name: Li, Dongjun Orcid: 0000-0002-1962-680X Affiliations: [*caltech] GitHub: dongjun826 - Name: Ma, Sizheng Orcid: 0000-0002-4645-453X Affiliations: [*caltech] GitHub: Sizheng-Ma - Name: Melchor, Denyz Orcid: 0000-0002-7854-1953 Affiliations: [*fullerton] GitHub: denyzamelchor - Name: Mendes, Iago Orcid: 0009-0007-9845-8448 Affiliations: [*caltech, *oberlin] GitHub: iago-mendes - Name: Morales, Marlo Orcid: 0000-0002-0593-4318 Affiliations: [*fullerton] GitHub: MarloMo - Name: Most, Elias R. Orcid: 0000-0002-0491-1210 Affiliations: [*caltech] GitHub: ermost - Name: Murphy, Michael Orcid: 0000-0003-3865-3034 Affiliations: [*cornell] GitHub: michaeldmurphy1 - Name: Nee, Peter James Orcid: 0000-0002-2362-5420 Affiliations: [*aei] GitHub: PunJustice - Name: Nishimura, Nami Orcid: 0009-0002-4398-9130 Affiliations: [*aei] GitHub: NamiNishimura73 - Name: Osorio, Alejandro Orcid: 0009-0000-5024-0086 Affiliations: [*fullerton] GitHub: ajosorio3 - Name: Pajkos, Michael A. Orcid: 0000-0002-4983-4589 Affiliations: [*caltech] GitHub: pajkosmi - Name: Pannone, Kyle Orcid: 0009-0005-8607-2113 Affiliations: [*fullerton] GitHub: Bronoulli - Name: Pineda, Jose Maria Orcid: 0009-0007-6694-8434 Affiliations: [*fullerton] GitHub: JosePineda684 - Name: Prasad, Vaishak Orcid: 0000-0001-6712-2457 Affiliations: [*icts] GitHub: vaishakp - Name: Ramirez, Teresita Orcid: 0000-0003-0994-115X Affiliations: [*fullerton] GitHub: trami18 - Name: Ring, Noah Orcid: 0000-0001-6510-4300 Affiliations: [*cornell] GitHub: nring21 - Name: Rüter, Hannes R. Orcid: 0000-0002-3442-5360 Affiliations: [*coimbra] GitHub: hrueter - Name: Sanchez, Jennifer Orcid: 0000-0002-5335-4924 Affiliations: [*fullerton] GitHub: jennifersanchez - Name: Stein, Leo C. Orcid: 0000-0001-7559-9597 Affiliations: [*umiss] GitHub: duetosymmetry - Name: Tellez, Daniel Orcid: 0009-0008-7784-2528 Affiliations: [*fullerton] GitHub: daniel20tellez - Name: Thomas, Sierra Orcid: 0000-0003-3574-2090 Affiliations: [*fullerton] GitHub: sierracthomas - Name: Tommasini, Vittoria Orcid: 0009-0001-4440-9751 Affiliations: [*caltech] GitHub: vtommasini - Name: Vieira, Daniel Orcid: 0000-0001-8019-0390 Affiliations: [*cornell, *koln] GitHub: dkvieira - Name: Wang, Xiyue Orcid: 0009-0006-3331-0832 Affiliations: [*caltech] GitHub: EmilyWang0130 - Name: Wlodarczyk, Tom Orcid: 0000-0003-0005-348X Affiliations: [*aei] GitHub: tomwlodarczyk - Name: Wu, David Orcid: 0000-0002-5287-4389 Affiliations: [*cornell] GitHub: DavidWu421 - Name: Yoo, Jooheon Orcid: 0000-0002-3251-0924 Affiliations: [*cornell] GitHub: jyoo1042 References: Description: | SpECTRE depends on these references. The keys refer to entries in the 'BibliographyFile'. We use BibTeX for our references so we can also cite them in publications. BibliographyFile: docs/Dependencies.bib List: - Blaze1 - Blaze2 - Charmpp1 - Charmpp2 - Charmpp3 - Gsl - Hdf5 - Libsharp - Libxsmm - MatplotLib1 - MatplotLib2 - NumPy - Paraview1 - Paraview2 - Pybind11 - Yamlcpp ================================================ FILE: README.md ================================================ [//]: # (Distributed under the MIT License.) [//]: # (See LICENSE.txt for details.) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/sxs-collaboration/spectre/blob/develop/LICENSE.txt) [![Standard](https://img.shields.io/badge/c%2B%2B-20-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) [![Build Status](https://github.com/sxs-collaboration/spectre/workflows/Tests/badge.svg?branch=develop)](https://github.com/sxs-collaboration/spectre/actions) [![codecov](https://codecov.io/gh/sxs-collaboration/spectre/graph/badge.svg?token=yyJ3uBPUE2)](https://codecov.io/gh/sxs-collaboration/spectre) [![release](https://img.shields.io/badge/release-v2026.04.01-informational)](https://github.com/sxs-collaboration/spectre/releases/tag/v2026.04.01) [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.19373346.svg)](https://doi.org/10.5281/zenodo.19373346) ![banner](docs/Images/banner.png) ## What is SpECTRE? SpECTRE is an open-source code for multi-scale, multi-physics problems in astrophysics and gravitational physics. It is based on high-order spectral finite element methods and massive parallelism. In the future, we hope that it can be applied to problems across discipline boundaries in fluid dynamics, geoscience, plasma physics, nuclear physics, and engineering. It runs at petascale and is designed for future exascale computers. SpECTRE is being developed in support of our collaborative Simulating eXtreme Spacetimes (SXS) research program into the multi-messenger astrophysics of black hole and neutron star mergers, core-collapse supernovae, and gamma-ray bursts. ## Gallery For an overview of some of SpECTRE's features and some simulations performed with SpECTRE, visit the gallery: - Gallery: https://spectre-code.org/gallery ## Documentation You find instructions on installing and running the code, as well as many guides and tutorials, in the documentation: - Documentation: https://spectre-code.org/ ## Citing SpECTRE Please cite SpECTRE in any publications that make use of its code or data. Cite the latest version that you use in your publication. The DOI for this version is: - DOI: [10.5281/zenodo.19373346](https://doi.org/10.5281/zenodo.19373346) You can cite this BibTeX entry in your publication: ```bib @software{spectrecode, author = "Deppe, Nils and Throwe, William and Kidder, Lawrence E. and Vu, Nils L. and Nelli, Kyle C. and Armaza, Crist\'obal and Bonilla, Marceline S. and H\'ebert, Fran\c{c}ois and Kim, Yoonsoo and Kumar, Prayush and Lovelace, Geoffrey and Macedo, Alexandra and Moxon, Jordan and O'Shea, Eamonn and Pfeiffer, Harald P. and Scheel, Mark A. and Teukolsky, Saul A. and Wittek, Nikolas A. and others", title = "\texttt{SpECTRE v2026.04.01}", version = "2026.04.01", publisher = "Zenodo", doi = "10.5281/zenodo.19373346", url = "https://spectre-code.org", howpublished = "\href{https://doi.org/10.5281/zenodo.19373346}{10.5281/zenodo.19373346}", license = "MIT", year = "2026", month = "4" } ``` To aid reproducibility of your scientific results with SpECTRE, we recommend you keep track of the version(s) you used and report this information in your publication. We also recommend you supply the YAML input files and, if appropriate, any additional C++ code you wrote to compile SpECTRE executables as supplemental material to the publication. See our [publication policy](https://spectre-code.org/publication_policies.html) for more information. ## Logos and visuals You can find logos and other visuals (e.g. to put on slides) in various formats, colors, and sizes here: - [Logos and visuals](https://drive.google.com/drive/folders/1GEvVrXNqlGojr3NBf7RMFo6BzFmf9Ww7?usp=share_link) ================================================ FILE: citation.bib ================================================ @software{spectrecode, author = "Deppe, Nils and Throwe, William and Kidder, Lawrence E. and Vu, Nils L. and Nelli, Kyle C. and Armaza, Crist\'obal and Bonilla, Marceline S. and H\'ebert, Fran\c{c}ois and Kim, Yoonsoo and Kumar, Prayush and Lovelace, Geoffrey and Macedo, Alexandra and Moxon, Jordan and O'Shea, Eamonn and Pfeiffer, Harald P. and Scheel, Mark A. and Teukolsky, Saul A. and Wittek, Nikolas A. and others", title = "\texttt{SpECTRE v2026.04.01}", version = "2026.04.01", publisher = "Zenodo", doi = "10.5281/zenodo.19373346", url = "https://spectre-code.org", howpublished = "\href{https://doi.org/10.5281/zenodo.19373346}{10.5281/zenodo.19373346}", license = "MIT", year = "2026", month = "4" } ================================================ FILE: cmake/AddCxxFlag.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Have to compile a file (can be empty) to check for flags. # Kokkos' nvcc_wrapper doesn't support taking the file as stdin, so we # have to write it to a file. set(_CHECK_CXX_FLAGS_SOURCE "${CMAKE_BINARY_DIR}/CMakeFiles/CheckCxxFlags.cpp") write_file(${_CHECK_CXX_FLAGS_SOURCE} "") # Checks if a flag is supported by the compiler and creates the target # TARGET_NAME whose INTERFACE_COMPILE_OPTIONS are set to the FLAG_TO_CHECK # - LANGUAGE: language to check, setting the compiler and generated property # - XTYPE: language as passed to the -x compiler flag # - FLAG_TO_CHECK: the CXX flag to add if the compiler supports it # - TARGET_NAME: the name of the target whose INTERFACE_COMPILE_OPTIONS are # set function(create_compile_flag_target LANGUAGE XTYPE FLAG_TO_CHECK TARGET_NAME) # In order to check for a -Wno-* flag in gcc, you have to check the # -W* version instead. See http://gcc.gnu.org/wiki/FAQ#wnowarning string(REGEX REPLACE ^-Wno- -W POSITIVE_FLAG_TO_CHECK ${FLAG_TO_CHECK}) # Escape quotes for compiler command string(REPLACE "\"" "\\\"" POSITIVE_FLAG_TO_CHECK ${POSITIVE_FLAG_TO_CHECK}) execute_process( COMMAND bash -c "LC_ALL=POSIX ${CMAKE_${LANGUAGE}_COMPILER} -Werror \ ${POSITIVE_FLAG_TO_CHECK} -x ${XTYPE} \ -c ${_CHECK_CXX_FLAGS_SOURCE} -o /dev/null" RESULT_VARIABLE RESULT ERROR_VARIABLE ERROR_FROM_COMPILATION OUTPUT_QUIET) if(NOT TARGET ${TARGET_NAME}) add_library(${TARGET_NAME} INTERFACE) endif(NOT TARGET ${TARGET_NAME}) if(${RESULT} EQUAL 0) string(REPLACE " " ";" FLAG_TO_CHECK ${FLAG_TO_CHECK}) set_property(TARGET ${TARGET_NAME} APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:${FLAG_TO_CHECK}>) endif(${RESULT} EQUAL 0) endfunction() # Checks if a CXX flag is supported by the compiler and creates the target # TARGET_NAME whose INTERFACE_COMPILE_OPTIONS are set to the FLAG_TO_CHECK # - FLAG_TO_CHECK: the CXX flag to add if the compiler supports it # - TARGET_NAME: the name of the target whose INTERFACE_COMPILE_OPTIONS are # set function(create_cxx_flag_target FLAG_TO_CHECK TARGET_NAME) create_compile_flag_target(CXX c++ "${FLAG_TO_CHECK}" "${TARGET_NAME}") endfunction() # Same, but for C. function(create_c_flag_target FLAG_TO_CHECK TARGET_NAME) create_compile_flag_target(C c "${FLAG_TO_CHECK}" "${TARGET_NAME}") endfunction() # Checks which of the CXX FLAGS_TO_CHECK are supported by the compiler # and creates the target TARGET_NAME whose INTERFACE_COMPILE_OPTIONS # are set to the FLAGS_TO_CHECK that are supported. If adding many flags, # this will be much faster than calling create_cxx_flags_target multiple times. # - LANGUAGE: language to check, setting the compiler and generated property # - XTYPE: language as passed to the -x compiler flag # - FLAGS_TO_CHECK: a semicolon separated string of CXX flags to try to add # for compilation. # - TARGET_NAME: the name of the target whose INTERFACE_COMPILE_OPTIONS are # set function(create_compile_flags_target LANGUAGE XTYPE FLAGS_TO_CHECK TARGET_NAME) # In order to check for a -Wno-* flag in gcc, you have to check the # -W* version instead. See http://gcc.gnu.org/wiki/FAQ#wnowarning set(POSITIVE_FLAGS_TO_CHECK) foreach(FLAG_TO_CHECK ${FLAGS_TO_CHECK}) string(REGEX REPLACE ^-Wno- -W POSITIVE_FLAG_TO_CHECK ${FLAG_TO_CHECK}) list(APPEND POSITIVE_FLAGS_TO_CHECK ${POSITIVE_FLAG_TO_CHECK}) endforeach() string(REPLACE ";" " " POSITIVE_FLAGS_WITH_SPACES "${POSITIVE_FLAGS_TO_CHECK}") execute_process( COMMAND bash -c "LC_ALL=POSIX ${CMAKE_${LANGUAGE}_COMPILER} -Werror \ ${POSITIVE_FLAGS_WITH_SPACES} -x ${XTYPE} \ -c ${_CHECK_CXX_FLAGS_SOURCE} -o /dev/null" RESULT_VARIABLE RESULT ERROR_VARIABLE ERROR_FROM_COMPILATION OUTPUT_QUIET) if(NOT TARGET ${TARGET_NAME}) add_library(${TARGET_NAME} INTERFACE) endif(NOT TARGET ${TARGET_NAME}) if(${RESULT} EQUAL 0) set_property(TARGET ${TARGET_NAME} APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:${FLAGS_TO_CHECK}>) else(${RESULT} EQUAL 0) # Check each flag to see if it was marked as "invalid" in the output unset(FLAGS_TO_ADD) foreach(FLAG ${POSITIVE_FLAGS_TO_CHECK}) string(FIND "${ERROR_FROM_COMPILATION}" "'${FLAG}'" FOUND_POS) if(${FOUND_POS} EQUAL -1) # For some reason: # list(FIND ${POSITIVE_FLAGS_TO_CHECK} ${FLAG} INDEX_OF_FLAG) # doesn't work with some compilers. This makes no sense but such is # life. As a work around we basically implement a find manually. # Find the index of the current flag in the POSITIVE_FLAGS_TO_CHECK # list. This is the index we use to get the original flag in the # FLAGS_TO_CHECK list. set(INDEX 0) foreach(POS_FLAG ${POSITIVE_FLAGS_TO_CHECK}) if("${POS_FLAG}" STREQUAL "${FLAG}") break() endif() MATH(EXPR INDEX "${INDEX}+1") endforeach() set(TARGET_INDEX ${INDEX}) set(INDEX 0) # Get original flag set(NEW_FLAG "") foreach(ORIGINAL_FLAG ${FLAGS_TO_CHECK}) if(${INDEX} EQUAL ${TARGET_INDEX}) set(NEW_FLAG ${ORIGINAL_FLAG}) break() endif() MATH(EXPR INDEX "${INDEX}+1") endforeach() # Add the flag to the list of flags to add. set(FLAGS_TO_ADD "${FLAGS_TO_ADD};${NEW_FLAG}") endif(${FOUND_POS} EQUAL -1) endforeach(FLAG ${FLAGS_TO_CHECK}) set_property(TARGET ${TARGET_NAME} APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:${FLAGS_TO_ADD}>) endif(${RESULT} EQUAL 0) endfunction() # Checks which of the CXX FLAGS_TO_CHECK are supported by the compiler # and creates the target TARGET_NAME whose INTERFACE_COMPILE_OPTIONS # are set to the FLAGS_TO_CHECK that are supported. If adding many flags, # this will be much faster than calling create_cxx_flags_target multiple times. # - FLAGS_TO_CHECK: a semicolon separated string of CXX flags to try to add # for compilation. # - TARGET_NAME: the name of the target whose INTERFACE_COMPILE_OPTIONS are # set function(create_cxx_flags_target FLAGS_TO_CHECK TARGET_NAME) create_compile_flags_target(CXX c++ "${FLAGS_TO_CHECK}" "${TARGET_NAME}") endfunction() # Same, but for C. function(create_c_flags_target FLAGS_TO_CHECK TARGET_NAME) create_compile_flags_target(C c "${FLAGS_TO_CHECK}" "${TARGET_NAME}") endfunction() set(CMAKE_SUPPORTS_LINK_OPTIONS OFF) if(CMAKE_VERSION VERSION_EQUAL 3.13 OR CMAKE_VERSION VERSION_GREATER 3.13) set(CMAKE_SUPPORTS_LINK_OPTIONS ON) endif(CMAKE_VERSION VERSION_EQUAL 3.13 OR CMAKE_VERSION VERSION_GREATER 3.13) if(CMAKE_SUPPORTS_LINK_OPTIONS) # Creates a target named TARGET_NAME that, if the linker flag FLAG_TO_CHECK # is supported, defines ${FLAG_TO_CHECK} as an INTERFACE_LINK_OPTION function(create_cxx_link_flag_target FLAG_TO_CHECK TARGET_NAME) include(CheckLinkerFlag) unset(CXX_LINKER_FLAG_WORKS CACHE) set(CMAKE_REQUIRED_QUIET 1) check_linker_flag(CXX ${FLAG_TO_CHECK} CXX_LINKER_FLAG_WORKS) unset(CMAKE_REQUIRED_QUIET) add_library(${TARGET_NAME} INTERFACE) if(CXX_LINKER_FLAG_WORKS) set_property(TARGET ${TARGET_NAME} APPEND PROPERTY INTERFACE_LINK_OPTIONS $<$:${FLAG_TO_CHECK}>) endif() endfunction() endif(CMAKE_SUPPORTS_LINK_OPTIONS) # Checks if a flag is supported by the linker and adds it if it is function(check_and_add_cxx_link_flag FLAG_TO_CHECK) include(CheckLinkerFlag) unset(CXX_LINKER_FLAG_WORKS CACHE) set(CMAKE_REQUIRED_QUIET 1) check_linker_flag(CXX ${FLAG_TO_CHECK} CXX_LINKER_FLAG_WORKS) unset(CMAKE_REQUIRED_QUIET) if(CXX_LINKER_FLAG_WORKS) set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} ${FLAG_TO_CHECK}" PARENT_SCOPE) endif() endfunction() ================================================ FILE: cmake/AddInputFileTests.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. spectre_define_test_timeout_factor_option(INPUT_FILE "input file") option(SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY "Minimum priority of input file \ tests to run. Possible values are: low (not usually run on CI), normal \ (run at least once on CI), high (run always on CI)." "normal") # Convert priority string to a number. if (NOT SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY) set(SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY "normal") endif() string(TOLOWER "${SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY}" SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY) if (${SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY} STREQUAL "high") set(SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY 1) elseif (${SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY} STREQUAL "normal") set(SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY 0) elseif (${SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY} STREQUAL "low") set(SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY -1) else() message(FATAL_ERROR "Unknown priority in option " "SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY: " "${SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY}. " "Possible values are: high, normal, low") endif() # Environment variables for test set(_INPUT_FILE_TEST_ENV_VARS "") # - Disable ASAN's leak sanitizer because Charm++ has false positives list(APPEND _INPUT_FILE_TEST_ENV_VARS "ASAN_OPTIONS=detect_leaks=0") # - Set PYTHONPATH to find Python modules list(APPEND _INPUT_FILE_TEST_ENV_VARS "PYTHONPATH=${PYTHONPATH}") function(add_single_input_file_test) cmake_parse_arguments( ARG "" "INPUT_FILE;EXECUTABLE;CHECK_TYPE;TIMEOUT" "COMMAND_LINE_ARGS;EXPECTED_EXIT_CODE;COPY_FILES" ${ARGN}) # Extract just the name of the input file get_filename_component(INPUT_FILE_NAME "${INPUT_FILE}" NAME) get_filename_component(INPUT_FILE_DIR "${INPUT_FILE}" DIRECTORY) # Extract the main subdirectory name string(FIND "${ARG_INPUT_FILE}" "tests/InputFiles/" POSITION_OF_INPUT_FILE_DIR) math(EXPR POSITION_OF_INPUT_FILE_DIR ${POSITION_OF_INPUT_FILE_DIR}+17 # 17 is the length of "tests/InputFiles/" ) string(SUBSTRING "${ARG_INPUT_FILE}" ${POSITION_OF_INPUT_FILE_DIR} -1 TEMP) string(FIND "${TEMP}" "/" POSITION_OF_SLASH) string(SUBSTRING "${TEMP}" 0 ${POSITION_OF_SLASH} EXECUTABLE_DIR_NAME) # Set tags for the test set(TAGS "InputFiles;${EXECUTABLE_DIR_NAME};${ARG_CHECK_TYPE}") string(TOLOWER "${TAGS}" TAGS) # Add the executable name as label, without converting to lower case. This # allows running all input file tests for a particular executable. list(APPEND TAGS ${ARG_EXECUTABLE}) set( CTEST_NAME "InputFiles.${EXECUTABLE_DIR_NAME}.${INPUT_FILE_NAME}.${ARG_CHECK_TYPE}" ) set( RUN_DIRECTORY "${EXECUTABLE_DIR_NAME}.${INPUT_FILE_NAME}.${ARG_CHECK_TYPE}" ) if("${ARG_CHECK_TYPE}" STREQUAL "execute_check_output") set(_CHECK_OUTPUT_FILES "true") else() set(_CHECK_OUTPUT_FILES "false") endif() if ("${ARG_CHECK_TYPE}" STREQUAL "parse") add_test( NAME ${CTEST_NAME} # This script is written below, and only once COMMAND sh ${PROJECT_BINARY_DIR}/tmp/RunInputFileTest.sh ${ARG_EXECUTABLE} ${ARG_INPUT_FILE} ${RUN_DIRECTORY} 0 false false "${ARG_COMMAND_LINE_ARGS} --check-options" "${ARG_COPY_FILES}" ) elseif("${ARG_CHECK_TYPE}" STREQUAL "execute" OR "${ARG_CHECK_TYPE}" STREQUAL "execute_check_output") add_test( NAME ${CTEST_NAME} # This script is written below, and only once COMMAND sh ${PROJECT_BINARY_DIR}/tmp/RunInputFileTest.sh ${ARG_EXECUTABLE} ${ARG_INPUT_FILE} ${RUN_DIRECTORY} ${ARG_EXPECTED_EXIT_CODE} ${_CHECK_OUTPUT_FILES} true "${ARG_COMMAND_LINE_ARGS}" "${ARG_COPY_FILES}" ) else() message(FATAL_ERROR "Unknown check for input file: ${ARG_CHECK_TYPE}." "Known checks are: execute") endif() # Increase timeout if address sanitizer is enabled. if (ASAN) math(EXPR TIMEOUT "4 * ${ARG_TIMEOUT}") else() set(TIMEOUT ${ARG_TIMEOUT}) endif() spectre_test_timeout(TIMEOUT ARG_INPUT_FILE ${TIMEOUT}) set_tests_properties( ${CTEST_NAME} PROPERTIES TIMEOUT ${TIMEOUT} LABELS "${TAGS}" ENVIRONMENT "${_INPUT_FILE_TEST_ENV_VARS}") endfunction() # Searches the directory INPUT_FILE_DIR for .yaml files and adds a test for each # one. See `WritingTests.md` for details on controlling input file tests. Add # input files to the whitelist at the bottom of this file to ignore those tests function(add_input_file_tests INPUT_FILE_DIR INPUT_FILE_WHITELIST) set(INPUT_FILE_LIST "") file(GLOB_RECURSE INPUT_FILE_LIST ${INPUT_FILE_DIR} "${INPUT_FILE_DIR}*.yaml") set(TIMEOUT 2) list(TRANSFORM INPUT_FILE_WHITELIST PREPEND ${INPUT_FILE_DIR}) foreach(INPUT_FILE ${INPUT_FILE_LIST}) # Only parse the input file if we are allowed to if (${INPUT_FILE} IN_LIST INPUT_FILE_WHITELIST) continue() endif() if (INPUT_FILE MATCHES "\\.overlay_[0-9]*\\.yaml$") continue() endif() file(READ ${INPUT_FILE} INPUT_FILE_CONTENTS) # Read the priority of the test specified in input file, empty is accepted. string(REGEX MATCH "Priority:[^\n]+" INPUT_FILE_PRIORITY "${INPUT_FILE_CONTENTS}") if("${INPUT_FILE_PRIORITY}" STREQUAL "") set(INPUT_FILE_PRIORITY "normal") else() string(REGEX REPLACE "Priority:[ ]*" "" INPUT_FILE_PRIORITY "${INPUT_FILE_PRIORITY}") string(STRIP "${INPUT_FILE_PRIORITY}" INPUT_FILE_PRIORITY) endif() # Translate strings to numbers string(TOLOWER "${INPUT_FILE_PRIORITY}" INPUT_FILE_PRIORITY) if (${INPUT_FILE_PRIORITY} STREQUAL "high") set(INPUT_FILE_PRIORITY 1) elseif (${INPUT_FILE_PRIORITY} STREQUAL "normal") set(INPUT_FILE_PRIORITY 0) elseif (${INPUT_FILE_PRIORITY} STREQUAL "low") set(INPUT_FILE_PRIORITY -1) else() message(FATAL_ERROR "Unknown priority in input file ${INPUT_FILE}: " "${INPUT_FILE_PRIORITY}. Possible values are: high, normal, low") endif() # Only add tests with at least the priority specified in # `SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY` if (${INPUT_FILE_PRIORITY} LESS ${SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY}) continue() endif() # Check if the executable name is present string(REGEX MATCH "Executable:[^\n]+" INPUT_FILE_EXECUTABLE "${INPUT_FILE_CONTENTS}") if("${INPUT_FILE_EXECUTABLE}" STREQUAL "") message(FATAL_ERROR "Could not find the executable in input " "file ${INPUT_FILE}. You must supply a line of the form:" "'Executable: EXECUTABLE_NAME'") endif() # Extract executable name, and remove trailing white space string(REGEX REPLACE "Executable:[ ]*" "" INPUT_FILE_EXECUTABLE "${INPUT_FILE_EXECUTABLE}") string(STRIP "${INPUT_FILE_EXECUTABLE}" INPUT_FILE_EXECUTABLE) string(REGEX MATCH "CommandLineArgs:[^\n]+" COMMAND_LINE_ARGS "${INPUT_FILE_CONTENTS}") string(REGEX REPLACE "CommandLineArgs:[ ]*" "" COMMAND_LINE_ARGS "${COMMAND_LINE_ARGS}") string(STRIP "${COMMAND_LINE_ARGS}" COMMAND_LINE_ARGS) string(REGEX MATCH "ExpectedExitCode:[^\n]+" EXPECTED_EXIT_CODE "${INPUT_FILE_CONTENTS}") string(REGEX REPLACE "ExpectedExitCode:[ ]*" "" EXPECTED_EXIT_CODE "${EXPECTED_EXIT_CODE}") string(STRIP "${EXPECTED_EXIT_CODE}" EXPECTED_EXIT_CODE) if("${EXPECTED_EXIT_CODE}" STREQUAL "") set(EXPECTED_EXIT_CODE "0") endif() # Read what tests to do. Currently "execute" and "parse" are available. string(REGEX MATCH "Check:[^\n]+" INPUT_FILE_CHECKS "${INPUT_FILE_CONTENTS}") # Extract list of checks to perform string(REGEX REPLACE "Check:[ ]*" "" INPUT_FILE_CHECKS "${INPUT_FILE_CHECKS}") string(STRIP "${INPUT_FILE_CHECKS}" INPUT_FILE_CHECKS) set(INPUT_FILE_CHECKS "${INPUT_FILE_CHECKS}") list(REMOVE_DUPLICATES "INPUT_FILE_CHECKS") # Convert all the checks to lower case to make life easier. string(TOLOWER "${INPUT_FILE_CHECKS}" INPUT_FILE_CHECKS) # Make sure that the 'parse' check is listed. If not, print an # error message that explains that it's needed and why. list(FIND "INPUT_FILE_CHECKS" "parse" FOUND_PARSE) if (${FOUND_PARSE} EQUAL -1) message(FATAL_ERROR "The input file: " "'${INPUT_FILE}' " "does not specify the 'parse' check. All input file tests must" " specify the 'parse' check which runs the executable passing" " the '--check-options' flag. With this flag the executable" " should check that the input file parses correctly and that" " the values specified in the input file do not violate any" " bounds or sanity checks.") endif (${FOUND_PARSE} EQUAL -1) # Read the timeout duration specified in input file, empty is accepted. # The default duration is 2 seconds. string(REGEX MATCH "Timeout:[^\n]+" INPUT_FILE_TIMEOUT "${INPUT_FILE_CONTENTS}") if("${INPUT_FILE_TIMEOUT}" STREQUAL "") set(INPUT_FILE_TIMEOUT "${TIMEOUT}") else() string(REGEX REPLACE "Timeout:[ ]*" "" INPUT_FILE_TIMEOUT "${INPUT_FILE_TIMEOUT}") string(STRIP "${INPUT_FILE_TIMEOUT}" INPUT_FILE_TIMEOUT) endif() # Read out the semicolon list of files to copy to the run directory. # The files are currently restricted to being in the same location # as the input file. This can be relaxed if necessary. set(COPY_FILES "") string(REGEX MATCH "CopyFiles:[^\n]+" COPY_FILES "${INPUT_FILE_CONTENTS}") if(NOT "${COPY_FILES}" STREQUAL "") string(REPLACE "CopyFiles: " "" COPY_FILES ${COPY_FILES}) string(REPLACE "CopyFiles:" "" COPY_FILES ${COPY_FILES}) endif() foreach(CHECK_TYPE ${INPUT_FILE_CHECKS}) add_single_input_file_test( INPUT_FILE ${INPUT_FILE} EXECUTABLE ${INPUT_FILE_EXECUTABLE} COMMAND_LINE_ARGS "${COMMAND_LINE_ARGS}" CHECK_TYPE ${CHECK_TYPE} TIMEOUT ${INPUT_FILE_TIMEOUT} EXPECTED_EXIT_CODE ${EXPECTED_EXIT_CODE} COPY_FILES "${COPY_FILES}" ) endforeach() add_dependencies(test-executables ${INPUT_FILE_EXECUTABLE}) endforeach() endfunction() # Dependencies will be added as the tests are processed. add_custom_target(test-executables) # Write command to execute an input file and clean its output into a shell # script, which makes it easier to chain multiple commands configure_file( ${CMAKE_SOURCE_DIR}/cmake/RunInputFileTest.sh ${PROJECT_BINARY_DIR}/tmp/RunInputFileTest.sh @ONLY) # These paths should be relative to the input file directory passed to # `add_input_file_tests` set(INPUT_FILE_WHITELIST "PreprocessCceWorldtube/PreprocessCceWorldtube.yaml" "PreprocessCceWorldtube/AdmFirstOrderDriverPreprocessCceWorldtube.yaml" "PreprocessCceWorldtube/AdmSecondOrderDriverPreprocessCceWorldtube.yaml") add_input_file_tests("${CMAKE_SOURCE_DIR}/tests/InputFiles/" "${INPUT_FILE_WHITELIST}") ================================================ FILE: cmake/AddSpectreExecutable.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Adds an executable by wrapping CMake's 'add_executable' but allows # us to inject dependencies, flags, etc. into the targets. function(add_spectre_executable TARGET_NAME) add_executable(${TARGET_NAME} ${ARGN}) # We need to link custom allocators before we link anything else so that # any third-party libraries, which generally should all be built as shared # libraries, use the allocator that we use. Unfortunately, how exactly # CMake decides on the linking order is not clear when using # INTERFACE_LINK_LIBRARIES and targets. To this end, we set a global # property SPECTRE_ALLOCATOR_LIBRARY that contains the link flag to link # to the memory allocator. By linking to the allocator library first # explicitly in target_link_libraries CMake correctly places the allocator # library as the first entry in the link libraries. We also link to the # SpectreAllocator target to pull in any additional allocator-related # flags, such as include directories. get_property( SPECTRE_ALLOCATOR_LIBRARY GLOBAL PROPERTY SPECTRE_ALLOCATOR_LIBRARY ) target_link_libraries( ${TARGET_NAME} PUBLIC ${SPECTRE_ALLOCATOR_LIBRARY} SpectreAllocator ) set(SPECTRE_KOKKOS_LAUNCHER "") if(SPECTRE_KOKKOS) # We need to make sure we don't drop the Kokkos link wrapper get_target_property( _RULE_LAUNCH_LINK ${TARGET_NAME} RULE_LAUNCH_LINK) if (_RULE_LAUNCH_LINK) set(SPECTRE_KOKKOS_LAUNCHER ${_RULE_LAUNCH_LINK}) endif() endif() set_target_properties( ${TARGET_NAME} PROPERTIES RULE_LAUNCH_LINK "${CMAKE_BINARY_DIR}/tmp/WrapExecutableLinker.sh ${SPECTRE_KOKKOS_LAUNCHER}" LINK_DEPENDS "${CMAKE_BINARY_DIR}/tmp/WrapExecutableLinker.sh" # Expose readable symbol names in backtrace (adds flags like -rdynamic) ENABLE_EXPORTS ON ) target_link_options(${TARGET_NAME} PRIVATE "-DEXECUTABLE_NAME=${TARGET_NAME}") # The `WrapExecutableLinker.sh` script needs the `InfoAtLink_flags.txt` file # generated by the `InfoAtLink` target add_dependencies( ${TARGET_NAME} InfoAtLink ) target_link_libraries( ${TARGET_NAME} PRIVATE CharmModuleInit SpectreFlags ) install(TARGETS ${TARGET_NAME} OPTIONAL RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endfunction() ================================================ FILE: cmake/AddStandaloneTests.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. spectre_define_test_timeout_factor_option(STANDALONE "standalone") # Helper function to set up a CMake target for a test executable. It # can safely be called multiple times for the same executable. function(add_standalone_test_executable EXECUTABLE_NAME) add_dependencies(test-executables ${EXECUTABLE_NAME}) if (TARGET ${EXECUTABLE_NAME}) return() endif() add_spectre_executable( ${EXECUTABLE_NAME} ${EXECUTABLE_NAME}.cpp ) target_link_libraries( ${EXECUTABLE_NAME} PRIVATE Catch2::Catch2 ) add_dependencies( ${EXECUTABLE_NAME} module_GlobalCache module_Main ) endfunction() # Helper function to set standard test properties for standalone tests. function(set_standalone_test_properties TEST_NAME) spectre_test_timeout(TIMEOUT STANDALONE 10) set_tests_properties( "${TEST_NAME}" PROPERTIES TIMEOUT "${TIMEOUT}" LABELS "standalone" ENVIRONMENT "ASAN_OPTIONS=detect_leaks=0") endfunction() # For tests that result in a failure it is necessary to redirect # output from stderr to stdout. However, it was necessary at least on # some systems to do this redirect inside a shell command. find_program(SHELL_EXECUTABLE "sh") if (NOT SHELL_EXECUTABLE) message(FATAL_ERROR "Could not find 'sh' shell to execute standalone failure tests") endif() # Add a standalone test named TEST_NAME that runs an executable with # no arguments. A test named Foo.Bar.Baz will run the executable # Test_Baz by default. # # A REGEX_TO_MATCH named argument may be passed, in which case the # test will pass if the output matches it, otherwise the test will # pass if the executable succeeds without any "ERROR" output. # # An EXECUTABLE named argument can be passed to override the # executable name. # # An INPUT_FILE named argument can be passed to pass an input file to # the executable. function(add_standalone_test TEST_NAME) cmake_parse_arguments( ARG "" "REGEX_TO_MATCH;EXECUTABLE;INPUT_FILE" "" ${ARGN}) if(DEFINED ARG_EXECUTABLE) set(EXECUTABLE_NAME "${ARG_EXECUTABLE}") else() # Extract last component of test name as executable name string(REGEX MATCH "[^.]*$" EXECUTABLE_NAME "${TEST_NAME}") set(EXECUTABLE_NAME "Test_${EXECUTABLE_NAME}") endif() add_standalone_test_executable("${EXECUTABLE_NAME}") if(DEFINED ARG_INPUT_FILE) set(INPUT_FILE_ARGS "--input-file ${CMAKE_CURRENT_SOURCE_DIR}/${ARG_INPUT_FILE}") else() set(INPUT_FILE_ARGS "") endif() add_test( NAME "${TEST_NAME}" COMMAND ${SHELL_EXECUTABLE} -c "${SPECTRE_TEST_RUNNER} ${CMAKE_BINARY_DIR}/bin/${EXECUTABLE_NAME} ${INPUT_FILE_ARGS} 2>&1" ) set_standalone_test_properties("${TEST_NAME}") if(NOT DEFINED ARG_REGEX_TO_MATCH) set_tests_properties( "${TEST_NAME}" PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR") else() set_tests_properties( "${TEST_NAME}" PROPERTIES PASS_REGULAR_EXPRESSION "${ARG_REGEX_TO_MATCH}") endif() endfunction() ================================================ FILE: cmake/BootstrapPyDeps.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(BOOTSTRAP_PY_DEPS "Install missing Python dependencies in the build directory" ${SPECTRE_FETCH_MISSING_DEPS}) option(BOOTSTRAP_PY_DEV_DEPS "Install missing Python dev dependencies in the build directory" ${SPECTRE_FETCH_MISSING_DEPS}) if (NOT (BOOTSTRAP_PY_DEPS OR BOOTSTRAP_PY_DEV_DEPS)) return() endif() message(STATUS "Bootstrapping missing Python dependencies to: \ ${SPECTRE_PYTHON_SITE_PACKAGES}") # Install the packages with pip set(_BOOTSTRAP_PY_DEPS_FLAG "") if (BOOTSTRAP_PY_DEPS) set(_BOOTSTRAP_PY_DEPS_FLAG -r ${CMAKE_SOURCE_DIR}/support/Python/requirements.txt) endif() set(_BOOTSTRAP_PY_DEV_DEPS_FLAG "") if (BOOTSTRAP_PY_DEV_DEPS) set(_BOOTSTRAP_PY_DEV_DEPS_FLAG -r ${CMAKE_SOURCE_DIR}/support/Python/dev_requirements.txt) endif() set(_BOOTSTRAP_PY_DEPS_LOG_FILE "${CMAKE_BINARY_DIR}/BootstrapPyDeps.log") execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${PYTHONPATH} ${Python_EXECUTABLE} -m pip install --disable-pip-version-check --prefix ${CMAKE_BINARY_DIR} --no-warn-script-location ${_BOOTSTRAP_PY_DEPS_FLAG} ${_BOOTSTRAP_PY_DEV_DEPS_FLAG} RESULT_VARIABLE _BOOTSTRAP_PY_DEPS_RESULT OUTPUT_FILE ${_BOOTSTRAP_PY_DEPS_LOG_FILE} ERROR_FILE ${_BOOTSTRAP_PY_DEPS_LOG_FILE} ) if (NOT _BOOTSTRAP_PY_DEPS_RESULT EQUAL 0) message(WARNING "Bootstrapping of Python dependencies failed." "See log file: ${_BOOTSTRAP_PY_DEPS_LOG_FILE}") endif() ================================================ FILE: cmake/CheckBrokenArray0.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Check whether the standard library is affected by # https://bugs.llvm.org/show_bug.cgi?id=35491 # This LLVM bug is fixed by commit 59cdf90ac8bea16abbb9d637c5124e69d2c75c09, # which is included in the LLVM 7 release. message(STATUS "Checking for broken std::array<..., 0>") try_compile( ARRAY0_WORKS ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/cmake/CheckBrokenArray0.cpp CMAKE_FLAGS -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED} -DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS} OUTPUT_VARIABLE TRY_COMPILE_OUTPUT ) if (ARRAY0_WORKS) message(STATUS "Checking for broken std::array<..., 0> -- works") else (ARRAY0_WORKS) message(STATUS "Checking for broken std::array<..., 0> -- broken") add_definitions(-DHAVE_BROKEN_ARRAY0) message(STATUS "Output when trying to compile broken array test:\n${TRY_COMPILE_OUTPUT}") endif (ARRAY0_WORKS) ================================================ FILE: cmake/CheckBrokenArray0.cpp ================================================ // Distributed under the MIT License. // Copyright (c) 2009-2017 by the contributors to libc++, listed at // https://llvm.org/svn/llvm-project/libcxx/trunk/CREDITS.TXT // This is a portion of // https://llvm.org/svn/llvm-project/libcxx/trunk/test/std/containers/sequences/array/begin.pass.cpp #include #include int main() { struct NoDefault { NoDefault(int) {} }; typedef NoDefault T; typedef std::array C; C c = {}; assert(c.begin() == c.end()); } ================================================ FILE: cmake/CheckCompilerVersion.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1) message(FATAL_ERROR "GCC version must be at least 9.1") endif () elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.0) message(FATAL_ERROR "Clang version must be at least 13.0") endif () elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") message(FATAL_ERROR "Intel compiler is not supported.") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.0.0) message(FATAL_ERROR "AppleClang version must be at least 13.0.0") endif () else () message( WARNING "The compiler ${CMAKE_CXX_COMPILER_ID} is unsupported! " "Compilation has only been tested with Clang and GCC." ) endif () ================================================ FILE: cmake/CodeCoverage.cmake ================================================ ################################################################################ # # \file cmake/CodeCoverage.cmake # \author J. Bakosi # \copyright 2012-2015, Jozsef Bakosi, 2016, Los Alamos National Security, LLC. # \brief Setup target for code coverage analysis # \date Wed 22 Feb 2017 07:39:09 AM MST # # Modifications: # 1) Change "Quinoa" to "SpECTRE" and "quinoa" to "spectre" # 2) Split lines to make commands more legible # 3) Silence CMake warnings on uninitialized variables in # `cmake_parse_arguments` ################################################################################ # ############################################################################## # Function to add code coverage target # # setup_target_for_coverage( # [TESTRUNNER_ARGS ...] # [DEPENDS dep1 dep2 ... ] ) # # Mandatory arguments: # -------------------- # # TEST_SUITE - Test TEST_SUITE name to be displayed in HTML report title. # # OUTPUT_PATH - Path to prepend to where the report is generated: # ${TARGET_NAME}/index.html. # # TARGET_NAME - The name of the code coverage target. The HTML report on code # coverage is generated at the OUTPUT_PATH /${TARGET_NAME}/index.html. # # TEST_RUNNER - Command line of the test runner. # # Optional arguments: # ------------------- # # TESTRUNNER_ARGS arg1 arg2 ... - Optional arguments to test runner. Pass them # in list form, e.g.: "-v;-g;group" for passing '-v -g group'. Default: "". # # DEPENDS dep1 dep2 ... - Optional dependencies added to test coverage target. # Default: "". Here all dependencies should be given that should be covered by # the test suite the coverage is being setup for, as well as those that are # required for successfully building the tests and the test runner. # # Author: J. Bakosi # # ############################################################################## function(SETUP_TARGET_FOR_COVERAGE TEST_SUITE OUTPUT_PATH TARGET_NAME TEST_RUNNER) if (NOT IS_ABSOLUTE ${OUTPUT_PATH}) set(OUTPUT_PATH ${CMAKE_BINARY_DIR}/${OUTPUT_PATH}) endif() if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git) message(FATAL_ERROR, "Not running in a git repo so we can't do " "code coverage") endif() set(multiValueArgs TESTRUNNER_ARGS DEPENDS IGNORE_COV) cmake_parse_arguments( ARG "" "" "${multiValueArgs}" ${ARGN}) if(NOT LCOV) MESSAGE(FATAL_ERROR "lcov not found! Aborting...") endif() if(NOT GENHTML) MESSAGE(FATAL_ERROR "genhtml not found! Aborting...") endif() if(NOT SED) MESSAGE(FATAL_ERROR "sed not found! Aborting...") endif() if(NOT GIT_HASH) message(FATAL_ERROR "Git hash not found! Aborting...") endif() # Set shortcut for output: OUTPUT_PATH/target set(OUTPUT ${OUTPUT_PATH}/${TARGET_NAME}) file(MAKE_DIRECTORY ${OUTPUT_PATH}) # Setup code coverage target add_custom_target( ${TARGET_NAME} # Cleanup any old intermediate data COMMAND ${CMAKE_COMMAND} -E remove ${OUTPUT}.base.info ${OUTPUT}.test.info ${OUTPUT}.total.info ${OUTPUT}.filtered.info # Cleanup lcov COMMAND ${LCOV} --gcov-tool ${GCOV} --directory . --zerocounters # Capture initial state yielding zero coverage baseline COMMAND ${LCOV} --gcov-tool ${GCOV} --capture --initial --directory . --output-file ${OUTPUT}.base.info # Run test TEST_SUITE COMMAND ${TEST_RUNNER} ${ARG_TESTRUNNER_ARGS} # Capture lcov counters COMMAND ${LCOV} --gcov-tool ${GCOV} --capture --rc lcov_branch_coverage=0 --directory . --output-file ${OUTPUT}.test.info # Combine trace files COMMAND ${LCOV} --gcov-tool ${GCOV} --rc lcov_branch_coverage=0 --add-tracefile ${OUTPUT}.base.info --add-tracefile ${OUTPUT}.test.info --output-file ${OUTPUT}.total.info # Filter out unwanted files COMMAND ${LCOV} --gcov-tool ${GCOV} --rc lcov_branch_coverage=0 --remove ${OUTPUT}.total.info '*/c++/*' '*/include/*' '*/boost/*' '*/charm/*' '*.decl.h' '*.def.h' '*/STDIN' '*/tut/*' '*/moduleinit*' '*InfoFromBuild.cpp' '${CMAKE_SOURCE_DIR}/src/Executables/*' ${ARG_IGNORE_COV} --output-file ${OUTPUT}.filtered.info # Generate HTML report COMMAND ${GENHTML} --legend --demangle-cpp --title ${GIT_HASH} -o ${OUTPUT} ${OUTPUT}.filtered.info # Customize page headers in generated html to own COMMAND find ${OUTPUT} -type f -print | xargs file | grep text | cut -f1 -d: | xargs ${SED} -i'.bak' 's/LCOV - code coverage report/SpECTRE ${TEST_SUITE} Test Code Coverage Report/g' COMMAND find ${OUTPUT} -type f -name \"*.bak\" -print | xargs file | grep text | cut -f1 -d: | xargs rm COMMAND find ${OUTPUT} -type f -print | xargs file | grep text | cut -f1 -d: | xargs ${SED} -i'.bak' 's^Test:^Commit:^g' COMMAND find ${OUTPUT} -type f -name \"*.bak\" -print | xargs file | grep text | cut -f1 -d: | xargs rm COMMAND find ${OUTPUT} -type f -print | xargs file | grep text | cut -f1 -d: | xargs ${SED} -i'.bak' 's^\\\([a-z0-9]\\{40\\}\\\)^ \\1^g' # Delete backup files created by sed COMMAND find ${OUTPUT} -type f -name \"*.bak\" -print | xargs file | grep text | cut -f1 -d: | xargs rm # Cleanup any intermediate data COMMAND ${CMAKE_COMMAND} -E remove ${OUTPUT}.base.info ${OUTPUT}.test.info ${OUTPUT}.total.info # Copy output into coverage.info to be used by codecov COMMAND mv ${OUTPUT}.filtered.info ${CMAKE_BINARY_DIR}/tmp/coverage.info # Set work directory for target WORKING_DIRECTORY ${CMAKE_BINARY_DIR} # Echo what is being done COMMENT "SpECTRE ${TEST_SUITE} Test Code Coverage Report" ) # Make test coverage target dependent on optional dependencies passed in using # keyword DEPENDS add_dependencies(${TARGET_NAME} ${ARG_DEPENDS}) # Output code coverage target enabled string(REPLACE ";" " " ARGUMENTS "${ARG_TESTRUNNER_ARGS}") message( STATUS "Enabling code coverage target '${TARGET_NAME}' tested by " "'${TEST_RUNNER} ${ARGUMENTS}', dependencies {${ARG_DEPENDS}}, " "report at ${OUTPUT}/index.html" ) endfunction() ================================================ FILE: cmake/CodeCoverageDetection.cmake ================================================ ################################################################################ # # \file cmake/CodeCoverageDetection.cmake # \author J. Bakosi # \copyright 2012-2015, Jozsef Bakosi, 2016, Los Alamos National Security, LLC. # \brief Detect prerequesites for code coverage analysis # \date Fri 03 Mar 2017 11:50:24 AM MST # # Modifications for SpECTRE: # 1) Auto find either llvm-cov or llvm-cov-${LLVM_VERSION} instead of using # a shell script that hard codes the LLVM version # 2) Formatting changes ################################################################################ # Attempt to find tools required for code coverage analysis if(NOT LLVM_COV_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(LLVM_COV_ROOT "") set(LLVM_COV_ROOT $ENV{LLVM_COV_ROOT}) endif() option(COVERAGE "Enable code coverage analysis." OFF) # Code coverage analysis only supported if all prerequisites found and the user # has requested it via the cmake variable COVERAGE=on.. if(COVERAGE) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) string( REGEX MATCH "^[0-9]+.[0-9]+" LLVM_VERSION "${CMAKE_CXX_COMPILER_VERSION}" ) find_program( LLVM_COV_BIN NAMES "llvm-cov-${LLVM_VERSION}" "llvm-cov" HINTS ${LLVM_COV_ROOT} ) configure_file( "${CMAKE_SOURCE_DIR}/tools/llvm-gcov.sh" "${CMAKE_BINARY_DIR}/llvm-gcov.sh" ) set(GCOV "${CMAKE_BINARY_DIR}/llvm-gcov.sh") elseif( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" ) find_program(GCOV gcov REQUIRED) endif() find_program(LCOV lcov REQUIRED) find_program(GENHTML genhtml REQUIRED) find_program(SED sed REQUIRED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") # Enable code coverage analysis. SET(CODE_COVERAGE ON) # Make flag enabling code coverage analysis available in parent cmake scope mark_as_advanced(CODE_COVERAGE) # Only include code coverage cmake functions if all prerequisites are met include(CodeCoverage) elseif(COVERAGE) message(FATAL_ERROR "Failed to enable code coverage analysis. Not all " "prerequisites found: gcov:${GCOV}, lcov:${LCOV}, genhtml:${GENHTML}," " sed:${SED}") endif() ================================================ FILE: cmake/EnableWarnings.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. include(AddCxxFlag) # On systems where we can't use -isystem (Cray), we don't want # all the warnings enabled because we get flooded with system warnings. option(ENABLE_WARNINGS "Enable the default warning level" ON) if(${ENABLE_WARNINGS}) create_cxx_flags_target( "-W;\ -Wall;\ -Wcast-align;\ -Wcast-qual;\ -Wdisabled-optimization;\ -Wdocumentation;\ -Wextra;\ -Wformat-nonliteral;\ -Wformat-security;\ -Wformat-y2k;\ -Wformat=2;\ -Winvalid-pch;\ -Wmissing-declarations;\ -Wmissing-field-initializers;\ -Wmissing-format-attribute;\ -Wmissing-include-dirs;\ -Wmissing-noreturn;\ -Wnewline-eof;\ -Wnon-virtual-dtor;\ -Wold-style-cast;\ -Woverloaded-virtual;\ -Wpacked;\ -Wpedantic;\ -Wpointer-arith;\ -Wredundant-decls;\ -Wshadow;\ -Wsign-conversion;\ -Wstack-protector;\ -Wswitch-default;\ -Wunreachable-code;\ -Wwrite-strings" SpectreWarnings) else() add_library(SpectreWarnings INTERFACE) endif() # Disable some warnings create_cxx_flags_target( "-Wno-dangling-reference;\ -Wno-documentation-unknown-command;\ -Wno-mismatched-tags;\ -Wno-interference-size;\ -Wno-non-template-friend;\ -Wno-type-limits;\ -Wno-undefined-var-template;\ -Wno-gnu-zero-variadic-macro-arguments;\ -Wno-noexcept-type" SpectreDisableSomeWarnings) target_link_libraries( SpectreWarnings INTERFACE SpectreDisableSomeWarnings ) # - GCC versions below 13 don't respect 'GCC diagnostic' pragmas to disable # warnings by the preprocessor: # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431 # So we disable the warning about unknown pragmas because we can't silence it. # - GCC has many false positives for `stringop-overflow`, `array-bounds`, and # `restrict`, specifically in libstdc++ with C++20, leading to # warnings from `__builtin_memcpy`. # - GCC has false-positive `use-after-free` warnings from Blaze's DynamicMatrix # constructor that gets inlined in many places. Rather than silencing the # warning at every call site or forcing no-inline, we silence it here. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") create_cxx_flags_target( "-Wno-unknown-pragmas;\ -Wno-stringop-overflow;\ -Wno-stringop-overread;\ -Wno-maybe-uninitialized;\ -Wno-array-bounds;\ -Wno-restrict;\ -Wno-use-after-free" SpectreDisableGccWarnings) target_link_libraries( SpectreWarnings INTERFACE SpectreDisableGccWarnings ) endif() # Suppress CUDA warnings that we don't want create_cxx_flag_target( "-Xcudafe \"--diag_suppress=177,186,191,554,1301,1305,2189,3060,20012\"" SpectreCudaWarnings) target_link_libraries( SpectreWarnings INTERFACE SpectreCudaWarnings ) target_link_libraries( SpectreFlags INTERFACE SpectreWarnings ) ================================================ FILE: cmake/FindBlaze.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. if(NOT BLAZE_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(BLAZE_ROOT "") set(BLAZE_ROOT $ENV{BLAZE_ROOT}) endif() find_path( BLAZE_INCLUDE_DIR PATH_SUFFIXES include NAMES blaze/Blaze.h HINTS ${BLAZE_ROOT} DOC "Blaze include directory. Used BLAZE_ROOT to set a search dir." ) set(BLAZE_INCLUDE_DIRS ${BLAZE_INCLUDE_DIR}) set(BLAZE_VERSION "") if(EXISTS "${BLAZE_INCLUDE_DIRS}/blaze/system/Version.h") # Extract version info from header file(READ "${BLAZE_INCLUDE_DIRS}/blaze/system/Version.h" BLAZE_FIND_HEADER_CONTENTS) string(REGEX MATCH "#define BLAZE_MAJOR_VERSION [0-9]+" BLAZE_MAJOR_VERSION "${BLAZE_FIND_HEADER_CONTENTS}") string(REPLACE "#define BLAZE_MAJOR_VERSION " "" BLAZE_MAJOR_VERSION ${BLAZE_MAJOR_VERSION}) string(REGEX MATCH "#define BLAZE_MINOR_VERSION [0-9]+" BLAZE_MINOR_VERSION "${BLAZE_FIND_HEADER_CONTENTS}") string(REPLACE "#define BLAZE_MINOR_VERSION " "" BLAZE_MINOR_VERSION ${BLAZE_MINOR_VERSION}) set(BLAZE_VERSION "${BLAZE_MAJOR_VERSION}.${BLAZE_MINOR_VERSION}" ) elseif(BLAZE_INCLUDE_DIRS) message(WARNING "Failed to find file " "'${BLAZE_INCLUDE_DIRS}/blaze/system/Version.h' " "while detecting the Blaze version.") endif() set(Blaze_VERSION ${BLAZE_VERSION}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args( Blaze FOUND_VAR BLAZE_FOUND REQUIRED_VARS BLAZE_INCLUDE_DIR BLAZE_INCLUDE_DIRS VERSION_VAR BLAZE_VERSION ) mark_as_advanced(BLAZE_INCLUDE_DIR BLAZE_INCLUDE_DIRS BLAZE_VERSION BLAZE_MAJOR_VERSION BLAZE_MINOR_VERSION Blaze_VERSION ) ================================================ FILE: cmake/FindBreathe.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. if(NOT BREATHE_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(BREATHE_ROOT "") set(BREATHE_ROOT $ENV{BREATHE_ROOT}) endif() # Look for an executable called breathe-apidoc find_program( BREATHE_APIDOC_EXECUTABLE NAMES breathe-apidoc PATHS ${BREATHE_ROOT} DOC "Path to breathe-apidoc executable") execute_process(COMMAND "${BREATHE_APIDOC_EXECUTABLE}" "--version" RESULT_VARIABLE VERSION_RESULT OUTPUT_VARIABLE VERSION_OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE) include(FindPackageHandleStandardArgs) if(VERSION_RESULT MATCHES 0) string(REGEX MATCH "[0-9]+\.[0-9]+[\.]?[0-9]*" BREATHE_APIDOC_VERSION ${VERSION_OUTPUT}) set(BREATHE_VERSION ${BREATHE_APIDOC_VERSION}) endif(VERSION_RESULT MATCHES 0) # Handle standard arguments to find_package like REQUIRED and QUIET find_package_handle_standard_args(Breathe REQUIRED_VARS BREATHE_APIDOC_EXECUTABLE BREATHE_VERSION BREATHE_APIDOC_VERSION VERSION_VAR BREATHE_VERSION) ================================================ FILE: cmake/FindCharm.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # FindCharm.cmake # # Finds a suitable Charm++ installation and exposes it via imported targets. # # This module requires you have set the `CHARM_ROOT` variable to a Charm++ # installation directory, e.g.: # # cmake -D CHARM_ROOT=/path/to/charm++/build-dir # # This is to ensure that SpECTRE builds with the Charm++ installation that you # intended to use. The `CHARM_ROOT/bin` directory should contain the Charm++ # compiler `charmc`. All information on include directories, library paths, # compiler flags etc. will be retrieved by invoking `charmc` with the # `-print-building-blocks` flag. Note that we do _not_ use `charmc` to wrap the # CMake compiler configuration. Instead, the information retrieved from `charmc` # is made available to CMake via imported targets. # # This module supports CMake "components" to load additional Charm++ modules. # You can load additional Charm++ modules like this: # # find_package(Charm 7.0.0 COMPONENTS EveryLB) # # This module exposes the following targets: # # - `Charmxx::charmxx`: All Charm++ libraries. # - `Charmxx::pup`: Only the Charm++ PUP serialization library. # - `Charmxx::main`: Defines the Charm++ main function. Link to compile # executables. # - `CharmModuleInit`: Provides the generated definitions of Charm++'s # module-init functions. option(CHARM_SHARED_LIBS "Link Charm++ shared libraries. Defaults to the \ value of 'BUILD_SHARED_LIBS' but can be overriden to enforce shared or static \ libraries for Charm++." ${BUILD_SHARED_LIBS}) option(CHARM_USE_MPI "Find and link MPI with Charm++. An attempt is made to \ determine automatically if MPI is needed, but this flag can be turned on to \ enable linking MPI if the automatic check fails." OFF) option(CHARM_TRACE_PROJECTIONS "Charm++ was built with projections support on. \ Enables '-tracemode projections'" OFF) option(CHARM_TRACE_SUMMARY "Charm++ was built with projections support on. \ Enables '-tracemode summary'" OFF) if (DEFINED ENV{CHARM_ROOT} AND "${CHARM_ROOT}" STREQUAL "") set(CHARM_ROOT "$ENV{CHARM_ROOT}") endif() if (NOT EXISTS "${CHARM_ROOT}") if ("${CHARM_ROOT}" STREQUAL "") message( FATAL_ERROR "CHARM_ROOT was not set. Pass it as a command-line arg: " "cmake -D CHARM_ROOT=/path/to/charm++/build-dir") endif() message( FATAL_ERROR "CHARM_ROOT=${CHARM_ROOT} does not exist. " "Please pass it as a command-line definition to cmake, i.e. " "cmake -D CHARM_ROOT=/path/to/charm++/build-dir" ) endif () # Find the Charm compiler `charmc` first so we can retrieve build info from it find_program(CHARM_COMPILER NAMES charmc PATH_SUFFIXES bin HINTS ${CHARM_ROOT} ENV CHARM_ROOT NO_DEFAULT_PATH DOC "The full path to the charm++ compiler 'charmc'" ) if(CHARM_COMPILER STREQUAL "CHARM_COMPILER-NOTFOUND") message(FATAL_ERROR "The Charm++ compiler 'charmc' could not be found. Make " "sure you have set 'CHARM_ROOT' to the path that contains 'bin/charmc'.") endif() # Assemble options for invoking `charmc`: # - Use static or shared libs if(CHARM_SHARED_LIBS) list(APPEND CHARMC_OPTIONS "-charm-shared") endif() # - Not linking the main function by default. We expose an extra target that # links it because we sometimes want to link Charm++ without a main function. list(APPEND CHARMC_OPTIONS "-nomain") list(APPEND CHARMC_OPTIONS "-nomain-module") if(CHARM_TRACE_PROJECTIONS) list(APPEND CHARMC_OPTIONS "-tracemode projections") endif() if(CHARM_TRACE_SUMMARY) list(APPEND CHARMC_OPTIONS "-tracemode summary") endif() # - Request optional Charm++ modules. They can be specified as `COMPONENTS` when # calling CMake's `find_package`. if(Charm_FIND_COMPONENTS) list(JOIN Charm_FIND_COMPONENTS "," CHARM_COMPONENTS_JOINED) list(APPEND CHARMC_OPTIONS "-modules ${CHARM_COMPONENTS_JOINED}") endif() # Invoke 'charmc' so that it outputs build info list(JOIN CHARMC_OPTIONS " " CHARMC_OPTIONS_JOINED) set(CHARM_BUILDING_BLOCKS_CMD "${CHARM_COMPILER} -print-building-blocks ${CHARMC_OPTIONS_JOINED}") message(STATUS "Charm++ 'charmc' is invoked as: ${CHARM_BUILDING_BLOCKS_CMD}") execute_process( COMMAND bash -c "${CHARM_BUILDING_BLOCKS_CMD}" OUTPUT_VARIABLE CHARM_BUILDING_BLOCKS ERROR_VARIABLE CHARM_BUILDING_BLOCKS_ERROR OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT CHARM_BUILDING_BLOCKS) if(CHARM_BUILDING_BLOCKS_ERROR MATCHES "lib_so directory not found" AND CHARM_SHARED_LIBS) message(STATUS "Charm++ is not built with shared-library support so we " "fall back to static libraries. Build Charm++ with the '--build-shared' " "option to enable shared libraries.") set(CHARM_SHARED_LIBS OFF) list(REMOVE_ITEM CHARMC_OPTIONS "-charm-shared") list(JOIN CHARMC_OPTIONS " " CHARMC_OPTIONS_JOINED) set(CHARM_BUILDING_BLOCKS_CMD "${CHARM_COMPILER} -print-building-blocks ${CHARMC_OPTIONS_JOINED}") execute_process( COMMAND bash -c "${CHARM_BUILDING_BLOCKS_CMD}" OUTPUT_VARIABLE CHARM_BUILDING_BLOCKS ERROR_VARIABLE CHARM_BUILDING_BLOCKS_ERROR OUTPUT_STRIP_TRAILING_WHITESPACE ) else() message(FATAL_ERROR "Failed retrieving Charm++ building blocks with " "command:\n ${CHARM_BUILDING_BLOCKS_CMD}\nPlease make sure the Charm++ " "version is at least 6.9.0. Error message:\n" "${CHARM_BUILDING_BLOCKS_ERROR}") endif() endif() string(REGEX REPLACE ";" "\\\\;" CHARM_BUILDING_BLOCKS_LIST "${CHARM_BUILDING_BLOCKS}") string(REGEX REPLACE "\n" ";" CHARM_BUILDING_BLOCKS_LIST "${CHARM_BUILDING_BLOCKS_LIST}") # Load the charm building blocks into CMake variables foreach(CHARM_BUILDING_BLOCK IN LISTS CHARM_BUILDING_BLOCKS_LIST) if(CHARM_BUILDING_BLOCK MATCHES "^([^=]+)='(.*)'$") set(${CMAKE_MATCH_1} "${CMAKE_MATCH_2}") string(STRIP "${${CMAKE_MATCH_1}}" ${CMAKE_MATCH_1}) else() message(SEND_ERROR "Unexpected output from charmc: ${CHARM_BUILDING_BLOCK}") endif() endforeach() # Validate the charm building blocks list(APPEND CHARM_REQUIRED_BUILDING_BLOCKS CHARM_CXX CHARM_CXX_FLAGS CHARM_LDXX_FLAGS CHARMINC # Not needed but available, could be added if needed: # CHARM_CC # CHARM_LD # CHARM_LDXX # CHARM_CC_FLAGS # CHARM_LD_FLAGS # CHARMBIN ) if(CHARM_SHARED_LIBS) list(APPEND CHARM_REQUIRED_BUILDING_BLOCKS CHARMLIBSO) else() list(APPEND CHARM_REQUIRED_BUILDING_BLOCKS CHARMLIB) endif() foreach(CHARM_REQUIRED_BUILDING_BLOCK IN LISTS CHARM_REQUIRED_BUILDING_BLOCKS) if(NOT ${CHARM_REQUIRED_BUILDING_BLOCK}) message(FATAL_ERROR "Could not find ${CHARM_REQUIRED_BUILDING_BLOCK} " "variable in output of command: ${CHARM_BUILDING_BLOCKS_CMD}") endif() endforeach() # Split flags into lists separate_arguments(CHARM_CXX_FLAGS) separate_arguments(CHARM_LDXX_FLAGS) # Define variables with standard names for compatibility, though these should # not be used outside this script. get_filename_component(CHARM_INCLUDE_DIR ${CHARMINC} ABSOLUTE) set(CHARM_INCLUDE_DIRS ${CHARM_INCLUDE_DIR}) if(CHARM_SHARED_LIBS) set(CHARM_LIBRARIES ${CHARMLIBSO}) else() set(CHARM_LIBRARIES ${CHARMLIB}) endif() # Find version file if(EXISTS "${CHARM_INCLUDE_DIR}/charm-version.h") set(CHARM_VERSION_FILE_VERSION "6_11") set(CHARM_VERSION_FILE_LOCATION "${CHARM_INCLUDE_DIR}/charm-version.h") elseif(EXISTS "${CHARM_INCLUDE_DIR}/VERSION") set(CHARM_VERSION_FILE_VERSION "pre_6_11") set(CHARM_VERSION_FILE_LOCATION "${CHARM_INCLUDE_DIR}/VERSION") elseif(EXISTS "${CHARM_ROOT}/VERSION") set(CHARM_VERSION_FILE_VERSION "pre_6_11") set(CHARM_VERSION_FILE_LOCATION "${CHARM_ROOT}/VERSION") else() message(FATAL_ERROR "Failed to find Charm++ version file") endif() # Parse version from file file(READ "${CHARM_VERSION_FILE_LOCATION}" CHARM_VERSION_FILE) if(CHARM_VERSION_FILE_VERSION STREQUAL "6_11") # Since version 6.11 the file is C++-compatible if(CHARM_VERSION_FILE MATCHES "#define CHARM_VERSION_MAJOR ([0-9]+)") set(CHARM_VERSION_MAJOR ${CMAKE_MATCH_1}) else() message(FATAL_ERROR "Could not parse CHARM_VERSION_MAJOR from file: " "${CHARM_VERSION_FILE_LOCATION}") endif() if(CHARM_VERSION_FILE MATCHES "#define CHARM_VERSION_MINOR ([0-9]+)") set(CHARM_VERSION_MINOR ${CMAKE_MATCH_1}) else() message(FATAL_ERROR "Could not parse CHARM_VERSION_MINOR from file: " "${CHARM_VERSION_FILE_LOCATION}") endif() if(CHARM_VERSION_FILE MATCHES "#define CHARM_VERSION_PATCH ([0-9]+)") set(CHARM_VERSION_PATCH ${CMAKE_MATCH_1}) else() message(FATAL_ERROR "Could not parse CHARM_VERSION_PATCH from file: " "${CHARM_VERSION_FILE_LOCATION}") endif() elseif(CHARM_VERSION_FILE_VERSION STREQUAL "pre_6_11") # Before version 6.11 the file contains only a string string(REGEX REPLACE "\n" "" CHARM_VERSION_FILE "${CHARM_VERSION_FILE}") string( REGEX REPLACE "([0-9])1([0-9])0([0-9])" "\\1;1\\2;\\3" CHARM_VERSIONS_PARSED ${CHARM_VERSION_FILE} ) list(GET CHARM_VERSIONS_PARSED 0 CHARM_VERSION_MAJOR) list(GET CHARM_VERSIONS_PARSED 1 CHARM_VERSION_MINOR) list(GET CHARM_VERSIONS_PARSED 2 CHARM_VERSION_PATCH) endif() set(CHARM_VERSION "${CHARM_VERSION_MAJOR}.${CHARM_VERSION_MINOR}.${CHARM_VERSION_PATCH}") # Filter the compiler and linker flags: # - Remove the macOS deployment target so the CMake setting is used. list(FILTER CHARM_CXX_FLAGS EXCLUDE REGEX "^-mmacosx-version-min=") list(FILTER CHARM_LDXX_FLAGS EXCLUDE REGEX "^-mmacosx-version-min=") # - Remove the C++ standard flag so the CMake setting is used. list(FILTER CHARM_CXX_FLAGS EXCLUDE REGEX "^-std=") # - Remove the standard library flag so the CMake setting is used. list(FILTER CHARM_CXX_FLAGS EXCLUDE REGEX "^-stdlib=") list(FILTER CHARM_LDXX_FLAGS EXCLUDE REGEX "^-stdlib=") # - Remove the -fPIC and -fPIE flags so the CMake setting is used. list(FILTER CHARM_CXX_FLAGS EXCLUDE REGEX "-fPI[CE]") list(FILTER CHARM_CXX_FLAGS EXCLUDE REGEX "-fpi[ce]") list(FILTER CHARM_LDXX_FLAGS EXCLUDE REGEX "-fPI[CE]") list(FILTER CHARM_LDXX_FLAGS EXCLUDE REGEX "-fpi[ce]") # - Remove the -rdynamic flag so the CMake setting is used. This flag is needed # for `backtrace` functions. We handle the flag in our own build system # (instead of taking it over from Charm++). list(FILTER CHARM_CXX_FLAGS EXCLUDE REGEX "-dynamic") list(FILTER CHARM_LDXX_FLAGS EXCLUDE REGEX "-rdynamic") # - Extract the include directories so we can set them properly with CMake. # That's better because they are declared as "SYSTEM", which silences warnings # from those headers. list(FILTER CHARM_CXX_FLAGS EXCLUDE REGEX "^-I${CHARMINC}$") set(CHARM_INCLUDE_EXTRA ${CHARM_CXX_FLAGS}) list(FILTER CHARM_INCLUDE_EXTRA INCLUDE REGEX "^-I.+") list(FILTER CHARM_CXX_FLAGS EXCLUDE REGEX "^-I.+") list(TRANSFORM CHARM_INCLUDE_EXTRA REPLACE "^-I" "") # Filter out relative paths to `./proc_management` that are added for some # backends (ucx and ofi), since those paths don't seem to exist list(FILTER CHARM_INCLUDE_EXTRA EXCLUDE REGEX "^[.]/proc_management") list(APPEND CHARM_INCLUDE_DIRS ${CHARM_INCLUDE_EXTRA}) # - Remove the rpath linker argument, since CMake adds it automatically. list(FILTER CHARM_LDXX_FLAGS EXCLUDE REGEX "^-Wl,-rpath,${CHARM_LIBRARIES}/?$") # - Extract lib directories list(FILTER CHARM_LDXX_FLAGS EXCLUDE REGEX "^-L${CHARM_LIBRARIES}$") set(CHARM_LIBRARIES_EXTRA ${CHARM_LDXX_FLAGS}) list(FILTER CHARM_LIBRARIES_EXTRA INCLUDE REGEX "^-L.+") list(FILTER CHARM_LDXX_FLAGS EXCLUDE REGEX "^-L.+") list(TRANSFORM CHARM_LIBRARIES_EXTRA REPLACE "^-L" "") list(APPEND CHARM_LIBRARIES ${CHARM_LIBRARIES_EXTRA}) # - Remove the link directory and find the libraries on the system so we can # configure them properly with CMake. That's more robust when switching # between static and shared libs builds. Instead of parsing the list of libs # below we could just hard-code lib names, but that may break with future # Charm versions and could be annoying to debug. However, it would give us # more control over which libs to link. Ideally, Charm++ would provide # exported targets with these libs. set(CHARM_LIB_NAMES ${CHARM_LDXX_FLAGS}) list(FILTER CHARM_LIB_NAMES INCLUDE REGEX "^-l.+") list(FILTER CHARM_LDXX_FLAGS EXCLUDE REGEX "^-l.+") list(TRANSFORM CHARM_LIB_NAMES REPLACE "^-l" "") list(JOIN CHARM_LIB_NAMES ", " CHARM_LIB_NAMES_OUTPUT) message(STATUS "Charm++ lib names: ${CHARM_LIB_NAMES_OUTPUT}") set(CHARM_LIBS_TO_FIND ${CHARM_LIB_NAMES}) # Also find the 'ckmain' library, which isn't included in the list of lib names # because we invoked charmc with '-nomain' list(APPEND CHARM_LIBS_TO_FIND ckmain) foreach(CHARM_LIB_NAME IN LISTS CHARM_LIBS_TO_FIND) # First, find the lib _only_ in CHARM_LIBRARIES. This ensures we prefer the # shared libs in the separate CHARM_ROOT/lib_so directory if requested. find_library(CHARM_LIB_${CHARM_LIB_NAME} NAMES ${CHARM_LIB_NAME} HINTS ${CHARM_LIBRARIES} NO_DEFAULT_PATH ) # Second, fall back to a wider search on the system find_library(CHARM_LIB_${CHARM_LIB_NAME} NAMES ${CHARM_LIB_NAME} HINTS ENV LIBRARY_PATH ) if ("${CHARM_LIB_${CHARM_LIB_NAME}}" STREQUAL "CHARM_LIB_${CHARM_LIB_NAME}-NOTFOUND") message(SEND_ERROR "Could not find Charm++ library '${CHARM_LIB_NAME}'. " "Make sure you have built Charm++ with support for this library, and you \ have loaded the appropriate modules.") endif() list(APPEND CHARM_LIBS ${CHARM_LIB_${CHARM_LIB_NAME}}) # Collect libs for the PUP serialization library so we can link it separately # if we want. The PUP functionality is in `conv-util` in Charm++ 6.10.2 and # in the combined `converse` lib in later versions. if(CHARM_LIB_NAME STREQUAL conv-util OR CHARM_LIB_NAME STREQUAL converse) list(APPEND PUP_LIBS ${CHARM_LIB_${CHARM_LIB_NAME}}) endif() endforeach() # - Extract libraries that are linked as object files (`conv-static` in Charm++ # 6.10.2). set(CHARM_LIB_conv-static ${CHARM_LDXX_FLAGS}) list(FILTER CHARM_LIB_conv-static INCLUDE REGEX "conv-static.o$") list(FILTER CHARM_LDXX_FLAGS EXCLUDE REGEX "conv-static.o$") # Report remaining flags that will be ignored. They have been used to compile # Charm++ but may not be compatible with the compiler that the SpECTRE build is # configured with. They may also include flags that have been chosen differently # for the SpECTRE build, e.g. optimization settings. The ignored flags are # printed out to catch cases where adding one of the flags could be useful. list(JOIN CHARM_CXX_FLAGS " " CHARM_CXX_FLAGS_OUTPUT) message(STATUS "These Charm++ compiler flags will be ignored: " "${CHARM_CXX_FLAGS_OUTPUT}") list(JOIN CHARM_LDXX_FLAGS " " CHARM_LDXX_FLAGS_OUTPUT) message(STATUS "These Charm++ linker flags will be ignored: " "${CHARM_LDXX_FLAGS_OUTPUT}") # Invoke `charmc` to generate definitions for the module-init functions. # # `charmc` writes a tiny temporary `moduleinit$$.C` file with a few functions # that often do nothing, compiles it and links it into every Charm module. We # have `charmc` generate this file and compile it into an object library that # can be linked into executables. The interface for this could be improved on # the Charm++ side. See this upstream issue: # https://github.com/UIUC-PPL/charm/issues/3210 set(CHARM_MODULEINIT_CMD "${CHARM_COMPILER} ${CHARMC_OPTIONS_JOINED} -o unused -save") execute_process( COMMAND bash -c "(${CHARM_MODULEINIT_CMD} || mv moduleinit*.C CharmModuleInit.C) \ && rm moduleinit*" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/tmp/ ERROR_VARIABLE CHARM_MODULEINIT_ERROR ) configure_file( ${CMAKE_BINARY_DIR}/tmp/CharmModuleInit.C ${CMAKE_BINARY_DIR} ) add_library(CharmModuleInit OBJECT ${CMAKE_BINARY_DIR}/CharmModuleInit.C) # -w -- suppress all warnings because this is charm-generated source set_property(TARGET CharmModuleInit APPEND PROPERTY COMPILE_OPTIONS $<$:-fPIC -w>) # Use the charm building blocks to construct imported targets # - Imported target with all Charm libs add_library(Charmxx::charmxx INTERFACE IMPORTED) target_include_directories(Charmxx::charmxx INTERFACE ${CHARM_INCLUDE_DIRS}) target_link_libraries(Charmxx::charmxx INTERFACE ${CHARM_LIBS}) # - Target just for the PUP serialization library. add_library(Charmxx::pup INTERFACE IMPORTED) target_include_directories(Charmxx::pup INTERFACE ${CHARM_INCLUDE_DIRS}) target_link_libraries(Charmxx::pup INTERFACE ${PUP_LIBS}) # - Target that defines the Charm++ main function. add_library(Charmxx::main INTERFACE IMPORTED) target_link_libraries( Charmxx::main INTERFACE Charmxx::charmxx ${CHARM_LIB_ckmain} ${CHARM_LIB_conv-static} ) # Add a preprocessing definition to indicate that a Charm++ main module is # available. This is used to conditionally compile Charm++-specific code # that assumes it is running in a Charm++ environment, such as the # `Parallel/CharmRegistration.hpp` code. target_compile_definitions( Charmxx::main INTERFACE SPECTRE_CHARM_HAS_MAIN ) # Find and link MPI if necessary # # We currently check if `CHARM_CXX` obviously calls into an MPI compiler wrapper # to turn MPI linking on automatically. In the future it may be necessary to # further extend support for Charm++ wrapping other compiler wrappers and turn # them into CMake targets, as is done with MPI here. if (CHARM_CXX MATCHES ".*mpicxx.*") set(CHARM_USE_MPI ON) endif() if (CHARM_USE_MPI) find_package(MPI REQUIRED) target_link_libraries(Charmxx::charmxx INTERFACE MPI::MPI_CXX) endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args( Charm # Only these paths are input variables, i.e. they are searched on the system # and can be specified on the command line to select the Charm installation. REQUIRED_VARS CHARM_COMPILER VERSION_VAR CHARM_VERSION ) mark_as_advanced( CHARM_COMPILER CHARM_INCLUDE_DIR CHARM_USE_MPI CHARM_VERSION_MAJOR CHARM_VERSION_MINOR CHARM_VERSION_PATCH CHARM_VERSION ) ================================================ FILE: cmake/FindClangFormat.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. if(NOT CLANG_FORMAT_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(CLANG_FORMAT_ROOT "") set(CLANG_FORMAT_ROOT $ENV{CLANG_FORMAT_ROOT}) endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") string( REGEX MATCH "^[0-9]+.[0-9]+" LLVM_VERSION "${CMAKE_CXX_COMPILER_VERSION}" ) find_program( CLANG_FORMAT_BIN NAMES "clang-format-${LLVM_VERSION}" "clang-format" HINTS ${CLANG_FORMAT_ROOT} ) else() find_program( CLANG_FORMAT_BIN NAMES "clang-format-4.0" "clang-format-3.9" "clang-format-3.8" "clang-format" ) endif() if (CLANG_FORMAT_BIN) execute_process(COMMAND ${CLANG_FORMAT_BIN} --version RESULT_VARIABLE CLANG_FORMAT_VERSION_RESULT OUTPUT_VARIABLE CLANG_FORMAT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) if(CLANG_FORMAT_VERSION_RESULT MATCHES 0) string(REGEX REPLACE "clang-format version " "" CLANG_FORMAT_VERSION ${CLANG_FORMAT_VERSION}) endif() # Look for a git-clang-format program in the same place as # clang-format. Versions of git-clang-format are not always # compatible with other clang-format executables. get_filename_component(CLANG_FORMAT_DIR ${CLANG_FORMAT_BIN} DIRECTORY) get_filename_component(CLANG_FORMAT_NAME ${CLANG_FORMAT_BIN} NAME) find_program( GIT_CLANG_FORMAT_BIN NAMES git-${CLANG_FORMAT_NAME} HINTS ${CLANG_FORMAT_DIR} NO_DEFAULT_PATH ) endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args( ClangFormat REQUIRED_VARS CLANG_FORMAT_BIN VERSION_VAR CLANG_FORMAT_VERSION ) mark_as_advanced(CLANG_FORMAT_VERSION) ================================================ FILE: cmake/FindFFTW.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Find FFTW3 (The Fastest Fourier Transform in the West) # http://www.fftw.org/ # # Defines the `FFTW::FFTW` target to link against. if(NOT FFTW_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(FFTW_ROOT "") set(FFTW_ROOT $ENV{FFTW_ROOT}) endif() find_path(FFTW_INCLUDE_DIR NAMES fftw3.h PATH_SUFFIXES include HINTS ${FFTW_ROOT} ) find_library(FFTW_LIB NAMES fftw3 PATH_SUFFIXES lib64 lib HINTS ${FFTW_ROOT} ) if (FFTW_INCLUDE_DIR AND FFTW_LIB) add_library(FFTW::FFTW INTERFACE IMPORTED) target_include_directories(FFTW::FFTW INTERFACE ${FFTW_INCLUDE_DIR}) target_link_libraries(FFTW::FFTW INTERFACE ${FFTW_LIB}) endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(FFTW REQUIRED_VARS FFTW_INCLUDE_DIR FFTW_LIB) mark_as_advanced(FFTW_INCLUDE_DIR FFTW_LIB) ================================================ FILE: cmake/FindFUKA.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Find the FUKA initial data code (https://bitbucket.org/fukaws/fuka/src/fuka/) # # Pass `FUKA_ROOT` to the CMake build configuration to set up the following # targets: # # - FUKA::Exporter: Functionality to load FUKA volume data and interpolate to # arbitrary points. if(NOT FUKA_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(FUKA_ROOT "") set(FUKA_ROOT $ENV{FUKA_ROOT}) endif() find_library( FUKA_LIB NAMES libkadath.a PATHS ${FUKA_ROOT} NO_DEFAULT_PATHS ) # Link MPI (should be the same MPI that FUKA was built with) find_package(MPI COMPONENTS C) if (FUKA_LIB AND MPI_C_FOUND) find_package(FFTW) if (FFTW_FOUND) add_library(FUKA::Exporter INTERFACE IMPORTED) target_link_libraries( FUKA::Exporter INTERFACE MPI::MPI_C FFTW::FFTW ${FUKA_LIB} ) endif() endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args( FUKA REQUIRED_VARS FUKA_LIB ) ================================================ FILE: cmake/FindGoogleBenchmark.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Find GOOGLE_BENCHMARK: https://github.com/google/benchmark # If not in one of the default paths specify # -DGOOGLE_BENCHMARK_ROOT=/path/to/GOOGLE_BENCHMARK to search there as well. if(NOT GOOGLE_BENCHMARK_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(GOOGLE_BENCHMARK_ROOT "") set(GOOGLE_BENCHMARK_ROOT $ENV{GOOGLE_BENCHMARK_ROOT}) endif() if(NOT GoogleBenchmark_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(GoogleBenchmark_ROOT "") set(GoogleBenchmark_ROOT $ENV{GoogleBenchmark_ROOT}) endif() find_path(GoogleBenchmark_INCLUDE_DIRS benchmark.h PATH_SUFFIXES include/benchmark HINTS ${GOOGLE_BENCHMARK_ROOT}) find_library(GoogleBenchmark_LIBRARIES NAMES benchmark PATH_SUFFIXES lib64 lib HINTS ${GOOGLE_BENCHMARK_ROOT} ${GoogleBenchmark_ROOT}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GoogleBenchmark FOUND_VAR GoogleBenchmark_FOUND REQUIRED_VARS GoogleBenchmark_INCLUDE_DIRS GoogleBenchmark_LIBRARIES) mark_as_advanced(GoogleBenchmark_INCLUDE_DIRS GoogleBenchmark_LIBRARIES) ================================================ FILE: cmake/FindJEMALLOC.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Find jemalloc: https://github.com/jemalloc/jemalloc # If not in one of the default paths specify -D JEMALLOC_ROOT=/path/to/jemalloc # to search there as well. if(NOT JEMALLOC_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(JEMALLOC_ROOT "") set(JEMALLOC_ROOT $ENV{JEMALLOC_ROOT}) endif() # find the jemalloc include directory find_path(JEMALLOC_INCLUDE_DIRS jemalloc/jemalloc.h PATH_SUFFIXES include HINTS ${JEMALLOC_ROOT}) find_library(JEMALLOC_LIBRARIES NAMES jemalloc PATH_SUFFIXES lib64 lib HINTS ${JEMALLOC_ROOT}) set(JEMALLOC_VERSION "") if(EXISTS "${JEMALLOC_INCLUDE_DIRS}/jemalloc/jemalloc.h") # Extract version info from header file(READ "${JEMALLOC_INCLUDE_DIRS}/jemalloc/jemalloc.h" JEMALLOC_FIND_HEADER_CONTENTS) string(REGEX MATCH "#define JEMALLOC_VERSION_MAJOR [0-9]+" JEMALLOC_MAJOR_VERSION "${JEMALLOC_FIND_HEADER_CONTENTS}") string(REPLACE "#define JEMALLOC_VERSION_MAJOR " "" JEMALLOC_MAJOR_VERSION "${JEMALLOC_MAJOR_VERSION}") string(REGEX MATCH "#define JEMALLOC_VERSION_MINOR [0-9]+" JEMALLOC_MINOR_VERSION "${JEMALLOC_FIND_HEADER_CONTENTS}") string(REPLACE "#define JEMALLOC_VERSION_MINOR " "" JEMALLOC_MINOR_VERSION "${JEMALLOC_MINOR_VERSION}") string(REGEX MATCH "#define JEMALLOC_VERSION_BUGFIX [0-9]+" JEMALLOC_SUBMINOR_VERSION "${JEMALLOC_FIND_HEADER_CONTENTS}") string(REPLACE "#define JEMALLOC_VERSION_BUGFIX " "" JEMALLOC_SUBMINOR_VERSION "${JEMALLOC_SUBMINOR_VERSION}") set(JEMALLOC_VERSION "${JEMALLOC_MAJOR_VERSION}.${JEMALLOC_MINOR_VERSION}\ .${JEMALLOC_SUBMINOR_VERSION}" ) else() message(WARNING "Failed to find file " "'${JEMALLOC_INCLUDE_DIRS}/jemalloc/jemalloc.h' " "while detecting the JEMALLOC version.") endif(EXISTS "${JEMALLOC_INCLUDE_DIRS}/jemalloc/jemalloc.h") include(FindPackageHandleStandardArgs) find_package_handle_standard_args( JEMALLOC FOUND_VAR JEMALLOC_FOUND REQUIRED_VARS JEMALLOC_INCLUDE_DIRS JEMALLOC_LIBRARIES VERSION_VAR JEMALLOC_VERSION ) mark_as_advanced(JEMALLOC_INCLUDE_DIRS JEMALLOC_LIBRARIES JEMALLOC_MAJOR_VERSION JEMALLOC_MINOR_VERSION JEMALLOC_SUBMINOR_VERSION JEMALLOC_VERSION) ================================================ FILE: cmake/FindLIBCXX.cmake ================================================ ################################################################################ # # \file cmake/FindLIBCXX.cmake # \author J. Bakosi # \copyright 2012-2015, Jozsef Bakosi, 2016, Los Alamos National Security, LLC. # \brief Find libc++ # \date Fri 20 Jan 2017 12:42:21 PM MST # ################################################################################ # From Quinoa: https://github.com/quinoacomputing/quinoa # # SpECTRE modifications: # - allow finding shared objects of libc++ and libc++abi # Find libc++. # See libc++: http://libcxx.llvm.org, libc++abi: http://libcxxabi.llvm.org. # # LIBCXX_FOUND - System has libc++ # LIBCXX_INCLUDE_DIRS - The libc++ include directory # LIBCXX_LIBRARIES - The libraries needed to use libc++ # LIBCXXABI_LIBRARIES - The libraries needed to use libc++abi # # Set the LIBCXX_ROOT cmake variable or shell environment variable before # calling find_package to a path to add an additional search path, e.g., # # Usage: # # set(LIBCXX_ROOT "/path/to/custom/libc++") # prefer over system # find_package(LibCXX) # if(LIBCXX_FOUND) # target_link_libraries (TARGET ${LIBCXX_LIBRARIES} ${LIBCXXABI_LIBRARIES}) # endif() if(NOT LIBCXX_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(LIBCXX_ROOT "") set(LIBCXX_ROOT $ENV{LIBCXX_ROOT}) endif() # Extract a reasonable place to look for the libraries from the compiler path string(REGEX REPLACE "/bin/clang\\+\\+" "" LIBCXX_PATH_FROM_COMPILER ${CMAKE_CXX_COMPILER}) # If already in cache, be silent if(LIBCXX_INCLUDE_DIRS AND LIBCXX_LIBRARIES AND LIBCXXABI_LIBRARIES) set (LIBCXX_FIND_QUIETLY TRUE) endif() find_path(LIBCXX_INCLUDE_DIR NAMES cmath HINTS ${LIBCXX_ROOT}/include/c++/v1 ${LIBCXX_PATH_FROM_COMPILER}/include/c++/v1 /usr/include/c++/v1) if(BUILD_SHARED_LIBS) find_library(LIBCXX_LIBRARIES NAMES c++ HINTS ${LIBCXX_ROOT}/lib ${LIBCXX_PATH_FROM_COMPILER}/lib) find_library(LIBCXXABI_LIBRARIES NAMES c++abi HINTS ${LIBCXX_ROOT}/lib ${LIBCXX_PATH_FROM_COMPILER}/lib) else() find_library(LIBCXX_LIBRARIES NAMES libc++.a libc++.so HINTS ${LIBCXX_ROOT}/lib ${LIBCXX_PATH_FROM_COMPILER}/lib) if(ARCH MATCHES "ppc64") set(LIBCXXABI_LIBRARIES " ") else() find_library(LIBCXXABI_LIBRARIES NAMES libc++abi.a libc++abi.so HINTS ${LIBCXX_ROOT}/lib ${LIBCXX_PATH_FROM_COMPILER}/lib) endif() endif() set(LIBCXX_INCLUDE_DIRS ${LIBCXX_INCLUDE_DIR}) # Handle the QUIETLY and REQUIRED arguments and set LIBCXX_FOUND to TRUE if # all listed variables are TRUE. INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS( LIBCXX DEFAULT_MSG LIBCXX_LIBRARIES LIBCXXABI_LIBRARIES LIBCXX_INCLUDE_DIRS ) MARK_AS_ADVANCED(LIBCXX_INCLUDE_DIRS LIBCXX_LIBRARIES LIBCXXABI_LIBRARIES) ================================================ FILE: cmake/FindLIBXSMM.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Find LIBXSMM: https://github.com/libxsmm/libxsmm # If not in one of the default paths specify -D LIBXSMM_ROOT=/path/to/LIBXSMM # to search there as well. if(NOT LIBXSMM_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(LIBXSMM_ROOT "") set(LIBXSMM_ROOT $ENV{LIBXSMM_ROOT}) endif() # find the LIBXSMM include directory find_path(LIBXSMM_INCLUDE_DIRS libxsmm.h PATH_SUFFIXES include HINTS ${LIBXSMM_ROOT}) find_library(LIBXSMM_LIBRARIES NAMES xsmm PATH_SUFFIXES lib64 lib HINTS ${LIBXSMM_ROOT}) set(LIBXSMM_VERSION "") function(get_libxsmm_version FILE MAJOR_PREFIX MINOR_PREFIX PATCH_PREFIX) if(NOT EXISTS ${FILE}) return() endif() # Extract version info from header file(READ ${FILE} LIBXSMM_FIND_HEADER_CONTENTS) string(REGEX MATCH "${MAJOR_PREFIX}[0-9]+" LIBXSMM_MAJOR_VERSION "${LIBXSMM_FIND_HEADER_CONTENTS}") if("${LIBXSMM_MAJOR_VERSION}" STREQUAL "") return() endif() string(REPLACE "${MAJOR_PREFIX}" "" LIBXSMM_MAJOR_VERSION "${LIBXSMM_MAJOR_VERSION}") string(REGEX MATCH "${MINOR_PREFIX}[0-9]+" LIBXSMM_MINOR_VERSION "${LIBXSMM_FIND_HEADER_CONTENTS}") string(REPLACE "${MINOR_PREFIX}" "" LIBXSMM_MINOR_VERSION "${LIBXSMM_MINOR_VERSION}") string(REGEX MATCH "${PATCH_PREFIX}[0-9]+" LIBXSMM_SUBMINOR_VERSION "${LIBXSMM_FIND_HEADER_CONTENTS}") string(REPLACE "${PATCH_PREFIX}" "" LIBXSMM_SUBMINOR_VERSION "${LIBXSMM_SUBMINOR_VERSION}") set(LIBXSMM_VERSION "${LIBXSMM_MAJOR_VERSION}.${LIBXSMM_MINOR_VERSION}.${LIBXSMM_SUBMINOR_VERSION}" ) set(LIBXSMM_VERSION ${LIBXSMM_VERSION} PARENT_SCOPE) endfunction(get_libxsmm_version FILE MAJOR_REGEX MINOR_REGEX PATCH_REGEX) if (LIBXSMM_INCLUDE_DIRS) get_libxsmm_version( ${LIBXSMM_INCLUDE_DIRS}/libxsmm.h "#define LIBXSMM_VERSION_MAJOR " "#define LIBXSMM_VERSION_MINOR " "#define LIBXSMM_VERSION_UPDATE " ) get_libxsmm_version( ${LIBXSMM_INCLUDE_DIRS}/libxsmm_config.h "#define LIBXSMM_CONFIG_VERSION_MAJOR " "#define LIBXSMM_CONFIG_VERSION_MINOR " "#define LIBXSMM_CONFIG_VERSION_UPDATE " ) get_libxsmm_version( ${LIBXSMM_INCLUDE_DIRS}/libxsmm_version.h "#define LIBXSMM_CONFIG_VERSION_MAJOR " "#define LIBXSMM_CONFIG_VERSION_MINOR " "#define LIBXSMM_CONFIG_VERSION_UPDATE " ) if("${LIBXSMM_VERSION}" STREQUAL "") message(WARNING "Failed to detect LIBXSMM version.") endif() endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args( LIBXSMM FOUND_VAR LIBXSMM_FOUND REQUIRED_VARS LIBXSMM_INCLUDE_DIRS LIBXSMM_LIBRARIES VERSION_VAR LIBXSMM_VERSION) mark_as_advanced(LIBXSMM_INCLUDE_DIRS LIBXSMM_LIBRARIES LIBXSMM_VERSION) if (NOT LIBXSMM_FOUND) return() endif() # Define imported target add_library(Libxsmm INTERFACE IMPORTED) set_property(TARGET Libxsmm APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${LIBXSMM_INCLUDE_DIRS}) set_property(TARGET Libxsmm APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${LIBXSMM_LIBRARIES}) # LIBXSMM falls back to BLAS find_package(BLAS REQUIRED) target_link_libraries(Libxsmm INTERFACE BLAS::BLAS) add_interface_lib_headers( TARGET Libxsmm HEADERS libxsmm.h ) ================================================ FILE: cmake/FindNumPy.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${PYTHONPATH} ${Python_EXECUTABLE} "-c" "import numpy as n; print(n.__version__); print(n.get_include());" RESULT_VARIABLE RESULT OUTPUT_VARIABLE OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE) if(RESULT MATCHES 0) string(REGEX REPLACE ";" "\\\\;" VALUES ${OUTPUT}) string(REGEX REPLACE "\r?\n" ";" VALUES ${VALUES}) list(GET VALUES 0 NUMPY_VERSION) list(GET VALUES 1 NUMPY_INCLUDE_DIRS) string(REGEX MATCH "^([0-9])+\\.([0-9])+\\.([0-9])+" __ver_check "${NUMPY_VERSION}") if("${__ver_check}" STREQUAL "") unset(NUMPY_VERSION) unset(NUMPY_INCLUDE_DIRS) message(STATUS "Failed to retrieve NumPy version and include path, but got instead:\n${OUTPUT}\n") endif() endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(NumPy REQUIRED_VARS NUMPY_INCLUDE_DIRS NUMPY_VERSION VERSION_VAR NUMPY_VERSION) if(NUMPY_FOUND) message(STATUS "NumPy ver. ${NUMPY_VERSION} found (include: ${NUMPY_INCLUDE_DIRS})") else() message(STATUS "NumPy not found!") endif() ================================================ FILE: cmake/FindPAPI.cmake ================================================ # Obtained from: https://github.com/LLNL/perf-dump # Try to find PAPI headers and libraries. # # Usage of this module as follows: # # find_package(PAPI) # # Variables used by this module, they can change the default behaviour and need # to be set before calling find_package: # # PAPI_PREFIX Set this variable to the root installation of # libpapi if the module has problems finding the # proper installation path. # # Variables defined by this module: # # PAPI_FOUND System has PAPI libraries and headers # PAPI_LIBRARIES The PAPI library # PAPI_INCLUDE_DIRS The location of PAPI headers if(NOT PAPI_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(PAPI_ROOT "") set(PAPI_ROOT $ENV{PAPI_ROOT}) endif() find_path( PAPI_PREFIX NAMES include/papi.h HINTS ${PAPI_ROOT} ) find_library( PAPI_LIBRARIES # Pick the static library first for easier run-time linking. NAMES libpapi.a papi HINTS ${PAPI_PREFIX}/lib ${HILTIDEPS}/lib ) find_path( PAPI_INCLUDE_DIRS NAMES papi.h HINTS ${PAPI_PREFIX}/include ${HILTIDEPS}/include ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args( PAPI DEFAULT_MSG PAPI_LIBRARIES PAPI_INCLUDE_DIRS ) mark_as_advanced( PAPI_PREFIX_DIRS PAPI_LIBRARIES PAPI_INCLUDE_DIRS ) ================================================ FILE: cmake/FindParaView.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_program(PVPYTHON_EXEC pvpython) # Get version and runtime environment variables if (PVPYTHON_EXEC) execute_process( COMMAND ${PVPYTHON_EXEC} --print --version OUTPUT_VARIABLE _OUTPUT ERROR_VARIABLE _OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE) string(REPLACE "\n" ";" _OUTPUT "${_OUTPUT}") foreach(_ENTRY ${_OUTPUT}) # Extract the ParaView version from the output string(FIND "${_ENTRY}" "paraview version " _FOUND) if(NOT ${_FOUND} EQUAL -1) set(PARAVIEW_VERSION ${_ENTRY}) endif() # On some machines ParaView needs specific environment variables set, e.g. # on CaltechHPC we need to set LD_LIBRARY_PATH. If other env variables # need to be set, then we need to possibly update this. string(FIND "${_ENTRY}" "LD_LIBRARY_PATH=" _FOUND) if(NOT ${_FOUND} EQUAL -1) set(PARAVIEW_PYTHON_ENV_VARS ${_ENTRY}) endif() endforeach() string(REPLACE "paraview version " "" PARAVIEW_VERSION "${PARAVIEW_VERSION}") endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(ParaView REQUIRED_VARS PVPYTHON_EXEC VERSION_VAR PARAVIEW_VERSION) # Get Python environment variables execute_process( COMMAND ${PVPYTHON_EXEC} -m paraview.inspect OUTPUT_VARIABLE _OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE _RESULT ERROR_QUIET) if (_RESULT EQUAL 0) string(REPLACE "\n" ";" _OUTPUT "${_OUTPUT}") list(GET _OUTPUT 0 PARAVIEW_PYTHON_VERSION) list(GET _OUTPUT 1 PARAVIEW_PYTHONPATH) string(REPLACE "version: " "" PARAVIEW_PYTHON_VERSION "${PARAVIEW_PYTHON_VERSION}") string(REPLACE "pythonpath entry: " "" PARAVIEW_PYTHONPATH "${PARAVIEW_PYTHONPATH}") else() # If for whatever reason pvpython call didn't work, try another search get_filename_component(PVPYTHON_BINDIR ${PVPYTHON_EXEC} DIRECTORY) get_filename_component(PVPYTHON_BASEDIR ${PVPYTHON_BINDIR} DIRECTORY) file(GLOB_RECURSE PARAVIEW_PYTHONPATH ${PVPYTHON_BASEDIR} "${PVPYTHON_BASEDIR}/lib*/python*/site-packages/paraview/simple.py" ) find_file(PARAVIEW_PYTHONPATH NAMES "simple.py" PATHS "${PVPYTHON_BASEDIR}" PATH_SUFFIXES "/.*" REQUIRED) # go back up to the site-packages get_filename_component(PARAVIEW_PYTHONPATH ${PARAVIEW_PYTHONPATH} DIRECTORY) get_filename_component(PARAVIEW_PYTHONPATH ${PARAVIEW_PYTHONPATH} DIRECTORY) endif() ================================================ FILE: cmake/FindPythonModule.cmake ================================================ # From: https://github.com/ivansafrin/Polycode/ # Find if a Python module is installed # Found at http://www.cmake.org/pipermail/cmake/2011-January/041666.html # To use do: find_python_module(PyQt4 REQUIRED) # if required # or: find_python_module(PyQt4) # if optional, check PY_PyQt4_FOUND # if(PY_PyQt4_FOUND) # # do stuff... # endif() function(find_python_module module) # Terminate early if the package has already been found if(PY_${module}_FOUND) return() endif() cmake_parse_arguments(ARG "REQUIRED" "" "" ${ARGN}) # Try to import the module and get its location, if it's not already cached if(NOT PY_${module}_LOCATION) # A module's location is usually a directory, but for binary modules # it's a .so file. execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${PYTHONPATH} ${Python_EXECUTABLE} "-c" "import re, ${module}; print(re.compile('/__init__.py.*').sub('',${module}.__file__))" RESULT_VARIABLE _${module}_status OUTPUT_VARIABLE _${module}_location ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if(_${module}_status EQUAL 0) set(PY_${module}_LOCATION ${_${module}_location} CACHE STRING "Location of Python module ${module}") endif() endif() # Make `find_package_handle_standard_args` error if the package is not found if(ARG_REQUIRED) set(PY_${module}_FIND_REQUIRED TRUE) endif() find_package_handle_standard_args(PY_${module} REQUIRED_VARS PY_${module}_LOCATION) set(PY_${module}_FOUND ${PY_${module}_FOUND} PARENT_SCOPE) endfunction(find_python_module) ================================================ FILE: cmake/FindScotch.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Find Scotch: https://www.labri.fr/perso/pelegrin/scotch/ # If not in one of the default paths specify -D SCOTCH_ROOT=/path/to/Scotch # to search there as well. if(NOT SCOTCH_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(SCOTCH_ROOT "") set(SCOTCH_ROOT $ENV{SCOTCH_ROOT}) endif() # Find the Scotch include directory find_path(SCOTCH_INCLUDE_DIR scotch.h PATH_SUFFIXES include HINTS ${SCOTCH_ROOT}) find_library(SCOTCH_LIB NAMES scotch PATH_SUFFIXES lib64 lib HINTS ${SCOTCH_ROOT}) find_library(SCOTCH_ERR_LIB NAMES scotcherr PATH_SUFFIXES lib64 lib HINTS ${SCOTCH_ROOT}) set(SCOTCH_LIBRARIES "${SCOTCH_LIB};${SCOTCH_ERR_LIB}") set(SCOTCH_VERSION "") file(READ "${SCOTCH_INCLUDE_DIR}/scotch.h" SCOTCH_FIND_HEADER_CONTENTS) set(SCOTCH_MAJOR_PREFIX "#define SCOTCH_VERSION ") set(SCOTCH_MINOR_PREFIX "#define SCOTCH_RELEASE ") set(SCOTCH_PATCH_PREFIX "#define SCOTCH_PATCHLEVEL ") string(REGEX MATCH "${SCOTCH_MAJOR_PREFIX}[0-9]+" SCOTCH_MAJOR_VERSION "${SCOTCH_FIND_HEADER_CONTENTS}") string(REPLACE "${SCOTCH_MAJOR_PREFIX}" "" SCOTCH_MAJOR_VERSION "${SCOTCH_MAJOR_VERSION}") string(REGEX MATCH "${SCOTCH_MINOR_PREFIX}[0-9]+" SCOTCH_MINOR_VERSION "${SCOTCH_FIND_HEADER_CONTENTS}") string(REPLACE "${SCOTCH_MINOR_PREFIX}" "" SCOTCH_MINOR_VERSION "${SCOTCH_MINOR_VERSION}") string(REGEX MATCH "${SCOTCH_PATCH_PREFIX}[0-9]+" SCOTCH_SUBMINOR_VERSION "${SCOTCH_FIND_HEADER_CONTENTS}") string(REPLACE "${SCOTCH_PATCH_PREFIX}" "" SCOTCH_SUBMINOR_VERSION "${SCOTCH_SUBMINOR_VERSION}") set(SCOTCH_VERSION "${SCOTCH_MAJOR_VERSION}.${SCOTCH_MINOR_VERSION}.${SCOTCH_SUBMINOR_VERSION}" ) set(Scotch_VERSION ${SCOTCH_VERSION}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args( Scotch FOUND_VAR SCOTCH_FOUND REQUIRED_VARS SCOTCH_INCLUDE_DIR SCOTCH_LIBRARIES VERSION_VAR SCOTCH_VERSION) mark_as_advanced(SCOTCH_INCLUDE_DIR SCOTCH_LIBRARIES SCOTCH_MAJOR_VERSION SCOTCH_MINOR_VERSION SCOTCH_PATCH_VERSION SCOTCH_VERSION Scotch_VERSION) ================================================ FILE: cmake/FindSleef.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Find Sleef: https://github.com/shibatch/sleef # If not in one of the default paths specify -D SLEEF_ROOT=/path/to/Sleef # to search there as well. if(NOT SLEEF_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(SLEEF_ROOT "") set(SLEEF_ROOT $ENV{SLEEF_ROOT}) endif() # find the SLEEF include directory find_path(SLEEF_INCLUDE_DIR sleef.h PATH_SUFFIXES include HINTS ${SLEEF_ROOT}) find_library(SLEEF_LIBRARIES NAMES sleef PATH_SUFFIXES lib64 lib HINTS ${SLEEF_ROOT}) set(SLEEF_VERSION "") if (EXISTS "${SLEEF_INCLUDE_DIR}/sleef.h") file(READ "${SLEEF_INCLUDE_DIR}/sleef.h" SLEEF_FIND_HEADER_CONTENTS) set(SLEEF_MAJOR_PREFIX "#define SLEEF_VERSION_MAJOR ") set(SLEEF_MINOR_PREFIX "#define SLEEF_VERSION_MINOR ") set(SLEEF_PATCH_PREFIX "#define SLEEF_VERSION_PATCHLEVEL ") string(REGEX MATCH "${SLEEF_MAJOR_PREFIX}[0-9]+" SLEEF_MAJOR_VERSION "${SLEEF_FIND_HEADER_CONTENTS}") string(REPLACE "${SLEEF_MAJOR_PREFIX}" "" SLEEF_MAJOR_VERSION "${SLEEF_MAJOR_VERSION}") string(REGEX MATCH "${SLEEF_MINOR_PREFIX}[0-9]+" SLEEF_MINOR_VERSION "${SLEEF_FIND_HEADER_CONTENTS}") string(REPLACE "${SLEEF_MINOR_PREFIX}" "" SLEEF_MINOR_VERSION "${SLEEF_MINOR_VERSION}") string(REGEX MATCH "${SLEEF_PATCH_PREFIX}[0-9]+" SLEEF_SUBMINOR_VERSION "${SLEEF_FIND_HEADER_CONTENTS}") string(REPLACE "${SLEEF_PATCH_PREFIX}" "" SLEEF_SUBMINOR_VERSION "${SLEEF_SUBMINOR_VERSION}") set(SLEEF_VERSION "${SLEEF_MAJOR_VERSION}.${SLEEF_MINOR_VERSION}.${SLEEF_SUBMINOR_VERSION}" ) endif() set(Sleef_VERSION ${SLEEF_VERSION}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args( Sleef FOUND_VAR SLEEF_FOUND REQUIRED_VARS SLEEF_INCLUDE_DIR SLEEF_LIBRARIES VERSION_VAR SLEEF_VERSION) mark_as_advanced(SLEEF_INCLUDE_DIR SLEEF_LIBRARIES SLEEF_MAJOR_VERSION SLEEF_MINOR_VERSION SLEEF_PATCH_VERSION SLEEF_VERSION Sleef_VERSION) add_library(Sleef INTERFACE IMPORTED) set_property(TARGET Sleef PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${SLEEF_INCLUDE_DIR}) set_property(TARGET Sleef APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${SLEEF_LIBRARIES}) add_interface_lib_headers( TARGET Sleef HEADERS sleef.h ) ================================================ FILE: cmake/FindSpEC.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Optionally link SpEC libraries. Pass `SPEC_ROOT` to the CMake build # configuration to set up the following targets: # # - SpEC::Exporter: Functionality to load SpEC volume data and interpolate to # arbitrary points. if(NOT SPEC_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(SPEC_ROOT "") set(SPEC_ROOT $ENV{SPEC_ROOT}) endif() if (SPEC_ROOT) set(SPEC_EXPORTER_ROOT ${SPEC_ROOT}/Support/ApplyObservers/Exporter) else() set(SPEC_EXPORTER_ROOT "") endif() find_library( SPEC_PACKAGED_EXPORTER_LIB NAMES libPackagedExporter.a PATHS ${SPEC_EXPORTER_ROOT} NO_DEFAULT_PATHS ) find_file( SPEC_EXPORTER_FACTORY_OBJECTS NAMES ExporterFactoryObjects.o PATHS ${SPEC_EXPORTER_ROOT} NO_DEFAULT_PATHS ) find_path( SPEC_EXPORTER_INCLUDE_DIR NAMES Exporter.hpp PATHS ${SPEC_EXPORTER_ROOT} NO_DEFAULT_PATHS ) # SpEC needs MPI. # NOTE: You should use the same MPI as SpEC. At least the same distribution. So # mixing OpenMPI and MPICH would be bad. find_package(MPI COMPONENTS C) if (SPEC_PACKAGED_EXPORTER_LIB AND SPEC_EXPORTER_FACTORY_OBJECTS AND SPEC_EXPORTER_INCLUDE_DIR AND MPI_C_FOUND) add_library(SpEC::Exporter INTERFACE IMPORTED) target_include_directories( SpEC::Exporter INTERFACE ${SPEC_EXPORTER_INCLUDE_DIR}) add_interface_lib_headers( TARGET SpEC::Exporter HEADERS Exporter.hpp ) target_link_libraries( SpEC::Exporter INTERFACE MPI::MPI_C # The order of these next two lines is important ${SPEC_EXPORTER_FACTORY_OBJECTS} ${SPEC_PACKAGED_EXPORTER_LIB} ) # Deal with FFTW3 # # If it was dynamically linked into SpEC then we need to dynamically link it # into SpECTRE. set(_MACHINE_DEF_FILE ${SPEC_ROOT}/MakefileRules/this_machine.def) if (EXISTS ${_MACHINE_DEF_FILE}) file(STRINGS ${_MACHINE_DEF_FILE} _MACHINE_DEF) # Filter starting comments list(FILTER _MACHINE_DEF EXCLUDE REGEX "^[ ]*#") # Remove inline comments list(TRANSFORM _MACHINE_DEF REPLACE "[ ]*#.*" "") string(REGEX MATCH "FFTW_LIB[^;]+" _FFTW3_DEF "${_MACHINE_DEF}") string(FIND ${_FFTW3_DEF} "-lfftw3" _FOUND_FFTW3_SHARED) # If we found a shared FFTW lib in SpEC, find and link FFTW here if(NOT ${_FOUND_FFTW3_SHARED} STREQUAL "-1") find_package(FFTW REQUIRED) target_link_libraries(SpEC::Exporter INTERFACE FFTW::FFTW) endif() endif() endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args( SpEC REQUIRED_VARS SPEC_PACKAGED_EXPORTER_LIB SPEC_EXPORTER_FACTORY_OBJECTS SPEC_EXPORTER_INCLUDE_DIR ) ================================================ FILE: cmake/FindTCMALLOC.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Find tcmalloc: https://github.com/gperftools/gperftools # If not in one of the default paths specify -D TCMALLOC_ROOT=/path/to/tcmalloc # to search there as well. if(NOT TCMALLOC_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(TCMALLOC_ROOT "") set(TCMALLOC_ROOT $ENV{TCMALLOC_ROOT}) endif() # find the tcmalloc include directory find_path(TCMALLOC_INCLUDE_DIRS gperftools/tcmalloc.h PATH_SUFFIXES include HINTS ${TCMALLOC_ROOT}) find_library(TCMALLOC_LIBRARIES NAMES tcmalloc PATH_SUFFIXES lib64 lib HINTS ${TCMALLOC_ROOT}) set(TCMALLOC_VERSION "") if(EXISTS "${TCMALLOC_INCLUDE_DIRS}/gperftools/tcmalloc.h") # Extract version info from header file(READ "${TCMALLOC_INCLUDE_DIRS}/gperftools/tcmalloc.h" TCMALLOC_FIND_HEADER_CONTENTS) string(REGEX MATCH "#define TC_VERSION_MAJOR [0-9]+" TCMALLOC_MAJOR_VERSION "${TCMALLOC_FIND_HEADER_CONTENTS}") string(REPLACE "#define TC_VERSION_MAJOR " "" TCMALLOC_MAJOR_VERSION "${TCMALLOC_MAJOR_VERSION}") string(REGEX MATCH "#define TC_VERSION_MINOR [0-9]+" TCMALLOC_MINOR_VERSION "${TCMALLOC_FIND_HEADER_CONTENTS}") string(REPLACE "#define TC_VERSION_MINOR " "" TCMALLOC_MINOR_VERSION "${TCMALLOC_MINOR_VERSION}") set(TCMALLOC_VERSION "${TCMALLOC_MAJOR_VERSION}.${TCMALLOC_MINOR_VERSION}" ) else() message(WARNING "Failed to find file " "'${TCMALLOC_INCLUDE_DIRS}/gperftools/tcmalloc.h' " "while detecting the TCMALLOC version.") endif(EXISTS "${TCMALLOC_INCLUDE_DIRS}/gperftools/tcmalloc.h") include(FindPackageHandleStandardArgs) find_package_handle_standard_args( TCMALLOC FOUND_VAR TCMALLOC_FOUND REQUIRED_VARS TCMALLOC_INCLUDE_DIRS TCMALLOC_LIBRARIES VERSION_VAR TCMALLOC_VERSION ) mark_as_advanced(TCMALLOC_INCLUDE_DIRS TCMALLOC_LIBRARIES TCMALLOC_MAJOR_VERSION TCMALLOC_MINOR_VERSION TCMALLOC_VERSION) ================================================ FILE: cmake/Findccache.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_program(CCACHE_EXEC ccache) if (CCACHE_EXEC) # Get version execute_process(COMMAND ${CCACHE_EXEC} --version OUTPUT_VARIABLE CCACHE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) # Keep only first line of output string(REGEX REPLACE "\n.*" "" CCACHE_VERSION ${CCACHE_VERSION}) # Remove "ccache version " prefix string(REGEX REPLACE "ccache version " "" CCACHE_VERSION ${CCACHE_VERSION}) endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args( ccache REQUIRED_VARS CCACHE_EXEC VERSION_VAR CCACHE_VERSION ) mark_as_advanced(CCACHE_VERSION) ================================================ FILE: cmake/PrintUsefulCMakeInfo.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # First append useful info to BuildInfo.txt file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "CMake version: ${CMAKE_VERSION}\n" "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}\n" "CMAKE_CXX_LINK_FLAGS: ${CMAKE_CXX_LINK_FLAGS}\n" "CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}\n" "CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}\n" "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}\n" "CMAKE_C_FLAGS_DEBUG: ${CMAKE_C_FLAGS_DEBUG}\n" "CMAKE_C_FLAGS_RELEASE: ${CMAKE_C_FLAGS_RELEASE}\n" "CMAKE_Fortran_FLAGS: ${CMAKE_Fortran_FLAGS}\n" "CMAKE_Fortran_FLAGS_DEBUG: ${CMAKE_Fortran_FLAGS_DEBUG}\n" "CMAKE_Fortran_FLAGS_RELEASE: ${CMAKE_Fortran_FLAGS_RELEASE}\n" "CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}\n" "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}\n" "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}\n" "CMAKE_CXX_COMPILER_VERSION: ${CMAKE_CXX_COMPILER_VERSION}\n" "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}\n" "CMAKE_C_COMPILER_VERSION: ${CMAKE_C_COMPILER_VERSION}\n" "CMAKE_Fortran_COMPILER: ${CMAKE_Fortran_COMPILER}\n" "CMAKE_Fortran_COMPILER_VERSION: ${CMAKE_Fortran_COMPILER_VERSION}\n" "Python version: ${Python_VERSION}\n" ) # Then write (slightly expanded) useful info to command line message(STATUS "\nUseful Information:") message(STATUS "Git description: ${GIT_DESCRIPTION}") message(STATUS "Git branch: ${GIT_BRANCH}") message(STATUS "Git hash: ${GIT_HASH}") message(STATUS "Build directory: ${CMAKE_BINARY_DIR}") message(STATUS "Source directory: ${CMAKE_SOURCE_DIR}") message(STATUS "Bin directory: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") message(STATUS "CMake modules path: ${CMAKE_MODULE_PATH}") message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") message(STATUS "CMAKE_CXX_LINK_FLAGS: ${CMAKE_CXX_LINK_FLAGS}") message(STATUS "CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") message(STATUS "CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}") message(STATUS "CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") message(STATUS "BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}") message(STATUS "USE_PCH: ${USE_PCH}") message(STATUS "ASAN: ${ASAN}") message(STATUS "UBSAN_UNDEFINED: ${UBSAN_UNDEFINED}") message(STATUS "UBSAN_INTEGER: ${UBSAN_INTEGER}") if (Python_FOUND) message(STATUS "Python: ${Python_EXECUTABLE}") message(STATUS "Python version: ${Python_VERSION}") else() message(STATUS "Python: Not found") endif() message(STATUS "BUILD_PYTHON_BINDINGS: ${BUILD_PYTHON_BINDINGS}") if(CLANG_TIDY_BIN) message(STATUS "Found clang-tidy: ${CLANG_TIDY_BIN}") elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") message( STATUS "Could not find clang-tidy even though LLVM clang is installed" ) endif() if (CODE_COVERAGE) message(STATUS "Code coverage enabled. All prerequisites found:") message(STATUS " gcov: ${GCOV}") message(STATUS " lcov: ${LCOV}") message(STATUS " genhtml: ${GENHTML}") message(STATUS " sed: ${SED}") endif() if(DOXYGEN_FOUND) message(STATUS "Doxygen: ${DOXYGEN_EXECUTABLE}") else() message(STATUS "Doxygen: Not found, documentation cannot be built.") endif() ================================================ FILE: cmake/ProhibitInSourceBuild.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. string( REGEX REPLACE "^${CMAKE_SOURCE_DIR}/([^/]*)/?.*$" "\\1" SUBDIR_OF_SOURCE_DIR ${CMAKE_BINARY_DIR} ) set(PROHIBITED_SUBDIRS "cmake" "containers" "docs" "external" "src" "support" "tests" "tools") if ("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}" OR ${SUBDIR_OF_SOURCE_DIR} IN_LIST PROHIBITED_SUBDIRS) message(FATAL_ERROR "\n" "You attempted to build ${PROJECT_NAME} in the directory:\n" " ${CMAKE_BINARY_DIR}\n" "In-source builds, however, are not allowed. " "Please create a directory and run cmake from there, passing the path " "to the source directory as the last argument; for example:\n" " cd ${CMAKE_SOURCE_DIR}\n" " mkdir build\n" " cd build\n" " cmake [OPTIONS] ${CMAKE_SOURCE_DIR}\n" "You also need to remove the CMakeCache.txt file and the " "CMakeFiles directory in the source directory, or you will trigger " "this error again, even when doing an out-of-source build. Run:\n" " rm -r ${CMAKE_BINARY_DIR}/CMakeCache.txt " "${CMAKE_BINARY_DIR}/CMakeFiles\n" ) endif() ================================================ FILE: cmake/RunInputFileTest.sh ================================================ #!/bin/sh -e # Distributed under the MIT License. # See LICENSE.txt for details. # Positional arguments to this script: # - $1: executable name # - $2: path to input file # - $3: directory name # - $4: space-separated list of expected exit codes # - $5: "true" to check output files or "false" to skip the check # - $6: "true" to check output files are present or "false" to skip # - $7: additional command-line arguments forwarded to the executable # - $8: extra files to copy # Set up test directory test_dir=@CMAKE_BINARY_DIR@/tests/InputFiles/$3 rm -rf $test_dir mkdir -p $test_dir cd $test_dir input_file=$2 check_output_values=$5 check_output_present=$6 input_dir=`dirname $input_file` for file in $8; do cp $input_dir/$file $test_dir done # Run the executable restart= for expected_code in $4 ; do if [ -z "$restart" ] ; then @SPECTRE_TEST_RUNNER@ @CMAKE_BINARY_DIR@/bin/$1 --input-file \ $input_file $7 exit_code=$? restart=0 else if [ $exit_code -ne 2 ] ; then echo "Must restart after exit code 2" >&2 exit 1 fi @SPECTRE_TEST_RUNNER@ @CMAKE_BINARY_DIR@/bin/$1 \ +restart Checkpoints/Checkpoint_$(printf %04d $restart) exit_code=$? restart=$(expr $restart + 1) fi if [ $exit_code -ne $expected_code ]; then echo "ERROR: Exited with ${exit_code} instead of ${expected_code}" >&2 exit 1 fi done # Check output and clean up if [ "$check_output_values" = "true" ]; then @Python_EXECUTABLE@ @CMAKE_SOURCE_DIR@/tools/CheckOutputFiles.py \ --input-file $input_file --run-directory $test_dir \ --cmake-source-directory @CMAKE_SOURCE_DIR@ \ --cmake-bin-directory @CMAKE_BINARY_DIR@ \ || exit 1 fi if [ "$check_output_present" = "true" ]; then @Python_EXECUTABLE@ -m spectre.tools.CleanOutput \ --output-dir $test_dir $input_file \ || exit 1 fi rm -rf $test_dir ================================================ FILE: cmake/SetBuildType.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # CMake lets the user define CMAKE_BUILD_TYPE on the command line and recognizes # the values "Debug", "Release", "RelWithDebInfo", and "MinSizeRel", which add # specific compiler or linker flags. CMake's default behavior is to add no # additional compiler or linker flags if the user does not define # CMAKE_BUILD_TYPE on the command line, or passes an unrecognized value. # We add a sanity check that checks if CMAKE_BUILD_TYPE is one of the recognized # values, and we also set the CMAKE_BUILD_TYPE to "Debug" if the user does not # specify it on the command line. In addition, we add "None" as a valid value # for CMAKE_BUILD_TYPE whose behavior is to add no additional compiler or linker # flags. This is done by defining the following flags analagous to those used by # the other build types. Additional build types can be defined in a similar # manner by defining the appropriate flags, and adding the name of the build # type to CMAKE_BUILD_TYPES below. set(CMAKE_CXX_FLAGS_NONE "" CACHE STRING "Additional flags used by the compiler for Build type None." FORCE) set(CMAKE_C_FLAGS_NONE "" CACHE STRING "Additional flags used by the compiler for Build type None." FORCE) set(CMAKE_EXE_LINKER_FLAGS_NONE "" CACHE STRING "Additional flags used by the linker for Build type None." FORCE) set(CMAKE_Fortran_FLAGS_NONE "" CACHE STRING "Additional flags used by the compiler for Build type None." FORCE) set(CMAKE_MODULE_LINKER_FLAGS_NONE "" CACHE STRING "Additional flags used by the linker for Build type None." FORCE) set(CMAKE_SHARED_LINKER_FLAGS_NONE "" CACHE STRING "Additional flags used by the linker for Build type None." FORCE) set(CMAKE_STATIC_LINKER_FLAGS_NONE "" CACHE STRING "Additional flags used by the linker for Build type None." FORCE) mark_as_advanced( CMAKE_CXX_FLAGS_NONE CMAKE_C_FLAGS_NONE CMAKE_EXE_LINKER_FLAGS_NONE CMAKE_Fortran_FLAGS_NONE CMAKE_MODULE_LINKER_FLAGS_NONE CMAKE_SHARED_LINKER_FLAGS_NONE CMAKE_STATIC_LINKER_FLAGS_NONE ) set(CMAKE_BUILD_TYPES "Debug" "Release" "None" "RelWithDebInfo" "MinSizeRel") if (NOT CMAKE_BUILD_TYPE) message(STATUS "CMAKE_BUILD_TYPE not specified, setting to 'Debug'") set( CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build: ${CMAKE_BUILD_TYPES}" FORCE ) else() if(NOT ${CMAKE_BUILD_TYPE} IN_LIST CMAKE_BUILD_TYPES) message( FATAL_ERROR "\n" "Invalid value for CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}\n" "Valid values: ${CMAKE_BUILD_TYPES}\n" ) endif() message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") endif() ================================================ FILE: cmake/SetCxxStandard.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) ================================================ FILE: cmake/SetOutputDirectory.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Set the directory where the libraries and executables are placed # The default can be overridden by specifying # `-D CMAKE_RUNTIME_OUTPUT_DIRECTORY=/path/` if (NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) set( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/" CACHE STRING "Choose the directory where executables are placed" FORCE ) endif (NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) if (NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) set( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/" CACHE STRING "Choose the directory where shared libraries are placed" FORCE ) endif (NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) if (NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY) set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/" CACHE STRING "Choose the directory where static libraries are placed" FORCE ) endif (NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY) ================================================ FILE: cmake/SetupAllocator.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Always create the target and global property so that we don't need to # special case elsewhere in the code. set_property(GLOBAL PROPERTY SPECTRE_ALLOCATOR_LIBRARY "") add_library(SpectreAllocator INTERFACE) # At some point we had issues with jemalloc/tcmalloc when using the sanitizers. # If this becomes an issue again then we can re-add the if(NOT ASAN) block # around the allocator setup. option(MEMORY_ALLOCATOR "Which allocator to use: SYSTEM, TCMALLOC, JEMALLOC (default)" OFF) set(JEMALLOC_LIB_TYPE "") # We need to link custom allocators before we link anything else so that # any third-party libraries, which generally should all be built as shared # libraries, use the allocator that we use. Unfortunately, how exactly # CMake decides on the linking order is not clear when using # INTERFACE_LINK_LIBRARIES and targets. To this end, we set a global # property SPECTRE_ALLOCATOR_LIBRARY that contains the link flag to link # to the memory allocator. By linking to the allocator library first # explicitly in target_link_libraries CMake correctly places the allocator # library as the first entry in the link libraries. We also link to the # SpectreAllocator target to pull in any additional allocator-related # flags, such as include directories. # # Targets can grab the link flags using: # # get_property( # SPECTRE_ALLOCATOR_LIBRARY # GLOBAL # PROPERTY SPECTRE_ALLOCATOR_LIBRARY # ) # target_link_libraries(${TARGET_NAME} # PUBLIC # ${SPECTRE_ALLOCATOR_LIBRARY} # SpectreAllocator # ) # # These need to be the first call to target_link_libraries of the target. if("${MEMORY_ALLOCATOR}" STREQUAL "JEMALLOC" OR "${MEMORY_ALLOCATOR}" STREQUAL "OFF") include(SetupJemalloc) target_link_libraries( SpectreAllocator INTERFACE Jemalloc ) get_property( SPECTRE_ALLOCATOR_LIBRARY TARGET Jemalloc PROPERTY INTERFACE_LINK_LIBRARIES ) set_property(GLOBAL PROPERTY SPECTRE_ALLOCATOR_LIBRARY ${SPECTRE_ALLOCATOR_LIBRARY}) elseif("${MEMORY_ALLOCATOR}" STREQUAL "TCMALLOC") include(SetupTcmalloc) target_link_libraries( SpectreAllocator INTERFACE Tcmalloc ) get_property( SPECTRE_ALLOCATOR_LIBRARY TARGET Tcmalloc PROPERTY INTERFACE_LINK_LIBRARIES ) set_property(GLOBAL PROPERTY SPECTRE_ALLOCATOR_LIBRARY ${SPECTRE_ALLOCATOR_LIBRARY}) elseif(NOT "${MEMORY_ALLOCATOR}" STREQUAL "SYSTEM") message(FATAL_ERROR "Unknown memory allocator specified '${MEMORY_ALLOCATOR}'. " "Known options are:\n" " SYSTEM, TCMALLOC, JEMALLOC (default)") else() message(STATUS "Using system default memory allocator.") endif() ================================================ FILE: cmake/SetupAutodiff.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Find autodiff (https://github.com/autodiff/autodiff) # # Note that Boost also has an autodiff module, but it uses templates to # distinguish multiple variables. This means a std::array or Tensor can't hold # the Boost autodiff variables. For example, to evaluate a 2D function f(x, y), # the type for x would be fvar and the type for y would be the nested # fvar>. On the other hand, the autodiff library works with a # simpler autodiff::dual or autodiff::var type, which can be stored in a # std::array or Tensor. option(SPECTRE_AUTODIFF "Enable automatic differentiation" OFF) if (NOT SPECTRE_AUTODIFF) return() endif() # we assume the found autodiff is newer than the GIT_TAG below, # which has not been in autodiff's official release. find_package(autodiff QUIET) if (NOT autodiff_FOUND) if (NOT SPECTRE_FETCH_MISSING_DEPS) message(FATAL_ERROR "Could not find autodiff. If you want to fetch " "missing dependencies automatically, set SPECTRE_FETCH_MISSING_DEPS=ON.") endif() message(STATUS "Fetching autodiff") include(FetchContent) FetchContent_Declare(autodiff GIT_REPOSITORY https://github.com/autodiff/autodiff # Choose an unreleased version on top of v1.1.2 that makes dependence on # Eigen optional. GIT_TAG cc2aa5726fdbb258d097f87b97da3d1022f8394e ${SPECTRE_FETCHCONTENT_BASE_ARGS} ) set(AUTODIFF_BUILD_TESTS OFF CACHE BOOL "Build autodiff tests") set(AUTODIFF_BUILD_EXAMPLES OFF CACHE BOOL "Build autodiff examples") set(AUTODIFF_BUILD_PYTHON OFF CACHE BOOL "Build autodiff Python bindings") set(AUTODIFF_BUILD_DOCS OFF CACHE BOOL "Build autodiff documentation") FetchContent_MakeAvailable(autodiff) if (CMAKE_VERSION VERSION_LESS 3.25) get_target_property(AUTODIFF_IID autodiff INTERFACE_INCLUDE_DIRECTORIES) set_target_properties(autodiff PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${AUTODIFF_IID}") endif() endif() set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS autodiff::autodiff ) ================================================ FILE: cmake/SetupBlas.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(BLAS REQUIRED) message(STATUS "BLAS libs: " ${BLAS_LIBRARIES}) file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "BLAS_LIBRARIES: ${BLAS_LIBRARIES}\n" ) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS BLAS::BLAS ) # Check if we have found OpenBLAS and can disable its multithreading, since it # conflicts with Charm++ parallelism. Details: # https://github.com/xianyi/OpenBLAS/wiki/Faq#multi-threaded # We use `execute_process` instead of `try_compile` to avoid potentially slow # disk IO. set( CHECK_DISABLE_OPENBLAS_MULTITHREADING_SOURCE "extern \"C\" { void openblas_set_num_threads(int); }\n\ int main() { openblas_set_num_threads(1); }" ) string(REPLACE ";" " " BLAS_LIBRARIES_JOINED_WITH_SPACES "${BLAS_LIBRARIES}") execute_process( COMMAND bash -c "${CMAKE_CXX_COMPILER} ${BLAS_LIBRARIES_JOINED_WITH_SPACES} -x c++ - <<< $'\ ${CHECK_DISABLE_OPENBLAS_MULTITHREADING_SOURCE}' -o /dev/null" RESULT_VARIABLE CHECK_DISABLE_OPENBLAS_MULTITHREADING_RESULT ERROR_VARIABLE CHECK_DISABLE_OPENBLAS_MULTITHREADING_ERROR OUTPUT_QUIET ) if(${CHECK_DISABLE_OPENBLAS_MULTITHREADING_RESULT} EQUAL 0) set(DISABLE_OPENBLAS_MULTITHREADING ON) add_definitions(-DDISABLE_OPENBLAS_MULTITHREADING) message(STATUS "Disabled OpenBLAS multithreading") else() message(STATUS "BLAS vendor is probably not OpenBLAS. Make sure it doesn't " "try to do multithreading that might conflict with Charm++ parallelism.") endif() ================================================ FILE: cmake/SetupBlaze.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(USE_SLEEF "Use Sleef to add more vectorized instructions." OFF) if(USE_SLEEF) # Try to find Sleef to increase vectorization find_package(Sleef) endif() if(SLEEF_FOUND) message(STATUS "Sleef libs: ${SLEEF_LIBRARIES}") message(STATUS "Sleef incl: ${SLEEF_INCLUDE_DIR}") message(STATUS "Sleef vers: ${SLEEF_VERSION}") file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "Sleef version: ${SLEEF_VERSION}\n" ) endif() # Every time we've upgraded blaze compatibility in the past, we've had to change # vector code, so we should expect to need changes again on each subsequent # release, so we should specify an exact version requirement. However, Blaze # hasn't been consistent in naming releases (version 3.8.2 has 3.9.0 written # in Version.h). find_package(Blaze 3.8) if (NOT Blaze_FOUND) if (NOT SPECTRE_FETCH_MISSING_DEPS) message(FATAL_ERROR "Could not find Blaze. If you want to fetch " "missing dependencies automatically, set SPECTRE_FETCH_MISSING_DEPS=ON.") endif() message(STATUS "Fetching Blaze") include(FetchContent) FetchContent_Declare(Blaze URL https://bitbucket.org/blaze-lib/blaze/downloads/blaze-3.8.2.tar.gz ${SPECTRE_FETCHCONTENT_BASE_ARGS} ) # Configure Blaze CMake variables. Most configuration is done below. set(BLAZE_SHARED_MEMORY_PARALLELIZATION 0 CACHE INTERNAL "Blaze SMP mode") FetchContent_MakeAvailable(Blaze) set(BLAZE_INCLUDE_DIR ${blaze_SOURCE_DIR}) set(BLAZE_VERSION "3.8.2") endif() message(STATUS "Blaze incl: ${BLAZE_INCLUDE_DIR}") message(STATUS "Blaze vers: ${BLAZE_VERSION}") file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "Blaze version: ${BLAZE_VERSION}\n" ) find_package(BLAS REQUIRED) find_package(GSL REQUIRED) find_package(LAPACK REQUIRED) add_library(Blaze INTERFACE IMPORTED) set_property(TARGET Blaze PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${BLAZE_INCLUDE_DIR}) target_link_libraries( Blaze INTERFACE BLAS::BLAS GSL::gsl # for BLAS header LAPACK::LAPACK ) set(_BLAZE_USE_SLEEF 0) if(SLEEF_FOUND) target_link_libraries( Blaze INTERFACE Sleef ) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS Sleef ) set(_BLAZE_USE_SLEEF 1) endif() # If BLAZE_USE_STRONG_INLINE=ON, Blaze will use this keyword to increase the # likelihood of inlining. If BLAZE_USE_STRONG_INLINE=OFF, uses inline keyword # as a fallback. option(BLAZE_USE_STRONG_INLINE "Increase likelihood of Blaze inlining." ON) set(_BLAZE_USE_STRONG_INLINE 0) if(BLAZE_USE_STRONG_INLINE) set(_BLAZE_USE_STRONG_INLINE 1) endif() # If BLAZE_USE_ALWAYS_INLINE=ON, Blaze will use this keyword to force inlining. # If BLAZE_USE_ALWAYS_INLINE=OFF or if the platform being used cannot 100% # guarantee inlining, uses BLAZE_STRONG_INLINE as a fallback. option(BLAZE_USE_ALWAYS_INLINE "Force Blaze inlining." ON) set(_BLAZE_USE_ALWAYS_INLINE 0) if(BLAZE_USE_ALWAYS_INLINE) set(_BLAZE_USE_ALWAYS_INLINE 1) endif() # Configure Blaze. Some of the Blaze configuration options could be optimized # for the machine we are running on. See documentation: # https://bitbucket.org/blaze-lib/blaze/wiki/Configuration%20and%20Installation#!step-2-configuration target_compile_definitions(Blaze INTERFACE # - Enable external BLAS kernels BLAZE_BLAS_MODE=1 # - Use BLAS header from GSL. We could also find and include a (or # similarly named) header that may be distributed with the BLAS # implementation, but it's not guaranteed to be available and may conflict # with the GSL header. Since we use GSL anyway, it's easier to use their # BLAS header. BLAZE_BLAS_INCLUDE_FILE= # - Set default matrix storage order to column-major, since many of our # functions are implemented for column-major layout. This default reduces # conversions. BLAZE_DEFAULT_STORAGE_ORDER=blaze::columnMajor # - Disable SMP parallelization. This disables SMP parallelization for all # possible backends (OpenMP, C++11 threads, Boost, HPX): # https://bitbucket.org/blaze-lib/blaze/wiki/Serial%20Execution#!option-3-deactivation-of-parallel-execution BLAZE_USE_SHARED_MEMORY_PARALLELIZATION=0 # - Disable MPI parallelization BLAZE_MPI_PARALLEL_MODE=0 # - Using the default cache size, which may have been configured automatically # by the Blaze CMake configuration for the machine we are running on. We # could override it here explicitly to tune performance. # BLAZE_CACHE_SIZE # - Disable padding for dynamic matrices. # Blaze warns that this may decrease performance: # https://bitbucket.org/blaze-lib/blaze/src/c4d9e85414370e880e5e79c86e3c8d4d38dcde7a/blaze/config/Optimizations.h#lines-52 # We haven't tested this much, so we may want to try enabling padding again. # To support padding, explicit calls to LAPACK functions need to pass # `.spacing()` instead of `.rows()/.columns()` to the `LDA`, `LDB`, etc. # parameters (see `[matrix_spacing]` in `Test_Spectral.cpp`). BLAZE_USE_PADDING=0 # - Always enable non-temporal stores for cache optimization of large data # structures: https://bitbucket.org/blaze-lib/blaze/wiki/Configuration%20Files#!streaming-non-temporal-stores BLAZE_USE_STREAMING=1 # - Skip initializing default-constructed structures for fundamental types BLAZE_USE_DEFAULT_INITIALIZATON=0 # Use Sleef for vectorization of more math functions BLAZE_USE_SLEEF=${_BLAZE_USE_SLEEF} # Set inlining settings BLAZE_USE_STRONG_INLINE=${_BLAZE_USE_STRONG_INLINE} BLAZE_USE_ALWAYS_INLINE=${_BLAZE_USE_ALWAYS_INLINE} ) # We need to make sure `BlazeExceptions.hpp` is included. It is included in the # PCH (see tools/SpectrePch.hpp). If there's no PCH, we need to include it here. if (NOT USE_PCH) target_compile_options(Blaze INTERFACE "$<$:SHELL:-include Utilities/BlazeExceptions.hpp>") endif() add_interface_lib_headers( TARGET Blaze HEADERS blaze/math/CustomVector.h blaze/math/DynamicMatrix.h blaze/math/DynamicVector.h blaze/system/Optimizations.h blaze/system/Version.h blaze/util/typetraits/RemoveConst.h ) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS Blaze ) ================================================ FILE: cmake/SetupBoost.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(Boost 1.60.0 REQUIRED COMPONENTS program_options) # CMake versions don't set this consistently set(Boost_VERSION "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}") message(STATUS "Boost libraries: ${Boost_LIBRARIES}") message(STATUS "Boost include: ${Boost_INCLUDE_DIRS}") message(STATUS "Boost version: ${Boost_VERSION}") file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "Boost version: ${Boost_VERSION}\n" ) # Boost organizes targets as: # - Boost::boost is the header-only parts of Boost # - Boost::COMPONENT are the components that need linking, e.g. program_options add_interface_lib_headers( TARGET Boost::boost HEADERS boost/algorithm/string.hpp boost/config.hpp boost/core/demangle.hpp boost/functional/hash.hpp boost/integer/common_factor_rt.hpp boost/iterator/transform_iterator.hpp boost/iterator/zip_iterator.hpp boost/make_shared.hpp boost/math/interpolators/barycentric_rational.hpp boost/math/special_functions/binomial.hpp boost/math/tools/roots.hpp boost/multi_array.hpp boost/multi_array/base.hpp boost/multi_array/extent_gen.hpp boost/numeric/odeint.hpp boost/numeric/odeint/integrate/integrate_adaptive.hpp> boost/numeric/odeint/stepper/controlled_runge_kutta.hpp boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp boost/numeric/odeint/stepper/generation/make_dense_output.hpp boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp boost/parameter/name.hpp boost/preprocessor.hpp boost/preprocessor/arithmetic/dec.hpp boost/preprocessor/arithmetic/inc.hpp boost/preprocessor/arithmetic/sub.hpp boost/preprocessor/control/expr_iif.hpp boost/preprocessor/control/iif.hpp boost/preprocessor/control/while.hpp boost/preprocessor/list/adt.hpp boost/preprocessor/list/fold_left.hpp boost/preprocessor/list/fold_right.hpp boost/preprocessor/list/for_each.hpp boost/preprocessor/list/for_each_product.hpp boost/preprocessor/list/size.hpp boost/preprocessor/list/to_tuple.hpp boost/preprocessor/list/transform.hpp boost/preprocessor/logical/bitand.hpp boost/preprocessor/logical/bool.hpp boost/preprocessor/logical/compl.hpp boost/preprocessor/punctuation/comma_if.hpp boost/preprocessor/repetition/for.hpp boost/preprocessor/repetition/repeat.hpp boost/preprocessor/tuple/elem.hpp boost/preprocessor/tuple/enum.hpp boost/preprocessor/tuple/reverse.hpp boost/preprocessor/tuple/size.hpp boost/preprocessor/tuple/to_list.hpp boost/preprocessor/variadic/elem.hpp boost/preprocessor/variadic/to_list.hpp boost/range/combine.hpp boost/shared_ptr.hpp boost/tuple/tuple.hpp boost/tuple/tuple_comparison.hpp boost/variant.hpp boost/variant/get.hpp boost/variant/variant.hpp ) set_property( TARGET Boost::program_options APPEND PROPERTY PUBLIC_HEADER boost/program_options.hpp ) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS Boost::boost Boost::program_options ) # We disable thread safety of Boost::shared_ptr since it makes them faster # to use and we do not share them between threads. If a thread-safe # shared_ptr is desired it must be implemented to work with Charm++'s threads # anyway. set_property(TARGET Boost::boost APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS $<$:BOOST_SP_DISABLE_THREADS> ) # Some older versions of boost don't play nice with new versions of Clang and # GCC-12. We can just blanket enable the BOOST_NO_CXX98_FUNCTION_BASE macro, # which is what boost does anyway with newer versions. set_property(TARGET Boost::boost APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS $<$:BOOST_NO_CXX98_FUNCTION_BASE> ) # With newer versions of boost, sometimes there are internal boost warnings # about deprecated headers. This disables those as we have no control over what # boost does internally. set_property(TARGET Boost::boost APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS $<$:BOOST_ALLOW_DEPRECATED_HEADERS>) # Old versions of boost only enabled variadic macros for known compilers. # This changed in boost 1.75.0, where variadic macros are always enabled. # We enable this here manually for older versions of boost so the code compiles # with nvcc. if(Boost_VERSION VERSION_LESS 1.75.0) set_property(TARGET Boost::boost APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS $<$:BOOST_PP_VARIADICS=1>) endif() # Override the boost index type to match the STL for Boost.MultiArray # (std::ptrdiff_t to std::size_t) # Note: This header guard changed in Boost 1.73.0 if(Boost_VERSION VERSION_GREATER_EQUAL 1.73.0) set(BOOST_MULTI_ARRAY_TYPES_HEADER_GUARD BOOST_MULTI_ARRAY_TYPES_HPP) else() set(BOOST_MULTI_ARRAY_TYPES_HEADER_GUARD BOOST_MULTI_ARRAY_TYPES_RG071801_HPP) endif() set_property(TARGET Boost::boost APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS $<$:${BOOST_MULTI_ARRAY_TYPES_HEADER_GUARD}>) # Work around boost not building with clang 15 (fixed in boost 1.83.0) # (https://github.com/boostorg/functional/pull/21) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND BOOST_VERSION VERSION_LESS 1.83.0) if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "15.0.0" OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "15.0.0") target_compile_definitions(Boost::boost INTERFACE _HAS_AUTO_PTR_ETC=0) endif() endif() ================================================ FILE: cmake/SetupCCache.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Use CCache if available to speed up builds # # CCache is particularly useful for speeding up builds on CI, where we can share # the cache between runs. It is also very useful for general development. # # To support precompiled headers (PCH) we follow the recommendations in the # ccache docs: # https://ccache.dev/manual/latest.html#_precompiled_headers # Our requirements for CCache with PCH are: # - Works with GCC and Clang. # - Deleting and recreating the build directory retains ~100% cache hit rate. # - `make clean` retains ~100% cache hit rate. # - Changing the PCH file in tools/SpectrePch.hpp invalidates the cache. # - Sharing caches between runs on CI works. option(USE_CCACHE "Use CCache if available to speed up builds" ON) set(CCACHE_LAUNCHER_EXTRA_ENV_VARS "" CACHE STRING "Env vars for ccache") if(NOT USE_CCACHE) return() endif() find_package(ccache) if (NOT CCACHE_EXEC) return() endif() execute_process(COMMAND realpath ${CCACHE_EXEC} OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE REAL_CCACHE_EXEC) # Configure ccache with environment variables set(_CCACHE_LAUNCHER_ENV_VARS ${CCACHE_LAUNCHER_EXTRA_ENV_VARS} "CCACHE_SLOPPINESS=pch_defines,time_macros,include_file_mtime,\ include_file_ctime") # The `locale` sloppiness is only available in ccache 3.6 and later if (CCACHE_VERSION VERSION_GREATER_EQUAL 3.6) string(APPEND _CCACHE_LAUNCHER_ENV_VARS ",locale") endif() # Invoke compiler through ccache set(CMAKE_CXX_COMPILER_LAUNCHER ${_CCACHE_LAUNCHER_ENV_VARS} ${REAL_CCACHE_EXEC}) set(CMAKE_C_COMPILER_LAUNCHER ${CMAKE_CXX_COMPILER_LAUNCHER}) message(STATUS "Using ccache for compilation. It is invoked as: " "${CMAKE_CXX_COMPILER_LAUNCHER}") # Add `-fno-pch-timestamp` flag to Clang to support precompiled headers # (see https://ccache.dev/manual/4.8.2.html#_precompiled_headers) # Note that `CMAKE_CXX_COMPILE_OPTIONS_CREATE_PCH` isn't part of the public API # so this may break in the future. For a discussion see: # https://discourse.cmake.org/t/ccache-clang-and-fno-pch-timestamp/7253/6 if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") list(APPEND CMAKE_CXX_COMPILE_OPTIONS_CREATE_PCH -Xclang -fno-pch-timestamp) endif() ================================================ FILE: cmake/SetupCatch.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(Catch2 3.4.0) if (NOT Catch2_FOUND) if (NOT SPECTRE_FETCH_MISSING_DEPS) message(FATAL_ERROR "Could not find Catch2. If you want to fetch " "missing dependencies automatically, set SPECTRE_FETCH_MISSING_DEPS=ON.") endif() message(STATUS "Fetching Catch2") include(FetchContent) FetchContent_Declare(Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG v3.4.0 GIT_SHALLOW TRUE ${SPECTRE_FETCHCONTENT_BASE_ARGS} ) FetchContent_MakeAvailable(Catch2) endif() ================================================ FILE: cmake/SetupCharm.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. set(SPECTRE_REQUIRED_CHARM_VERSION 7.0.0) option(USE_SCOTCH_LB "Use the charm++ ScotchLB module" OFF) set(SCOTCHLB_COMPONENT "") if (USE_SCOTCH_LB) find_package(Scotch REQUIRED) message(STATUS "Scotch libs: " ${SCOTCH_LIBRARIES}) message(STATUS "Scotch incl: " ${SCOTCH_INCLUDE_DIR}) message(STATUS "Scotch vers: " ${SCOTCH_VERSION}) file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "Scotch version: ${SCOTCH_VERSION}\n" ) add_library(Scotch INTERFACE IMPORTED) set_property(TARGET Scotch APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${SCOTCH_INCLUDE_DIR}) set_property(TARGET Scotch APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${SCOTCH_LIBRARIES}) add_interface_lib_headers( TARGET Scotch HEADERS scotch.h ) set(SCOTCHLB_COMPONENT ScotchLB) endif() find_package(Charm ${SPECTRE_REQUIRED_CHARM_VERSION} REQUIRED COMPONENTS EveryLB ${SCOTCHLB_COMPONENT} ) if(CHARM_VERSION VERSION_LESS 8.0.0) message(NOTICE "Charm++ versions less than 8.0.0 have known bugs with \ element creation. Dynamic h-refinement is disabled.") endif() if (USE_SCOTCH_LB) target_link_libraries(Charmxx::charmxx INTERFACE Scotch) endif() if(CHARM_TRACE_PROJECTIONS OR CHARM_TRACE_PROJECTIONS) set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_OPTIONS -DSPECTRE_CHARM_PROJECTIONS -DSPECTRE_CHARM_NON_ACTION_WALLTIME_EVENT_ID=1000 ) endif() file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "Charm++ version: ${CHARM_VERSION}\n" "CHARM_COMPILER: ${CHARM_COMPILER}\n" "CHARM_SHARED_LIBS: ${CHARM_SHARED_LIBS}\n" "CHARM_BUILDING_BLOCKS:\n${CHARM_BUILDING_BLOCKS}\n" ) add_interface_lib_headers( TARGET Charmxx::charmxx HEADERS charm++.h ) add_interface_lib_headers( TARGET Charmxx::pup HEADERS pup.h pup_stl.h ) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS Charmxx::charmxx Charmxx::pup ) get_filename_component(CHARM_BINDIR ${CHARM_COMPILER} DIRECTORY) # In order to avoid problems when compiling in parallel we manually copy the # charmrun script over, rather than having charmc do it for us. configure_file( "${CHARM_BINDIR}/charmrun" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/charmrun" COPYONLY ) include(SetupCharmModuleFunctions) # Make sure Charm++ was patched. If not you can get thread local storage errors # when loading the python bindings. if(NOT APPLE AND CHARM_VERSION VERSION_EQUAL 7.0.0 AND BUILD_PYTHON_BINDINGS) # Check that the patch was applied: set(CHARM_CHECK_FILE "${CHARM_INCLUDE_DIR}/conv-mach-opt.sh") if (EXISTS ${CHARM_CHECK_FILE}) set(_CHARM_CMAKE_FILE_TO_CHECK ${CHARM_CHECK_FILE}) file(READ ${_CHARM_CMAKE_FILE_TO_CHECK} FILE_CONTENTS) set(_EXPECTED_TLS_STRING "-ftls-model=initial-exec") string(FIND "${FILE_CONTENTS}" ${_EXPECTED_TLS_STRING} _LOCATION_OF_TLS) if (NOT ${_LOCATION_OF_TLS} EQUAL -1) message(FATAL_ERROR "Found -ftls-model=initial-exec flag. " "It looks like you forgot to apply the Charm++ patch. " "This is necessary when using the python bindings.") endif() else() message(STATUS "Unable to check if Charm++ was patched. " "Missing file ${CHARM_CHECK_FILE}") endif() endif() ================================================ FILE: cmake/SetupCharmModuleFunctions.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Add a function to generate the charm interface files for the module. function(add_charm_module MODULE) # Arguments: # MODULE: Name of the Charm++ module. if (NOT TARGET module_All) # Target that will have all the Charm modules as dependencies add_custom_target(module_All) endif() set(_VERSION_SUFFIX "_v${CHARM_VERSION}") add_custom_command( OUTPUT ${MODULE}.decl.h ${MODULE}.def.h DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${MODULE}.ci COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/${MODULE}.ci ${MODULE}.ci COMMAND ${CHARM_COMPILER} -no-charmrun ${MODULE}.ci COMMAND ${CMAKE_SOURCE_DIR}/tools/patch_charm_modules.sh ${MODULE} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} `pwd` ${_VERSION_SUFFIX} ) add_custom_target( module_${MODULE} DEPENDS ${MODULE}.decl.h ${MODULE}.def.h ) add_dependencies( module_All module_${MODULE} ) endfunction() ================================================ FILE: cmake/SetupClangFormat.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(ClangFormat) if(CLANG_FORMAT_BIN AND EXISTS ${CMAKE_SOURCE_DIR}/.git AND Git_FOUND) get_filename_component(CLANG_FORMAT_NAME ${CLANG_FORMAT_BIN} NAME) add_custom_target( git-clang-format COMMAND export PATH=${CMAKE_SOURCE_DIR}/tools:$$PATH && cd ${CMAKE_SOURCE_DIR} && ${GIT_EXECUTABLE} ${CLANG_FORMAT_NAME} -f ) endif() ================================================ FILE: cmake/SetupClangTidy.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. if(NOT CLANG_TIDY_ROOT) # Need to set to empty to avoid warnings with --warn-uninitialized set(CLANG_TIDY_ROOT "") set(CLANG_TIDY_ROOT $ENV{CLANG_TIDY_ROOT}) endif() if(NOT CMAKE_CXX_CLANG_TIDY AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") string( REGEX MATCH "^[0-9]+.[0-9]+" LLVM_VERSION "${CMAKE_CXX_COMPILER_VERSION}" ) find_program( CLANG_TIDY_BIN NAMES "clang-tidy-${LLVM_VERSION}" "clang-tidy" HINTS ${CLANG_TIDY_ROOT} ) elseif(CMAKE_CXX_CLANG_TIDY) set(CLANG_TIDY_BIN "${CMAKE_CXX_CLANG_TIDY}") endif() if (CLANG_TIDY_BIN) message(STATUS "clang-tidy: ${CLANG_TIDY_BIN}") set(MODULES_TO_DEPEND_ON module_All Libsharp ) if (TARGET SpectrePch) list(APPEND MODULES_TO_DEPEND_ON SpectrePch) endif() configure_file( ${CMAKE_SOURCE_DIR}/tools/ClangTidyAll.sh ${CMAKE_BINARY_DIR}/ClangTidyAll.sh @ONLY IMMEDIATE ) add_custom_target( clang-tidy COMMAND ${CLANG_TIDY_BIN} --quiet -p ${CMAKE_BINARY_DIR} \${FILE} ) add_dependencies( clang-tidy ${MODULES_TO_DEPEND_ON} ) add_custom_target( clang-tidy-all COMMAND ${CMAKE_BINARY_DIR}/ClangTidyAll.sh \${NUM_THREADS} ) add_dependencies( clang-tidy-all ${MODULES_TO_DEPEND_ON} ) add_custom_target( clang-tidy-hash COMMAND ${CMAKE_SOURCE_DIR}/tools/ClangTidyHash.sh ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR} \${HASH} \${NUM_THREADS} ) add_dependencies( clang-tidy-hash ${MODULES_TO_DEPEND_ON} ) else() message(STATUS "clang-tidy: Not using clang or couldn't find clang-tidy.") endif() ================================================ FILE: cmake/SetupCxxFlags.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(DEBUG_SYMBOLS "Add -g to CMAKE_CXX_FLAGS if ON, -g0 if OFF." ON) option(OVERRIDE_ARCH "The architecture to use. Default is native." OFF) option(SPECTRE_DEBUG "Enable ASSERTs and other SPECTRE_DEBUG options" OFF) # Because of a bug in macOS on Apple Silicon, executables larger than 2GB in # size cannot run. This option minimizes executable size to avoid this bug. It # is enabled by default on Apple Silicon. set(_SPECTRE_OPTIMIZE_SIZE_DEFAULT OFF) if(APPLE AND "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64") set(_SPECTRE_OPTIMIZE_SIZE_DEFAULT ON) endif() option(SPECTRE_OPTIMIZE_SIZE "Optimize for executable size instead of speed" ${_SPECTRE_OPTIMIZE_SIZE_DEFAULT}) option(SPECTRE_DEBUG_Og "Compile Debug builds with -Og instead of -O0" OFF) if (CMAKE_BUILD_TYPE STREQUAL "Debug") set(SPECTRE_DEBUG ON) endif() if(${SPECTRE_DEBUG}) set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS SPECTRE_DEBUG) endif() option(SPECTRE_NAN_INIT "Initialize memory to NaN is various places" ${SPECTRE_DEBUG}) if(${SPECTRE_NAN_INIT}) set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS SPECTRE_NAN_INIT) endif() set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSPECTRE_DEBUG") if(${SPECTRE_OPTIMIZE_SIZE}) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Oz") elseif(${SPECTRE_DEBUG_Og}) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Og") set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -Og") endif() if(NOT ${DEBUG_SYMBOLS}) string(REPLACE "-g " "-g0 " CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) endif() # Always build with -g so we can view backtraces, etc. when production code # fails. This can be overridden by passing `-D DEBUG_SYMBOLS=OFF` to CMake if(${DEBUG_SYMBOLS}) set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_OPTIONS -g) endif(${DEBUG_SYMBOLS}) # Always compile only for the current architecture. This can be overridden # by passing `-D OVERRIDE_ARCH=THE_ARCHITECTURE` to CMake if(NOT "${OVERRIDE_ARCH}" STREQUAL "OFF") set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_OPTIONS # The -mno-avx512f flag is necessary to avoid a Blaze 3.8 bug. The flag # should be re-enabled when we can insist on Blaze 3.9 which will include # a fix that allows this vectorization flag again. $<$:-march=${OVERRIDE_ARCH} -mno-avx512f> $<$:-march=${OVERRIDE_ARCH} -mno-avx512f> $<$:-march=${OVERRIDE_ARCH} -mno-avx512f>) else() # Apple Silicon Macs do not support the -march flag or the -mno-avx512f flag if((NOT APPLE OR NOT "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64") # sometimes ARM architectures use the name "aarch64" AND NOT "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "aarch64" ) set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:-march=native -mno-avx512f> $<$:-march=native -mno-avx512f> $<$:-march=native -mno-avx512f>) endif() endif() # We are getting multiple types of linker warnings on macOS: # - "ranlib: archive library: tmp/libSpectrePchLib.a the table of contents is # empty (no object file members in the library define global symbols)": # Yes, some of our libs have no symbols. Doesn't seem like a problem. # - "-undefined dynamic_lookup may not work with chained fixups": # This warning appears when compiling Python bindings. Chained fixups were # introduced in AppleClang 13 and enabled by default in macOS 12. See these # upstream issues: # - CPython: https://github.com/python/cpython/issues/97524 # - Pybind11: https://github.com/pybind/pybind11/pull/4301 # - CMake: https://gitlab.kitware.com/cmake/cmake/-/issues/24044 # Disabling chained fixups with `-Wl-no_fixup_chains` leads to linker warnings # about inconsistent visibility settings in different translation units. We # probably have to wait for an upstream solution to this issue. # - "could not create compact unwind for SYMBOL: registers X and # Y not saved contiguously in frame": # We have seen these warnings on Apple Silicon chips. # Disabling compact unwind with the flags # -Wl,-keep_dwarf_unwind # -Wl,-no_compact_unwind # seems to work on some machines, but leads to segfaults on others. We haven't # investigated this in any more detail. # For now we just suppress these linker warnings altogether, since we haven't # encountered any problems with them and some are upstream issues. if(APPLE) target_link_options( SpectreFlags INTERFACE -Wl,-w ) endif() # We always want a detailed backtrace of template errors to make debugging them # easier set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:-ftemplate-backtrace-limit=0>) # Increase bracket depth for fold expressions # (see also https://github.com/llvm/llvm-project/issues/48973) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0) set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:-fbracket-depth=1024>) endif() # Disable cmath setting the error flag. This allows the compiler to more # aggressively vectorize code since it doesn't need to respect some global # state. set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:-fno-math-errno> $<$:-fno-math-errno> $<$:-fno-math-errno>) # Allow the compiler to transform divisions into multiplication by the # reciprocal. set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:-freciprocal-math> $<$:-freciprocal-math> $<$:-freciprocal-math>) # -ffp-exception-behavior=maytrap - By default, the LLVM optimizer assumes # floating point exceptions are ignored. # -fnon-call-exceptions - By default, GCC does not allow signal handlers to # throw exceptions. # Note: -ffp-exception-behavior is not supported on ARM64 architectures if((NOT APPLE OR NOT "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64") AND NOT "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "aarch64" ) create_c_flags_target( "-ffp-exception-behavior=maytrap;-fnon-call-exceptions" SpectreFpExceptions ) create_cxx_flags_target( "-ffp-exception-behavior=maytrap;-fnon-call-exceptions" SpectreFpExceptions ) target_link_libraries( SpectreFlags INTERFACE SpectreFpExceptions ) else() # On ARM64, we can't trap FP exceptions, so just enable non-call exceptions create_c_flags_target( "-fnon-call-exceptions" SpectreFpExceptions ) create_cxx_flags_target( "-fnon-call-exceptions" SpectreFpExceptions ) target_link_libraries( SpectreFlags INTERFACE SpectreFpExceptions ) endif() file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "SPECTRE_DEBUG: ${SPECTRE_DEBUG}\n" "SPECTRE_NAN_INIT: ${SPECTRE_NAN_INIT}\n" ) ================================================ FILE: cmake/SetupDoxygen.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Targets to preprocess the documentation # - Convert all `.ipynb` files in `docs/` to markdown, so they get picked up by # Doxygen. get_filename_component(_PY_BIN_DIR ${Python_EXECUTABLE} DIRECTORY) find_program(NBCONVERT jupyter-nbconvert HINTS ${_PY_BIN_DIR}) if (NBCONVERT STREQUAL "NBCONVERT-NOTFOUND") message(STATUS "jupyter-nbconvert not found. Preprocessing .ipynb files for \ documentation disabled.") else() message(STATUS "Found jupyter-nbconvert: ${NBCONVERT}") add_custom_target( doc-notebooks-to-markdown COMMAND find ${CMAKE_SOURCE_DIR}/docs -name "*.ipynb" | xargs ${NBCONVERT} --to markdown --log-level=WARN --output-dir ${CMAKE_BINARY_DIR}/docs/tmp/notebooks_md ) endif() find_package(Doxygen) if (DOXYGEN_FOUND) set(SPECTRE_DOXYGEN_GROUPS "${CMAKE_BINARY_DIR}/docs/tmp/GroupDefs.hpp") # The layout file is doxygen version dependent. There was a significant # change in version 1.9.8 to support C++ modules. Doxygen modules were # renamed topics. Minor changes in doxygen version may cause warnings # about the layout file, but can appear to cause no problems if(DOXYGEN_VERSION VERSION_LESS 1.9.8) set(DOXYGEN_LAYOUT_FILE "${PROJECT_SOURCE_DIR}/docs/config/DoxygenLayout_1_8_10.xml") else() set(DOXYGEN_LAYOUT_FILE "${PROJECT_SOURCE_DIR}/docs/config/DoxygenLayout_1_9_8.xml" ) endif() # For INPUT_FILTER in Doxyfile. Using Python instead of Perl here increases # docs generation time by ~25%. Runtimes are 102s (no filter), 108s (Perl) and # 135s (Python) at the time of writing (Mar 2022). find_package(Perl) set(SPECTRE_DOX_GENERATE_HTML "YES") set(SPECTRE_DOX_GENERATE_XML "NO") configure_file( docs/Doxyfile.in ${PROJECT_BINARY_DIR}/docs/DoxyfileHtml @ONLY IMMEDIATE ) # Configure file that contains doxygen groups configure_file(docs/GroupDefs.hpp ${SPECTRE_DOXYGEN_GROUPS}) # Construct the command that calls Doxygen set( GENERATE_DOCS_COMMAND "${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/docs/DoxyfileHtml" ) # Make sure the Doxygen version is compatible with the CSS, or print a # warning. Notes: # - We use https://github.com/jothepro/doxygen-awesome-css release v2.2.0, # which ensures compatibility with Doxygen v1.9.1 - v1.9.4 and v1.9.6. # When upgrading Doxygen, it's probably also a good idea to upgrade the CSS # files in `docs/config/`. # - The Doxygen release v1.9.1 has a bug so namespaces don't show up in # groups. It is fixed in v1.9.2. # - The Doxygen release v1.9.2 breaks the ordering of pages in the tree view # (sidebar). It is fixed in v1.9.3. if(DOXYGEN_VERSION VERSION_LESS 1.9.3) set(_DOX_WARNING "Your Doxygen version ${DOXYGEN_VERSION} may not be \ compatible with the stylesheet, so the documentation may look odd or not \ function correctly. Use Doxygen version 1.9.3 or higher.") message(STATUS ${_DOX_WARNING}) # The 'warning' in this message will fail the `doc-check` target (see below) set( GENERATE_DOCS_COMMAND "${GENERATE_DOCS_COMMAND} && echo 'WARNING: ${_DOX_WARNING}'" ) endif() # Construct the command that calls doxygen, but only outputs warnings with a # few lines of context to stderr. Fails with exit code 1 if warnings are # found. Remains silent and succeeds with exit code 0 if everything is fine. # We write this into a shell script to make it easier to append the # postprocessing command. set( GENERATE_AND_CHECK_DOCS_SCRIPT "\ #!/bin/sh\n\ ! (${GENERATE_DOCS_COMMAND}) 2>&1 | grep -A 6 -i 'warning' >&2\n" ) include(FindPythonModule) find_python_module(bs4) find_python_module(pybtex) if (PY_bs4_FOUND AND PY_pybtex_FOUND) # Construct the command that runs the postprocessing over the Doxygen HTML # output set( DOCS_POST_PROCESS_COMMAND "${Python_EXECUTABLE} \ ${CMAKE_SOURCE_DIR}/docs/config/postprocess_docs.py \ --html-dir ${PROJECT_BINARY_DIR}/docs/html \ --references-files ${CMAKE_SOURCE_DIR}/docs/References.bib \ ${CMAKE_SOURCE_DIR}/docs/Dependencies.bib" ) # Append postprocessing to doxygen commands # The commands are supposed to run the postprocessing even if the doc # generation failed with warnings, so that we output useful documentation # in any case. The commands exit successfully only if both generation and # postprocessing succeeded. set( GENERATE_DOCS_COMMAND "${GENERATE_DOCS_COMMAND} && ${DOCS_POST_PROCESS_COMMAND} -v" ) set( GENERATE_AND_CHECK_DOCS_SCRIPT "${GENERATE_AND_CHECK_DOCS_SCRIPT}\ generate_docs_exit=$?\n\ ${DOCS_POST_PROCESS_COMMAND} && exit \${generate_docs_exit}\n" ) else() message(WARNING "Doxygen documentation postprocessing is disabled because" " Python dependencies were not found:") if (NOT PY_bs4_FOUND) message(WARNING "BeautifulSoup4 missing. " "Install with: pip install beautifulsoup4") endif() if (NOT PY_pybtex_FOUND) message(WARNING "Pybtex missing. Install with: pip install pybtex") endif() endif() # Parse the command into a CMake list for the `add_custom_target` separate_arguments(GENERATE_DOCS_COMMAND) add_custom_target( doc COMMAND ${GENERATE_DOCS_COMMAND} DEPENDS ${PROJECT_BINARY_DIR}/docs/DoxyfileHtml ${SPECTRE_DOXYGEN_GROUPS} ) # Write the shell script to a file to call it in the `add_custom_target` file( WRITE ${PROJECT_BINARY_DIR}/docs/tmp/GenerateAndCheckDocs.sh ${GENERATE_AND_CHECK_DOCS_SCRIPT} ) add_custom_target( doc-check COMMAND sh ${PROJECT_BINARY_DIR}/docs/tmp/GenerateAndCheckDocs.sh DEPENDS ${PROJECT_BINARY_DIR}/docs/DoxyfileHtml ${SPECTRE_DOXYGEN_GROUPS} ) set(SPECTRE_DOX_GENERATE_HTML "NO") set(SPECTRE_DOX_GENERATE_XML "YES") configure_file( docs/Doxyfile.in ${PROJECT_BINARY_DIR}/docs/DoxyfileXml @ONLY IMMEDIATE ) add_custom_target( doc-xml COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/docs/DoxyfileXml DEPENDS ${PROJECT_BINARY_DIR}/docs/DoxyfileXml ${SPECTRE_DOXYGEN_GROUPS} ) if (TARGET doc-notebooks-to-markdown) add_dependencies(doc doc-notebooks-to-markdown) add_dependencies(doc-check doc-notebooks-to-markdown) add_dependencies(doc-xml doc-notebooks-to-markdown) endif() find_program(LCOV lcov) find_program(GENHTML genhtml) find_program(SED sed) # Use [coverxygen](https://github.com/psycofdj/coverxygen) to check the level # of documentation coverage. find_python_module(coverxygen) if (LCOV AND GENHTML AND SED AND PY_coverxygen_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git AND Git_FOUND) set(DOX_COVERAGE_OUTPUT "${CMAKE_BINARY_DIR}/docs/html/doc_coverage/") add_custom_target( doc-coverage COMMAND ${Python_EXECUTABLE} -m coverxygen --xml-dir ${CMAKE_BINARY_DIR}/docs/xml --src-dir ${CMAKE_SOURCE_DIR} --output ${CMAKE_BINARY_DIR}/docs/tmp/doc_coverage.info COMMAND ${LCOV} --remove ${CMAKE_BINARY_DIR}/docs/tmp/doc_coverage.info '${CMAKE_SOURCE_DIR}/src/Executables/*' '${CMAKE_SOURCE_DIR}/tests/*' '${CMAKE_SOURCE_DIR}/citelist' '${CMAKE_SOURCE_DIR}/[generated]' --output ${CMAKE_BINARY_DIR}/docs/tmp/doc_coverage.info COMMAND ${LCOV} --summary ${CMAKE_BINARY_DIR}/docs/tmp/doc_coverage.info COMMAND ${GENHTML} --legend --no-function-coverage --no-branch-coverage --title ${GIT_HASH} ${CMAKE_BINARY_DIR}/docs/tmp/doc_coverage.info -o ${DOX_COVERAGE_OUTPUT} COMMAND find ${DOX_COVERAGE_OUTPUT} -type f -print | xargs file | grep text | cut -f1 -d: | xargs ${SED} -i'.bak' 's/LCOV - code coverage report/ SpECTRE Documentation Coverage Report/g' COMMAND find ${DOX_COVERAGE_OUTPUT} -type f -print | xargs file | grep text | cut -f1 -d: | xargs ${SED} -i'.bak' 's^Test:^ Commit:^g' COMMAND find ${DOX_COVERAGE_OUTPUT} -type f -print | xargs file | grep text | cut -f1 -d: | xargs ${SED} -i'.bak' 's^\\\([a-z0-9]\\{40\\}\\\)^ \\1^g' # Delete backup files created by sed COMMAND find ${DOX_COVERAGE_OUTPUT} -type f -name \"*.bak\" -print | xargs file | grep text | cut -f1 -d: | xargs rm DEPENDS ${PROJECT_BINARY_DIR}/docs/DoxyfileXml ${SPECTRE_DOXYGEN_GROUPS} doc-xml # Set work directory for target WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "SpECTRE Documentation Coverage" ) endif() else(DOXYGEN_FOUND) message(WARNING "Doxygen is needed to build the documentation.") endif (DOXYGEN_FOUND) ================================================ FILE: cmake/SetupFormaline.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # When running formaline when SpECTRE was not built from a Git repository # we need a list of all the files and directories in the root of the source # directory that are tracked by Git. I.e. # git ls-tree --full-tree --name-only HEAD set(SPECTRE_FORMALINE_LOCATIONS .claude .clang-format .clang-tidy .claude .codecov.yaml .codex .devcontainer .dockerignore .github .gitignore citation.bib CITATION.cff cmake CMakeLists.txt containers docs external LICENSE.txt Metadata.yaml pyproject.toml README.md .skills setup.cfg src support tests tools ) find_package(Git) if(EXISTS ${CMAKE_SOURCE_DIR}/.git AND Git_FOUND) execute_process( COMMAND ${GIT_EXECUTABLE} ls-tree --full-tree --name-only HEAD WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE FORMALINE_GIT_FILES_TRACKED OUTPUT_STRIP_TRAILING_WHITESPACE ) string(REPLACE "\n" ";" FORMALINE_GIT_FILES_TRACKED "${FORMALINE_GIT_FILES_TRACKED}") # Check all elements in SPECTRE_FORMALINE_LOCATIONS are in # FORMALINE_GIT_FILES_TRACKED. We don't just check that the sorted lists # are equal because we want to be able to print out exactly which file # or directory is missing. foreach(FILE ${SPECTRE_FORMALINE_LOCATIONS}) list(FIND FORMALINE_GIT_FILES_TRACKED ${FILE} FOUND_FILE) if(${FOUND_FILE} EQUAL -1) message(FATAL_ERROR "Couldn't find the file or directory \"${FILE}\" in the " "source directory. You need to remove the entry \"${FILE}\" " "from the CMake variable SPECTRE_FORMALINE_LOCATIONS in " "cmake/SetupFormaline.cmake") endif() endforeach() # Check all elements in FORMALINE_GIT_FILES_TRACKED are in # SPECTRE_FORMALINE_LOCATIONS. We don't just check that the sorted lists # are equal because we want to be able to print out exactly which file # or directory is missing. foreach(FILE ${FORMALINE_GIT_FILES_TRACKED}) list(FIND SPECTRE_FORMALINE_LOCATIONS ${FILE} FOUND_FILE) if(${FOUND_FILE} EQUAL -1) message(FATAL_ERROR "Couldn't find the file or directory \"${FILE}\" in the " "CMake variable SPECTRE_FORMALINE_LOCATIONS in " "cmake/SetupFormaline.cmake. You need to add \"${FILE}\" " "to the CMake variable SPECTRE_FORMALINE_LOCATIONS in " "cmake/SetupFormaline.cmake") endif() endforeach() endif() option(USE_FORMALINE "Use Formaline to encode the source tree into executables and output files." ON) # APPLE instead of ${APPLE} is intentional if (APPLE) set(USE_FORMALINE OFF) endif (APPLE) if (USE_FORMALINE) # Create a variable that is space-delimited to insert into the Formaline # shell script string(REPLACE ";" " " SPECTRE_FORMALINE_LOCATIONS_SHELL "${SPECTRE_FORMALINE_LOCATIONS}") configure_file( ${CMAKE_SOURCE_DIR}/tools/Formaline.sh ${CMAKE_BINARY_DIR}/tmp/Formaline.sh @ONLY ) else() file(REMOVE ${CMAKE_BINARY_DIR}/tmp/Formaline.sh) endif() ================================================ FILE: cmake/SetupFortran.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(SPECTRE_Fortran_STATIC_LIBS "Link static versions of libgfortran and libquadmath" OFF) if(SPECTRE_Fortran_STATIC_LIBS) unset(CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES) find_library(gfortran NAMES libgfortran.a) find_library(quadmath NAMES libquadmath.a) endif() ================================================ FILE: cmake/SetupFuka.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(FUKA) if (FUKA_FOUND) file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "FUKA: ${FUKA_ROOT}\n" ) endif() ================================================ FILE: cmake/SetupGitHooks.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Allow disabling the Git hooks because if you are running the code in a # container the host may not have all the right things installed. option( USE_GIT_HOOKS "Set up the git hooks for sanity checks." ON) if(USE_GIT_HOOKS) # Check that the source dir is writable. If it is we set up git hooks, if not # then there probably won't be any commits anyway... EXECUTE_PROCESS(COMMAND test -w ${CMAKE_SOURCE_DIR} RESULT_VARIABLE CHECK_SOURCE_DIR_WRITABLE_RESULT) # The logic is inverted because shell if(NOT CHECK_SOURCE_DIR_WRITABLE_RESULT AND EXISTS ${CMAKE_SOURCE_DIR}/.git) find_package(ClangFormat) find_package(Git) # We use several client-side git hooks to ensure commits are correct as # early as possible. configure_file( ${CMAKE_SOURCE_DIR}/tools/Hooks/pre-commit.sh ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit @ONLY ) configure_file( ${CMAKE_SOURCE_DIR}/tools/Hooks/CheckFileSize.py ${CMAKE_SOURCE_DIR}/.git/hooks/CheckFileSize.py @ONLY ) endif() endif() ================================================ FILE: cmake/SetupGoldOrLldLinker.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(USE_LD "Override the default linker. Options are: ld, gold, lld" OFF) if (USE_LD) if("${USE_LD}" STREQUAL "gold") find_program(GNU_GOLD_LINKER "ld.gold") if (NOT GNU_GOLD_LINKER) message(FATAL_ERROR "ld.gold requested but could not find executable") endif() check_and_add_cxx_link_flag("-fuse-ld=gold") elseif("${USE_LD}" STREQUAL "lld") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") message(FATAL_ERROR "GCC does not support linking with LLD. " "If this has changed please remove this error message " "and submit a pull request.") endif() find_program(LLD_LINKER "ld.lld") if (NOT LLD_LINKER) message(FATAL_ERROR "ld.lld requested but could not find executable") endif() check_and_add_cxx_link_flag("-fuse-ld=lld") elseif(NOT "${USE_LD}" STREQUAL "ld") message(FATAL_ERROR "USE_LD must be one of 'ld', 'gold' or 'lld' but got '${USE_LD}'") endif() else() if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # GCC currently only supports linking with ld.gold, not ld.lld find_program(GNU_GOLD_LINKER "ld.gold") if (GNU_GOLD_LINKER) check_and_add_cxx_link_flag("-fuse-ld=gold") endif() else() find_program(LLD_LINKER "ld.lld") if (LLD_LINKER) check_and_add_cxx_link_flag("-fuse-ld=lld") else() find_program(GNU_GOLD_LINKER "ld.gold") if (GNU_GOLD_LINKER) check_and_add_cxx_link_flag("-fuse-ld=gold") endif() endif() endif() endif() ================================================ FILE: cmake/SetupGoogleBenchmark.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(GoogleBenchmark QUIET) if (${GoogleBenchmark_FOUND}) message(STATUS "Google Benchmark libs: " ${GoogleBenchmark_LIBRARIES}) message(STATUS "Google Benchmark incl: " ${GoogleBenchmark_INCLUDE_DIRS}) file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "Google Benchmark found\n" ) add_library(GoogleBenchmark INTERFACE IMPORTED) set_property(TARGET GoogleBenchmark PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${GoogleBenchmark_INCLUDE_DIRS}) set_property(TARGET GoogleBenchmark PROPERTY INTERFACE_LINK_LIBRARIES ${GoogleBenchmark_LIBRARIES}) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS GoogleBenchmark ) endif() ================================================ FILE: cmake/SetupGsl.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(GSL_STATIC "Link static versions of GNU Scientific Library" OFF) if(${GSL_STATIC}) set(_BACKUP_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") endif(${GSL_STATIC}) find_package(GSL REQUIRED) if(${GSL_STATIC}) set(CMAKE_FIND_LIBRARY_SUFFIXES ${_BACKUP_CMAKE_FIND_LIBRARY_SUFFIXES}) endif(${GSL_STATIC}) message(STATUS "GSL libs: ${GSL_LIBRARIES}") message(STATUS "GSL incl: ${GSL_INCLUDE_DIR}") message(STATUS "GSL vers: ${GSL_VERSION}") file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "GSL version: ${GSL_VERSION}\n" ) # Link external BLAS library. We don't need the GSL::gslcblas target. find_package(BLAS REQUIRED) target_link_libraries( GSL::gsl INTERFACE BLAS::BLAS ) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS GSL::gsl GSL::gslcblas ) ================================================ FILE: cmake/SetupHdf5.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(HDF5 REQUIRED COMPONENTS C) message(STATUS "HDF5 libs: " ${HDF5_C_LIBRARIES}) message(STATUS "HDF5 incl: " ${HDF5_C_INCLUDE_DIRS}) message(STATUS "HDF5 vers: " ${HDF5_VERSION}) if(NOT TARGET hdf5::hdf5) add_library(hdf5::hdf5 INTERFACE IMPORTED) set_target_properties( hdf5::hdf5 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${HDF5_C_INCLUDE_DIRS}" INTERFACE_LINK_LIBRARIES "${HDF5_C_LIBRARIES}" ) if(DEFINED HDF5_C_DEFINITIONS) set_target_properties( hdf5::hdf5 PROPERTIES INTERFACE_COMPILE_FLAGS "${HDF5_C_DEFINITIONS}" ) endif() endif() if(NOT TARGET HDF5::HDF5) add_library(HDF5::HDF5 INTERFACE IMPORTED) set_target_properties( HDF5::HDF5 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${HDF5_C_INCLUDE_DIRS}" INTERFACE_LINK_LIBRARIES "${HDF5_C_LIBRARIES}" ) if(DEFINED HDF5_C_DEFINITIONS) set_target_properties( HDF5::HDF5 PROPERTIES INTERFACE_COMPILE_FLAGS "${HDF5_C_DEFINITIONS}" ) endif() endif() if(HDF5_IS_PARALLEL) find_package(MPI COMPONENTS C) if(MPI_FOUND) target_link_libraries(hdf5::hdf5 INTERFACE MPI::MPI_C) target_link_libraries(HDF5::HDF5 INTERFACE MPI::MPI_C) else() message(WARNING "HDF5 is built with MPI support, but MPI was not found. " "You may encounter build issues with HDF5, such as missing headers.") endif() endif() if(HDF5_USE_STATIC_LIBRARIES) # If we are using static libraries for HDF5, try to use static libraries # for the libsz and transitive libaec dependency. These aren't very # common, while other dependencies like libz are, so we leave those # as shared library dependencies. get_target_property( _HDF5_INTERFACE_LINK_LIBS HDF5::HDF5 INTERFACE_LINK_LIBRARIES) string(FIND "${_HDF5_INTERFACE_LINK_LIBS}" "libsz.so" _LOCATION_OF_LIBSZ) if (NOT ${_LOCATION_OF_LIBSZ} EQUAL -1) find_library(_libsz NAMES libsz.a) if(_libsz) string(REPLACE "libsz.so" "libsz.a" _HDF5_INTERFACE_LINK_LIBS "${_HDF5_INTERFACE_LINK_LIBS}") find_library(_libaec NAMES libaec.a) if(_libaec) list(APPEND _HDF5_INTERFACE_LINK_LIBS ${_libaec}) endif() endif() endif() string(FIND "${_HDF5_INTERFACE_LINK_LIBS}" "libcrypto.so" _LOCATION_OF_LIBCRYPTO) if (NOT ${_LOCATION_OF_LIBCRYPTO} EQUAL -1) find_library(_libcrypto NAMES libcrypto.a) if(_libcrypto) string(REPLACE "libcrypto.so" "libcrypto.a" _HDF5_INTERFACE_LINK_LIBS "${_HDF5_INTERFACE_LINK_LIBS}") endif() endif() string(FIND "${_HDF5_INTERFACE_LINK_LIBS}" "libz.so" _LOCATION_OF_LIBZ) if (NOT ${_LOCATION_OF_LIBZ} EQUAL -1) find_library(_libz NAMES libz.a) if(_libz) string(REPLACE "libz.so" "libz.a" _HDF5_INTERFACE_LINK_LIBS "${_HDF5_INTERFACE_LINK_LIBS}") endif() endif() set_target_properties( HDF5::HDF5 PROPERTIES INTERFACE_LINK_LIBRARIES "${_HDF5_INTERFACE_LINK_LIBS}" ) endif() # Check if file locking API is available. The versions supporting this feature # are listed here: # https://github.com/HDFGroup/hdf5/blob/develop/doc/file-locking.md include(CheckCXXSourceCompiles) set(CMAKE_REQUIRED_LIBRARIES HDF5::HDF5) check_cxx_source_compiles( "#include \n\ int main() {\n\ const hid_t fapl_id = H5Pcopy(H5P_DEFAULT);\n\ H5Pset_file_locking(fapl_id, false, true);\n\ }" HDF5_SUPPORTS_SET_FILE_LOCKING) if(${HDF5_SUPPORTS_SET_FILE_LOCKING}) set_property( TARGET hdf5::hdf5 APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS HDF5_SUPPORTS_SET_FILE_LOCKING) else() message(WARNING "The HDF5 library does not support 'H5Pset_file_locking'. " "This means that simulations may crash when you read H5 files while " "the simulation is trying to access them. To avoid this, set the " "environment variable\n" " HDF5_USE_FILE_LOCKING=FALSE\n" "when running simulations, or load an HDF5 module that supports " "'H5Pset_file_locking'. Supporting versions are listed here:\n" "https://github.com/HDFGroup/hdf5/blob/develop/doc/file-locking.md") endif() include(CheckCXXSourceRuns) set(CMAKE_REQUIRED_LIBRARIES HDF5::HDF5) # Logic from src/Utilities/ErrorHandling/FloatingPointExceptions.cpp check_cxx_source_runs( [=[ #include #ifdef __APPLE__ #ifndef __arm64__ #define SPECTRE_FPE_CSR 1 #include #endif #else #define SPECTRE_FPE_FENV 1 #include #endif int main(int /*argc*/, char** /*argv*/) { #if SPECTRE_FPE_CSR _mm_setcsr(_MM_MASK_MASK & ~(_MM_MASK_OVERFLOW | _MM_MASK_INVALID | _MM_MASK_DIV_ZERO)); #elif SPECTRE_FPE_FENV feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); #endif H5Tcopy(H5T_NATIVE_DOUBLE); return 0; } ]=] HDF5_INIT_WITHOUT_FPES ) if(NOT HDF5_INIT_WITHOUT_FPES) message(FATAL_ERROR "The HDF5 library triggers FPEs during initialization. See upstream bug " "https://github.com/HDFGroup/hdf5/issues/3831. Either switch to an " "unaffected version or apply the patch referenced from that issue.") endif() set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS HDF5::HDF5 ) file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "HDF5 version: ${HDF5_VERSION}\n" ) # Find HDF5 tools get_filename_component(HDF5_TOOLS_DIR HDF5_DIFF_EXECUTABLE DIRECTORY) find_program(HDF5_REPACK_EXECUTABLE h5repack HINTS ${HDF5_TOOLS_DIR}) ================================================ FILE: cmake/SetupInformer.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Configure info from build to give access to unit test path, # SpECTRE version, etc. (things known at CMake time) configure_file( ${CMAKE_SOURCE_DIR}/src/Informer/InfoAtCompile.cpp ${CMAKE_BINARY_DIR}/Informer/InfoAtCompile.cpp ) option( STUB_EXECUTABLE_OBJECT_FILES "Replace executable object files with stubs to reduce disk usage." OFF ) set(WRAP_EXECUTABLE_LINKER_USE_STUB_OBJECT_FILES "false") if (STUB_EXECUTABLE_OBJECT_FILES) set(WRAP_EXECUTABLE_LINKER_USE_STUB_OBJECT_FILES "true") endif (STUB_EXECUTABLE_OBJECT_FILES) configure_file( ${CMAKE_SOURCE_DIR}/tools/WrapExecutableLinker.sh ${CMAKE_BINARY_DIR}/tmp/WrapExecutableLinker.sh @ONLY ) option( STUB_LIBRARY_OBJECT_FILES "Replace library object files with stubs to reduce disk usage." OFF ) set(WRAP_LIBRARY_LINKER_USE_STUB_OBJECT_FILES "false") if (STUB_LIBRARY_OBJECT_FILES) set(WRAP_LIBRARY_LINKER_USE_STUB_OBJECT_FILES "true") endif (STUB_LIBRARY_OBJECT_FILES) configure_file( ${CMAKE_SOURCE_DIR}/tools/WrapLibraryLinker.sh ${CMAKE_BINARY_DIR}/tmp/WrapLibraryLinker.sh @ONLY ) ================================================ FILE: cmake/SetupJemalloc.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(JEMALLOC REQUIRED) message(STATUS "jemalloc libs: " ${JEMALLOC_LIBRARIES}) message(STATUS "jemalloc incl: " ${JEMALLOC_INCLUDE_DIRS}) message(STATUS "jemalloc vers: " ${JEMALLOC_VERSION}) file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "jemalloc version: ${JEMALLOC_VERSION}\n" ) add_library(Jemalloc INTERFACE IMPORTED) set_property(TARGET Jemalloc APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${JEMALLOC_LIBRARIES}) set_property(TARGET Jemalloc PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${JEMALLOC_INCLUDE_DIRS}) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS Jemalloc ) # Determine whether we are using JEMALLOC as a shared or static library. # Since libraries can be named, e.g. libjemalloc.so.2 we just search for # the extension after stripping the directories. It's unlikely jemalloc # will rename themselves to "alloc.so" and then we'd have libs like # "alloc.so.a" get_filename_component( JEMALLOC_LIB_NAME ${JEMALLOC_LIBRARIES} NAME ) if(APPLE) string(FIND "${JEMALLOC_LIB_NAME}" ".dylib" FOUND_SHARED) else() string(FIND "${JEMALLOC_LIB_NAME}" ".so" FOUND_SHARED) endif() if(${FOUND_SHARED} STREQUAL -1) string(FIND "${JEMALLOC_LIB_NAME}" ".a" FOUND_STATIC) if(${FOUND_STATIC} EQUAL -1) message(FATAL_ERROR "Failed to determine whether JEMALLOC is a shared or " "static library. Found: ${JEMALLOC_LIBRARIES}") endif() set(JEMALLOC_LIB_TYPE STATIC) else() set(JEMALLOC_LIB_TYPE SHARED) endif() mark_as_advanced(JEMALLOC_LIB_TYPE) if("${JEMALLOC_LIB_TYPE}" STREQUAL STATIC) message(WARNING "It's probably a better idea to use jemalloc as a shared " "library. Statically linking jemalloc might work but has not been tested.") endif() ================================================ FILE: cmake/SetupKokkos.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(SPECTRE_KOKKOS "Use Kokkos" OFF) if(SPECTRE_KOKKOS) find_package(Kokkos) if (Kokkos_FOUND) # Found external Kokkos installation, so just check that a few important # features are enabled if (Kokkos_ENABLE_CUDA) # Allow constexpr functions to be called from device code # without the need for a device annotation. # See https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#constexpr-functions-and-function-templates if (NOT Kokkos_ENABLE_CUDA_CONSTEXPR) message(FATAL_ERROR "Kokkos_ENABLE_CUDA_CONSTEXPR must be ON. " "Please recompile Kokkos with this option enabled.") endif() # Allow CUDA code in static libs, see # https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#using-separate-compilation-in-cuda # We may have to look into LTO if this has a performance penalty. if (NOT Kokkos_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE) message(FATAL_ERROR "Kokkos_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE " "must be ON. Please recompile Kokkos with this option enabled.") endif() if (BUILD_SHARED_LIBS) message(FATAL_ERROR "Building with shared libs is not supported when " "building with CUDA support. Set BUILD_SHARED_LIBS=OFF.") endif() endif() # Kokkos_ENABLE_CUDA else() # Kokkos_FOUND # Kokkos not found, so we will try to fetch it. if (NOT SPECTRE_FETCH_MISSING_DEPS) message(FATAL_ERROR "Could not find Kokkos. If you want to fetch " "missing dependencies automatically, set SPECTRE_FETCH_MISSING_DEPS=ON.") endif() # Configure the Kokkos build set(Kokkos_ENABLE_AGGRESSIVE_VECTORIZATION ON CACHE BOOL "Kokkos aggressive vectorization") if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR SPECTRE_DEBUG) message(STATUS "Enabling Kokkos debug mode") set(Kokkos_ENABLE_DEBUG ON CACHE BOOL "Most general debug settings") set(Kokkos_ENABLE_DEBUG_BOUNDS_CHECK ON CACHE BOOL "Bounds checking on Kokkos views") set(Kokkos_ENABLE_DEBUG_DUALVIEW_MODIFY_CHECK ON CACHE BOOL "Sanity checks on Kokkos DualView") endif() if(Kokkos_ENABLE_CUDA) set(CMAKE_CUDA_STANDARD 20) set(CMAKE_CUDA_STANDARD_REQUIRED ON) enable_language(CUDA) find_package(CUDAToolkit REQUIRED) set(Kokkos_ENABLE_CUDA_CONSTEXPR ON CACHE BOOL "Enable constexpr in CUDA") set(Kokkos_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE ON CACHE BOOL "Enable relocatable device code in CUDA") if (BUILD_SHARED_LIBS) message(FATAL_ERROR "Building with shared libs is not supported when " "building with CUDA support. Set BUILD_SHARED_LIBS=OFF.") endif() endif() message(STATUS "Fetching Kokkos") include(FetchContent) FetchContent_Declare(Kokkos GIT_REPOSITORY https://github.com/kokkos/kokkos.git GIT_TAG 4.4.00 GIT_SHALLOW TRUE ${SPECTRE_FETCHCONTENT_BASE_ARGS} ) FetchContent_MakeAvailable(Kokkos) endif() endif() # Determine if the compiler is NVIDIA's nvcc (if not already determined by # Kokkos) if (NOT DEFINED KOKKOS_CXX_COMPILER_ID) execute_process( COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE _COMPILER_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) string(REPLACE "\n" " " _COMPILER_VERSION ${_COMPILER_VERSION}) string(FIND ${_COMPILER_VERSION} "nvcc" _COMPILER_IS_NVCC) if(${_COMPILER_IS_NVCC} GREATER -1) set(KOKKOS_CXX_COMPILER_ID "NVIDIA") else() set(KOKKOS_CXX_COMPILER_ID ${CMAKE_CXX_COMPILER_ID}) endif() endif() # Include CUDA as system headers to suppress warnings. NVCC seems to include # CUDA headers as `-I` instead of `-isystem` for some reason (as of # version 12.6). if (CUDAToolkit_INCLUDE_DIRS) create_cxx_flag_target( "-Xcompiler \"-isystem${CUDAToolkit_INCLUDE_DIRS}\"" SpectreCudaSystemInclude) target_link_libraries( SpectreWarnings INTERFACE SpectreCudaSystemInclude ) endif() ================================================ FILE: cmake/SetupLIBCXX.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if (NOT USE_LIBCXX) option(USE_LIBCXX "Use libc++ as standard library" OFF) endif() if (USE_LIBCXX) include(CheckCXXCompilerFlag) unset(CXX_FLAG_WORKS CACHE) set(CMAKE_REQUIRED_QUIET 1) check_cxx_compiler_flag("-stdlib=libc++" CXX_FLAG_WORKS) unset(CMAKE_REQUIRED_QUIET) # If we cannot use the -stdlib=libc++ flag directly we must find libc++ # explicity by searching on the file system if (CXX_FLAG_WORKS AND NOT LIBCXX_ROOT) message(STATUS "libc++: Compiler supports -stdlib=libc++, no need to find " "libc++ explicity. Specify `LIBCXX_ROOT` to use a specified version of " "libc++. If the specified version is not found we fall back to the " "system libc++, if available.") else() find_package(LIBCXX REQUIRED) set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}\ -L${LIBCXXABI_LIBRARIES} -L${LIBCXX_LIBRARIES}" ) include_directories(${LIBCXX_INCLUDE_DIRS}) message(STATUS "libc++ include: ${LIBCXX_INCLUDE_DIRS}") message(STATUS "libc++ libraries: ${LIBCXX_LIBRARIES}") endif() set(CMAKE_CXX_FLAGS "-stdlib=libc++ ${CMAKE_CXX_FLAGS}") option( LIBCXX_DEBUG "Enable debug mode for libc++ in Debug builds" OFF ) if(LIBCXX_DEBUG) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_LIBCPP_DEBUG=0") endif() endif() endif() ================================================ FILE: cmake/SetupLIBCXXCharm.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # We need to add the link flag after finding packages because adding a # compilation flag to the linker flags causes packages/libraries to not be # always be found correctly. if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND USE_LIBCXX) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++") endif() ================================================ FILE: cmake/SetupLIBXSMM.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(LIBXSMM 1.16.1) if (NOT LIBXSMM_FOUND) if (NOT SPECTRE_FETCH_MISSING_DEPS) message(FATAL_ERROR "Could not find LIBXSMM. If you want to fetch " "missing dependencies automatically, set SPECTRE_FETCH_MISSING_DEPS=ON.") endif() message(STATUS "Fetching LIBXSMM") # This FetchContent code is adapted from the libxsmm docs: # https://libxsmm.readthedocs.io/en/latest/#rules-for-building-libxsmm include(FetchContent) FetchContent_GetProperties(xsmm) if(NOT xsmm_POPULATED) # Need an unreleased version to be compatible with newer glibc versions FetchContent_Populate(xsmm GIT_REPOSITORY https://github.com/libxsmm/libxsmm.git GIT_TAG 10b7dc82b3c46157e76eb40e4e959555f895b24d SUBBUILD_DIR ${CMAKE_BINARY_DIR}/_deps/xsmm-subbuild SOURCE_DIR ${CMAKE_BINARY_DIR}/_deps/xsmm-src BINARY_DIR ${CMAKE_BINARY_DIR}/_deps/xsmm-build ) endif() set(LIBXSMMROOT ${xsmm_SOURCE_DIR}) file(GLOB _GLOB_XSMM_SRCS LIST_DIRECTORIES false CONFIGURE_DEPENDS ${LIBXSMMROOT}/src/*.c) list(REMOVE_ITEM _GLOB_XSMM_SRCS ${LIBXSMMROOT}/src/libxsmm_generator_gemm_driver.c) list(REMOVE_ITEM _GLOB_XSMM_SRCS ${LIBXSMMROOT}/src/libxsmm_binaryexport_generator.c) set(XSMM_INCLUDE_DIRS ${LIBXSMMROOT}/include) add_library(xsmm STATIC ${_GLOB_XSMM_SRCS}) target_include_directories(xsmm SYSTEM PUBLIC ${XSMM_INCLUDE_DIRS}) target_compile_definitions(xsmm PUBLIC LIBXSMM_DEFAULT_CONFIG) # Link BLAS find_package(BLAS REQUIRED) target_link_libraries(xsmm PUBLIC BLAS::BLAS) # Provide `Libxsmm` target add_library(Libxsmm ALIAS xsmm) endif() set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS Libxsmm ) ================================================ FILE: cmake/SetupLapack.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(LAPACK REQUIRED) message(STATUS "LAPACK libs: " ${LAPACK_LIBRARIES}) file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "LAPACK_LIBRARIES: ${LAPACK_LIBRARIES}\n" ) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS LAPACK::LAPACK ) ================================================ FILE: cmake/SetupLicenseInfo.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. set(_LIST_OF_3PLS Blaze Boost Brigand Catch2 Charm Gsl Hdf5 Jemalloc Libbacktrace Libsharp Libxsmm OpenBlas Pybind11 Xsimd YamlCpp ) file(READ "${CMAKE_SOURCE_DIR}/LICENSE.txt" SPECTRE_MIT_LICENSE) file(READ "${CMAKE_SOURCE_DIR}/external/Licenses/SpectreGpl3License.txt" SPECTRE_GPL3_LICENSE) set(SPECTRE_LICENSE_CXX_STRING " SpECTRE source code is distributed under the MIT License, while SpECTRE executables and libraries, generally machine code, is distributed under the GNU Public License v3, or GPL3. The SpECTRE source code is freely available at https://github.com/sxs-collaboration/spectre/ SpECTRE copyright for source, executables, libraries, and machine code is: Copyright 2017 - 2026 Simulating eXtreme Spacetimes Collaboration SpECTRE source code MIT license: ${SPECTRE_MIT_LICENSE} SpECTRE executable, library, and machine code license: ${SPECTRE_GPL3_LICENSE} Third Party Libraries: ") # Note: C++ compilers only need to support 65,000 characters in raw string # literals, so we split this over 3 strings. 1 for the SpECTRE licenses, # and two of the 3PLs. set(SPECTRE_3PL_CXX_STRING0 "") set(SPECTRE_3PL_CXX_STRING1 "") set(SPECTRE_3PL_DOX_STRING "${SPECTRE_LICENSE_CXX_STRING}") foreach(_3PL ${_LIST_OF_3PLS}) if(EXISTS "${CMAKE_SOURCE_DIR}/external/Licenses/${_3PL}Copyright.txt") file(READ "${CMAKE_SOURCE_DIR}/external/Licenses/${_3PL}Copyright.txt" _3PL_COPYRIGHT) else() set(_3PL_COPYRIGHT "") endif() file(READ "${CMAKE_SOURCE_DIR}/external/Licenses/${_3PL}License.txt" _3PL_LICENSE) string(COMPARE LESS ${_3PL} "Libbacktrace" _STRING_0_or_1) if(_STRING_0_or_1) set(SPECTRE_3PL_CXX_STRING0 "${SPECTRE_3PL_CXX_STRING0}${_3PL}\n${_3PL_COPYRIGHT}\nDistributed under \ the license\n${_3PL_LICENSE}\n\n\n") else() set(SPECTRE_3PL_CXX_STRING1 "${SPECTRE_3PL_CXX_STRING1}${_3PL}\n${_3PL_COPYRIGHT}\nDistributed under \ the license\n${_3PL_LICENSE}\n\n\n") endif() set(SPECTRE_3PL_DOX_STRING "${SPECTRE_3PL_DOX_STRING}###${_3PL}\n${_3PL_COPYRIGHT}\nDistributed under \ the license\n```\n${_3PL_LICENSE}\n```\n\n\n") endforeach() ================================================ FILE: cmake/SetupLinkTimeOptimization.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(SPECTRE_LTO "Use link-time optimization if available" OFF) include(CheckIPOSupported) check_ipo_supported(RESULT _RESULT OUTPUT _OUTPUT) if(_RESULT AND SPECTRE_LTO) option(SPECTRE_LTO_CORES "Number of cores to use for LTO" OFF) if (NOT SPECTRE_LTO_CORES) set(SPECTRE_LTO_CORES "auto") endif() target_link_options(SpectreFlags INTERFACE -flto=${SPECTRE_LTO_CORES}) message(STATUS "Link-time optimizations enabled with ${SPECTRE_LTO_CORES}") else() target_link_options(SpectreFlags INTERFACE -fno-lto) message(STATUS "Link-time optimizations disabled (no LTO)") endif() ================================================ FILE: cmake/SetupListTargets.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. add_custom_target( list-targets COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target help | grep -v " depend$" | grep -v " edit_cache$" | grep -v " module_" VERBATIM ) add_custom_target(targets COMMAND DEPENDS list-targets) add_custom_target(list COMMAND DEPENDS list-targets) ================================================ FILE: cmake/SetupNinjaColors.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. if ("${CMAKE_GENERATOR}" STREQUAL "Ninja") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$,$>: -fdiagnostics-color=always>) elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$,$>: -fcolor-diagnostics>) else () message( WARNING "Not sure how to get color output with" " Ninja and compiler id ${CMAKE_CXX_COMPILER_ID}") endif () endif () ================================================ FILE: cmake/SetupOpenMP.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(ENABLE_OPENMP "Enable OpenMP in some parts of the code" OFF) if (ENABLE_OPENMP) find_package(OpenMP COMPONENTS CXX) endif() ================================================ FILE: cmake/SetupPapi.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. if(NOT USE_PAPI) option(USE_PAPI "Search for and include PAPI" OFF) endif() # Do not set up PAPI again if it was already done once if(USE_PAPI AND NOT TARGET Papi) find_package(PAPI REQUIRED) add_library(Papi INTERFACE IMPORTED) set_property(TARGET Papi APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PAPI_INCLUDE_DIRS}) set_property(TARGET Papi APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "SPECTRE_USE_PAPI") set_property(TARGET Papi APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${PAPI_LIBRARIES}) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS Papi ) endif(USE_PAPI AND NOT TARGET Papi) ================================================ FILE: cmake/SetupParaView.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(ENABLE_PARAVIEW "Try to find ParaView to enable 3D rendering tools" OFF) if (NOT ENABLE_PARAVIEW) return() endif() find_package(ParaView REQUIRED) # Help `find_python_module` find ParaView if (PARAVIEW_PYTHONPATH) set(PY_paraview_LOCATION ${PARAVIEW_PYTHONPATH}/paraview) endif() ================================================ FILE: cmake/SetupPch.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Support for precompiled headers (PCH) # ===================================== # # Precompiled headers are a way to speed up compilation by precompiling # frequently used headers. # # We have the following requirements on the PCH: # - it must be rebuilt whenever anything it includes is changed. # - it must be removed when running `make clean` # - it must be generated before any object files are built that # use it # - it must be able to use flags from other targets (since in modern CMake # flags, etc. are propagated via targets) # - the correct flags to include the PCH must be propagated to any targets # that use the PCH. # # We use CMake's PCH support to accomplish this. It is documented here: # https://cmake.org/cmake/help/latest/command/target_precompile_headers.html. # # The PCH is generated by compiling a source file that includes all the headers # we want to precompile. These precompiled headers are listed in # `tools/SpectrePch.hpp`. # # Instructions for using the PCH: # ------------------------------- # # Targets can use the PCH generated for the `SpectrePch` library. They must also # link the `SpectrePchFlags` library so they compile with the same flags as the # PCH. Make sure to check the PCH exist before using them: # # if(TARGET SpectrePch) # target_precompile_headers(${TARGET_NAME} REUSE_FROM SpectrePch) # target_link_libraries(${TARGET_NAME} PRIVATE SpectrePchFlags) # endif() # This library tracks all compiler flags to build the PCH. Targets that use # the PCH must link this library so they compile with the same flags as the # PCH. add_library(SpectrePchFlags INTERFACE) target_link_libraries( SpectrePchFlags INTERFACE Blaze Brigand Charmxx::charmxx Charmxx::pup HDF5::HDF5 SpectreFlags SpectreKokkos ) # Targets can reuse the PCH generated for this library. They must also link # the `SpectrePchFlags` library. Notes: # - We store the PCH header in ${CMAKE_SOURCE_DIR}/tools so that it is not # accidentally included anywhere. # - We also store a source file that just includes the PCH header so the # library has something to compile. # - This is an object library because we don't need to actually link it, we # only need to build it so it generates the PCH. configure_file( ${CMAKE_SOURCE_DIR}/tools/SpectrePch.hpp ${CMAKE_BINARY_DIR} ) set(SPECTRE_PCH_HEADER ${CMAKE_BINARY_DIR}/SpectrePch.hpp) file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/SpectrePch.cpp CONTENT "#include \"${SPECTRE_PCH_HEADER}\"\n") add_library( SpectrePch OBJECT ${CMAKE_BINARY_DIR}/SpectrePch.cpp) target_precompile_headers( SpectrePch PRIVATE ${SPECTRE_PCH_HEADER} ) target_link_libraries( SpectrePch PRIVATE SpectrePchFlags ) ================================================ FILE: cmake/SetupPic.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Set up position independent code by default since this is required # for our python libraries. # # We cannot use CMake's set(CMAKE_POSITION_INDEPENDENT_CODE ON) # because that enables -fPIC in shared libraries and -fPIE on executables. # While what CMake does is technically the optimal thing to do, it means # we would need to generate two PCHs, one built with -fPIC and one with # -fPIE. More specifically, we'd need to generate one using a library target # and one using an executable target, which would double the amount of code # in SetupPch.cmake for a currently unknown benefit. set_property(TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:-fPIC> $<$:-fPIC> $<$:-fPIC>) ================================================ FILE: cmake/SetupProfiling.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(ENABLE_PROFILING "Enables various options to make profiling easier" OFF) option(KEEP_FRAME_POINTER "Add keep frame pointer for profiling" OFF) add_library(Profiling::KeepFramePointer IMPORTED INTERFACE) add_library(Profiling::EnableProfiling IMPORTED INTERFACE) if (KEEP_FRAME_POINTER OR ENABLE_PROFILING) set_property( TARGET Profiling::KeepFramePointer APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:-fno-omit-frame-pointer> $<$:-mno-omit-leaf-frame-pointer> ) endif() if (ENABLE_PROFILING) set_property( TARGET Profiling::EnableProfiling APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS $<$:SPECTRE_PROFILING> ) endif() target_link_libraries( SpectreFlags INTERFACE Profiling::EnableProfiling Profiling::KeepFramePointer ) ================================================ FILE: cmake/SetupPybind11.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(BUILD_PYTHON_BINDINGS "Build the python bindings for SpECTRE" ON) if(BUILD_PYTHON_BINDINGS) # Make sure to find Python first so it's consistent with pybind11 find_package(Python REQUIRED COMPONENTS Interpreter Development) # Try to find the pybind11-config tool to find pybind11's CMake config files find_program(PYBIND11_CONFIG_TOOL pybind11-config) set(PYBIND11_CMAKEDIR "") if(PYBIND11_CONFIG_TOOL) execute_process( COMMAND "${PYBIND11_CONFIG_TOOL}" "--cmakedir" OUTPUT_VARIABLE PYBIND11_CMAKEDIR OUTPUT_STRIP_TRAILING_WHITESPACE) message(STATUS "Found pybind11-config tool (${PYBIND11_CONFIG_TOOL}) and " "determined CMake dir: ${PYBIND11_CMAKEDIR}") endif() find_package(pybind11 2.7.0 REQUIRED HINTS ${PYBIND11_CMAKEDIR} ${SPECTRE_PYTHON_SITE_PACKAGES} ${Python_SITEARCH} ${Python_SITELIB} ${Python_STDARCH} ${Python_STDLIB} ) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS pybind11::headers ) message(STATUS "Pybind11 include: ${pybind11_INCLUDE_DIR}") endif() ================================================ FILE: cmake/SetupPypp.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # To run Python tests we need the development component (libs and include dirs). # It provides the `Python::Python` imported target. We find the interpreter # component as well to make sure the find is consistent with earlier finds that # only looked for the interpreter, possibly guided by the Python_EXECUTABLE # variable set by the user. find_package(Python REQUIRED COMPONENTS Interpreter Development) # CMake's FindPython has trouble finding NumPy when it isn't installed in the # Python executable's directory, and can't be given hints either (as of CMake # version 3.25). So we find NumPy ourselves (which isn't much different to # what FindPython does internally anyway). find_package(NumPy 1.10 REQUIRED) message(STATUS "NumPy incl: " ${NUMPY_INCLUDE_DIRS}) message(STATUS "NumPy vers: " ${NUMPY_VERSION}) file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "NumPy version: ${NUMPY_VERSION}\n" ) # Also check that SciPy is installed include(FindPythonModule) find_python_module(scipy REQUIRED) add_library(Python::NumPy INTERFACE IMPORTED) set_property(TARGET Python::NumPy PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${NUMPY_INCLUDE_DIRS}) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS Python::NumPy Python::Python ) ================================================ FILE: cmake/SetupSanitizers.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(ASAN "Add AddressSanitizer compile flags" OFF) # We handle the sanitizers using targets for the compile options, but modify # CMAKE_EXE_LINKER_FLAGS for the linker flags because the sanitizers should # only be linked into the final executable and CMake doesn't support linker # interface flags before CMake 3.13. add_library(Sanitizers IMPORTED INTERFACE) add_library(Sanitizers::Address IMPORTED INTERFACE) add_library(Sanitizers::UbInteger IMPORTED INTERFACE) add_library(Sanitizers::UbUndefined IMPORTED INTERFACE) if (ASAN) set_property( TARGET Sanitizers::Address APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:-fno-omit-frame-pointer -fsanitize=address> ) set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address" ) endif () option(UBSAN_UNDEFINED "Add UBSan undefined behavior compile flags" OFF) if (UBSAN_UNDEFINED) set_property( TARGET Sanitizers::UbUndefined APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:-fno-omit-frame-pointer -fsanitize=undefined> ) set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined" ) endif() option(UBSAN_INTEGER "Add UBSan unsigned integer overflow compile flags" OFF) if (UBSAN_INTEGER) set_property( TARGET Sanitizers::UbInteger APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$:-fno-omit-frame-pointer -fsanitize=integer> ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=integer" ) set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=integer" ) endif() target_link_libraries( SpectreFlags INTERFACE Sanitizers::Address Sanitizers::UbInteger Sanitizers::UbUndefined ) ================================================ FILE: cmake/SetupSpec.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(SpEC) # Make SpEC scripts available in Python. These can be used until we have ported # them to SpECTRE. if (SPEC_ROOT) set(PYTHONPATH "${SPEC_ROOT}/Support/Python:\ ${SPEC_ROOT}/Support/DatDataManip:${PYTHONPATH}") endif() if (NOT SpEC_FOUND) return() endif() file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "SpEC exporter: ${SPEC_EXPORTER_ROOT}\n" ) ================================================ FILE: cmake/SetupSpectreInlining.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(SPECTRE_USE_ALWAYS_INLINE "Force SpECTRE inlining." ON) set(_SPECTRE_USE_ALWAYS_INLINE 0) if(SPECTRE_USE_ALWAYS_INLINE) set(_SPECTRE_USE_ALWAYS_INLINE 1) endif() set_property( TARGET SpectreFlags APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS $<$:SPECTRE_USE_ALWAYS_INLINE=${_SPECTRE_USE_ALWAYS_INLINE}> ) ================================================ FILE: cmake/SetupSphinx.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Setup Sphinx to generate documentation for our Python modules. The HTML output # is placed in docs/html/py/ so we can link to it from Doxygen. # We have also experimented with generating our C++ documentation with Sphinx. # See issue: https://github.com/sxs-collaboration/spectre/issues/2138 set(SPHINX_SOURCE ${CMAKE_BINARY_DIR}/docs/sphinx) set(SPHINX_BUILD ${CMAKE_BINARY_DIR}/docs/html/py) configure_file( ${CMAKE_SOURCE_DIR}/docs/conf.py ${SPHINX_SOURCE}/conf.py @ONLY ) configure_file( ${CMAKE_SOURCE_DIR}/docs/index.rst ${SPHINX_SOURCE}/index.rst ) configure_file( ${CMAKE_SOURCE_DIR}/docs/cli.rst ${SPHINX_SOURCE}/cli.rst ) file( COPY ${CMAKE_SOURCE_DIR}/docs/_templates DESTINATION ${SPHINX_SOURCE} ) add_custom_target(py-docs COMMAND ${CMAKE_COMMAND} -E env ${CMAKE_BINARY_DIR}/bin/python-spectre -m sphinx -b html ${SPHINX_SOURCE} ${SPHINX_BUILD} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating Python documentation" ) add_dependencies(py-docs all-pybindings) ================================================ FILE: cmake/SetupStl.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Create an C++ standard library target for tracking dependencies # through includes throughout SpECTRE. if(NOT TARGET Stl) add_library(Stl INTERFACE IMPORTED) add_interface_lib_headers( TARGET Stl HEADERS algorithm any array atomic barrier bit bitset cassert cctype cerrno cfenv cfloat charconv chrono cinttypes climits clocale cmath codecvt compare complex concepts condition_variable coroutine csetjmp csignal cstdarg cstddef cstdint cstdio cstdlib cstring ctime cuchar cwchar cwctype deque exception execution format forward_list fstream functional future initializer_list iomanip ios iosfwd iostream istream iterator latch limits list locale map memory memory_resource mutex new numbers numeric optional ostream queue random ranges ratio regex scoped_allocator semaphore set shared_mutex source_location span sstream stack stdexcept stop_token streambuf string string_view strstream syncstream system_error thread tuple type_traits typeindex typeinfo unordered_map unordered_set utility valarray variant vector version # UNIX/Linux specific headers dirent.h libgen.h sys/stat.h sys/types.h unistd.h xmmintrin.h ) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS Stl ) endif(NOT TARGET Stl) ================================================ FILE: cmake/SetupTcmalloc.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(TCMALLOC REQUIRED) message(STATUS "tcmalloc libs: " ${TCMALLOC_LIBRARIES}) message(STATUS "tcmalloc incl: " ${TCMALLOC_INCLUDE_DIRS}) file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "tcmalloc version: ${TCMALLOC_VERSION}\n" ) add_library(Tcmalloc INTERFACE IMPORTED) set_property(TARGET Tcmalloc APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${TCMALLOC_LIBRARIES}) set_property(TARGET Tcmalloc PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${TCMALLOC_INCLUDE_DIRS}) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS Tcmalloc ) ================================================ FILE: cmake/SetupXsimd.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # To turn this off, one should provide an alternative # SIMD backend that supports elementary functions # or the auto-differentiation in SpECTRE ceases to # work option(USE_XSIMD "Use xsimd if it is available" ON) if(USE_XSIMD) find_package(xsimd QUIET) if (NOT xsimd_FOUND) if (NOT SPECTRE_FETCH_MISSING_DEPS) message(FATAL_ERROR "Could not find xsimd. If you want to fetch " "missing dependencies automatically, set SPECTRE_FETCH_MISSING_DEPS=ON.") endif() message(STATUS "Fetching xsimd") include(FetchContent) FetchContent_Declare(xsimd GIT_REPOSITORY https://github.com/xtensor-stack/xsimd GIT_TAG 13.2.0 ${SPECTRE_FETCHCONTENT_BASE_ARGS} ) FetchContent_MakeAvailable(xsimd) set(xsimd_INCLUDE_DIRS ${xsimd_SOURCE_DIR}/include) set(xsimd_VERSION "13.2.0") if (NOT CMAKE_VERSION VERSION_GREATER_EQUAL 3.25) get_target_property(XSIMD_IID xsimd INTERFACE_INCLUDE_DIRECTORIES) set_target_properties(xsimd PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${XSIMD_IID}") endif() endif() if(xsimd_VERSION VERSION_LESS 11.0.1) message(FATAL_ERROR "xsimd must be at least 11.0.1, got ${xsimd_VERSION}") endif() message(STATUS "xsimd incld: ${xsimd_INCLUDE_DIRS}") message(STATUS "xsimd vers: ${xsimd_VERSION}") file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "xsimd version: ${xsimd_VERSION}\n" ) add_interface_lib_headers( TARGET xsimd HEADERS xsimd/xsimd.hpp ) # As long as we want xsimd support to be optional we need to be # able to figure out if we have it available. # # To enable use with Blaze, add: # -DBLAZE_USE_XSIMD=1 target_compile_definitions( xsimd INTERFACE $<$:SPECTRE_USE_XSIMD> ) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS xsimd ) # Currently we still have some compatibility bugs to sort out between Blaze # and xsimd. Once that's done we will enable combining the two. # # target_link_libraries( # Blaze # INTERFACE # xsimd # ) endif() ================================================ FILE: cmake/SetupYamlCpp.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. find_package(YAML_CPP NAMES yaml-cpp) if (NOT YAML_CPP_FOUND) if (NOT SPECTRE_FETCH_MISSING_DEPS) message(FATAL_ERROR "Could not find yaml-cpp. If you want to fetch " "missing dependencies automatically, set SPECTRE_FETCH_MISSING_DEPS=ON.") endif() message(STATUS "Fetching yaml-cpp") include(FetchContent) FetchContent_Declare(yaml-cpp GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git GIT_TAG 0.8.0 GIT_SHALLOW TRUE ${SPECTRE_FETCHCONTENT_BASE_ARGS} ) FetchContent_MakeAvailable(yaml-cpp) endif() # New versions of yaml-cpp define the target `yaml-cpp::yaml-cpp`. Old versions # define the deprecated target `yaml-cpp`. if (NOT TARGET yaml-cpp::yaml-cpp) add_library(yaml-cpp::yaml-cpp INTERFACE IMPORTED) target_link_libraries(yaml-cpp::yaml-cpp INTERFACE yaml-cpp) endif() set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS yaml-cpp::yaml-cpp ) ================================================ FILE: cmake/SpectreAddCatchTests.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # # This file contains functions used by CMake to add Catch tests to CTest. # # Catch is a testing framework available on Github: # https://github.com/philsquared/Catch # It supports a variety of different styles of tests including BDD and fixture # tests. # # Usage # ===== # To run the tests, type 'ctest' in the build directory. You can specify # a regex to match the test name using 'ctest -R Unit.Blah', or run all # tests with a certain tag using 'ctest -L tag' # # Attributes # ========== # Attributes allow you to modify properties of the test. Attributes are # specified as follows: # // [[TimeOut, 10]] # // [[OutputRegex, A regular expression that is expected to match the output # // from the test]] # SPECTRE_TEST_CASE("Unit.Blah", "[Unit]") { # # Note the space after the comma! # # Available attributes are: # TimeOut - override the default timeout and set the timeout to N seconds. This # should be set very sparingly since unit tests are designed to be # short. If your test is too long you should consider testing smaller # portions of the code if possible, or writing an integration test # instead. # OutputRegex - When testing failure modes the exact error message must be # tested, not just that the test failed. Since the string passed # is a regular expression you must escape any regex tokens. For # example, to match "some (word) and" you must specify the # string "some \(word\) and". add_custom_target(unit-tests) spectre_define_test_timeout_factor_option(UNIT "unit") # Environment variables for test set(_CATCH_TEST_ENV_VARS "") # - Disable ASAN's leak sanitizer because Charm++ has false positives list(APPEND _CATCH_TEST_ENV_VARS "ASAN_OPTIONS=detect_leaks=0") # - Set PYTHONPATH to find Python modules list(APPEND _CATCH_TEST_ENV_VARS "PYTHONPATH=${PYTHONPATH}") # Main function - the only one designed to be called from outside this module. function(spectre_add_catch_tests TEST_TARGET) get_target_property(SOURCE_FILES ${TEST_TARGET} SOURCES) list(FILTER SOURCE_FILES EXCLUDE REGEX "TestMain.*$") # For each of the source files, we use spectre_parse_file to find all the # Catch tests inside the source file and add them to CTest. # We ignore the Charm++ generated header files. file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/tmp") unset(ABSOLUTE_SOURCE_FILES) foreach (SOURCE_FILE ${SOURCE_FILES}) string(REGEX MATCH ".*(decl.h|def.h)" CHARM_INTERFACE_FILE "${SOURCE_FILE}") if (NOT CHARM_INTERFACE_FILE) if (NOT IS_ABSOLUTE ${SOURCE_FILE}) set(SOURCE_FILE ${CMAKE_CURRENT_LIST_DIR}/${SOURCE_FILE}) endif() set(ABSOLUTE_SOURCE_FILES "${ABSOLUTE_SOURCE_FILES};${SOURCE_FILE}") endif() endforeach() execute_process( COMMAND ${Python_EXECUTABLE} ${CMAKE_SOURCE_DIR}/cmake/SpectreParseTests.py ${ABSOLUTE_SOURCE_FILES} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/tmp RESULT_VARIABLE PARSED_TESTS_SUCCESSFULLY) if (${PARSED_TESTS_SUCCESSFULLY} GREATER 0) message(FATAL_ERROR "Failed to parse test files") endif() set_property(GLOBAL PROPERTY SPECTRE_FAILURE_TESTS_PROPERTY "") foreach (SOURCE_FILE ${ABSOLUTE_SOURCE_FILES}) spectre_parse_file(${SOURCE_FILE} ${TEST_TARGET}) endforeach () get_property( SPECTRE_FAILURE_TESTS GLOBAL PROPERTY SPECTRE_FAILURE_TESTS_PROPERTY) set_property(GLOBAL PROPERTY SPECTRE_FAILURE_TESTS_PROPERTY "") # Generate shell script that runs all non-failure tests manually string(REPLACE ";" " " SPECTRE_FAILURE_TESTS "${SPECTRE_FAILURE_TESTS}") file(WRITE "${CMAKE_BINARY_DIR}/tmp/NonFailureTests${TEST_TARGET}.sh" "#!/bin/bash -e\n" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TEST_TARGET} ${SPECTRE_FAILURE_TESTS}") file(COPY "${CMAKE_BINARY_DIR}/tmp/NonFailureTests${TEST_TARGET}.sh" DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE ) file(REMOVE "${CMAKE_BINARY_DIR}/tmp/NonFailureTests${TEST_TARGET}.sh") endfunction() # Parses the cpp file and extracts the tests specified in it. Each test is then # added to CTest, and the run command is adjusted according to timeout, # willfail, and serialization needs. function(spectre_parse_file SOURCE_FILE TEST_TARGET) if (NOT EXISTS ${SOURCE_FILE}) message(WARNING "Could not find source file:\n\"${SOURCE_FILE}\"\nfor \ tests\n.") return() endif () file(STRINGS ${SOURCE_FILE} CONTENTS NEWLINE_CONSUME) # Remove commented out tests so they are not added to ctest string(REGEX REPLACE "\n[ \t]*//+[^\n]+" "\n" CONTENTS "${CONTENTS}") # The regex searches for SPECTRE_TEST_CASE_METHOD, SCENARIO and SPECTRE_TEST_CASE # to find tests that need to be added. TESTS will be a list of all tests # found in the SOURCE_FILE. string(REGEX MATCHALL "(CATCH_)?(SPECTRE_TEST_CASE_METHOD|SCENARIO|SPECTRE_TEST_CASE)[ \t]*\\([^\)]+\\)[ \t]*{" TESTS "${CONTENTS}") set(FAILURE_TESTS "") foreach (TEST_NAME ${TESTS}) # Get test type and fixture if applicable string(REGEX MATCH "(CATCH_)?(SPECTRE_TEST_CASE_METHOD|SCENARIO|SPECTRE_TEST_CASE)" TEST_TYPE "${TEST_NAME}") # Get string parts of test definition string(REGEX MATCHALL "\"[^\"]+\"" TEST_STRINGS "${TEST_NAME}") # Strip wrapping quotation marks of each element of the list # TEST_STRINGS string(REGEX REPLACE "^\"(.*)\"$" "\\1" TEST_STRINGS "${TEST_STRINGS}") # If a test name went on multiple lines, there will either be a sequence # .";" or ";". from the line break (after replacing all the whitespace with # ;) Remove these from the test string string(REPLACE ".\";\"" "." TEST_STRINGS "${TEST_STRINGS}") string(REPLACE "\";\"." "." TEST_STRINGS "${TEST_STRINGS}") # Remove the last set of quotation marks string(REPLACE "\";\"" ";" TEST_STRINGS "${TEST_STRINGS}") # Validate that a test name and tags have been provided list(LENGTH TEST_STRINGS TEST_STRINGS_LENGTH) if (NOT TEST_STRINGS_LENGTH EQUAL 2) message(FATAL_ERROR "You must provide a valid test name and tags " "for all tests in ${SOURCE_FILE}. Cannot use the test:\n" "\"${TEST_STRINGS}\"\n") endif () # Assign name and tags list(GET TEST_STRINGS 0 NAME) if ("${TEST_TYPE}" STREQUAL "SCENARIO") set(NAME "Scenario: ${NAME}") endif () set(CTEST_NAME "${NAME}") # Gets the TAGS of the test which is element 1 of TEST_STRINGS, # strips the enclosing brackets, and makes a list list(GET TEST_STRINGS 1 TAGS) string(TOLOWER "${TAGS}" TAGS) string(REPLACE "]" ";" TAGS "${TAGS}") string(REPLACE "[" "" TAGS "${TAGS}") # These files are generated by the SpectreParseTests.py if(NOT EXISTS "${CMAKE_BINARY_DIR}/tmp/${CTEST_NAME}.output_regex") message(FATAL_ERROR "Failed to parse out the test ${TEST_NAME} in the file ${SOURCE_FILE}." " This means the python script cmake/SpectreParseTests.py failed to " "correctly identify the tests.") endif() file(READ "${CMAKE_BINARY_DIR}/tmp/${CTEST_NAME}.output_regex" OUTPUT_REGEX) file(REMOVE "${CMAKE_BINARY_DIR}/tmp/${CTEST_NAME}.output_regex") file(READ "${CMAKE_BINARY_DIR}/tmp/${CTEST_NAME}.timeout" TIMEOUT) file(REMOVE "${CMAKE_BINARY_DIR}/tmp/${CTEST_NAME}.timeout") # The default TIMEOUT is set to -1, but overwritten by each type # of test or a specified TIMEOUT attribute for a given test. # Thus we can use it to check if each test has been tagged by an # appropriate type. if (TIMEOUT EQUAL -1) message(FATAL_ERROR "You must set at least one tag of value [unit] " "for \"${NAME}\" in ${SOURCE_FILE}\n") endif () # Triple timeout if address sanitizer is enabled. if (ASAN) math(EXPR TIMEOUT "3 * ${TIMEOUT}") endif() spectre_test_timeout(TIMEOUT UNIT ${TIMEOUT}) # Add the test and set its properties # - Skip benchmarks during unit testing add_test(NAME ${CTEST_NAME} COMMAND ${SPECTRE_TEST_RUNNER} $ \"${NAME}\" --durations yes --warn NoAssertions --skip-benchmarks --name "\"$.${CTEST_NAME}\"") # Check if the test is supposed to fail. If so then let ctest know # that a failed test is actually a pass. if (NOT "${OUTPUT_REGEX}" STREQUAL "") if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") set(OUTPUT_REGEX "${OUTPUT_REGEX}|### No ASSERT tests in release mode ###") endif() set_tests_properties( ${CTEST_NAME} PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran" TIMEOUT ${TIMEOUT} PASS_REGULAR_EXPRESSION "${OUTPUT_REGEX}" LABELS "${TAGS}" ENVIRONMENT "${_CATCH_TEST_ENV_VARS}") set(FAILURE_TESTS "\"~${CTEST_NAME}\";${FAILURE_TESTS}") else () set_tests_properties( ${CTEST_NAME} PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran" TIMEOUT ${TIMEOUT} LABELS "${TAGS}" ENVIRONMENT "${_CATCH_TEST_ENV_VARS}") endif () endforeach () set_property(GLOBAL PROPERTY SPECTRE_FAILURE_TESTS ${FAILURE_TESTS}) get_property( SPECTRE_FAILURE_TESTS GLOBAL PROPERTY SPECTRE_FAILURE_TESTS_PROPERTY) set(SPECTRE_FAILURE_TESTS "${SPECTRE_FAILURE_TESTS};${FAILURE_TESTS}") set_property(GLOBAL PROPERTY SPECTRE_FAILURE_TESTS_PROPERTY ${SPECTRE_FAILURE_TESTS}) endfunction() ================================================ FILE: cmake/SpectreAddInterfaceLibraryHeaders.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Adds the header files to the target. # # Usage: # # add_interface_lib_headers( # TARGET TARGET_NAME # HEADERS # A.hpp # B.hpp # C.hpp # ) # # This function is intended to be used with libraries added using add_library # or added by CMake's provided find_package (e.g. Boost). The # add_spectre_library handles adding header files for targets correctly and # so this function does not need to be used for libraries added with # add_spectre_library. function(add_interface_lib_headers) cmake_parse_arguments( ARG "" "TARGET" "HEADERS" ${ARGN}) if(NOT TARGET ${ARG_TARGET}) message(FATAL_ERROR "Unknown target '${ARG_TARGET}'" ) endif(NOT TARGET ${ARG_TARGET}) get_target_property( TARGET_TYPE ${ARG_TARGET} TYPE ) if(NOT ${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) message(FATAL_ERROR "The target '${ARG_TARGET}' is not an INTERFACE library and so " "add_interface_lib_headers should not be used to add header files " "to it." ) endif(NOT ${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) get_property( SPECTRE_INTERFACE_LIBRARY_HEADERS GLOBAL PROPERTY SPECTRE_INTERFACE_LIBRARY_HEADERS ) # Switch to delimiting the headers by ':' because CMake uses ';' to delimit # elements of a list. string(REPLACE ";" ":" TARGET_HEADERS "${ARG_TARGET}=${ARG_HEADERS}") # BEGIN ADD EXISTING HEADERS # This block checks if the current target already has a list of header files # associated with it. If so, then we parse the current headers from the # string SPECTRE_INTERFACE_LIBRARY_HEADERS. Once we've parsed out the # _PREVIOUS_HEADERS we append them to the list of current headers, # (TARGET_HEADERS). Finally, we remove the current target from the interface # libaries string (SPECTRE_INTERFACE_LIBRARY_HEADERS) because we add it with # the new headers later. set(_PREVIOUS_HEADERS "") string(FIND "${SPECTRE_INTERFACE_LIBRARY_HEADERS}" "${ARG_TARGET}=" _POSITION_OF_TARGET) if (NOT ${_POSITION_OF_TARGET} EQUAL -1) string(SUBSTRING "${SPECTRE_INTERFACE_LIBRARY_HEADERS}" ${_POSITION_OF_TARGET} -1 _PREVIOUS_HEADERS) string(FIND "${_PREVIOUS_HEADERS}" "=" POSITION_OF_THIS_EQUALS) math(EXPR POSITION_OF_THIS_EQUALS_PLUS_ONE "${POSITION_OF_THIS_EQUALS} + 1") string(SUBSTRING "${_PREVIOUS_HEADERS}" ${POSITION_OF_THIS_EQUALS_PLUS_ONE} -1 _PREVIOUS_HEADERS) string(FIND "${_PREVIOUS_HEADERS}" "=" POSITION_OF_NEXT_EQUALS) string(SUBSTRING "${_PREVIOUS_HEADERS}" 0 ${POSITION_OF_NEXT_EQUALS} _PREVIOUS_HEADERS) string(FIND "${_PREVIOUS_HEADERS}" ";" POSITION_OF_LAST_SEMI REVERSE) string(SUBSTRING "${_PREVIOUS_HEADERS}" 0 ${POSITION_OF_LAST_SEMI} _PREVIOUS_HEADERS) set(TARGET_HEADERS "${TARGET_HEADERS}:${_PREVIOUS_HEADERS}") string(REPLACE "${ARG_TARGET}=${_PREVIOUS_HEADERS}" "" SPECTRE_INTERFACE_LIBRARY_HEADERS "${SPECTRE_INTERFACE_LIBRARY_HEADERS}") endif() string(REPLACE ";;" ";" SPECTRE_INTERFACE_LIBRARY_HEADERS "${SPECTRE_INTERFACE_LIBRARY_HEADERS}") list(APPEND SPECTRE_INTERFACE_LIBRARY_HEADERS ${TARGET_HEADERS}) # END ADD EXISTING HEADERS set_property( GLOBAL PROPERTY SPECTRE_INTERFACE_LIBRARY_HEADERS ${SPECTRE_INTERFACE_LIBRARY_HEADERS} ) endfunction(add_interface_lib_headers) # Returns a list of all the header files for the target `TARGET` # by setting the variable with the name `${RESULT_NAME}` # # Usage: # get_target_headers(MyTarget MY_TARGET_HEADERS) function(get_target_headers TARGET RESULT_NAME) get_target_property( TARGET_TYPE ${TARGET} TYPE ) if(${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) get_property( _SPECTRE_INTERFACE_LIBRARY_HEADERS GLOBAL PROPERTY SPECTRE_INTERFACE_LIBRARY_HEADERS ) foreach(_LIB ${_SPECTRE_INTERFACE_LIBRARY_HEADERS}) string(REPLACE "${TARGET}=" "" _LIB_HEADERS ${_LIB}) if(NOT ${_LIB} STREQUAL ${_LIB_HEADERS}) string(REPLACE ":" ";" _LIB_HEADERS ${_LIB_HEADERS}) set(${RESULT_NAME} ${_LIB_HEADERS} PARENT_SCOPE) break() endif(NOT ${_LIB} STREQUAL ${_LIB_HEADERS}) endforeach(_LIB ${_SPECTRE_INTERFACE_LIBRARY_HEADERS}) else(${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) get_property( _HEADER_FILES TARGET ${TARGET} PROPERTY PUBLIC_HEADER ) set(${RESULT_NAME} ${_HEADER_FILES} PARENT_SCOPE) endif(${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) endfunction(get_target_headers TARGET) ================================================ FILE: cmake/SpectreAddLibraries.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. add_custom_target(libs) function(ADD_SPECTRE_LIBRARY LIBRARY_NAME) add_library(${LIBRARY_NAME} ${ARGN}) add_dependencies(libs ${LIBRARY_NAME}) get_target_property( LIBRARY_IS_IMPORTED ${LIBRARY_NAME} IMPORTED ) get_target_property( LIBRARY_TYPE ${LIBRARY_NAME} TYPE ) # We do _not_ link a custom allocator here, such as jemalloc or tcmalloc, but # only dynamically link it into executables. This allows to use the libraries # in Python bindings, where the custom allocator would cause problems. if (NOT ${LIBRARY_TYPE} STREQUAL INTERFACE_LIBRARY) set(SPECTRE_KOKKOS_LAUNCHER "") if(SPECTRE_KOKKOS) # We need to make sure we don't drop the Kokkos link wrapper get_target_property( _RULE_LAUNCH_LINK ${LIBRARY_NAME} RULE_LAUNCH_LINK) if (_RULE_LAUNCH_LINK) set(SPECTRE_KOKKOS_LAUNCHER ${_RULE_LAUNCH_LINK}) endif() endif() set_target_properties( ${LIBRARY_NAME} PROPERTIES RULE_LAUNCH_LINK "${CMAKE_BINARY_DIR}/tmp/WrapLibraryLinker.sh ${SPECTRE_KOKKOS_LAUNCHER}" LINK_DEPENDS "${CMAKE_BINARY_DIR}/tmp/WrapLibraryLinker.sh" ) endif (NOT ${LIBRARY_TYPE} STREQUAL INTERFACE_LIBRARY) if (NOT "${LIBRARY_NAME}" MATCHES "^SpectrePch" AND NOT ${LIBRARY_IS_IMPORTED} AND NOT ${LIBRARY_TYPE} STREQUAL INTERFACE_LIBRARY AND TARGET SpectrePch) target_precompile_headers(${LIBRARY_NAME} REUSE_FROM SpectrePch) target_link_libraries(${LIBRARY_NAME} PRIVATE SpectrePchFlags) endif() if (${LIBRARY_TYPE} STREQUAL INTERFACE_LIBRARY) target_link_libraries( ${LIBRARY_NAME} INTERFACE SpectreFlags ) else() target_link_libraries( ${LIBRARY_NAME} PUBLIC SpectreFlags ) set_property( TARGET ${LIBRARY_NAME} PROPERTY FOLDER ${CMAKE_CURRENT_SOURCE_DIR} ) endif() if (BUILD_SHARED_LIBS AND NOT ${LIBRARY_TYPE} STREQUAL INTERFACE_LIBRARY) install(TARGETS ${LIBRARY_NAME} OPTIONAL LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() endfunction() ================================================ FILE: cmake/SpectreAddTestLibs.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Add an executable with Catch2 unit tests and register them with CTest. # # This function is named `add_test_library` although it adds an executable for # historical reasons. We can refactor this in the future. We can also switch to # `catch_discover_tests` instead of our own test parsing code in the future. # At that point we can remove the `SOURCE_FILES` argument of this function and # instead use the standard `target_sources` to add the source files (currently # the `SOURCE_FILES` are needed to parse the tests). # # Parameters: # - TEST_EXEC_NAME The name of the test executable to add # - SOURCE_FILES The source files to compile into the executable function(add_test_library TEST_EXEC_NAME SOURCE_FILES) cmake_parse_arguments(ARG WITH_CHARM "" "" ${ARGN}) add_spectre_executable( ${TEST_EXEC_NAME} ${SOURCE_FILES} ) add_dependencies(unit-tests ${TEST_EXEC_NAME}) target_link_libraries( ${TEST_EXEC_NAME} PRIVATE Catch2::Catch2 Framework ) # Use either the Charm++ or the non-Charm++ TestMain if (ARG_WITH_CHARM) target_sources( ${TEST_EXEC_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/tests/Unit/TestMainCharm.cpp ) add_dependencies( ${TEST_EXEC_NAME} module_TestMainCharm ) else() target_sources( ${TEST_EXEC_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/tests/Unit/TestMain.cpp ) endif() # Register the tests with CTest. # We may want to switch to `catch_discover_tests` and remove our own test # parsing code in the future. Before we do, we should check if it supports all # the features we use. # catch_discover_tests(${TEST_EXEC_NAME}) spectre_add_catch_tests(${TEST_EXEC_NAME}) endfunction() # Shared test libs are currently unsupported on macOS because Catch2 static # variables are not properly initialized. This is only needed for test helper # libraries with Catch2 assertions in them. set(SPECTRE_TEST_LIBS_TYPE "") if(APPLE) set(SPECTRE_TEST_LIBS_TYPE STATIC) endif() ================================================ FILE: cmake/SpectreCheckDependencies.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. include(SpectreCheckTargetDependencies) function(check_spectre_libs_dependencies) get_property( SPECTRE_TPLS GLOBAL PROPERTY SPECTRE_THIRD_PARTY_LIBS ) get_property( SPECTRE_LIBS TARGET libs PROPERTY MANUALLY_ADDED_DEPENDENCIES ) foreach(TARGET_TO_CHECK ${ARGN}) check_target_dependencies( TARGET ${TARGET_TO_CHECK} ALL_TARGETS ${SPECTRE_TPLS} ${SPECTRE_LIBS} ALLOWED_EXTRA_TARGETS SpectreAllocator SpectreFlags SpectrePchFlags ERROR_ON_FAILURE ) endforeach(TARGET_TO_CHECK ${ARGN}) endfunction(check_spectre_libs_dependencies) option(CHECK_LIBRARY_DEPENDENCIES "Check link dependencies of SpECTRE libraries" OFF) option(CHECK_ALL_DEPENDENCIES "Check link dependencies of all SpECTRE targets" OFF) if(CHECK_LIBRARY_DEPENDENCIES OR CHECK_ALL_DEPENDENCIES) get_property( SPECTRE_LIBS TARGET libs PROPERTY MANUALLY_ADDED_DEPENDENCIES ) check_spectre_libs_dependencies( ${SPECTRE_LIBS} ) endif(CHECK_LIBRARY_DEPENDENCIES OR CHECK_ALL_DEPENDENCIES) ================================================ FILE: cmake/SpectreCheckTargetDependencies.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. include(SpectreAddInterfaceLibraryHeaders) # Get the list of absolute paths of header files for target `TARGET_NAME`. # # Sets the variable `HEADER_FILES` in parent scope to return the result function(_absolute_header_paths TARGET_NAME) get_target_headers(${TARGET_NAME} _HEADER_FILES) get_property( _INCLUDE_DIR TARGET ${TARGET_NAME} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ) list(LENGTH _INCLUDE_DIR _NUMBER_OF_INCLUDE_DIRS) if(${_NUMBER_OF_INCLUDE_DIRS} GREATER 1) message(FATAL_ERROR "Currently _absolute_header_paths only supports a single " "INTERFACE_INCLUDE_DIRECTORIES for finding header files. Support for " "multiple INTERFACE_INCLUDE_DIRECTORIES can be added if needed.") endif(${_NUMBER_OF_INCLUDE_DIRS} GREATER 1) unset(_ABS_HEADER_FILES) foreach(HEADER ${_HEADER_FILES}) if(IS_ABSOLUTE ${HEADER}) list(APPEND _ABS_HEADER_FILES ${HEADER}) else() list(APPEND _ABS_HEADER_FILES "${_INCLUDE_DIR}/${HEADER}") endif() endforeach(HEADER ${_HEADER_FILES}) # "Return" HEADER_FILES by setting it in PARENT_SCOPE set(HEADER_FILES ${_ABS_HEADER_FILES} PARENT_SCOPE) endfunction(_absolute_header_paths TARGET_NAME) # Get the list of absolute paths of source files for target `TARGET_NAME`. # # Sets the variable `SOURCE_FILES` in parent scope to return the result function(_absolute_source_paths TARGET_NAME) get_property( _SOURCE_FILES TARGET ${TARGET_NAME} PROPERTY SOURCES ) get_property( _LOCATION TARGET ${TARGET_NAME} PROPERTY FOLDER ) unset(_ABS_SOURCE_FILES) foreach(SOURCE ${_SOURCE_FILES}) if(IS_ABSOLUTE ${SOURCE}) list(APPEND _ABS_SOURCE_FILES ${SOURCE}) else() list(APPEND _ABS_SOURCE_FILES "${_LOCATION}/${SOURCE}") endif() endforeach(SOURCE ${_SOURCE_FILES}) # "Return" SOURCE_FILES by setting it in PARENT_SCOPE set(SOURCE_FILES ${_ABS_SOURCE_FILES} PARENT_SCOPE) endfunction(_absolute_source_paths TARGET_NAME) # Get the list of SpECTRE includes (i.e. not for 3rd party libraries) # for the target `TARGET_NAME`. # # Sets the variable `SPECTRE_INCLUDES` in parent scope to return the result function(_extract_spectre_includes FILE_NAME) file(READ ${FILE_NAME} FILE_CONTENTS) string(REGEX MATCHALL "\n#include \"[^\n]+\"" _RAW_SPECTRE_INCLUDES ${FILE_CONTENTS}) unset(SPECTRE_INCLUDES) foreach(INCLUDE ${_RAW_SPECTRE_INCLUDES}) string(REPLACE "\n#include \"" "" INCLUDE "${INCLUDE}") string(REPLACE "\"" "" INCLUDE "${INCLUDE}") list(APPEND SPECTRE_INCLUDES ${INCLUDE}) endforeach(INCLUDE ${_RAW_SPECTRE_INCLUDES}) # "Return" SPECTRE_INCLUDES by setting it in PARENT_SCOPE set(SPECTRE_INCLUDES ${SPECTRE_INCLUDES} PARENT_SCOPE) endfunction(_extract_spectre_includes FILE_NAME) # Get the list of 3rd party library includes for the target `TARGET_NAME`. # # Sets the variable `TPL_INCLUDES` in parent scope to return the result function(_extract_tpl_includes FILE_NAME) file(READ ${FILE_NAME} FILE_CONTENTS) string(REGEX MATCHALL "\n#include <[^\n]+>" _RAW_TPL_INCLUDES ${FILE_CONTENTS}) unset(TPL_INCLUDES) foreach(INCLUDE ${_RAW_TPL_INCLUDES}) string(REPLACE "\n#include <" "" INCLUDE "${INCLUDE}") string(REPLACE ">" "" INCLUDE "${INCLUDE}") list(APPEND TPL_INCLUDES ${INCLUDE}) endforeach(INCLUDE ${_RAW_TPL_INCLUDES}) # "Return" TPL_INCLUDES by setting it in PARENT_SCOPE set(TPL_INCLUDES ${TPL_INCLUDES} PARENT_SCOPE) endfunction(_extract_tpl_includes FILE_NAME) # Make the path of `HEADER_FILE` which belongs to the target `TARGET_NAME` # an absolute path. # # Sets the variable `ABS_HEADER_FILE` in parent scope to return the result function(_make_header_path_absolute TARGET_NAME HEADER_FILE) get_property( _INCLUDE_DIR TARGET ${TARGET_NAME} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ) if(IS_ABSOLUTE ${HEADER_FILE}) set(_ABS_HEADER_FILE ${HEADER_FILE}) else() set(_ABS_HEADER_FILE "${_INCLUDE_DIR}/${HEADER_FILE}") endif() # "Return" ABS_HEADER_FILE by setting it in PARENT_SCOPE set(ABS_HEADER_FILE ${_ABS_HEADER_FILE} PARENT_SCOPE) endfunction(_make_header_path_absolute TARGET_NAME HEADER_FILE) # Gets the dependencies for a list of includes of one of the source or # header files of the target `TARGET_NAME` # # The `_get_deps_for_includes` function builds a list of all dependencies # by finding the target that provides each header file in `INCLUDES_OF_FILE`. # `INCLUDES_OF_FILE` must be a list of includes from a file (either header # or source file) of the target `TARGET_NAME`. If `RECURSE_THROUGH_INCLUDES` # is `TRUE` then for each header file in `INCLUDES_OF_FILE` that is also an # include of the target `TARGET_NAME` then the header file will also have its # dependencies searched and added to the list of dependencies. # # Example usage: # # _get_deps_for_includes( # TARGET_C # "TARGET_A;TARGET_B;TARGET_C;TARGET_D" # "cmath;utility;vector" # FALSE # ) # # Arguments: # # TARGET_NAME: the target for which to check the link libraries/dependencies # LIST_OF_ALL_TARGETS: a list of all the targets that might be dependencies # of the target ${TARGET_NAME} # INCLUDES_OF_FILE: # a list of header files for which to get the dependencies. # RECURSE_THROUGH_INCLUDES: # if TRUE then any include in any of ${INCLUDES_OF_FILE} # that is also an include of the target ${TARGET_NAME} has its # dependencies added. # # Since the recursion will cause an infinite loop if there are cyclic includes # we limit the recursion depth to 20, at which point an error message is # displayed that there may be cyclic dependencies # # Returns by setting `TARGET_DEPS` in parent scope function(_get_deps_for_includes TARGET_NAME LIST_OF_ALL_TARGETS INCLUDES_OF_FILE RECURSE_THROUGH_INCLUDES) # Implement guard against infinite recursion when there are cyclic # includes in a library. get_property( GET_DEPS_FOR_SPECTRE_INCLUDES_PATH GLOBAL PROPERTY GET_DEPS_FOR_SPECTRE_INCLUDES_PATH ) list(LENGTH GET_DEPS_FOR_SPECTRE_INCLUDES_PATH RECURSE_DEPTH) if(${RECURSE_DEPTH} GREATER 20) message(FATAL_ERROR " Found what appears to be a cyclic loop in the header files." " The header path is: ${GET_DEPS_FOR_SPECTRE_INCLUDES_PATH}" ) endif(${RECURSE_DEPTH} GREATER 20) get_target_headers(${TARGET_NAME} TARGET_HEADER_FILES) unset(_TARGET_DEPS) # Now loop over all spectre targets to see if any of them # expose these includes foreach(CURRENT_INCLUDE ${INCLUDES_OF_FILE}) # If we are checking header files and the header file is part of # this target, possibly recurse the header files, and skipping search # through targets for which one provides the header file (we know it's us). if(${CURRENT_INCLUDE} IN_LIST TARGET_HEADER_FILES) if(RECURSE_THROUGH_INCLUDES) # Sets ABS_HEADER_FILE _make_header_path_absolute(${TARGET_NAME} ${CURRENT_INCLUDE}) # Sets SPECTRE_INCLUDES _extract_spectre_includes(${ABS_HEADER_FILE}) set_property( GLOBAL APPEND PROPERTY GET_DEPS_FOR_CURRENT_INCLUDES_PATH ${CURRENT_INCLUDE} ) # Sets TARGET_DEPS _get_deps_for_includes(${TARGET_NAME} "${LIST_OF_ALL_TARGETS}" "${CURRENT_INCLUDES}" ${RECURSE_THROUGH_INCLUDES}) # "Pop" last element by setting the property to what it was at the # start of the function call. set_property( GLOBAL PROPERTY GET_DEPS_FOR_CURRENT_INCLUDES_PATH ${GET_DEPS_FOR_CURRENT_INCLUDES_PATH} ) # Get the dependencies of the header file, since these are all # also PRIVATE dependencies of the target. foreach(_TARGET ${TARGET_DEPS}) if(NOT ${_TARGET} IN_LIST _TARGET_DEPS) list(APPEND _TARGET_DEPS ${_TARGET}) endif(NOT ${_TARGET} IN_LIST _TARGET_DEPS) endforeach(_TARGET ${TARGET_DEPS}) continue() else(RECURSE_THROUGH_INCLUDES) continue() endif(RECURSE_THROUGH_INCLUDES) endif(${CURRENT_INCLUDE} IN_LIST TARGET_HEADER_FILES) unset(_TARGET_WITH_INCLUDE) foreach(DEP_TARGET ${LIST_OF_ALL_TARGETS}) if(${DEP_TARGET} STREQUAL ${TARGET_NAME}) continue() endif(${DEP_TARGET} STREQUAL ${TARGET_NAME}) # Get the header files of DEP_TARGET and see if any of the # includes are part of DEP_TARGET. get_target_headers(${DEP_TARGET} _DEP_TARGET_HEADERS) if(${CURRENT_INCLUDE} IN_LIST _DEP_TARGET_HEADERS) set(_TARGET_WITH_INCLUDE ${DEP_TARGET}) break() endif(${CURRENT_INCLUDE} IN_LIST _DEP_TARGET_HEADERS) endforeach(DEP_TARGET ${LIST_OF_ALL_TARGETS}) if(NOT _TARGET_WITH_INCLUDE) message(FATAL_ERROR "No known targets supply the file ${CURRENT_INCLUDE} included in " "file ${HEADER_OR_SOURCE} of target ${TARGET_NAME}." ) endif(NOT _TARGET_WITH_INCLUDE) if(NOT ${_TARGET_WITH_INCLUDE} IN_LIST _TARGET_DEPS) list(APPEND _TARGET_DEPS ${_TARGET_WITH_INCLUDE}) endif(NOT ${_TARGET_WITH_INCLUDE} IN_LIST _TARGET_DEPS) endforeach(CURRENT_INCLUDE ${INCLUDES_OF_FILE}) # "Return" TARGET_DEPS by setting it in PARENT_SCOPE set(TARGET_DEPS ${_TARGET_DEPS} PARENT_SCOPE) endfunction(_get_deps_for_includes TARGET_NAME LIST_OF_ALL_TARGETS INCLUDES_OF_FILE RECURSE_THROUGH_INCLUDES) # Returns the dependencies for the target # # Arguments # # TARGET_NAME: # the target for which to check the link libraries/dependencies # LIST_OF_ALL_TARGETS: # a list of all the targets that might be dependencies # of the target ${TARGET_NAME} # LIST_OF_FILES: # a list of the files for which to get the dependencies. Can be # header/tpp or source files. # RECURSE_INCLUDES: # if TRUE then the dependencies of the target's included header files # will also be added. This is used when source files are passed because # the dependencies of the header files must be marked as PUBLIC # # Returns by setting `TARGET_DEPS` in parent scope function(_get_deps_for_target TARGET_NAME LIST_OF_ALL_TARGETS LIST_OF_FILES RECURSE_INCLUDES) unset(_TARGET_DEPS) foreach(HEADER_OR_SOURCE ${LIST_OF_FILES}) if(IS_ABSOLUTE "${HEADER_OR_SOURCE}") # Sets SPECTRE_INCLUDES _extract_spectre_includes("${HEADER_OR_SOURCE}") else() message(FATAL_ERROR "All paths of files passed to _get_deps_for_target must be absolute " "but received ${HEADER_OR_SOURCE}.") endif() # Sets TARGET_DEPS _get_deps_for_includes(${TARGET_NAME} "${LIST_OF_ALL_TARGETS}" "${SPECTRE_INCLUDES}" ${RECURSE_INCLUDES}) foreach(_TARGET ${TARGET_DEPS}) if(NOT ${_TARGET} IN_LIST _TARGET_DEPS) list(APPEND _TARGET_DEPS ${_TARGET}) endif(NOT ${_TARGET} IN_LIST _TARGET_DEPS) endforeach(_TARGET ${TARGET_DEPS}) # Third party library includes # Sets TPL_INCLUDES _extract_tpl_includes("${HEADER_OR_SOURCE}") # Sets TARGET_DEPS _get_deps_for_includes(${TARGET_NAME} "${LIST_OF_ALL_TARGETS}" "${TPL_INCLUDES}" FALSE) foreach(_TARGET ${TARGET_DEPS}) if(NOT ${_TARGET} IN_LIST _TARGET_DEPS) list(APPEND _TARGET_DEPS ${_TARGET}) endif(NOT ${_TARGET} IN_LIST _TARGET_DEPS) endforeach(_TARGET ${TARGET_DEPS}) endforeach(HEADER_OR_SOURCE ${LIST_OF_FILES}) # Alphabetize the list of dependencies list(SORT _TARGET_DEPS) # "Return" the target dependencies set(TARGET_DEPS ${_TARGET_DEPS} PARENT_SCOPE) endfunction(_get_deps_for_target TARGET_NAME LIST_OF_FILES LIST_OF_ALL_TARGETS) # Add the libraries for the `target_link_libraries` command # for a target. # # Arguments # # TARGET_DEPS: # dependencies of the target # TARGET_DEPS_TYPE: # the type of dependencies, INTERFACE/PRIVATE/PUBLIC # TARGET_LINK_LIBRARIES_COMMAND: # the target_link_libraries command so far # # Returns by setting `TARGET_LINK_LIBS_COMMAND` in parent scope function(_add_targets_to_link_libs TARGET_DEPS TARGET_DEPS_TYPE TARGET_LINK_LIBS_COMMAND) list(LENGTH TARGET_DEPS _NUM_TARGET_DEPS) set(_TARGET_LINK_LIBS_COMMAND "${TARGET_LINK_LIBS_COMMAND}" ) if(${_NUM_TARGET_DEPS} GREATER 0) set( _TARGET_LINK_LIBS_COMMAND "${_TARGET_LINK_LIBS_COMMAND}\n" " ${TARGET_DEPS_TYPE}" ) foreach(_DEP ${TARGET_DEPS}) set( _TARGET_LINK_LIBS_COMMAND "${_TARGET_LINK_LIBS_COMMAND}\n" " ${_DEP}" ) endforeach(_DEP ${_TARGET_DEPS}) set(_TARGET_LINK_LIBS_COMMAND "${_TARGET_LINK_LIBS_COMMAND}\n " ) string(REPLACE ";" "" _TARGET_LINK_LIBS_COMMAND ${_TARGET_LINK_LIBS_COMMAND}) endif(${_NUM_TARGET_DEPS} GREATER 0) # "Return" the target dependencies set(TARGET_LINK_LIBS_COMMAND ${_TARGET_LINK_LIBS_COMMAND} PARENT_SCOPE) endfunction(_add_targets_to_link_libs TARGET_DEPS TARGET_DEPS_TYPE TARGET_LINK_LIBS_COMMAND) # Queries the INTERFACE_LINK_LIBRARIES of TARGET. This is done recursively. function(_get_interface_link_libraries TARGET) get_target_property(_INTERFACE_LIBS ${TARGET} INTERFACE_LINK_LIBRARIES) set(LINK_LIBS_FOR_TARGET "") foreach(_INTERFACE_LIB ${_INTERFACE_LIBS}) if (_INTERFACE_LIB) list(APPEND LINK_LIBS_FOR_TARGET ${_INTERFACE_LIB}) if (TARGET ${_INTERFACE_LIB}) set(OUTPUT_LIST "") _get_interface_link_libraries(${_INTERFACE_LIB}) list(APPEND LINK_LIBS_FOR_TARGET ${OUTPUT_LIST}) endif() endif() endforeach() # "Return" dependencies to calling function set(OUTPUT_LIST ${LINK_LIBS_FOR_TARGET} PARENT_SCOPE) endfunction(_get_interface_link_libraries OUTPUT_LIST TARGET) # Checks the dependencies for the target ${TARGET_NAME} and if they are # incorrect produces an error message with the correct dependencies. # # TARGET_NAME: # the target for which to check the link libraries/dependencies # TARGET_LINK_LIBS_COMMAND: # the target_link_libraries CMake command so far # TARGET_INTERFACE_DEPS: # the INTERFACE link libraries for the target # TARGET_PRIVATE_DEPS: # the PRIVATE link libraries for the target # TARGET_PUBLIC_DEPS: # the PUBLIC link libraries for the target # LIST_OF_ALLOWED_EXTRA_TARGETS: # a list of allowed extra dependencies. An example of an extra dependency # is the SpectreFlags target, which supplies no header files and there is # not strictly a dependency of ${TARGET_NAME} but can be specified as a # dependency in order to add compiler flags or definitions to the target. # ERROR_ON_FAILURE: # if specified, then CMake will produce an error if the dependencies are # incorrect. Otherwise the variable TARGET_DEPENDENCIES_ERROR_MESSAGE # is set in the parent scope function(_check_and_print_dependencies TARGET_NAME TARGET_LINK_LIBS_COMMAND TARGET_INTERFACE_DEPS TARGET_PRIVATE_DEPS TARGET_PUBLIC_DEPS LIST_OF_ALLOWED_EXTRA_TARGETS) cmake_parse_arguments( ARG "ERROR_ON_FAILURE" "" "" ${ARGN}) # We add the dependencies of allowed targets as additional allowed targets. # This avoids the situation where target A is allowed, but A depends on B, # and therefore every target has a dependency on B. The helper function # ensures the dependencies are added recursively. set(WORKING_LIST ${LIST_OF_ALLOWED_EXTRA_TARGETS}) foreach(_ALLOWED_EXTRA_TARGET ${LIST_OF_ALLOWED_EXTRA_TARGETS}) set(OUTPUT_LIST "") _get_interface_link_libraries(${_ALLOWED_EXTRA_TARGET}) list(APPEND WORKING_LIST ${OUTPUT_LIST}) endforeach() list(REMOVE_DUPLICATES WORKING_LIST) set(LIST_OF_ALLOWED_EXTRA_TARGETS ${WORKING_LIST}) get_property( _INTERFACE_LIBS TARGET ${TARGET_NAME} PROPERTY INTERFACE_LINK_LIBRARIES ) # The property INTERFACE_LINK_LIBRARIES contains generator expressions for # private link-time dependencies. We will be handling these private # dependencies explicitly below, so here we want to remove them from the list # of interface dependencies. The generators have format "$" list(FILTER _INTERFACE_LIBS EXCLUDE REGEX "\\$") unset(_MISSING_INTERFACE_LIBS) foreach(_INTERFACE_DEP ${TARGET_INTERFACE_DEPS}) if(NOT ${_INTERFACE_DEP} IN_LIST _INTERFACE_LIBS) list(APPEND _MISSING_INTERFACE_LIBS ${_INTERFACE_DEP}) endif(NOT ${_INTERFACE_DEP} IN_LIST _INTERFACE_LIBS) endforeach(_INTERFACE_DEP ${TARGET_INTERFACE_DEPS}) get_target_property( TARGET_TYPE ${TARGET_NAME} TYPE ) set(_NUM_MISSING_PRIVATE_LIBS 0) set(_NUM_MISSING_PUBLIC_LIBS 0) unset(_EXTRA_INTERFACE_LIBS) unset(_EXTRA_PRIVATE_LIBS) unset(_EXTRA_PUBLIC_LIBS) if(NOT ${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) get_property( _PRIVATE_LIBS TARGET ${TARGET_NAME} PROPERTY LINK_LIBRARIES ) # Check to see if any interface-only dependencies are also # PRIVATE/PUBLIC foreach(_INTERFACE_DEP ${TARGET_INTERFACE_DEPS}) if(${_INTERFACE_DEP} IN_LIST _PRIVATE_LIBS) list(APPEND _MISSING_INTERFACE_LIBS ${_INTERFACE_DEP}) endif(${_INTERFACE_DEP} IN_LIST _PRIVATE_LIBS) endforeach(_INTERFACE_DEP ${TARGET_INTERFACE_DEPS}) unset(_MISSING_PRIVATE_LIBS) foreach(_PRIVATE_DEP ${TARGET_PRIVATE_DEPS}) if(NOT ${_PRIVATE_DEP} IN_LIST _PRIVATE_LIBS) list(APPEND _MISSING_PRIVATE_LIBS ${_PRIVATE_DEP}) endif(NOT ${_PRIVATE_DEP} IN_LIST _PRIVATE_LIBS) endforeach(_PRIVATE_DEP ${TARGET_PRIVATE_DEPS}) list(LENGTH _MISSING_PRIVATE_LIBS _NUM_MISSING_PRIVATE_LIBS) unset(_MISSING_PUBLIC_LIBS) foreach(_PUBLIC_DEP ${TARGET_PUBLIC_DEPS}) if(NOT ${_PUBLIC_DEP} IN_LIST _PRIVATE_LIBS OR NOT ${_PUBLIC_DEP} IN_LIST _INTERFACE_LIBS) list(APPEND _MISSING_PUBLIC_LIBS ${_PUBLIC_DEP}) endif(NOT ${_PUBLIC_DEP} IN_LIST _PRIVATE_LIBS OR NOT ${_PUBLIC_DEP} IN_LIST _INTERFACE_LIBS) endforeach(_PUBLIC_DEP ${TARGET_PUBLIC_DEPS}) list(LENGTH _MISSING_PUBLIC_LIBS _NUM_MISSING_PUBLIC_LIBS) # Now check for extra target link libraries that aren't needed. unset(_PUBLIC_LIBS) foreach(_INTERFACE_LIB ${_INTERFACE_LIBS}) if(${_INTERFACE_LIB} IN_LIST _PRIVATE_LIBS) list(APPEND _PUBLIC_LIBS ${_INTERFACE_LIB}) endif(${_INTERFACE_LIB} IN_LIST _PRIVATE_LIBS) endforeach(_INTERFACE_LIB ${_INTERFACE_LIBS}) foreach(_PUBLIC_LIB ${_PUBLIC_LIBS}) list(REMOVE_ITEM _INTERFACE_LIBS ${_PUBLIC_LIB}) list(REMOVE_ITEM _PRIVATE_LIBS ${_PUBLIC_LIB}) if(NOT ${_PUBLIC_LIB} IN_LIST TARGET_PUBLIC_DEPS AND NOT ${_PUBLIC_LIB} IN_LIST LIST_OF_ALLOWED_EXTRA_TARGETS) list(APPEND _EXTRA_PUBLIC_LIBS ${_PUBLIC_LIB}) endif(NOT ${_PUBLIC_LIB} IN_LIST TARGET_PUBLIC_DEPS AND NOT ${_PUBLIC_LIB} IN_LIST LIST_OF_ALLOWED_EXTRA_TARGETS) endforeach(_PUBLIC_LIB ${_PUBLIC_LIBS}) foreach(_PRIVATE_LIB ${_PRIVATE_LIBS}) if(NOT ${_PRIVATE_LIB} IN_LIST TARGET_PRIVATE_DEPS AND NOT ${_PRIVATE_LIB} IN_LIST LIST_OF_ALLOWED_EXTRA_TARGETS) list(APPEND _EXTRA_PRIVATE_LIBS ${_PRIVATE_LIB}) endif(NOT ${_PRIVATE_LIB} IN_LIST TARGET_PRIVATE_DEPS AND NOT ${_PRIVATE_LIB} IN_LIST LIST_OF_ALLOWED_EXTRA_TARGETS) endforeach(_PRIVATE_LIB ${_PRIVATE_LIBS}) foreach(_INTERFACE_LIB ${_INTERFACE_LIBS}) if(NOT ${_INTERFACE_LIB} IN_LIST TARGET_INTERFACE_DEPS AND NOT ${_INTERFACE_LIB} IN_LIST LIST_OF_ALLOWED_EXTRA_TARGETS) list(APPEND _EXTRA_INTERFACE_LIBS ${_INTERFACE_LIB}) endif(NOT ${_INTERFACE_LIB} IN_LIST TARGET_INTERFACE_DEPS AND NOT ${_INTERFACE_LIB} IN_LIST LIST_OF_ALLOWED_EXTRA_TARGETS) endforeach(_INTERFACE_LIB ${_INTERFACE_LIBS}) else(NOT ${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) foreach(_INTERFACE_DEP ${_INTERFACE_LIBS}) if(NOT ${_INTERFACE_DEP} IN_LIST TARGET_INTERFACE_DEPS AND NOT ${_INTERFACE_DEP} IN_LIST LIST_OF_ALLOWED_EXTRA_TARGETS) list(APPEND _EXTRA_INTERFACE_LIBS ${_INTERFACE_DEP}) endif() endforeach(_INTERFACE_DEP ${_INTERFACE_LIBS}) endif(NOT ${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) list(LENGTH _MISSING_INTERFACE_LIBS _NUM_MISSING_INTERFACE_LIBS) list(LENGTH _EXTRA_INTERFACE_LIBS _NUM_EXTRA_INTERFACE_LIBS) list(LENGTH _EXTRA_PRIVATE_LIBS _NUM_EXTRA_PRIVATE_LIBS) list(LENGTH _EXTRA_PUBLIC_LIBS _NUM_EXTRA_PUBLIC_LIBS) set(_MISSING_LIBS FALSE) set(_ERROR_MSG " Missing dependencies for target ${TARGET_NAME}") if(${_NUM_MISSING_INTERFACE_LIBS} GREATER 0) set(_ERROR_MSG "${_ERROR_MSG}\n Missing interface libs:\n ${_MISSING_INTERFACE_LIBS}") set(_MISSING_LIBS TRUE) endif(${_NUM_MISSING_INTERFACE_LIBS} GREATER 0) if(${_NUM_MISSING_PRIVATE_LIBS} GREATER 0) set(_ERROR_MSG "${_ERROR_MSG}\n Missing private libs:\n ${_MISSING_PRIVATE_LIBS}") set(_MISSING_LIBS TRUE) endif(${_NUM_MISSING_PRIVATE_LIBS} GREATER 0) if(${_NUM_MISSING_PUBLIC_LIBS} GREATER 0) set(_ERROR_MSG "${_ERROR_MSG}\n Missing public libs:\n ${_MISSING_PUBLIC_LIBS}") set(_MISSING_LIBS TRUE) endif(${_NUM_MISSING_PUBLIC_LIBS} GREATER 0) if(${_NUM_EXTRA_INTERFACE_LIBS} GREATER 0 OR ${_NUM_EXTRA_PRIVATE_LIBS} GREATER 0 OR ${_NUM_EXTRA_PUBLIC_LIBS} GREATER 0) set(_ERROR_MSG " Extra dependencies for target ${TARGET_NAME}") endif() if(${_NUM_EXTRA_INTERFACE_LIBS} GREATER 0) set(_ERROR_MSG "${_ERROR_MSG}\n Extra interface libs:\n ${_EXTRA_INTERFACE_LIBS}") set(_MISSING_LIBS TRUE) endif(${_NUM_EXTRA_INTERFACE_LIBS} GREATER 0) if(${_NUM_EXTRA_PRIVATE_LIBS} GREATER 0) set(_ERROR_MSG "${_ERROR_MSG}\n Extra private libs:\n ${_EXTRA_PRIVATE_LIBS}") set(_MISSING_LIBS TRUE) endif(${_NUM_EXTRA_PRIVATE_LIBS} GREATER 0) if(${_NUM_EXTRA_PUBLIC_LIBS} GREATER 0) set(_ERROR_MSG "${_ERROR_MSG}\n Extra public libs:\n ${_EXTRA_PUBLIC_LIBS}") set(_MISSING_LIBS TRUE) endif(${_NUM_EXTRA_PUBLIC_LIBS} GREATER 0) if(NOT ARG_ERROR_ON_FAILURE) set( TARGET_DEPS_ERROR_MESSAGE "" PARENT_SCOPE ) endif(NOT ARG_ERROR_ON_FAILURE) if(_MISSING_LIBS) set(TARGET_LINK_LIBS_COMMAND " target_link_libraries(\n" " ${TARGET_NAME}" ) _add_targets_to_link_libs( "${TARGET_INTERFACE_DEPS}" "INTERFACE" "${TARGET_LINK_LIBS_COMMAND}") _add_targets_to_link_libs( "${TARGET_PRIVATE_DEPS}" "PRIVATE" "${TARGET_LINK_LIBS_COMMAND}") _add_targets_to_link_libs( "${TARGET_PUBLIC_DEPS}" "PUBLIC" "${TARGET_LINK_LIBS_COMMAND}") set(TARGET_LINK_LIBS_COMMAND "${TARGET_LINK_LIBS_COMMAND} )" ) if(${ARG_ERROR_ON_FAILURE}) message(FATAL_ERROR "${_ERROR_MSG}\n \n" " Correct target_link_libraries command is:\n" "${TARGET_LINK_LIBS_COMMAND}" ) else(${ARG_ERROR_ON_FAILURE}) set( TARGET_DEPS_ERROR_MESSAGE "${_ERROR_MSG}\n \n\ Correct target_link_libraries command is:\n\ ${TARGET_LINK_LIBS_COMMAND}" PARENT_SCOPE ) endif(${ARG_ERROR_ON_FAILURE}) endif(_MISSING_LIBS) endfunction(_check_and_print_dependencies TARGET_NAME TARGET_LINK_LIBS_COMMAND TARGET_INTERFACE_DEPS TARGET_PRIVATE_DEPS TARGET_PUBLIC_DEPS LIST_OF_ALLOWED_EXTRA_TARGETS) # Check that the link libraries of the target are correct and if not, # provide an error with the correct target link libraries. # # Example usage: # # check_target_dependencies( # TARGET ${TARGET_TO_CHECK} # ALL_TARGETS # ${SPECTRE_TPLS} # ${SPECTRE_LIBS} # ALLOWED_EXTRA_TARGETS # SpectreFlags # ERROR_ON_FAILURE # ) # # Arguments: # # TARGET: # the target for which to check the link libraries/dependencies # ALL_TARGETS: # a list of all the targets that might be dependencies of the target # ${TARGET} # ALLOWED_EXTRA_TARGETS: # a list of allowed extra dependencies. An example of an extra dependency # is the SpectreFlags target, which supplies no header files and therefore # is not strictly a dependency of ${TARGET} but can be specified as # dependency in order to add compiler flags or definitions to the target. # ERROR_ON_FAILURE: # if specified, then CMake will produce an error if the dependencies are # incorrect. Otherwise the variable TARGET_DEPENDENCIES_ERROR_MESSAGE # is set in the parent scope function(check_target_dependencies) cmake_parse_arguments( ARG "ERROR_ON_FAILURE" "TARGET" "ALL_TARGETS;ALLOWED_EXTRA_TARGETS" ${ARGN}) # Sets HEADER_FILES _absolute_header_paths(${ARG_TARGET}) # Sets TARGET_DEPS _get_deps_for_target(${ARG_TARGET} "${ARG_ALL_TARGETS}" "${HEADER_FILES}" FALSE) set(_TARGET_INTERFACE_DEPS ${TARGET_DEPS}) list(REMOVE_ITEM _TARGET_INTERFACE_DEPS Stl) get_target_property( TARGET_TYPE ${ARG_TARGET} TYPE ) unset(_TARGET_PRIVATE_DEPS) unset(_TARGET_PUBLIC_DEPS) if(NOT ${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) # Sets SOURCE_FILES _absolute_source_paths(${ARG_TARGET}) # Sets TARGET_DEPS _get_deps_for_target(${ARG_TARGET} "${ARG_ALL_TARGETS}" "${SOURCE_FILES}" TRUE) set(_TARGET_PRIVATE_DEPS ${TARGET_DEPS}) # We only use the Stl target to be able to keep track of all header files # and to be able to claim with certainly that an extra header file is # present. Since there are no explicit includes or link dependencies that # need to be added, we don't want the extra noise of explicitly depending # on Stl everywhere in the code and so we remove it from the list. list(REMOVE_ITEM _TARGET_PRIVATE_DEPS Stl) # Now need to figure out what the PUBLIC libraries are unset(_TARGET_PUBLIC_DEPS) foreach(_PRIVATE_DEP ${_TARGET_PRIVATE_DEPS}) if(${_PRIVATE_DEP} IN_LIST _TARGET_INTERFACE_DEPS) list(APPEND _TARGET_PUBLIC_DEPS ${_PRIVATE_DEP}) endif(${_PRIVATE_DEP} IN_LIST _TARGET_INTERFACE_DEPS) endforeach(_PRIVATE_DEP ${_TARGET_PRIVATE_DEPS}) # Remove PRIVATE deps from INTERFACE and PUBLIC lists foreach(_PUBLIC_DEP ${_TARGET_PUBLIC_DEPS}) list(REMOVE_ITEM _TARGET_PRIVATE_DEPS ${_PUBLIC_DEP}) list(REMOVE_ITEM _TARGET_INTERFACE_DEPS ${_PUBLIC_DEP}) endforeach(_PUBLIC_DEP ${_TARGET_PUBLIC_DEPS}) endif(NOT ${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) set(ERROR_ON_FAILURE "") if(ARG_ERROR_ON_FAILURE) set(ERROR_ON_FAILURE ERROR_ON_FAILURE) endif(ARG_ERROR_ON_FAILURE) _check_and_print_dependencies( ${ARG_TARGET} "${TARGET_LINK_LIBS_COMMAND}" "${_TARGET_INTERFACE_DEPS}" "${_TARGET_PRIVATE_DEPS}" "${_TARGET_PUBLIC_DEPS}" "${ARG_ALLOWED_EXTRA_TARGETS}" ${ERROR_ON_FAILURE} ) if(NOT ARG_ERROR_ON_FAILURE) set( TARGET_DEPS_ERROR_MESSAGE "${TARGET_DEPS_ERROR_MESSAGE}" PARENT_SCOPE ) endif(NOT ARG_ERROR_ON_FAILURE) endfunction(check_target_dependencies) ================================================ FILE: cmake/SpectreGetGitHash.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. set(GIT_HASH "") set(GIT_BRANCH_COMMAND "") set(GIT_BRANCH "") set(GIT_DESCRIPTION_COMMAND "") set(GIT_DESCRIPTION "") if(EXISTS ${CMAKE_SOURCE_DIR}/.git) find_package(Git) if(Git_FOUND) execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse HEAD WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ) set(GIT_BRANCH_COMMAND "${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD") execute_process( COMMAND bash -c "${GIT_BRANCH_COMMAND}" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE ) set(GIT_DESCRIPTION_COMMAND "${GIT_EXECUTABLE} describe \ --always --first-parent --match 'v[0-9]*' HEAD") execute_process( COMMAND bash -c "${GIT_DESCRIPTION_COMMAND}" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE GIT_DESCRIPTION OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_VARIABLE GIT_DESCRIPTION_ERROR ERROR_STRIP_TRAILING_WHITESPACE ) if(GIT_DESCRIPTION) message(STATUS "Git description: ${GIT_DESCRIPTION}") else() message(STATUS "Could not determine git description (" "${GIT_DESCRIPTION_ERROR}). Using commit hash instead.") set(GIT_DESCRIPTION ${GIT_HASH}) endif() endif() else() message(STATUS "Not running in a git repository. Some features are disabled.") endif() file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "Git description: ${GIT_DESCRIPTION}\n" "Git branch: ${GIT_BRANCH}\n" "Git hash: ${GIT_HASH}\n" ) ================================================ FILE: cmake/SpectreInitializeVariables.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. if(NOT CMAKE_CXX_LINK_FLAGS) set(CMAKE_CXX_LINK_FLAGS "") endif() ================================================ FILE: cmake/SpectreLoadMetadata.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Read the following information from the `Metadata.yaml` file: # - SPECTRE_NAME: Name # - SPECTRE_HOMEPAGE: Homepage # - SPECTRE_VERSION: Version # - SPECTRE_DOI: Doi # - SPECTRE_ZENODO_ID: ZenodoId file(READ "${CMAKE_SOURCE_DIR}/Metadata.yaml" SPECTRE_METADATA_FILE) # Split lines into cmake list string(REGEX REPLACE ";" "\\\\;" SPECTRE_METADATA_FILE "${SPECTRE_METADATA_FILE}") string(REGEX REPLACE "\n" ";" SPECTRE_METADATA_FILE "${SPECTRE_METADATA_FILE}") # Read data from the file set(SPECTRE_NAME "") set(SPECTRE_HOMEPAGE "") set(SPECTRE_VERSION "") set(SPECTRE_DOI "") set(SPECTRE_ZENODO_ID "") foreach(LINE ${SPECTRE_METADATA_FILE}) if("${LINE}" MATCHES "^Name: (.*)$") set(SPECTRE_NAME ${CMAKE_MATCH_1}) endif() if("${LINE}" MATCHES "^Homepage: (.*)$") set(SPECTRE_HOMEPAGE ${CMAKE_MATCH_1}) endif() if("${LINE}" MATCHES "^Version: (.*)$") set(SPECTRE_VERSION ${CMAKE_MATCH_1}) endif() if("${LINE}" MATCHES "^Doi: (.*)$") set(SPECTRE_DOI ${CMAKE_MATCH_1}) endif() if("${LINE}" MATCHES "^ZenodoId: (.*)$") set(SPECTRE_ZENODO_ID ${CMAKE_MATCH_1}) endif() endforeach() # Check we have read all required keys if(NOT SPECTRE_NAME) message( FATAL_ERROR "Could not determine project name. Please check the " "Metadata.yaml file exists and has a line that matches: ^Name: (.*)$") endif() if(NOT SPECTRE_HOMEPAGE) message( WARNING "Could not determine project homepage. Please check the " "Metadata.yaml file exists and has a line that matches: ^Homepage: (.*)$") endif() if(NOT SPECTRE_VERSION) message( FATAL_ERROR "Could not determine release version. Please check the " "Metadata.yaml file exists and has a line that matches: ^Version: (.*)$") endif() if(NOT SPECTRE_DOI) message( WARNING "Could not determine DOI. Please check the " "Metadata.yaml file exists and has a line that matches: ^Doi: (.*)$") endif() if(NOT SPECTRE_ZENODO_ID) message( WARNING "Could not determine Zenodo ID. Please check the " "Metadata.yaml file exists and has a line that matches: ^ZenodoId: (.*)$") endif() message(STATUS "${SPECTRE_NAME} release version: ${SPECTRE_VERSION}") file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "SpECTRE Version: ${SPECTRE_VERSION}\n" ) ================================================ FILE: cmake/SpectreParseTests.py ================================================ #!/usr/bin/env python # Distributed under the MIT License. # See LICENSE.txt for details. import re # A list of all the allowed ctest labels/Catch tags for tests allowed_tags = [ "Actions", "Ader", "ApparentHorizonFinder", "Burgers", "Cce", "CompilationTest", "ControlSystem", "DataStructures", "Domain", "Elasticity", "Elliptic", "EquationsOfState", "ErrorHandling", "Evolution", "Fluxes", "ForceFree", "GeneralizedHarmonic", "GrMhd", "H5", "Hydro", "IO", "Informer", "Limiters", "LinearAlgebra", "LinearOperators", "LinearSolver", "M1Grey", "NumericalAlgorithms", "Observers", "Options", "Parallel", "ParallelAlgorithms", "PointwiseFunctions", "Pypp", "Python", "RelativisticEuler", "RootFinding", "ScalarAdvection", "Serialization", "Spectral", "Time", "Unit", "Utilities", "VariableFixing", ] # Words disallowed in tests disallowed_test_name_portions = ["Functors"] # Allowed test attributes allowed_test_attributes = ["TimeOut", "OutputRegex"] # All the timeout times for the different types of tests. The order here # matters. Whichever time is specified last is what will be used for the # test if it is of multiple types. default_tag_timeouts = [("unit", 5)] allowed_tags = [x.lower() for x in allowed_tags] allowed_test_attributes = [x.lower() for x in allowed_test_attributes] def parse_source_file(file_name): # Read the file and remove include directives to make life easier. file_string = str( re.compile("#include.*\n").sub("", str(open(file_name, "r").read())) ) # The (.*?); part of the regex is to capture the first line of the test # body. However, if the test case does not (yet) contain any semicolons then # we accidentally fail to find a test. test_regex = re.compile( r"(\/\/ \[\[.*?)?SPECTRE_TEST_CASE\((.*?)\) {(.*?);", re.DOTALL ) test_cases_found = re.findall(test_regex, file_string) if not test_cases_found and not "static_assert" in file_string: print( "\n\nERROR!!!\nFailed to find any test cases in the file ", file_name, ) print( "This occurs when neither a static_assert nor any " "SPECTRE_TEST_CASE are found. You may incorrectly hit this error" " message if your test case does not yet contain any code. " "Specifically, if your test case does not contain a semicolon." "\n\n\n\n" ) sys.exit(1) for attributes, test_name, test_body_first_line in test_cases_found: # Capture the name of the test into the first group and the tags into # the second. For example, # "Unit.My.Test", "[Unit][My]" # test_name == Unit.My.Test # group(2) == [Unit][My] # # Also handle cases where the name is very long and goes onto multiple # lines, # "Unit.My.Test.Name." # "Is.Very.Long", # "[Unit][My]" # test_name == Unit.My.Test.Name.Is.Very.Long # group(2) == [Unit][My] parsed_name = re.search(r'"(.*)",[\s]*"(.*)"', test_name, re.S) test_name = "".join(parsed_name.group(1).replace('"', "").split()) for disallowed_name in disallowed_test_name_portions: if test_name.lower().find(disallowed_name.lower()) != -1: print( "\nERROR: Found disallowed portion of a test name '%s' " "the test named '%s' in the file %s." % (disallowed_name, test_name, file_name) ) exit(1) test_tags = parsed_name.group(2).lower().replace("[", "")[:-1] test_tags = test_tags.split("]") for test_tag in test_tags: if not test_tag in allowed_tags: print( "\nERROR: The tag '%s' is not allowed but was found in " "the test '%s' in the file '%s'. To allow it add it to " "the 'allowed_tags' list in " "$SPECTRE_ROOT/cmake/SpectreParseTests.py. The currently " "allowed tags are:\n%s\n\n" % (test_tag, test_name, file_name, allowed_tags) ) exit(1) test_timeout = -1 for tag, timeout in default_tag_timeouts: if tag in test_tags: test_timeout = timeout # Parse the test attributes should_have_output_regex = "OUTPUT_TEST()" in test_body_first_line output_regex = "" all_attributes_by_name = re.findall( r"\[\[([^,]+), (.*?)\]\]", attributes, re.DOTALL ) for attribute in all_attributes_by_name: if not attribute[0].lower() in allowed_test_attributes: print( "\nERROR: Found unknown test attribute '%s' applied " "to test '%s' in file %s." % (attribute[0], test_name, file_name) ) exit(1) if attribute[0].lower() == "timeout": test_timeout = attribute[1] if attribute[0].lower() == "outputregex": if not should_have_output_regex: print( "\nERROR: The test '%s' in the file '%s' has the " "attribute OutputRegEx, but does not contain the " "macro OUTPUT_TEST() as its first line.\n" % (test_name, file_name) ) exit(1) output_regex = attribute[1].replace("\n//", "") if should_have_output_regex and output_regex == "": print( "\nERROR: The test '%s' in the file '%s' was marked as an " "OUTPUT_TEST(), but " "failed to produce a parsable OutputRegex attribute! " "The syntax is // [[OutputRegex, ]] as " "a comment before the SPECTRE_TEST_CASE.\n" % (test_name, file_name) ) exit(1) open("%s.timeout" % test_name, "w").write("%s" % test_timeout) open("%s.output_regex" % test_name, "w").write("%s" % output_regex) if __name__ == "__main__": import sys source_files = sys.argv[1:] for filename in source_files: parse_source_file(filename) ================================================ FILE: cmake/SpectrePythonExecutable.sh ================================================ #!/bin/bash -e # Distributed under the MIT License. # See LICENSE.txt for details. PYTHONPATH="@PYTHONPATH@" @PYTHON_EXEC_ENV_VARS@ @Python_EXECUTABLE@ \ @PYTHON_EXE_COMMAND@ "$@" ================================================ FILE: cmake/SpectreSetSiteName.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. site_name(HOSTNAME) file(APPEND "${CMAKE_BINARY_DIR}/BuildInfo.txt" "Hostname: ${HOSTNAME}\n" "Host system: ${CMAKE_HOST_SYSTEM}\n" "Host system version: ${CMAKE_HOST_SYSTEM_VERSION}\n" "Host system processor: ${CMAKE_HOST_SYSTEM_PROCESSOR}\n" ) ================================================ FILE: cmake/SpectreSetupFlagsTarget.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # The library that contains all the flags for building SpECTRE targets. # Generator expressions should be used to limit flag scopes to specific # languages and compilers. add_library(SpectreFlags INTERFACE) ================================================ FILE: cmake/SpectreSetupPythonPackage.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. if (ENABLE_PYTHON) spectre_define_test_timeout_factor_option(PYTHON "Python") option(PY_DEV_MODE "Enable development mode for the Python package, meaning \ that Python files are symlinked rather than copied to the build directory" OFF) function(configure_or_symlink_py_file SOURCE_FILE TARGET_FILE) if(PY_DEV_MODE) get_filename_component(_TARGET_FILE_DIR ${TARGET_FILE} DIRECTORY) execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${_TARGET_FILE_DIR}) execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${SOURCE_FILE} ${TARGET_FILE}) else() configure_file(${SOURCE_FILE} ${TARGET_FILE} @ONLY) endif() endfunction() set(SPECTRE_PYTHON_PREFIX "${SPECTRE_PYTHON_PREFIX_PARENT}/spectre") # Create the root __init__.py file configure_or_symlink_py_file( "${CMAKE_SOURCE_DIR}/support/Python/__init__.py" "${SPECTRE_PYTHON_PREFIX}/__init__.py" ) # Create the root __main__.py entry point configure_or_symlink_py_file( "${CMAKE_SOURCE_DIR}/support/Python/__main__.py" "${SPECTRE_PYTHON_PREFIX}/__main__.py" ) # Also link the main entry point to bin/ set(PYTHON_EXE_COMMAND "-m spectre") set(PYTHON_EXEC_ENV_VARS "") # At some point we needed to preload jemalloc for the Python bindings to work, # otherwise we got "cannot allocate memory in static TLS block" errors when # using jemalloc. This is fixed by avoiding to link jemalloc into libraries in # the first place (we only dynamically link it into executables). If we want to # link jemalloc into libraries again (e.g. to use jemalloc features explicitly # in the code), the best way to do this would be to build jemalloc with a prefix # and use it as a custom allocator where needed, instead of generically # replacing the system allocator. # # ParaView needs specific environment variables set, e.g. 'LD_LIBRARY_PATH', but # they can interfere with simulations, e.g. when they point to ParaView's # bundled MPI which may be different to the MPI we built with. Therefore we # disable this for now. This means we can't use the pre-built ParaView binaries # that bundle their own MPI and Python, unless we find a way to set the needed # environment variables only when running ParaView. Everything should work # when using a ParaView built with the same MPI and Python as the rest of # SpECTRE. # if(PARAVIEW_PYTHON_ENV_VARS) # string(APPEND PYTHON_EXEC_ENV_VARS " ${PARAVIEW_PYTHON_ENV_VARS}") # endif() # # HDF5 file locking can be a problem when a simulation is writing data and we # try to read it at the same time. We disable file locking by default when # writing H5 files in simulations (see H5File.hpp), but readers may still have # file locking enabled (e.g. h5py does this by default) and this creates file # locks at the system level that prevent the simulation from writing to the # file. Therefore we disable file locking here to avoid crashing simulations. # Better solutions are described in H5File.hpp. string(APPEND PYTHON_EXEC_ENV_VARS " HDF5_USE_FILE_LOCKING=FALSE") configure_file( "${CMAKE_SOURCE_DIR}/cmake/SpectrePythonExecutable.sh" "${CMAKE_BINARY_DIR}/tmp/spectre") file(COPY "${CMAKE_BINARY_DIR}/tmp/spectre" DESTINATION "${CMAKE_BINARY_DIR}/bin" FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) configure_file( "${CMAKE_SOURCE_DIR}/cmake/SpectrePythonExecutable.sh" "${CMAKE_BINARY_DIR}/tmp/spectre") file(COPY "${CMAKE_BINARY_DIR}/tmp/spectre" DESTINATION "${CMAKE_BINARY_DIR}/bin" FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) # Also link the Python interpreter to bin/python-spectre as an easy way to jump # into a Python shell or run a script that uses pybindings set(PYTHON_EXE_COMMAND "") configure_file( "${CMAKE_SOURCE_DIR}/cmake/SpectrePythonExecutable.sh" "${CMAKE_BINARY_DIR}/tmp/python-spectre") file(COPY "${CMAKE_BINARY_DIR}/tmp/python-spectre" DESTINATION "${CMAKE_BINARY_DIR}/bin" FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) # Write configuration files for installing the Python modules file(STRINGS ${CMAKE_SOURCE_DIR}/support/Python/requirements.txt SPECTRE_PY_DEPS) file(STRINGS ${CMAKE_SOURCE_DIR}/support/Python/dev_requirements.txt SPECTRE_PY_DEV_DEPS) list(FILTER SPECTRE_PY_DEPS EXCLUDE REGEX "^#") list(FILTER SPECTRE_PY_DEV_DEPS EXCLUDE REGEX "^#") list(REMOVE_ITEM SPECTRE_PY_DEPS "") list(REMOVE_ITEM SPECTRE_PY_DEV_DEPS "") list(JOIN SPECTRE_PY_DEPS "\n " SPECTRE_PY_DEPS_OUTPUT) list(JOIN SPECTRE_PY_DEV_DEPS "\n " SPECTRE_PY_DEV_DEPS_OUTPUT) configure_or_symlink_py_file( "${CMAKE_SOURCE_DIR}/pyproject.toml" "${SPECTRE_PYTHON_PREFIX_PARENT}/pyproject.toml") configure_or_symlink_py_file( "${CMAKE_SOURCE_DIR}/setup.cfg" "${SPECTRE_PYTHON_PREFIX_PARENT}/setup.cfg") # Write a file to be able to set up the new python path. file(WRITE "${CMAKE_BINARY_DIR}/tmp/LoadPython.sh" "#!/bin/sh\n" "export PYTHONPATH=${PYTHONPATH}\n" ) configure_file( "${CMAKE_BINARY_DIR}/tmp/LoadPython.sh" "${CMAKE_BINARY_DIR}/bin/LoadPython.sh") # Install the SpECTRE Python package to the CMAKE_INSTALL_PREFIX, using pip. # This will install the package into the expected subdirectory, typically # `lib/pythonX.Y/site-packages/`. It also creates symlinks to entry points # specified in `setup.py`. install( CODE "execute_process(\ COMMAND ${Python_EXECUTABLE} -m pip install \ --no-deps --no-input --no-cache-dir --no-index --ignore-installed \ --disable-pip-version-check --no-build-isolation \ --prefix ${CMAKE_INSTALL_PREFIX} ${SPECTRE_PYTHON_PREFIX_PARENT} \ )" ) endif() add_custom_target(all-pybindings) # Add a python module, either with or without python bindings and with # or without additional python files. If bindings are being provided then # the library will be named Py${MODULE_NAME}, e.g. if MODULE_NAME is # DataStructures then the library name is PyDataStructures. # # - MODULE_NAME The name of the module, e.g. DataStructures. # # - MODULE_PATH Path inside the module, e.g. submodule0/submodule1 would # result in loading spectre.submodule0.submodule1 # # - SOURCES The C++ source files for bindings. Omit if no bindings # are being generated. # # - LIBRARY_NAME The name of the C++ libray, e.g. PyDataStructures. # Required if SOURCES are specified. Must begin with "Py". # # - PYTHON_FILES List of the python files (relative to # ${CMAKE_SOURCE_DIR}/src) to add to the module. Omit if # no python files are to be provided. function(SPECTRE_PYTHON_ADD_MODULE MODULE_NAME) if (NOT ENABLE_PYTHON) return() endif() set(SINGLE_VALUE_ARGS MODULE_PATH LIBRARY_NAME) set(MULTI_VALUE_ARGS SOURCES PYTHON_FILES) cmake_parse_arguments( ARG "" "${SINGLE_VALUE_ARGS}" "${MULTI_VALUE_ARGS}" ${ARGN}) set(MODULE_LOCATION "${SPECTRE_PYTHON_PREFIX}/${ARG_MODULE_PATH}/${MODULE_NAME}") get_filename_component(MODULE_LOCATION ${MODULE_LOCATION} ABSOLUTE) # Add our python library, if it has sources if(BUILD_PYTHON_BINDINGS AND NOT "${ARG_SOURCES}" STREQUAL "") if("${ARG_LIBRARY_NAME}" STREQUAL "") message(FATAL_ERROR "Set a LIBRARY_NAME for Python module " "'${MODULE_NAME}' that has sources.") endif() if(NOT "${ARG_LIBRARY_NAME}" MATCHES "^Py") message(FATAL_ERROR "The LIBRARY_NAME for Python module " "'${MODULE_NAME}' must begin with 'Py' but is '${ARG_LIBRARY_NAME}'.") endif() Python_add_library(${ARG_LIBRARY_NAME} MODULE ${ARG_SOURCES}) set_target_properties( ${ARG_LIBRARY_NAME} PROPERTIES # These can be turned on once we support them INTERPROCEDURAL_OPTIMIZATION OFF CXX__VISIBILITY_PRESET OFF VISIBLITY_INLINES_HIDDEN OFF ) if (TARGET SpectrePch) target_precompile_headers(${ARG_LIBRARY_NAME} REUSE_FROM SpectrePch) target_link_libraries(${ARG_LIBRARY_NAME} PRIVATE SpectrePchFlags) endif() # In order to avoid runtime errors about missing compatibility functions # defined in the PythonBindings library, we need to link in the whole # archive. This is not needed on macOS. if (APPLE) target_link_libraries( ${ARG_LIBRARY_NAME} PUBLIC PythonBindings ) else() target_link_libraries( ${ARG_LIBRARY_NAME} PUBLIC -Wl,--whole-archive PythonBindings -Wl,--no-whole-archive ) endif() target_link_libraries( ${ARG_LIBRARY_NAME} PRIVATE CharmModuleInit SpectreFlags ) # We don't want the 'lib' prefix for python modules, so we set the output # name set_target_properties( ${ARG_LIBRARY_NAME} PROPERTIES PREFIX "" LIBRARY_OUTPUT_NAME "_Pybindings" LIBRARY_OUTPUT_DIRECTORY ${MODULE_LOCATION} ) # We need --no-as-needed since each python module needs to depend on all the # shared libraries in order to run successfully. set(PY_LIB_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS}") if(NOT APPLE) set(PY_LIB_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,--no-as-needed") endif() set_target_properties( ${ARG_LIBRARY_NAME} PROPERTIES LINK_FLAGS "${PY_LIB_LINK_FLAGS}" ) if(BUILD_TESTING) add_dependencies(test-executables ${ARG_LIBRARY_NAME}) endif() add_dependencies(all-pybindings ${ARG_LIBRARY_NAME}) endif(BUILD_PYTHON_BINDINGS AND NOT "${ARG_SOURCES}" STREQUAL "") # configure the Python source files into the build directory foreach(PYTHON_FILE ${ARG_PYTHON_FILES}) # Configure file get_filename_component(PYTHON_FILE_JUST_NAME "${CMAKE_CURRENT_SOURCE_DIR}/${PYTHON_FILE}" NAME) configure_or_symlink_py_file( "${CMAKE_CURRENT_SOURCE_DIR}/${PYTHON_FILE}" "${MODULE_LOCATION}/${PYTHON_FILE_JUST_NAME}" ) endforeach(PYTHON_FILE ${ARG_PYTHON_FILES}) # Create empty __init__.py files if none exist # We walk up the tree until we get to ${SPECTRE_PYTHON_PREFIX} set(CURRENT_MODULE ${MODULE_LOCATION}) while(NOT ${CURRENT_MODULE} STREQUAL ${SPECTRE_PYTHON_PREFIX}) set(INIT_FILE_LOCATION "${CURRENT_MODULE}/__init__.py") if(NOT EXISTS ${INIT_FILE_LOCATION}) file(WRITE ${INIT_FILE_LOCATION} "") endif() get_filename_component(CURRENT_MODULE "${CURRENT_MODULE}/.." ABSOLUTE) endwhile() endfunction() # Add headers if Python bindings are being built function (spectre_python_headers LIBRARY_NAME) if(NOT BUILD_PYTHON_BINDINGS) return() endif() spectre_target_headers( ${LIBRARY_NAME} # Forward all remaining arguments ${ARGN} ) endfunction() # Link with the LIBRARIES if Python bindings are being built function (spectre_python_link_libraries LIBRARY_NAME) if(NOT BUILD_PYTHON_BINDINGS) return() endif() target_link_libraries( ${LIBRARY_NAME} # Forward all remaining arguments ${ARGN} ) endfunction() # Add the DEPENDENCIES if Python bindings are being built function (spectre_python_add_dependencies LIBRARY_NAME) if(NOT BUILD_PYTHON_BINDINGS) return() endif() add_dependencies( ${LIBRARY_NAME} # Forward all remaining arguments ${ARGN} ) endfunction() # Register a python test file with ctest. # - TEST_NAME The name of the test, # e.g. "Unit.DataStructures.Python.DataVector" # # - FILE The file to add, e.g. Test_DataVector.py # # - TAGS A semicolon separated list of labels for the test, # e.g. "Unit;DataStructures;Python" # - PY_MODULE_DEPENDENCY # The python module that this test depends on # Set to None if there is no python module dependency # # Optionally: # - TIMEOUT secs Set the test timeout (default 2) function(SPECTRE_ADD_PYTHON_TEST TEST_NAME FILE TAGS PY_MODULE_DEPENDENCY) cmake_parse_arguments(ARG "" TIMEOUT "" ${ARGN}) if(DEFINED ARG_TIMEOUT) set(TIMEOUT ${ARG_TIMEOUT}) else() set(TIMEOUT 2) endif() get_filename_component(FILE "${FILE}" ABSOLUTE) string(TOLOWER "${TAGS}" TAGS) add_test( NAME "${TEST_NAME}" COMMAND ${Python_EXECUTABLE} ${FILE} ) spectre_test_timeout(TIMEOUT PYTHON ${TIMEOUT}) set(_PY_TEST_ENV_VARS "PYTHONPATH=${PYTHONPATH}") # The fail regular expression is what Python.unittest returns when no # tests are found to be run. We treat this as a test failure. set_tests_properties( "${TEST_NAME}" PROPERTIES FAIL_REGULAR_EXPRESSION "Ran 0 test" TIMEOUT ${TIMEOUT} LABELS "${TAGS};Python" ENVIRONMENT "${_PY_TEST_ENV_VARS}" ) # check if this is a unit test, and if so add it to the dependencies foreach(LABEL ${TAGS}) string(TOLOWER "${LABEL}" LOWER_LABEL) string(TOLOWER "${PY_MODULE_DEPENDENCY}" LOWER_DEP) if("${LOWER_LABEL}" STREQUAL "unit" AND NOT "${LOWER_DEP}" STREQUAL "none") add_dependencies(unit-tests ${PY_MODULE_DEPENDENCY}) endif() endforeach() endfunction() # Register a python test file that uses bindings with ctest. # - TEST_NAME The name of the test, # e.g. "Unit.DataStructures.Python.DataVector" # # - FILE The file to add, e.g. Test_DataVector.py # # - TAGS A semicolon separated list of labels for the test, # e.g. "Unit;DataStructures;Python" # - PY_MODULE_DEPENDENCY # The python module that this test depends on # Set to None if there is no python module dependency # # Optionally: # - TIMEOUT secs Set the test timeout (default 2) function(SPECTRE_ADD_PYTHON_BINDINGS_TEST TEST_NAME FILE TAGS PY_MODULE_DEPENDENCY) if(NOT BUILD_PYTHON_BINDINGS) return() endif() spectre_add_python_test( ${TEST_NAME} ${FILE} "${TAGS}" ${PY_MODULE_DEPENDENCY} ${ARGN}) endfunction() # Add a convenient target name for the pybindings. add_custom_target(cli) add_dependencies(cli all-pybindings) ================================================ FILE: cmake/SpectreSetupTesting.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. include(CTest) set(SPECTRE_TEST_RUNNER "" CACHE STRING "Run test executables through the given wrapper.") option(SPECTRE_TEST_TIMEOUT_FACTOR "Multiply timeout for tests by this factor") function(spectre_define_test_timeout_factor_option TEST_TYPE HELP_NAME) option(SPECTRE_${TEST_TYPE}_TEST_TIMEOUT_FACTOR "Multiply timeout for ${HELP_NAME} tests by this factor") endfunction () # Multiply BASE_TIMEOUT by the user specified option for TEST_TYPE function(spectre_test_timeout RETURN_VARIABLE TEST_TYPE BASE_TIMEOUT) if (SPECTRE_${TEST_TYPE}_TEST_TIMEOUT_FACTOR) set(FACTOR ${SPECTRE_${TEST_TYPE}_TEST_TIMEOUT_FACTOR}) elseif (SPECTRE_TEST_TIMEOUT_FACTOR) set(FACTOR ${SPECTRE_TEST_TIMEOUT_FACTOR}) else () set(FACTOR 1) endif () # Note: "1" is parsed as "ON" by cmake if (NOT "${FACTOR}" STREQUAL ON) math(EXPR RESULT "${FACTOR} * ${BASE_TIMEOUT}") else () set(RESULT ${BASE_TIMEOUT}) endif () set(${RETURN_VARIABLE} ${RESULT} PARENT_SCOPE) endfunction () ================================================ FILE: cmake/SpectreTargetHeaders.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Add header files for CMake to track for a given library # or executable. # # The header and source files together are used to track dependencies between # targets automatically in SpECTRE. Specifically, CI checks that the # dependencies of a target supply all the header files used in a library. # While this checking still requires includes to be correct (be they checked # manually or automatically), it significantly lowers the burden of correct # dependency management on developers. # # Additionally, some IDEs perform better if the header files for libraries # are known. # # Usage: # spectre_target_headers( # TARGET_NAME # INCLUDE_DIRECTORY /path/to/include/relative/to # HEADERS # A.hpp # B.hpp # B.tpp # C.hpp) # # Arguments: # - TARGET_NAME: the name of the library or executable # - INCLUDE_DIRECTORY: the directory relative to which the header # files must be included in C++ files. E.g. # `${CMAKE_SOURCE_DIR}/src` if the include paths are # relative to `${CMAKE_SOURCE_DIR}/src`. # - HEADERS: the HEADERS argument is a list of all the headers files # to append, including tpp files, relative to the current # source directory. function(spectre_target_headers TARGET_NAME) cmake_parse_arguments( ARG "" "INCLUDE_DIRECTORY" "HEADERS" ${ARGN}) get_target_property( TARGET_TYPE ${TARGET_NAME} TYPE ) if(NOT ARG_INCLUDE_DIRECTORY) message(FATAL_ERROR "Must specify the include directory relative to which the " "header files for a library will be included when calling " "spectre_target_headers. The named argument is INCLUDE_DIRECTORY. " "Call was made for target ${TARGET_NAME}.") endif(NOT ARG_INCLUDE_DIRECTORY) # Note: Search the list because an empty HEADERS is okay. list(FIND ARGN "HEADERS" _FOUND_HEADERS) if(${_FOUND_HEADERS} EQUAL -1) message(FATAL_ERROR "No HEADERS section specified in call to spectre_target_headers " "for target ${TARGET_NAME}. You must specificy HEADERS before " "listing the header files.") endif() if(NOT ${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) get_property( INCLUDE_DIRS TARGET ${TARGET_NAME} PROPERTY INCLUDE_DIRECTORIES ) if(NOT ${ARG_INCLUDE_DIRECTORY} IN_LIST INCLUDE_DIRS) set_property( TARGET ${TARGET_NAME} APPEND PROPERTY INCLUDE_DIRECTORIES ${ARG_INCLUDE_DIRECTORY} ) endif(NOT ${ARG_INCLUDE_DIRECTORY} IN_LIST INCLUDE_DIRS) endif(NOT ${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) get_property( INTERFACE_INCLUDE_DIRS TARGET ${TARGET_NAME} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ) if(NOT ${ARG_INCLUDE_DIRECTORY} IN_LIST INTERFACE_INCLUDE_DIRS) set_property( TARGET ${TARGET_NAME} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${ARG_INCLUDE_DIRECTORY} ) endif(NOT ${ARG_INCLUDE_DIRECTORY} IN_LIST INTERFACE_INCLUDE_DIRS) unset(_HEADER_FILES) foreach(HEADER ${ARG_HEADERS}) if(NOT HEADER STREQUAL "PRIVATE" AND NOT HEADER STREQUAL "PUBLIC" AND NOT HEADER STREQUAL "INTERFACE" AND NOT IS_ABSOLUTE "${HEADER}") set(_ABSOLUTE_PATH "${CMAKE_CURRENT_LIST_DIR}/${HEADER}") file(RELATIVE_PATH HEADER ${ARG_INCLUDE_DIRECTORY} ${_ABSOLUTE_PATH}) endif() list(APPEND _HEADER_FILES ${HEADER}) endforeach() if(${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) add_interface_lib_headers( TARGET ${TARGET_NAME} HEADERS ${_HEADER_FILES} ) else(${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) set_property( TARGET ${TARGET_NAME} APPEND PROPERTY PUBLIC_HEADER ${_HEADER_FILES} ) endif(${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) endfunction(spectre_target_headers TARGET_NAME) ================================================ FILE: cmake/SpectreTargetSources.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Alias for target_sources. function(spectre_target_sources TARGET) target_sources(${TARGET} ${ARGN}) endfunction() ================================================ FILE: cmake/StripSymbols.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. option(STRIP_SYMBOLS "Strip symbols from executables" OFF) if (STRIP_SYMBOLS) if (APPLE) message(FATAL_ERROR "Stripping all symbols is currently not supported on " "macOS. Please disable the `STRIP_SYMBOLS` flag.") else (APPLE) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--strip-all") endif (APPLE) endif(STRIP_SYMBOLS) ================================================ FILE: cmake/UpdateAddExecutables.cmake ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. function(add_spectre_executable TARGET_NAME) _add_spectre_executable(${TARGET_NAME} ${ARGN}) if (USE_PCH) get_target_property( TARGET_IS_IMPORTED ${TARGET_NAME} IMPORTED ) if(NOT ${TARGET_IS_IMPORTED} AND TARGET SpectrePch) target_precompile_headers(${TARGET_NAME} REUSE_FROM SpectrePch) target_link_libraries(${TARGET_NAME} PRIVATE SpectrePchFlags) endif() endif (USE_PCH) endfunction() ================================================ FILE: containers/Dockerfile.buildenv ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # If you change this file please push the new images to DockerHub. If you do not # have permission to push to DockerHub please coordinate with someone who does. # Since changes to this image affect our testing infrastructure it is important # all changes be carefully reviewed before they are pushed. # # GitHub Actions (recommended method) # # This is how you use GitHub Actions to build and push the new images: # # 1. Push your changes to the `develop` branch on your fork of the spectre # repository on GitHub (https://github.com/YOURNAME/spectre). # 2. Go to https://github.com/YOURNAME/spectre/actions/workflows/BuildDockerContainer.yaml. # 3. Select "Run workflow". Here you can select the location on DockerHub where # you want the new images pushed. Select `sxscollaboration/spectre` (which is # used by CI) or a location on your own DockerHub account. Either way, you # need to set the `DOCKERHUB_USERNAME` and `DOCKERHUB_TOKEN` secrets in the # repository to credentials that have write access. # 4. The images will be built and pushed to DockerHub and CI will run over them. # See `.github/workflows/BuildDockerContainer.yaml` for details. # # Local build & push (can be tedious and time consuming) # # What you need to push to Dockerhub is: # # Arch: linux/amd64,linux/arm64 # # Note that cross compiling can be slow, so for testing just do amd64 # # or arm64 depending on your CPU. Docker builds the image in a way # # that when someone clones it, depending on their CPU architecture, # # they will get either the amd64 or arm64 version. # Ubuntu version: 22.04 (default) # --platform linux/amd64,linux/arm64 # --target dev # -t sxscollaboration/spectre:dev # # Arch: linux/amd64 # Ubuntu version: 18.04 # --platform linux/amd64 # --target dev # -t sxscollaboration/spectre:dev1804 # --build-arg UBUNTU_VERSION=18.04 # # Docker must be run as root on your machine. There are 4 different images in # this Dockerfile, but you can ignore the 'deploy_static_execs_and_libs' since # it's only used in CI. Here is how to build them for x86_64 (for Apple Silicon, # replace linux/amd64 with linux/arm64): # # 1. `dev` # # cd $SPECTRE_HOME # docker build --target dev -t sxscollaboration/spectre:dev \ # --platform linux/amd64 \ # -f ./containers/Dockerfile.buildenv . # # # Cross compiling for AMD64 and ARM64: # # # # To check if you can cross compile, first run # # docker buildx ls # # This will look something like: # # NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT \ # # PLATFORMS # # default* docker # # \_ default \_ default running v0.13.2 \ # # linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386 # # # # Note that the DRIVER/ENDPOINT is 'docker'. We want to instead use # # 'docker-container'. To do this, run # # docker buildx create --name mybuilder --bootstrap --use # # When you run 'docker buildx ls' now you should see # # mybuilder* docker-container # # The asterisk means docker will use this builder. You are now ready to # # cross-compile code. # # # # This is documented at: # # https://docs.docker.com/build/building/multi-platform/#getting-started # # docker buildx build --target dev -t sxscollaboration/spectre:dev \ # --platform linux/amd64,linux/arm64 \ # -f ./containers/Dockerfile.buildenv --push . # # You DO NOT need to push the below. CI does that automatically. # # 3. `demo` To build this, you MUST first push the `dev` images to # DockerHub as the `demo` image uses the remote `dev` image. # # docker push sxscollaboration/spectre:dev # # To build `demo`, you must be in $SPECTRE_ROOT and there cannot be a # directory named `build` in $SPECTRE_ROOT because the image will create # this directory (in the container). # # cd $SPECTRE_HOME # rm -rf build/ # docker build --target demo -t sxscollaboration/spectre:demo \ # --platform linux/amd64 \ # -f ./containers/Dockerfile.buildenv . # # and then to push the `demo` image to DockerHub: # # docker push sxscollaboration/spectre:demo # # 4. `deploy_static_execs_and_libs` This is used for building various # executables and libraries with an old enough version of glibc so # that the resulting executables are quite portable. This must be built # as, but should generally only be done in CI unless you are debugging # the container build. # # docker build --target deploy_static_execs_and_libs --platform linux/amd64 \ # --build-arg UBUNTU_VERSION=18.04 -f ./containers/Dockerfile.buildenv . # # That is, it uses Ubuntu 18.04 and AMD64. There is no support for ARM and # newer versions of Ubuntu will limit compatibility. ARG UBUNTU_VERSION=22.04 FROM ubuntu:${UBUNTU_VERSION} AS base ARG UBUNTU_VERSION=22.04 # See # https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope # for how TARGETARCH is defined. ARG TARGETARCH # Install add-apt-repository and basic tools RUN if [ ${UBUNTU_VERSION} = 18.04 ] && [ "$TARGETARCH" = "arm64" ]; then \ echo "Cannot use Ubuntu 18.04 with ARM" && exit 1; fi && apt-get update -y \ && apt-get install -y software-properties-common wget git file \ && add-apt-repository ppa:ubuntu-toolchain-r/test # Add LLVM apt repository for newer versions of clang RUN wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | \ tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc \ && if [ ${UBUNTU_VERSION} = 18.04 ]; then \ add-apt-repository -y \ 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-17 main'; \ elif [ ${UBUNTU_VERSION} = 22.04 ]; then \ add-apt-repository -y \ 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-16 main'; \ else \ exit 1; \ fi # Install compilers and build tools RUN apt-get update -y \ && if [ ${UBUNTU_VERSION} = 18.04 ]; then \ apt-get install -y gcc-10 g++-10 gfortran-10 clang-17; \ else \ apt-get install -y gcc g++ gfortran clang clang-format clang-tidy cmake; \ fi \ && apt-get install -y lld bison flex libncurses-dev gdb autoconf automake \ ninja-build lcov \ && if [ ${UBUNTU_VERSION} = 18.04 ]; then \ wget -O cmake-install.sh \ "https://github.com/Kitware/CMake/releases/download/v3.28.1/cmake-3.28.1-linux-x86_64.sh" \ && chmod +x ./cmake-install.sh && ./cmake-install.sh --skip-license \ --prefix=/usr/local && rm cmake-install.sh; \ fi # Install SpECTRE dependencies that are available through apt # # We intentionally don't install libboost-all-dev because that installs # Boost.MPI, which installs OpenMPI into the container. When MPI is # installed inside the container it makes it very difficult to use # Singularity on HPC systems to interface with the system MPI library. # The system MPI libraries are usually configured to take advantage of # InfiniBand or various other networking layers. RUN apt-get update -y \ && apt-get install -y \ libopenblas-dev liblapack-dev \ libgsl-dev \ libboost-dev libboost-program-options-dev \ libboost-thread-dev libboost-tools-dev libssl-dev \ libhdf5-dev hdf5-tools \ libarpack2-dev \ libbenchmark-dev \ && if [ ${UBUNTU_VERSION} = 18.04 ]; then \ wget https://github.com/jbeder/yaml-cpp/archive/refs/tags/0.8.0.tar.gz \ && tar xf 0.8.0.tar.gz && mkdir ./yaml-cpp-0.8.0/build \ && cd ./yaml-cpp-0.8.0/build \ && cmake \ -D CMAKE_C_COMPILER=gcc-10 \ -D CMAKE_CXX_COMPILER=g++-10 \ -D CMAKE_BUILD_TYPE=Release \ -D YAML_BUILD_SHARED_LIBS=OFF \ -D BUILD_SHARED_LIBS=OFF \ -D YAML_ENABLE_PIC=ON \ -D POSITION_INDEPENDENT_CODE=ON \ -D YAML_CPP_BUILD_TESTS=OFF \ -D YAML_CPP_BUILD_CONTRIB=OFF \ -D CMAKE_INSTALL_PREFIX=/usr/local \ .. \ && make ${PARALLEL_MAKE_ARG} && make install \ && cd ../.. && rm -rf ./0.8.0.tar.gz ./yaml-cpp-0.8.0; \ else \ apt-get install -y libjemalloc2 libjemalloc-dev libyaml-cpp-dev; \ fi # Install Python packages # We only install packages that are needed by the build system (e.g. to compile # Python bindings or build documentation) or used by Python code that is # unit-tested. Any other packages can be installed on-demand. # - We use python-is-python3 because on Ubuntu 20.04 /usr/bin/python was removed # to aid in tracking down anything that depends on python 2. However, many # scripts use `/usr/bin/env python` to find python so restore it. # - We install h5py explicitly from binary so that cross compilation is quicker. COPY support/Python/requirements.txt requirements.txt COPY support/Python/dev_requirements.txt dev_requirements.txt ENV DEBIAN_FRONTEND noninteractive RUN apt-get update -y \ && if [ ${UBUNTU_VERSION} = 18.04 ]; then \ apt-get install -y zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev \ libssl-dev libreadline-dev libffi-dev libsqlite3-dev wget libbz2-dev \ make \ && wget https://www.python.org/ftp/python/3.10.1/Python-3.10.1.tgz \ && tar -xf Python-3.10.1.tgz && cd ./Python-3.10.1 \ && ./configure --enable-optimizations && make ${PARALLEL_MAKE_ARG} \ && make altinstall && cd ../ \ && rm -rf ./Python-3.10.1.tgz ./Python-3.10.1 \ && python3.10 -m pip install --upgrade pip \ && pip3.10 --no-cache-dir install --only-binary=h5py -r requirements.txt \ -r dev_requirements.txt; \ else \ apt-get install -y python3-pip python-is-python3 pkg-config \ && pip3 --no-cache-dir install --only-binary=h5py -r requirements.txt \ -r dev_requirements.txt; \ fi \ && rm requirements.txt dev_requirements.txt # Enable bash-completion by installing it and then adding it to the .bashrc file RUN apt-get update -y \ && apt-get install -y bash-completion \ && printf "if [ -f /etc/bash_completion ] && ! shopt -oq posix; then\n\ . /etc/bash_completion\nfi\n\n" >> /root/.bashrc # WARNING: We switch to an empty container briefly!!! # # Cross-compile dependencies on the host system that take a long time to build # when emulating the target architecture. The `xbuild` stage is an image with # the same architecture as the host. It compiles the packages for the target # architecture. Then we can copy the compiled packages into the `base` image. # # Note: because we only cross-compile the latest Ubuntu version we support, # we just delete the executables on Ubuntu 18.04 and disable doxygen and ccache. FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx FROM --platform=$BUILDPLATFORM ubuntu:22.04 AS xbuild WORKDIR /root COPY --from=xx / / ARG TARGETPLATFORM ARG UBUNTU_VERSION=22.04 ARG PARALLEL_MAKE_ARG=-j4 # Install build dependencies for the host system RUN apt-get update -y \ && apt-get install -y cmake clang lld flex bison wget git # Install build dependencies for the target architecture # # We need libstd++ to work on the target arch that we are cross-compiling for RUN xx-apt-get update -y \ && xx-apt-get install -y --no-install-recommends \ libc6-dev libstdc++-10-dev # - Ccache RUN wget https://github.com/ccache/ccache/releases/download/v4.8.2/ccache-4.8.2.tar.gz -O ccache.tar.gz \ && tar -xzf ccache.tar.gz \ && mv ccache-* ccache \ && cd ccache \ && mkdir build && cd build \ && cmake $(xx-clang --print-cmake-defines) \ -D HAVE_ASM_SSE2=OFF -D HAVE_ASM_SSE41=OFF \ -D HAVE_ASM_AVX2=OFF -D HAVE_ASM_AVX512=OFF \ -D CMAKE_BUILD_TYPE=Release .. \ && make $PARALLEL_MAKE_ARG # - Doxygen RUN wget https://github.com/doxygen/doxygen/archive/Release_1_14_0.tar.gz -O doxygen.tar.gz \ && tar -xzf doxygen.tar.gz \ && mv doxygen-* doxygen \ && cd doxygen \ && mkdir build && cd build \ && cmake $(xx-clang --print-cmake-defines) \ -D CMAKE_BUILD_TYPE=Release .. \ && make $PARALLEL_MAKE_ARG # WARNING: We now copy the things from the "xbuild" container/image into the # xbuild-test container to make sure the copying works. We do the # actual copy into the spectre container below. # FROM base AS xbuild-test ARG UBUNTU_VERSION=22.04 COPY --from=xbuild /root/ccache/build/ccache /usr/local/bin RUN ccache --version COPY --from=xbuild /root/doxygen/build/bin/doxygen /usr/local/bin RUN doxygen --version COPY --from=xbuild /usr/local/bin/cmake /work/ RUN /work/cmake --version \ && if [ ${UBUNTU_VERSION} = 18.04 ]; then \ rm /usr/local/bin/ccache /usr/local/bin/doxygen; \ else \ mv /work/cmake /usr/local/bin; \ fi # WARNING: We are now back in the spectre container. We create two base # images for the 2 possible target architectures and then select # the one we need as the `dev` container below. This is essentially an # `if` in the Dockerfile. # # Install software that we can't install through apt. We have to distinguish # between different architectures for many of those. FROM base AS base-amd64 ENV CHARM_ARCH=x86_64 ENV TEX_ARCH=x86_64 FROM base AS base-arm64 ENV CHARM_ARCH=arm8 ENV TEX_ARCH=aarch64 FROM base-${TARGETARCH} AS dev ARG TARGETARCH ARG UBUNTU_VERSION=22.04 ARG PARALLEL_MAKE_ARG=-j4 ARG DEBIAN_FRONTEND=noninteractive # We install dependencies not available through apt manually rather than using # Spack since Spack ends up building a lot of dependencies from scratch # that we don't need. Thus, not building the deps with Spack reduces total # build time of the Docker image. # - Blaze RUN git clone --depth 1 --branch v3.8.1 https://bitbucket.org/blaze-lib/blaze.git blaze \ && mv blaze/blaze /usr/local/include \ && rm -rf blaze* # - Catch2 RUN wget https://github.com/catchorg/Catch2/archive/refs/tags/v3.14.0.tar.gz -O catch.tar.gz \ && tar -xzf catch.tar.gz && rm catch.tar.gz \ && mv Catch2-* Catch2 \ && cd Catch2 \ && cmake -B build -D BUILD_TESTING=OFF \ -D CMAKE_POSITION_INDEPENDENT_CODE=ON \ && cd build \ && make $PARALLEL_MAKE_ARG install \ && cd ../.. && rm -rf Catch2 # - Ccache COPY --from=xbuild /root/ccache/build/ccache /usr/local/bin # - Doxygen COPY --from=xbuild /root/doxygen/build/bin/doxygen /usr/local/bin # - Libbacktrace RUN git clone https://github.com/ianlancetaylor/libbacktrace \ && cd libbacktrace \ && ./configure --prefix=/usr/local \ && make $PARALLEL_MAKE_ARG install \ && cd .. && rm -rf libbacktrace # - LibXSMM RUN if [ "$TARGETARCH" = "arm64" ] ; then \ git clone --single-branch --branch main --depth 1 \ https://github.com/libxsmm/libxsmm.git libxsmm \ && cd libxsmm \ && make $PARALLEL_MAKE_ARG PREFIX=/usr/local/ PLATFORM=1 install \ && cd .. \ && rm -rf libxsmm; \ else \ wget https://github.com/libxsmm/libxsmm/archive/1.16.1.tar.gz \ -O libxsmm.tar.gz \ && tar -xzf libxsmm.tar.gz \ && mv libxsmm-* libxsmm \ && cd libxsmm \ && make $PARALLEL_MAKE_ARG PREFIX=/usr/local/ install \ && cd .. \ && rm -rf libxsmm libxsmm.tar.gz; \ fi # - xsimd https://github.com/xtensor-stack/xsimd RUN wget http://github.com/xtensor-stack/xsimd/archive/refs/tags/11.1.0.tar.gz -O xsimd.tar.gz \ && tar -xzf xsimd.tar.gz && rm xsimd.tar.gz \ && cd ./xsimd-* \ && mkdir build \ && cd ./build \ && cmake -D CMAKE_BUILD_TYPE=Release \ -D CMAKE_INSTALL_PREFIX=/usr/local ../ \ && make install \ && cd ../.. && rm -rf xsimd-* # Update ld cache to find shared libs in /usr/local/lib/ RUN ldconfig WORKDIR /work # Download and build the Charm++ version used by SpECTRE # We check out only a specific branch in order to reduce the repo size. # # We remove the `doc` and `example` directories since these aren't useful to us # in the container and we want to reduce the size of the container. We do NOT # remove the `tmp` directories inside the Charm++ build directories because # Charm++ stores non-temporary files (such as headers) that are needed when # building with Charm++ in the `tmp` directories. # # We build with debug symbols to make debugging Charm++-interoperability # easier for people, and build with O2 to reduce build size. RUN wget https://raw.githubusercontent.com/sxs-collaboration/spectre/develop/support/Charm/v7.0.0.patch RUN git clone --single-branch --branch v7.0.1 --depth 1 \ https://github.com/UIUC-PPL/charm charm_7_0_0 \ && cd /work/charm_7_0_0 \ && git checkout v7.0.1 \ && git apply /work/v7.0.0.patch \ && ./build charm++ multicore-linux-${CHARM_ARCH} gcc \ ${PARALLEL_MAKE_ARG} -g -O2 --build-shared --with-production \ && rm -r /work/charm_7_0_0/doc /work/charm_7_0_0/examples ENV CHARM_ROOT="/work/charm_7_0_0/multicore-linux-${CHARM_ARCH}-gcc" # Set the environment variable SPECTRE_CONTAINER so we can check if we are # inside a container (0 is true in bash) ENV SPECTRE_CONTAINER 0 # The singularity containers work better if the locale is set properly RUN apt-get update -y \ && apt-get install -y locales language-pack-fi language-pack-en \ && export LANGUAGE=en_US.UTF-8 \ && export LANG=en_US.UTF-8 \ && export LC_ALL=en_US.UTF-8 \ && locale-gen en_US.UTF-8 \ && dpkg-reconfigure locales # Install bibtex for Doxygen bibliography management # We first install the TeXLive infrastructure according to the configuration in # support/TeXLive/texlive.profile and then use it to install the bibtex package. # # WARNING: if you are rebuilding the container in late March/early April you # might have version mismatches between the TeXLive installer respositories like # CTAN. You can then use the previous year's TeXLive until CTAN is updated. E.g. # wget \ # ftp://tug.org/historic/systems/texlive/2025/tlnet-final/install-tl-unx.tar.gz # and # install-tl-*/install-tl -profile=texlive.profile \ # -repository ftp://tug.org/historic/systems/texlive/2025/tlnet-final RUN if [ ${UBUNTU_VERSION} = 22.04 ]; then \ mkdir /work/texlive && cd /work/texlive \ && wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz \ && tar -xzf install-tl-unx.tar.gz \ && rm install-tl-unx.tar.gz \ && wget https://raw.githubusercontent.com/sxs-collaboration/spectre/develop/support/TeXLive/texlive.profile \ && install-tl-*/install-tl -profile=texlive.profile \ && rm -r install-tl-* texlive.profile install-tl.log \ && /work/texlive/bin/${TEX_ARCH}-linux/tlmgr install bibtex \ ; fi ENV PATH="${PATH}:/work/texlive/bin/${TEX_ARCH}-linux" # Remove the apt-get cache in order to reduce image size RUN apt-get -y clean WORKDIR /work # Deploy compiled executables to an image that can be run on HPC systems. # - We could also compile in the dev container and then copy the executables to # a minimal deploy container to reduce its size. That requires keeping track # of the shared libraries that are needed to run the executables, so to make # things easier we just base the deploy container on the dev container. # - We inherit from the remote image rather than the local dev because it is # faster on release CI to just pull the remote dev image rather than having to # build the dev container again. We could pre-fetch the dev image and then # build from the local cache, but that didn't work right away. FROM sxscollaboration/spectre:dev AS deploy ARG BUILDARCH ARG TARGETARCH ARG UBUNTU_VERSION=22.04 ARG PARALLEL_MAKE_ARG=-j2 COPY . spectre/ RUN mkdir spectre/build && cd spectre/build \ && cmake \ -D CMAKE_C_COMPILER=clang \ -D CMAKE_CXX_COMPILER=clang++ \ -D CMAKE_Fortran_COMPILER=gfortran \ -D CMAKE_BUILD_TYPE=Release \ -D DEBUG_SYMBOLS=OFF \ -D BUILD_PYTHON_BINDINGS=ON \ -D MEMORY_ALLOCATOR=SYSTEM \ .. # Skip compiling the executables if we are emulating the target architecture # because that takes a long time. They can be compiled on-demand. RUN if [ "$TARGETARCH" = "$BUILDARCH" ] ; then \ cd spectre/build \ && make ${PARALLEL_MAKE_ARG} cli \ && make ${PARALLEL_MAKE_ARG} CharacteristicExtract \ && make ${PARALLEL_MAKE_ARG} PreprocessCceWorldtube \ && make ${PARALLEL_MAKE_ARG} WriteCceWorldtubeCoordsToFile \ && make ${PARALLEL_MAKE_ARG} SolveXcts \ ; fi ENV SPECTRE_HOME /work/spectre ENV PATH $SPECTRE_HOME/build/bin:$PATH ENV PYTHONPATH $SPECTRE_HOME/build/bin/python:$PYTHONPATH # Set the CLI as entrypoint ENTRYPOINT ["spectre"] CMD ["--help"] # Build a demo image with extra software used in the tutorials. FROM deploy AS demo ARG BUILDARCH ARG TARGETARCH ARG UBUNTU_VERSION=22.04 ARG PARALLEL_MAKE_ARG=-j4 # vim and emacs for editing files # Also ffmpeg for making movies with paraview output pngs # paraview needs curl RUN apt-get update -y \ && apt-get install -y vim emacs-nox ffmpeg curl # Install headless paraview so we can run pvserver in the container # Note: there is no arm64 linux binary of paraview available, so don't # install paraview when building for Apple Silicon. Apple Silicon users # should install a binary of ParaView for Mac and move data to be # visualized outside of the container. RUN if [ "$TARGETARCH" != "arm64" ] ; then \ wget -O paraview.tar.gz --no-check-certificate "https://www.paraview.org/paraview-downloads/download.php?submit=Download&version=v5.10&type=binary&os=Linux&downloadFile=ParaView-5.10.1-osmesa-MPI-Linux-Python3.9-x86_64.tar.gz" \ && tar -xzf paraview.tar.gz \ && rm paraview.tar.gz \ && mv ParaView-* /opt/paraview; \ fi ENV PATH "/opt/paraview/bin:$PATH" # Build the executables used in the tutorial RUN if [ "$TARGETARCH" = "$BUILDARCH" ] ; then \ cd spectre/build \ && make ${PARALLEL_MAKE_ARG} ExportCoordinates3D \ && make ${PARALLEL_MAKE_ARG} EvolveScalarAdvection2D \ ; fi RUN pip3 --no-cache-dir install jupyterlab # Used for compiling the static executables and libraries during CI so that we # can release statically linked versions of our executables and libraries # for other groups to use. FROM sxscollaboration/spectre:dev1804 AS deploy_static_execs_and_libs ARG BUILDARCH ARG TARGETARCH ARG UBUNTU_VERSION=18.04 ARG PARALLEL_MAKE_ARG=-j4 WORKDIR /work COPY . spectre/ # Build SpECTRE with as many static libraries as possible. Because we cannot # statically link to glibc (it is unsupported and causes a lot of undefined # behavior) we build using Ubuntu 18.04 to support a fairly old version of # glibc. RUN if [ ${UBUNTU_VERSION} != 18.04 ] && [ "$TARGETARCH" != "amd64" ]; then \ echo "Must use Ubuntu 18.04 with AMD64 for deploying static execs" \ && exit 1; fi \ && mkdir spectre/build && cd spectre/build \ && cmake \ -D CMAKE_C_COMPILER=gcc-10 \ -D CMAKE_CXX_COMPILER=g++-10 \ -D CMAKE_Fortran_COMPILER=gfortran-10 \ -D CMAKE_BUILD_TYPE=Release \ -D DEBUG_SYMBOLS=OFF \ -D BUILD_PYTHON_BINDINGS=OFF \ -D MEMORY_ALLOCATOR=SYSTEM \ -D BUILD_SHARED_LIBS=OFF \ -D ENABLE_PARAVIEW=OFF \ -D Boost_USE_STATIC_LIBS=ON \ -D BLA_STATIC=ON \ -D GSL_STATIC=ON \ -D HDF5_USE_STATIC_LIBRARIES=ON \ -D SPECTRE_Fortran_STATIC_LIBS=ON \ -D YAMLCPP_STATIC_LIBRARY=ON \ -D USE_GIT_HOOKS=OFF \ -D OVERRIDE_ARCH=haswell \ -D USE_LD=gold \ -D gfortran=/usr/lib/gcc/x86_64-linux-gnu/9/libgfortran.a \ -D quadmath=/usr/lib/gcc/x86_64-linux-gnu/9/libquadmath.a \ -D BUILD_DOCS=OFF \ -D USE_CCACHE=OFF \ .. \ && make ${PARALLEL_MAKE_ARG} CharacteristicExtract PreprocessCceWorldtube \ WriteCceWorldtubeCoordsToFile \ && ctest -LE unit -R CharacteristicExtract -E KleinGordon ================================================ FILE: docs/.nojekyll ================================================ ================================================ FILE: docs/CODE_OF_CONDUCT.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # SpECTRE Code of Conduct {#code_of_conduct} With the goal of supporting our community in doing the best science we can, we expect that all contributors and maintainers of SpECTRE: - Behave professionally in a way that is welcoming and respectful to all participants. - Behave in a way that is free from any form of discrimination, harassment, or retaliation. - Treat each other with collegiality and respect and help to create a supportive working environment. This code of conduct is not an exhaustive list of things that you should or should not do. Rather, take it in the spirit in which it’s intended — a guide to make it easier to communicate and participate in the community. This code of conduct applies to all spaces managed by the SpECTRE project. This includes Slack channels, wikis, mailing lists, issue trackers, pull request comments, SpECTRE project events, and any other forums created by the project for communication. It applies to all of your communication and conduct in these spaces, including emails, chats, things you say, slides, videos, posters, signs, or even t-shirts you display in these spaces. In addition, violations of this code outside these spaces may, in rare cases, affect a person’s ability to participate within them, when the conduct amounts to an egregious violation of this code. If you believe someone is violating the code of conduct, we ask that you report it by emailing conduct@spectre-code.org. For more details please see our \ref reporting_guide "Reporting Guide". If you would rather not formally report your concern, you should feel free to discuss it informally and confidentially with one of the project leaders. More specifically, we expect members of the SpECTRE community to: - Be friendly and patient. During teleconferences and meetings, participants who wish to speak should feel free to type “hand up” or similar in the comment box, as needed, to get the chairs’ attention. Meeting/teleconference chairs are encouraged to make space for those unfamiliar with the topic of discussion to ask questions and engage. - Be welcoming. We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, colour, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion or lack thereof, and mental and physical ability. - Be considerate. Your work will be used by other people, and you in turn will depend on the work of others. Any decision you take will affect users and colleagues, and you should take those consequences into account. Remember that we are a world-wide community, so you might not be communicating in someone else’s primary language. - Be respectful. Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It is important to remember that a community where people feel uncomfortable or threatened is not a productive one. Members of the SpECTRE community should be respectful when dealing with other members as well as with people outside the community. - Be careful in the words that you choose and be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren’t acceptable. This includes, but is not limited to: - Violent threats or language directed against another person. - Discriminatory jokes and language. - Posting sexually explicit or violent material. - Posting (or threatening to post) other people’s personally identifying information (“doxing”). - Personal insults, especially those using racist or sexist terms. - Unwelcome sexual attention. - Advocating for, or encouraging, any of the above behavior. In general, if someone asks you to stop, then stop. Persisting in such behavior after being asked to stop is considered harassment. - When we disagree, try to understand why. Disagreements, both social and technical, happen all the time, and SpECTRE is no exception. It is important that we resolve disagreements and differing views constructively. Remember that we are different. The strength of communities comes from having a varied community, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint does not mean that they are wrong. Do not forget that it is human to err and blaming each other does not get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes. ### Attribution This Code of Conduct is adapted from the [SXS Collaboration Code of Conduct](https://www.black-holes.org/sxs_code_of_conduct.pdf), which is based on a draft of the [LLVM Code of Conduct](https://llvm.org/docs/CodeOfConduct.html) which is adapted from [Django Project Code of Conduct](https://www.djangoproject.com/conduct/) which used text from the [Speak Up! Code of Conduct](http://web.archive.org/web/20141109123859/http://speakup.io/coc.html). ================================================ FILE: docs/CONTRIBUTING.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Contributing to SpECTRE {#contributing_to_spectre} \tableofcontents # Contributing to SpECTRE {#contributing_to_spectre_2} The following is a set of guidelines for contributing to SpECTRE, which is hosted in the [Simulating eXtreme Spacetimes Organization](https://github.com/sxs-collaboration) on GitHub. ## Code of Conduct This project and everyone participating in it is governed by the \ref code_of_conduct "SpECTRE Code of Conduct". By participating, you are expected to uphold this code. Please report possible violations of the code of conduct to conduct@spectre-code.org. ## What should I know before I get started? {#getting-started} SpECTRE is being developed in support of our collaborative Simulating eXtreme Spacetimes (SXS) research program into the multi-messenger astrophysics of neutron star mergers, core-collapse supernovae, and gamma-ray bursts. As such, almost all of the current contributors to SpECTRE are members of SXS institutions, and a large amount of discussion about SpECTRE is done in internal SXS meetings. If you are a member of SXS and wish to get involved, please contact one of the project leaders. In the future, we hope that SpECTRE can be applied to problems across discipline boundaries, and that it can be a true community code. At the present time, however, SpECTRE cannot yet solve realistic problems, and broad overview documentation is in an early, incomplete stage. Therefore, if you are not a member of SXS, but are interested in contributing to SpECTRE, we strongly encourage you to contact us at questions@spectre-code.org to discuss possible contributions. ## How Can I Contribute? {#how-can-i-contribute} ### Reporting Bugs {#reporting-bugs} This section guides you through submitting a bug report for SpECTRE. Following these guidelines helps maintainers and the community understand your report, reproduce the behavior, and find related reports. Before creating bug reports, please **perform a [search](https://github.com/sxs-collaboration/spectre/issues)** to see if the problem has already been reported. If it has **and the issue is still open**, please add a comment to the existing issue instead of opening a new one. > **Note:** If you find a **Closed** issue that seems like it is the > same thing that you're experiencing, please open a new issue and > include a link to the original issue in the body of your new one. #### How Do I Submit A (Good) Bug Report? {#submit-bug-report} Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). When you are creating a bug report, please **include as many details as possible**. Please fill out the template completely. The provided information helps us resolve issues faster. Explain the problem and include additional details to help maintainers reproduce the problem: * **Use a clear and descriptive title** for the issue to identify the problem. * **Describe the exact steps which reproduce the problem** in as much detail as possible. For example, start by explaining how you started SpECTRE, e.g. the exact command you used in the terminal, or the contents of the batch job script you used. * **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior. * **Explain which behavior you expected to see instead and why.** Provide more context by answering these questions: * **Can you reproduce the problem in both debug and release mode?** (this is controlled by the CMake flag `CMAKE_BUILD_TYPE`) * **Did the problem start happening recently** (e.g. after updating to a new version/commit of SpECTRE) or was this always a problem? * If the problem started happening recently, **can you reproduce the problem in an older version/commit?** What's the most recent version/commit in which the problem doesn't happen? * **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens. * **Can you reproduce the problem on another machine?** * **Can you reproduce the problem in the docker container?** (see the \ref installation "Installation notes") Include details about your configuration and environment: * **Add as an attachment** (or add the contents of) the following: - The text output by SpECTRE (including any stack trace) - The input file(s) - $SPECTRE_BUILD_DIR/BuildInfo.txt * **What is the name and version of the OS you're using**? * If possible (for SXS computers or HPC systems), a **path to a run directory** that is accessible by SpECTRE core developers. ### Suggesting Enhancements {#suggesting-enhancements} This section guides you through submitting an enhancement suggestion for SpECTRE, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion and find related suggestions. Before creating enhancement suggestions, please **perform a [search](https://github.com/sxs-collaboration/spectre/issues)** to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. #### How Do I Submit A (Good) Enhancement Suggestion? {#submit-enhancement} Enhancement suggestions are tracked as [GitHub issues](https://guides.github.com/features/issues/). When you are creating an enhancement suggestion, please **include as many details as possible** as you fill in the template. * **Use a clear and descriptive title** for the issue to identify the suggestion. * **Provide a step-by-step description of the suggested enhancement** in as many details as possible. * **Explain why this enhancement would be useful** to most SpECTRE users. ### Your First Code Contribution {#first-code-contribution} Unsure where to begin contributing to SpECTRE? You can start by looking through these `good first issue` and `help wanted` issues: * [Good first issues][good-first-issue] - issues which should only require a few lines of code, and a test or two. * [Help wanted issues][help-wanted] - issues which should be a bit more involved than `good first issue`s. #### Local development {#local-development} SpECTRE can be developed locally. For instructions on how to do this, see the following sections in the [SpECTRE documentation](https://spectre-code.org/): * [Installing SpECTRE](installation.html) * [Running Status Checks Locally](github_actions_guide.html#perform-checks-locally) ## Pull Requests {#pull-requests} Code contributions to SpECTRE follow a [pull request model](https://help.github.com/articles/about-pull-requests/) The process described here has several goals: - Maintain SpECTRE's code and documentation quality - Reach science goals in a timely manner - Fix problems that are important to users - Engage the community in working toward the best possible code - Enable a sustainable system for SpECTRE's maintainers to review contributions Please follow these steps to have your contribution considered by the maintainers: 1. Follow the \ref code_review_guide "code review guidelines", the \ref writing_unit_tests "guide to writing unit tests", and the \ref writing_good_dox "guide to writing documentation" 2. Follow all instructions in the pull request template. Reference related issues and pull requests. 3. After you submit your pull request, verify that all [status checks](https://help.github.com/articles/about-status-checks/) are passing > If a status check is failing, and you believe that the failure is > unrelated to your change, please leave a comment on the pull > request explaining why you believe the failure is unrelated. A > maintainer will re-run the status check for you. If we conclude > that the failure was a false positive, then we will open an issue > to track that problem with our status check suite. Only those status check failures that occur in the containerized build environment are your responsibility to fix. If you encounter an issue with a status check that runs in an environment that you do not have access to, e.g. on macOS or on a supercomputer, please notify `@sxs-collaboration/spectre-core-devs`. They will refer the issue to a person who has access to that environment. Unless requested by the reviewers, the PR will not be held up until the issue is resolved. While the prerequisites above must be satisfied prior to having your pull request reviewed, the reviewers may ask you to complete additional design work, tests, or other changes before your pull request can be ultimately accepted. ## How SpECTRE pull request reviews are conducted {#pull-request-reviews} > Note that these are guidelines and not rigid rules. Please make your pull requests as small as reasonably possible, as smaller pull requests are easier to review. In general, longer pull requests take longer to review, with the time scaling exponentially with the number of lines changed. Therefore if your pull request is too large, we may ask you to break it up into several smaller pull requests. If you would like feedback on a pull request prior to it being ready for formal review, please open it [in draft mode](https://github.blog/2019-02-14-introducing-draft-pull-requests/) and [request reviews][request-reviews] from whomever you wish to get feedback from. As long as the PR is in draft mode it will not be reviewed, aside from the feedback requested. > Below, days mean business days, so if the time period includes the > weekend, add two days, and for major holidays add a day. > Furthermore, most of us are academics, and we occasionally go to > conferences which may lead to delays in the review process. Also do > not expect much to happen between December 20th and January 3rd. Most pull requests submitted to SpECTRE will be reviewed in the following manner: - Within two days, one of the [SpECTRE core developers](#core-developers) will either review the PR or assign reviewers. If this has not happened after two days, please [request a review][request-reviews] and select the `@sxs-collaboration/spectre-core-devs` team. Also feel free to [ping the core developers][github-ping] (e.g `@sxs-collaboration/spectre-core-devs please assign reviewers`) if they fail to respond in a timely manner. - Assigned reviewers should either confirm that they are able to review (by reviewing or providing a reasonable timeframe for their review) or decline within two days so another reviewer can be assigned. - Anyone is welcome to self-assign themselves as a reviewer. - Assigned reviewers should submit their review in as timely a manner as possible. - Anyone can request changes within either the first two days of the pull request, or within a day after the initial reviews of the assigned reviewers. After this period, only the assigned reviewers can request changes, unless someone believes the code is wrong. Non-reviewers are allowed to make comments, which the pull request author is encouraged to address. Alternatively the author can create an issue with the suggested changes, assigned to themselves, which would then be addressed in a subsequent pull request by the author. - If any requested change is unclear to the author, they should ping the reviewer and ask for clarification. Authors and reviewers are encouraged to talk to one another (in person, via Google hangout, or some other verbal method if possible) to resolve any issues. - Reviewers are encouraged to [ping others \@GITHUB_USERNAME][github-ping] to get opinions on code they are unsure about. - It is permissible to have a group code review led by one of the reviewers. The reviewer should comment on who was present at the group review. - If necessary, pull requests can also be discussed at one of the weekly SpECTRE meetings. - If changes are requested, the author should fix all of them in one or more fixup commits (where the first line of the commit message should begin with `fixup`) and push them to the PR branch. Fixup commits make reviews significantly faster because the reviewers don't have to review the full PR again, but only the parts that changed. - After pushing fixup commits, the author should [re-request reviews from the reviewers][request-reviews]. They can also ping the reviewers that the pull request is updated. - Once a pull request is updated, the reviewers should either request further changes or approve the PR. - Once all reviewers have approved the PR or given the okay to squash, the author should [rebase on develop and then squash their commits](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History) into one or more self-contained commits (such that the code will compile and pass all tests after each commit). The squashed commits will need to be force pushed. - Once all reviewers have approved the pull request, someone should ping the `@sxs-collaboration/spectre-core-devs`. If one of the original reviewers is a core developer, this is not necessary and the core developer can merge the pull request. - One of the core developers will perform a final cursory review, requesting changes only for major problems, and commenting on other possible changes. - The pull request author should address all final requested changes and may either also fix final suggested changes, or create an issue with the suggested changes, which will be addressed in a subsequent pull request by the author. - The SpECTRE core developer will merge the pull request once all comments have been addressed, all reviewers have approved the PR, the code passes CI and all pull requests the pull request depends on have been merged. When approvals are dismissed by minor changes, such as rebasing, squashing fixup commits or adding a missing include, the core developer may merge the PR without waiting for all reviewers to re-approve the PR. In addition to the guidelines above, we apply the following exceptions based on the type of change: - Critical bug fixes (i.e. the code is broken) can be merged after two expedited reviews by SpECTRE core developers. If necessary, an issue can be created if further changes are desired. - PRs that add documentation don't need to be perfect, since having some docs is better than having none. Reviewers should approve after one or at most two rounds of review and allow further minor changes to be done in follow-ups. - "Small" or "trivial" PRs can be merged immediately by core developers. Examples for such PRs are: - Fixing typos in documentation or adding (small amounts of) documentation - Fixing missing includes or missing linked libraries - Adding Python bindings - Formatting code - Refactoring, renaming or moving files with no change in functionality (unless potentially controversial) It is the reviewing core developer's responsibility to decide if the PR is "small" or "trivial" enough to merge immediately. If they are unsure, they should fall back to the usual procedure of giving people two days to assign themselves as reviewers and/or reach out to whoever they think might want to review the PR. - Pull requests that are designated `new design` are expected to have a longer review period, including discussions during weekly SpECTRE meetings. SpECTRE core developers will provide reasonable review deadlines once the new design is finalized. ### Git Commit Message Guidelines {#git-commit-messages} * Use the present tense ("Add feature" not "Added feature") * Use the imperative mood ("Move cursor to..." not "Moves cursor to...") * Limit the first line to 72 characters or less * If needed, a blank second line followed by a more complete description ### SpECTRE core developers {#core-developers} SpECTRE core developers are people who are very familiar with the entire code, comfortable with modern C++, and willing to take the responsibility of overseeing the code as a whole. [Current SpECTRE core developers](https://github.com/orgs/sxs-collaboration/teams/spectre-core-devs) can be pinged on GitHub at `@sxs-collaboration/spectre-core-devs`. It is expected that as more contributors become familiar with SpECTRE, additional people will be added to the list of core developers. [good-first-issue]:https://github.com/sxs-collaboration/spectre/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22+sort%3Acomments-desc [help-wanted]:https://github.com/sxs-collaboration/spectre/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+sort%3Acomments-desc [github-ping]:https://github.blog/2011-03-23-mention-somebody-they-re-notified/ [request-reviews]:https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/requesting-a-pull-request-review ================================================ FILE: docs/Changelog.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Changelog {#changelog} The complete changelog for released versions of the code is available on GitHub: - [Changelog for releases on GitHub](https://github.com/sxs-collaboration/spectre/releases) Changes since the last release are printed below. ================================================ FILE: docs/Contributing/Contributing.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Contributing to SpECTRE {#contributing_index} - \subpage contributing_to_spectre - \subpage code_of_conduct - \subpage reporting_guide ================================================ FILE: docs/Contributing/ReportingGuide.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # SpECTRE Code of Conduct - Reporting Guide {#reporting_guide} \tableofcontents If you believe someone is violating the code of conduct, you can always file a report by emailing conduct@spectre-code.org, or discuss it informally and confidentially with one of the project leaders. **All reports will be kept confidential.** If you believe anyone is in physical danger, please notify appropriate law enforcement first. If you are unsure what law enforcement agency is appropriate, please include this in your report and we will attempt to notify them. Reports of violations of the code of conduct can be as formal or informal as needed for the situation at hand. If possible, please include as much information as you can. If you feel comfortable, please consider including: - Your contact info (so we can get in touch with you if we need to follow up). - Names (real, nicknames, or pseudonyms) of any individuals involved. If there were other witnesses besides you, please try to include them as well. - When and where the incident occurred. Please be as specific as possible. - Your account of what occurred. If there is a publicly available record (e.g. a mailing list archive or Slack logs) please include a link. - Any extra context you believe existed for the incident. - If you believe this incident is ongoing. - Any other information you believe we should have. ### What happens after you file a report? You will receive an email from the Code of Conduct Committee or project leader(s) you contacted, acknowledging receipt within 24 hours (and we will aim to respond much quicker than that). We will review the incident and try to determine: - What happened and who was involved. - Whether this event constitutes a code of conduct violation. - Whether this is an ongoing situation, or if there is a threat to anyone’s physical safety. Once the Code of Conduct Committee or contacted project leader(s) have a complete account of the events we will make a decision on how to respond, possibly in consultation with the full Executive Committee (excluding anyone involved in the incident). Responses may include: - Nothing, if we determine no violation occurred or it has already been appropriately resolved. - Providing either moderation or mediation to ongoing interactions (where appropriate, safe, and desired by both parties). - A private reprimand from the working group to the individuals involved. - An imposed vacation (i.e. asking someone to “take a week off” from a mailing list or Slack). - Escalation to the appropriate institutions. - Involvement of relevant law enforcement if appropriate. If the situation is not resolved within one week, we’ll respond within one week to the original reporter with an update and explanation. Once we’ve determined our response, we will separately contact the original reporter and other individuals to let them know what actions (if any) we’ll be taking. We will take into account feedback from the individuals involved on the appropriateness of our response, but we don’t guarantee we’ll act on it. ### Code of Conduct Committee The current members of the Code of Conduct Committee (and the only people that see emails sent to conduct@spectre-code.org) are: - Saul Teukolsky - Harald Pfeiffer SpECTRE is being developed in support of our collaborative Simulating eXtreme Spacetimes (SXS) research program into the multi-messenger astrophysics of neutron star mergers, core-collapse supernovae, and gamma-ray bursts. As such, it falls under the managerial oversight of the SXS Executive Committee whose current members are: - Matthew Duez - Francois Foucart - Lawrence Kidder - Geoffrey Lovelace - Harald Pfeiffer - Mark Scheel - Leo Stein - Saul Teukolsky - Aaron Zimmerman ================================================ FILE: docs/Dependencies.bib ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # When editing this file, please follow the guidelines in # https://spectre-code.org/writing_good_dox.html#writing_dox_citations. @INPROCEEDINGS{Blaze1, author = {Iglberger, Klaus and Hager, Georg and Treibig, Jan and Rüde, Ulrich}, booktitle = {2012 International Conference on High Performance Computing \& Simulation (HPCS)}, title = {High performance smart expression template math libraries}, year = {2012}, pages = {367-373}, doi = {10.1109/HPCSim.2012.6266939} } @article{Blaze2, author = {Iglberger, Klaus and Hager, Georg and Treibig, Jan and R\"{u}de, Ulrich}, title = {Expression Templates Revisited: A Performance Analysis of Current Methodologies}, journal = {SIAM Journal on Scientific Computing}, volume = {34}, number = {2}, pages = {C42-C69}, year = {2012}, doi = {10.1137/110830125}, URL = {https://doi.org/10.1137/110830125} } @software{Charmpp1, author = {Kale, Laxmikant and Acun, Bilge and Bak, Seonmyeong and Becker, Aaron and Bhandarkar, Milind and Bhat, Nitin and Bhatele, Abhinav and Bohm, Eric and Bordage, Cyril and Brunner, Robert and Buch, Ronak and Chakravorty, Sayantan and Chandrasekar, Kavitha and Choi, Jaemin and Denardo, Michael and DeSouza, Jayant and Diener, Matthias and Dokania, Harshit and Dooley, Isaac and Fenton, Wayne and Galvez, Juan and Gioachin, Fillipo and Gupta, Abhishek and Gupta, Gagan and Gupta, Manish and Gursoy, Attila and Harsh, Vipul and Hu, Fang and Huang, Chao and Jagathesan, Narain and Jain, Nikhil and Jetley, Pritish and Jindal, Prateek and Kanakagiri, Raghavendra and Koenig, Greg and Krishnan, Sanjeev and Kumar, Sameer and Kunzman, David and Lang, Michael and Langer, Akhil and Lawlor, Orion and Wai Lee, Chee and Lifflander, Jonathan and Mahesh, Karthik and Mendes, Celso and Menon, Harshitha and Mei, Chao and Meneses, Esteban and Mikida, Eric and Miller, Phil and Mokos, Ryan and Narayanan, Venkatasubrahmanian and Ni, Xiang and Nomura, Kevin and Paranjpye, Sameer and Ramachandran, Parthasarathy and Ramkumar, Balkrishna and Ramos, Evan and Robson, Michael and Saboo, Neelam and Saletore, Vikram and Sarood, Osman and Senthil, Karthik and Shah, Nimish and Shu, Wennie and B. Sinha, Amitabh and Sun, Yanhua and Sura, Zehra and Totoni, Ehsan and Varadarajan, Krishnan and Venkataraman, Ramprasad and Wang, Jackie and Wesolowski, Lukasz and White, Sam and Wilmarth, Terry and Wright, Jeff and Yelon, Joshua and Zheng, Gengbin}, doi = {10.5281/zenodo.3370873}, month = {Aug}, title = {{The Charm++ Parallel Programming System}}, url = {https://charm.cs.illinois.edu}, year = {2019} } @software{Charmpp2, author = {Laxmikant Kale and Bilge Acun and Seonmyeong Bak and Aaron Becker and Milind Bhandarkar and Nitin Bhat and Abhinav Bhatele and Eric Bohm and Cyril Bordage and Robert Brunner and Ronak Buch and Sayantan Chakravorty and Kavitha Chandrasekar and Jaemin Choi and Michael Denardo and Jayant DeSouza and Matthias Diener and Harshit Dokania and Isaac Dooley and Wayne Fenton and Zane Fink and Juan Galvez and Pathikrit Ghosh and Fillipo Gioachin and Abhishek Gupta and Gagan Gupta and Manish Gupta and Attila Gursoy and Vipul Harsh and Fang Hu and Chao Huang and Narain Jagathesan and Nikhil Jain and Pritish Jetley and Prateek Jindal and Raghavendra Kanakagiri and Greg Koenig and Sanjeev Krishnan and Sameer Kumar and David Kunzman and Michael Lang and Akhil Langer and Orion Lawlor and Chee Wai Lee and Jonathan Lifflander and Karthik Mahesh and Celso Mendes and Harshitha Menon and Chao Mei and Esteban Meneses and Eric Mikida and Phil Miller and Ryan Mokos and Venkatasubrahmanian Narayanan and Xiang Ni and Kevin Nomura and Sameer Paranjpye and Parthasarathy Ramachandran and Balkrishna Ramkumar and Evan Ramos and Michael Robson and Neelam Saboo and Vikram Saletore and Osman Sarood and Karthik Senthil and Nimish Shah and Wennie Shu and Amitabh B. Sinha and Yanhua Sun and Zehra Sura and Justin Szaday and Ehsan Totoni and Krishnan Varadarajan and Ramprasad Venkataraman and Jackie Wang and Lukasz Wesolowski and Sam White and Terry Wilmarth and Jeff Wright and Joshua Yelon and Gengbin Zheng}, title = {{UIUC-PPL}/charm: {Charm++} version 7.0.0}, month = oct, year = 2021, publisher = {Zenodo}, version = {v7.0.0}, doi = {10.5281/zenodo.5597907}, url = {https://doi.org/10.5281/zenodo.5597907} } @incollection{Charmpp3, title = {Charm++: Parallel programming with message-driven objects}, author = {Kale, Laxmikant V and Krishnan, Sanjeev}, booktitle = {Parallel programming using C++}, editor = {Gregory V. Wilson and Paul Lu}, publisher = {The MIT Press}, pages = {175--213}, year = 1996, } @book{Gsl, title = {{GNU} Scientific Library Reference Manual}, author = {Galassi, M. and others}, publisher = {Network Theory Ltd.}, isbn = {9780954612078}, year = {2009}, edition = {3} } @software{Hdf5, author = {{The HDF Group}}, title = "{Hierarchical Data Format, version 5}", year = {1997-2023}, note = {https://www.hdfgroup.org/HDF5/} } @ARTICLE{Libsharp, author = {{Reinecke}, M. and {Seljebotn}, D.~S.}, title = "{Libsharp - spherical harmonic transforms revisited}", journal = {Astronomy and Astrophysics}, keywords = {methods: numerical, cosmic background radiation, large-scale structure of Universe, Physics - Computational Physics}, year = 2013, month = jun, volume = {554}, eid = {A112}, pages = {A112}, doi = {10.1051/0004-6361/201321494}, archivePrefix ={arXiv}, eprint = {1303.4945}, primaryClass = {physics.comp-ph}, adsurl = {https://ui.adsabs.harvard.edu/abs/2013A&A...554A.112R}, adsnote = {Provided by the SAO/NASA Astrophysics Data System} } @inproceedings{Libxsmm, author = {Heinecke, Alexander and Henry, Greg and Hutchinson, Maxwell and Pabst, Hans}, title = {{LIBXSMM}: {Accelerating} Small Matrix Multiplications by Runtime Code Generation}, year = {2016}, isbn = {9781467388153}, publisher = {IEEE Press}, booktitle = {Proceedings of the International Conference for High Performance Computing, Networking, Storage and Analysis}, articleno = {84}, numpages = {11}, pages = {1-11}, location = {Salt Lake City, Utah}, series = {SC '16} } @Article{MatplotLib1, Author = {Hunter, J. D.}, Title = {Matplotlib: A 2D graphics environment}, Journal = {Computing in Science \& Engineering}, Volume = {9}, Number = {3}, Pages = {90--95}, abstract = {Matplotlib is a 2D graphics package used for Python for application development, interactive scripting, and publication-quality image generation across user interfaces and operating systems.}, publisher = {IEEE COMPUTER SOC}, doi = {10.1109/MCSE.2007.55}, year = 2007 } @software{MatplotLib2, author = {Thomas A Caswell and Michael Droettboom and Antony Lee and John Hunter and Eric Firing and Elliott Sales de Andrade and Tim Hoffmann and David Stansby and Jody Klymak and Nelle Varoquaux and Jens Hedegaard Nielsen and Benjamin Root and Ryan May and Phil Elson and Darren Dale and Jae-Joon Lee and Jouni K. Seppänen and Damon McDougall and Andrew Straw and Paul Hobson and Christoph Gohlke and Tony S Yu and Eric Ma and Adrien F. Vincent and Steven Silvester and Charlie Moad and Nikita Kniazev and hannah and Elan Ernest and Paul Ivanov}, title = {matplotlib/matplotlib: {REL:} v3.3.0}, month = jul, year = 2020, publisher = {Zenodo}, version = {v3.3.0}, doi = {10.5281/zenodo.3948793}, url = {https://doi.org/10.5281/zenodo.3948793} } @Article{NumPy, title = {Array programming with {NumPy}}, author = {Charles R. Harris and K. Jarrod Millman and St{\'{e}}fan J. van der Walt and Ralf Gommers and Pauli Virtanen and David Cournapeau and Eric Wieser and Julian Taylor and Sebastian Berg and Nathaniel J. Smith and Robert Kern and Matti Picus and Stephan Hoyer and Marten H. van Kerkwijk and Matthew Brett and Allan Haldane and Jaime Fern{\'{a}}ndez del R{\'{i}}o and Mark Wiebe and Pearu Peterson and Pierre G{\'{e}}rard-Marchant and Kevin Sheppard and Tyler Reddy and Warren Weckesser and Hameer Abbasi and Christoph Gohlke and Travis E. Oliphant}, year = {2020}, month = sep, journal = {Nature}, volume = {585}, number = {7825}, pages = {357--362}, doi = {10.1038/s41586-020-2649-2}, publisher = {Springer Science and Business Media {LLC}}, url = {https://doi.org/10.1038/s41586-020-2649-2} } @book{Paraview1, author = {Ayachit, Utkarsh}, title = {The ParaView Guide: A Parallel Visualization Application}, year = {2015}, isbn = {1930934300}, publisher = {Kitware, Inc.}, address = {Clifton Park, NY, USA}, } @book{Paraview2, title = {{ParaView}: {An} end-user tool for large-data visualization}, author = {J. Ahrens and Berk Geveci and C. Law}, publisher = {Elsevier}, isbn = {9780123875822}, year = {2005} } @software{Pybind11, author = {Wenzel Jakob and Jason Rhinelander and Dean Moldovan}, year = {2017}, note = {https://github.com/pybind/pybind11}, title = {pybind11 -- Seamless operability between C++11 and Python} } @software{Yamlcpp, title = {yaml-cpp}, author = {Beder, Jesse and Woehlke, Matthew and Breitbart, Jens and Wolchok, Scott and Hackimov, Azamat H. and Snape, Jamie and Hamlet, Oliver and Novotny, Paul and Tambre, Raul and Reinhold, Stefan and Vaucher, Alain and Zaitsev, Alexander and Anokhin, Alexander and Karatarakis, Alexander and Maloney, Andy and Polukhin, Antony and Brandenburg, Craig M. and Ibanez, Dan and Gladkikh, Denis and Eich, Florian and Dumont, Guillaume and Trigg, Haydn and King, Jim and Frederico, Joel and Hamilton, Jonathan and Langley, Joseph and Hämäläinen, Lassi and Blair, Matt and Duggan, Michael Welsh and Wang, Olli and Stotko, Patrick and Levine, Peter and Bena, Petr and Cordoba, Rodrigo Hernandez and Schmidt, Ryan and Gottlieb, Simon Gene and Prilmeier, Franz and Zhang, Tanki and Ishi, Tatsuyuki and Lyngmo, Ted and Mataré, Victor and Konečný, Michael and USDOE}, abstractNote = {A {YAML} parser and emitter in {C++}.}, doi = {10.11578/dc.20220817.13}, url = {https://www.osti.gov/biblio/1881863}, year = {2009}, month = {9} } ================================================ FILE: docs/DevGuide/Amr.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Adaptive mesh refinement (AMR) {#dev_guide_amr} \tableofcontents ### Introduction SpECTRE implements a block-based anisotropic h-p adaptive mesh refinement (AMR) algorithm. Currently AMR can only occur at global synchronization points, but it is planned to remove this restriction in the future. \warning AMR is still under active development. The elliptic executables fully support AMR. The evolution executables currently only support p-adaptivity, and only when using a global time stepper, and only when using a DG method. The executable will abort with an ERROR if local time stepping or h-refinement is done. Here is an overview of what is described in detail in the sections below: - \ref dev_guide_amr_algorithm "AMR Algorithm": An overview of the parallel phases, actions, and components that are used to do adaptive mesh refinement. - \ref dev_guide_amr_criteria "AMR Criteria": Describes the expectations and restrictions on concrete classes implementing adaptive mesh refinement criteria. - \ref dev_guide_amr_policies "AMR Policies": Describes restrictions and assumptions of the current algorithm, and what would be required to relax them. - \ref dev_guide_amr_projectors "AMR Projectors": Describes the requirements on concrete classes which project data to the new or modified elements after mesh refinement. - \ref dev_guide_amr_metavariables "AMR Metavariables": Describes the code that needs to be added to the metavariables of an executable in order to enable adaptive mesh refinement. - \ref dev_guide_amr_input_options "Controlling AMR": Describes the options in the input file that control the behavior of adaptive mesh refinement. ### AMR Algorithm {#dev_guide_amr_algorithm} The AMR algorithm requires communication via simple actions between the elements of the array component that are responsible for the Element%s of the Domain and a singleton amr::Component. See \ref dev_guide_parallelization_foundations "Parallelization and Core Concepts" for an overview of phases, actions, metavariables, and other SpECTRE parallelization concepts. Currently the AMR algorithm is run over several phases when a phase change is triggered by an executable. See \ref dev_guide_amr_input_options "Controlling AMR" for how to control when the AMR phases are triggered. #### Evaluating refinement criteria When AMR is triggered, the executable should enter Parallel::Phase::EvaluateAmrCriteria. In this phase, the amr::Component triggers the simple action amr::Actions::EvaluateRefinementCriteria on each element of the array component (specified by `metavariables::amr::element_array`). Each element evaluates (in order) the user-specified refinement criteria, each of which returns a refinement decision in each logical dimension of the element represented as an amr::Flag. The overall refinement decision in each logical dimension is obtained by taking the highest priority decision in the dimension over all criteria, where amr::Flag::Split has the highest priority and amr::Flag::Join has the lowest. See \ref dev_guide_amr_criteria "AMR Criteria" for more details on implementing criteria. Once the overall refinement decision based on the refinement criteria is made, the decision may be modified to satisfy the \ref dev_guide_amr_policies "AMR Policies". Finally, the element sends its decision (and other information in amr::Info) to its neighbors by calling the simple action amr::Actions::UpdateAmrDecision. In amr::Actions::UpdateAmrDecision, an element decides whether or not it needs to update its own refinement decision (or other information in amr::Info) based on decisions (or other information in amr::Info) sent by its neighbor. Possible reasons to update the refinement decision are, e.g., if a sibling neighbor does not want to join an element that had initially decided to join, or if any of the amr::Policies would be violated. If the refinement decision (or other information in amr::Info) of the element changes, the element will send its updated amr::Info to its neighbors. Note that simple actions are executed asynchronusly, so both amr::Actions::EvaluateRefinementCriteria and amr::Actions::UpdateAmrDecision have to handle the possibility that they are executed out of order. For example, amr::Actions::UpdateAmrDecision could be executed before amr::Actions::EvaluateRefinementCriteria. Eventually all elements will reach a state where they do not need to send new information to their neighbors, thus reaching a state of quiescence. When this happens Parallel::Phase::EvaluateAmrCriteria ends. At this point all elements have reached a consensus on how the domain should be adapted, but no changes have been made to the domain. In order to adjust the domain, the executable should next start Parallel::Phase::AdjustDomain. #### Adjusting the domain At the beginning of Parallel::Phase::AdjustDomain, the amr::Component calls amr::Actions::AdjustDomain on each element of the array component (specified by `metavariables::amr::element_array`). If the element wants to split in any dimension, it will call the simple action amr::Actions::CreateChild on the amr::Component in order to create new refined elements that will replace the existing element. If the element wants to join in any dimension, it will either call amr::Actions::CreateParent on the amr::Component (if it is the joining sibling with the lowest SegmentId in each dimension being joined) or do nothing in order to create a single new coarsened element that will replace multiple existing elements. If the element neither wants to split nor join in any dimension, then the element mutates items in its db::DataBox. First the Element, Mesh and neighbor Mesh are updated. Then the element calls the \ref dev_guide_amr_projectors "AMR Projectors" that will update all the mutable items in the db::DataBox. Finally the amr::Info of the element and its neighbors are reset and cleared so they are ready for a future invocation of AMR. When amr::Actions::CreateChild is executed by the amr::Component, it creates a new element in the `metavariables::amr::element_array` passing a Parallel::SimpleActionCallback that will be executed after the new element is created. The callback will be either to call amr::Actions::CreateChild again for the next child to be created, or amr::Actions::SendDataToChildren which will be invoked on the element that is being split. amr::Actions::SendDataToChildren will then invoke amr::Actions::InitializeChild on each new child element, passing along all of the mutable items in its db::DataBox. amr::Actions::SendDataToChildren will then deregister and delete the element being split. amr::Actions::InitializeChild will create its Element, Mesh, and neighbor Mesh, and then call the \ref dev_guide_amr_projectors "AMR Projectors" that will update all the mutable items in its db::DataBox. When amr::Actions::CreateParent is executed by the amr::Component, it creates a new element in the `metavariables::amr::element_array` passing a Parallel::SimpleActionCallback that will be executed after the new element is created. The callback will be amr::Actions::CollectDataFromChildren which will be invoked on one of the elements that are joining. amr::Actions::CollectDataFromChildren will then invoke either itself on another element that is joining or amr::Actions::InitializeParent on the new parent element, collecting all of the mutable items in each joining element's db::DataBox. amr::Actions::CollectDataFromChildren will then deregister and delete the element that is joining. amr::Actions::InitializeParent will create its Element, Mesh, and neighbor Mesh, and then call the \ref dev_guide_amr_projectors "AMR Projectors" that will update all the mutable items in its db::DataBox. When all of the actions finish, a state of quiescence is reached. When this happens Parallel::Phase::AdjustDomain ends. The executable should now either return to the phase which triggered AMR, or enter Parallel::Phase::CheckDomain. ### AMR Criteria {#dev_guide_amr_criteria} When amr::Actions::EvaluateRefinementCriteria is executed, for each element, it loops over a list of criteria that is specified in the input file options (See \ref dev_guide_amr_input_options "Controling AMR"). Each criterion must be an option-creatable class derived from amr::Criterion (see its documentation for a list of requirements for the derived classes). In particular, each criterion should compute an array of amr::Flag%s that represent the recommended refinemenent choice in each logical dimension. These choices can be computed from any items in the db::DataBox of the element or additional compute items specified by the criterion. It is expected that a criterion will compute something and then either choose to recommend refinement, no change, or coarsening the element either in size (h-refinement) or polynomial order (p-refinement). A criterion does not need to handle anything that is enforced by the amr::Policies such as worry about bounds on the refinement level or number of grid points. ### AMR Policies {#dev_guide_amr_policies} The current AMR algorithm has a set of rules that are enforced after the overall refinement choice is determined from the AMR criteria. The following rules simplify the code: - An Element cannot join if it is splitting in any dimension. Instead any amr::Flag::Join is changed to amr::Flag::DoNothing. Relaxing this restriction would be a non-trivial change that would require more complicated logic in determining if neighboring elements can join, as well as an additional code path to handle the creation and initialization of the new elements. This should not be a significant restriction as in most cases when this would occur it is unlikely that the siblings of the Element would agree to a valid join. - In two or three spatial dimensions, there must be a 2:1 balance (i.e. within one refinement level) between neighbors in the dimension(s) parallel to the face of the element. Relaxing this restriction would be a significant change to the code as the code for communicating boundary corrections assumes 2:1 balance. In order to maintain 2:1 balance with neighboring elements, a choice of amr::Flag::Join may be changed to amr::Flag::DoNothing, and amr::Flag::DoNothing may be changed to amr::Flag::Split. The following policies are among those controlled by input file options (see \ref dev_guide_amr_input_options "Controlling AMR" and the documentation for amr::Policies): - Whether to do isotropic or anisotropic refinement. If isotropic refinement is done, the AMR decision in each dimension are changed to the decision of the dimension with the highest priority amr::Flag (i.e. amr::Flag::Split has the highest priority). - Whether or not to enforce 2:1 balance for the refinement level in the direction perpendicular to the face. - The minimum and maximum of the refinement level and the number of grid points. The actual bounds on these will be the stricter of those specified by the input file and those set by the code. For the number of grid points, the code bounds are set by Spectral::minimum_number_of_points and Spectral::maximum_number_of_points for the Spectral::Basis and Spectral::Quadrature of the Mesh. For the refinement level, the minimum is zero, and the maximum is set by `ElementId::max_refinement_level`. ### AMR Projectors {#dev_guide_amr_projectors} After the grid adapts, the mutable items in the DataBox of new or existing elements must be updated. The Element, Mesh, neighbor Mesh, amr::Info, and neighbor amr::Info along with the items in `Parallel::Tags::distributed_object_tags` are automatically updated by the AMR actions, but all other items must be explicitly updated via projectors that conform to amr::protocols::Projector. If any mutable item has not been explicitly handled by any of the projectors, a `static_assert` will be triggered listing the tags for the items that have not been projected. When a new element is created, the items in its DataBox are default constructed. Their Element, Mesh, and neighbor Mesh are mutated to their desired state. Then the AMR projectors are called, passing along the items in the DataBox(es) from their splitting parent element or joining children elements. Existing elements first mutate their Element, Mesh, and neighbor Mesh, and then call the AMR projectors, passing along the old Element and Mesh. The `return_tags` of each projector lists the tags for the items that the projector mutates. From the pre-AMR state, the projector must compute the post-AMR state of these items. Typically during Parallel::Phase::Initialization, a group of items will be initialized by a specific action or mutator in the action `Initialization::Actions::InitializeItems`. Therefore it makes sense to create a projector that will handle the same group of items. However some items are initialized from input file options, while others are left default initialized and not mutated by any initialization action. These items will still need to be handled by some projector. Two convenience projectors are provided: amr::projectors::DefaultInitialize which value initializes the items corresponding to the listed tags; and amr::projectors::CopyFromCreatorOrLeaveAsIs that will either copy the item from the parent (or children, asserting that all children agree) of a newly created element, or leave the item unmodified for an existing element for the items corresponding to the listed tags. The list of projectors is specified in `metavariables::amr::projectors` in the executable, and the projectors are evaluated in the order in which they are specified. ### Enabling AMR for an executable {#dev_guide_amr_metavariables} In order to enable AMR for an executable, the following changes need to be made in the metavariables: - The addition of a struct named `amr` such as the following example: ``` struct amr : tt::ConformsTo<::amr::protocols::AmrMetavariables> { using element_array = dg_element_array; using projectors = tmpl::list<::amr::projectors::DefaultInitialize< domain::Tags::InitialExtents, domain::Tags::InitialRefinementLevels, evolution::dg::Tags::Quadrature>>; static constexpr bool keep_coarse_grids = false; }; ``` where `element_array` specifies the array component on which AMR will operate and `projectors` is a type list of amr::projectors that govern how the items in the DataBox for the `element_array` are updated after refinement. - The addition of amr::Component to the `component_list` of the metavariables - The addition (or modification) of the following `tmpl::pair`s in `factory_creation::factory_classes`: ``` tmpl::pair, tmpl::pair< PhaseChange, tmpl::list< PhaseControl::VisitAndReturn< Parallel::Phase::EvaluateAmrCriteria>, PhaseControl::VisitAndReturn, PhaseControl::VisitAndReturn>, ``` where `LIST_OF_CRITERIA` should be a list of amr::Criteria. - The addition of the following item in the list of PhaseActions for the component specified in `amr::element_array`: ``` Parallel::PhaseActions>, ``` - The possible addition of `PhaseControl::Actions::ExecutePhaseChange` to the action list for the appropriate Phase in the PhaseAction of the `amr::element_array` - The addition of the mutator `amr::Initialization::Initialize` to the list of mutators in `Initialization::Actions::InitializeItems` in the Parallel::PhaseActions list for Parallel::Phase::Initialization. - The appropriate includes for all of the above. ### Controlling AMR {#dev_guide_amr_input_options} There are two places in the input file that control how and when AMR happens. The "how" is controlled by the option group `Amr`. Here you list the amr::Criteria being used, the available options for the amr::Policies, and the `Verbosity` of diagnostic messages that are printed. Here is an example: ``` Amr: Criteria: - TruncationError: VariablesToMonitor: [Psi] AbsoluteTarget: 1.e-6 RelativeTarget: 1.0 Policies: EnforceTwoToOneBalanceInNormalDirection: true Isotropy: Anisotropic Limits: RefinementLevel: Auto NumGridPoints: Auto ErrorBeyondLimits: False AllowCoarsening: True Verbosity: Verbose ``` Note that the values `Auto` for the Limits options choose the default limits set by the code. Also note that if a criterion tries to refine beyond the limits, whether or not the code should error is controlled by `ErrorBeyondLimits`. "When" AMR happens is controlled by specifying a Trigger and a list of `PhaseChanges` in the top-level option `PhaseChangesAndTriggers`. For example: ``` PhaseChangeAndTriggers: - Trigger: Slabs: EvenlySpaced: Interval: 10 Offset: 0 PhaseChanges: - VisitAndReturn(EvaluateAmrCriteria) - VisitAndReturn(AdjustDomain) - VisitAndReturn(CheckDomain) ``` Both `EvaluateAmrCriteria` and `AdjustDomain` are required in order for AMR to work. `VisitAndReturn(CheckDomain)` performs diagnostics and can be omitted. To turn off AMR, omit the three phase changes above. ================================================ FILE: docs/DevGuide/AutomaticVersioning.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Automatic versioning {#dev_guide_automatic_versioning} \tableofcontents Our automated tests can tag and publish a release automatically when requested. The automation is implemented as a [GitHub Actions](https://docs.github.com/actions) workflow in the file `.github/workflows/Tests.yaml`. ## Creating releases The GitHub workflow responsible for automated testing also allows creating a release when dispatched manually. To create a release (roughly on the first Monday of each month and/or when needed for publications), follow these instructions: 1. **Check for bugs on `develop`.** If you are aware of any major bugs in the code on `develop`, check with the (other) core developers if it would be better to wait with the release until those bugs are fixed. 2. **Check the release notes.** Find the latest run of the [`Tests` workflow on the `develop` branch](https://github.com/sxs-collaboration/spectre/actions/workflows/Tests.yaml?query=branch%3Adevelop). Select the "Files and formatting" job and the "Print release notes" step within. Go through the release notes, checking the following in particular: - Label bugfix PRs with the `bugfix` label so they appear in the "Bugfixes" section and don't clutter the list. - Label PRs that you want to highlight with the `new feature` label, so they appear at the top. The selection is up to you. - Add upgrade instructions to PRs where they are missing, to help other developers with rebasing their code. 3. **Dispatch the release.** Go to the GitHub Actions page for the [`Tests` workflow](https://github.com/sxs-collaboration/spectre/actions/workflows/Tests.yaml?query=branch%3Adevelop). [Select "Run workflow"](https://docs.github.com/actions/managing-workflow-runs/manually-running-a-workflow) and the `develop` branch. Type in a valid release version name, such as "2021.05.04", and hit "Run workflow". The release will only be created if if the version name matches the format defined in \ref versioning_and_releases _and_ if it matches the current date. Therefore, if you wait too long with the next step, the release will fail and you have to dispatch it again. It is probably best to hold off merging PRs while the release workflow runs, to avoid possible conflicts. Therefore, warn the (other) core devs. 4. **Ask for approval.** Once the unit tests are complete, the release workflow will wait for approval before publishing the release on GitHub and Zenodo. Notify the (other) core devs so one of them can review and approve the release (don't approve the release yourself). You can point them to these guidelines: Guidelines for reviewing a release: - Check for bugs on `develop` (see point 1. above). - Check the release notes (see point 2. above). ## Release notes The release notes are compiled automatically based on the activity in the repository since the last release. They will contain a list of merged pull-requests. Pull-requests labeled "new feature" or "bugfix" on GitHub will be classified as such in the release notes. The script `tools/CompileReleaseNotes.py` generates the release notes and can also be invoked manually with a Python 3 interpreter to retrieve an overview of what happened in the repository recently. The script requires you install `GitPython`, `PyGithub` and `tqdm` in your Python environment. ================================================ FILE: docs/DevGuide/Brigand.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Metaprogramming with Brigand {#brigand} \tableofcontents \tableofcontents{HTML:2} [comment]: # (The \pars improve the spacing in the generated document when) [comment]: # (many \snippets are involved.) \par In SpECTRE, most complex TMP is done using the [Brigand metaprogramming library](https://github.com/edouarda/brigand). Brigand is a collection of templated classes, type aliases, and functions, primarily intended to help with the manipulation and use of lists of types. This document is organized to roughly parallel the structure of the C++ standard, rather than following Brigand's classifications. \par Brigand provides all of its functionality in the `brigand` namespace, but in SpECTRE we have aliased this namespace to `tmpl`, and the latter should be preferred. \par All functionality described here is provided by SpECTRE's Brigand wrapper header: \snippet Test_TMPLDocumentation.cpp include \par Examples in this document use the following declarations and definitions: \snippet Test_TMPLDocumentation.cpp example_declarations \section Metafunctions \par A metafunction is an analog of a familiar C++ function that is coded in the C++ type system. It turns out that, using metafunction programming, it is possible to perform arbitrary computations at compile time. \par There are multiple ways to encode a calculation in the type system. When using Brigand, the relevant ones are eager and lazy metafunctions. \subsection lazy Eager and lazy metafunctions \par Metafunctions commonly appear in two forms: eager and lazy. Lazy metafunctions are templated structs (or templated aliases to structs) with a `type` member alias that indicates the result: \snippet Test_TMPLDocumentation.cpp metafunctions:lazy The type traits in the standard library, such as std::is_same, are lazy metafunctions. \par Eager metafunctions are aliases to their result types. As a trivial case, struct templates can be viewed as eager metafunctions returning themselves. An eager version of the previous example could be implemented as: \snippet Test_TMPLDocumentation.cpp metafunctions:eager The standard library provides eager versions of some of its metafunctions (generally those that modify a type, rather than predicates) using an `_t` suffix. When both versions are provided, it is often convenient (and less error prone!) to define the eager version in terms of the lazy version: \snippet Test_TMPLDocumentation.cpp metafunctions:eager_from_lazy And the two definitions agree: \snippet Test_TMPLDocumentation.cpp metafunctions:agreement \note The standard library also provides versions of many of its type traits with an `_v` suffix. These evaluate to compile-time *values*, rather than types. They can be useful for metaprogramming, but are not the types of metafunctions being discussed here. \par Eager metafunctions are usually more convenient to use, so what is the point of additionally creating lazy ones? The answer is that lazy metafunctions can be used as compile-time functors. As a simple example, we can write an (eager) metafunction that calls an arbitrary lazy metafunction twice \snippet Test_TMPLDocumentation.cpp metafunctions:call_lazy_metafunction and get the expected output: \snippet Test_TMPLDocumentation.cpp metafunctions:call_lazy_metafunction_assert But it fails if you try to call an arbitrary *eager* metafunction twice in the same way, because the function is evaluated too early, resulting in the `List1` metafunction being acted upon instead of `eager_add_list`: \snippet Test_TMPLDocumentation.cpp metafunctions:call_eager_metafunction \snippet Test_TMPLDocumentation.cpp metafunctions:call_eager_metafunction_assert (In this simple case we could have used a template template parameter to pass the eager metafunction in a form more similar to a runtime lambda, but the possibilities for generic manipulation of parameter lists containing template template parameters are limited, so their use must be minimized in complex metaprogramming.) \note In practice, lazy metafunctions are often implemented as empty structs inheriting from other lazy metafunctions. The entire inheritance chain then inherits a `type` alias from the ultimate base class. \par Most of the standard Brigand functions are eager, but many have lazy versions in the nested `tmpl::lazy` namespace. These are indicated by calls to the `HAS_LAZY_VERSION` macro in the examples below. \subsection metalambdas Brigand metalambdas \par This use of lazy metafunctions is too limited for general use, however, because it requires the definition of a new templated struct for every new function. Brigand uses a more general notation, known as metalambdas. A metalambda is a (possibly nested set of) lazy metafunctions with some template arguments replaced by the placeholders `tmpl::_1`, `tmpl::_2`, etc. These are the first, second, etc., arguments of the metalambda, and will be replaced by the actual arguments when the lambda is used. The lazy nature of the metafunctions prevents them from prematurely evaluating to results based on the literal placeholder types. The \ref apply "tmpl::apply" function can be used to evaluate a metalambda with specified arguments, and many other Brigand functions take metalambdas that are evaluated internally. \subsection metalambda_structure Evaluation of metalambdas \note None of the terminology introduced in this section is standard. \par When evaluating a metalambda, the values of any \ref args "arguments" encountered are taken from the evaluation's argument stack. The argument stack is a stack (in the CS sense) of collections of zero or more arguments. The values of any \ref args "arguments" that are evaluated are taken from the collection at the head of the stack. The remaining collections are arguments captures in closures, and will not be present in code not using \ref defer "tmpl::defer". \par The \ref apply "tmpl::apply" metafunction is the Brigand metafunction for evaluating metalambdas. It can be called explicitly, and is called internally by many other functions. It takes a metalambda and arguments to be passed to that metalambda. The argument stack for the evaluation has one entry: the passed arguments. \par The argument stack can gain additional entries through the creation of metaclosures using \ref defer "tmpl::defer". When \ref defer "tmpl::defer" is evaluated, it produces a \ref metalambda_metaclosure "metaclosure" containing a copy of the current argument stack, acting as the lambda captures. When that metaclosure is evaluated, the previously active stack is replaced by the stored stack with the head of the old stack pushed onto it. \par This makes \ref args "arguments" in a \ref metalambda_metaclosure "metaclosure" refer to the arguments "passed" to it. (No explicit call syntax is used, but the arguments are inherited from the calling context.) The captured arguments are accessible using \ref parent "tmpl::parent", which pops off the last entry in the argument stack. \par There are eight forms that a metalambda can take: an argument, a lazy expression, a bind expression, a pin expression, a defer expression, a parent expression, a constant, or a metaclosure. \subsubsection args Argument \par An argument is one of the structs `tmpl::_1`, `tmpl::_2`, or `tmpl::args` for `unsigned int` n. The additional aliases `tmpl::_3`, `tmpl::_4`, ..., `tmpl::_9` are provided to `tmpl::args<2>`, `tmpl::args<3>`, ..., `tmpl::args<8>`. (The first two arguments have dedicated types in addition to the general `tmpl::args<0>` and `tmpl::args<1>`. My best guess is for performance reasons.) \snippet Test_TMPLDocumentation.cpp tmpl::args When evaluated, they give the first (`tmpl::_1`), second (`tmpl::_2`), or zero-indexed Nth (`tmpl::args`) entry from the collection of arguments at the top of the argument stack. \snippet Test_TMPLDocumentation.cpp tmpl::args:eval Additionally, `tmpl::_state` and `tmpl::_element` are aliased to `tmpl::_1` and `tmpl::_2`, primarily for use with \ref fold "tmpl::fold". \par When evaluating a metalambdas, the metalambda must be passed enough arguments to define all argument placeholders in its body. When evaluating using \ref apply "tmpl::apply", arguments are passed as template parameters after the metalambda. Other Brigand functions that evaluate metalambdas pass them a specified number of arguments (usually 1 or 2). Failure to pass enough arguments may error or produce unintuitive results. \subsubsection metalambda_lazy Lazy expression \par A lazy expression is a fully-specialized struct template with only type template parameters that is not a specialization of \ref pin "tmpl::pin", \ref defer "tmpl::defer", or \ref parent "tmpl::parent" and is not a \ref metalambda_metaclosure "metaclosure". When evaluated, each of its template parameters is evaluated as a metalambda and replaced by the result, and then the struct's `type` type alias is the result of the full lazy-expression. \snippet Test_TMPLDocumentation.cpp metalambda_lazy \subsubsection bind Bind expression \par A bind expression is a specialization of `tmpl::bind`. It wraps an eager metafunction and its arguments. When evaluated, the arguments are each evaluated as metalambdas, and then the results are passed to the eager metafunction. \snippet Test_TMPLDocumentation.cpp tmpl::bind \note The `tmpl::bind` metafunction does not convert an eager metafunction to a lazy one. It is handled specially in the evaluation code. \subsubsection pin Pin expression \par A pin expression is a specialization of `tmpl::pin`. Evaluating a pin expression gives the (unevaluated) argument to `tmpl::pin`. This can be used to force a type to be treated as a \ref metalambda_constant "constant", even if it would normally be treated as a different type of metalambda (usually a \ref metalambda_lazy "lazy expression"). \snippet Test_TMPLDocumentation.cpp tmpl::pin \par Pin expressions are often used to protect template arguments to eager metafunctions: \snippet Test_TMPLDocumentation.cpp tmpl::pin:protect_eager \subsubsection defer Defer expression \par A defer expression is a specialization of `tmpl::defer`. It does not evaluate its argument, but results in a \ref metalambda_metaclosure "metaclosure" containing the passed metalambda and the current argument stack. \par Example: \snippet Test_TMPLDocumentation.cpp tmpl::defer The evaluation here proceeds as follows: 1. The innermost eager metafunction is the second \ref apply "tmpl::apply". It creates an argument stack with one collection containing the single argument `Type1` and proceeds to evaluate `tmpl::defer`. 2. Evaluating the defer expression creates a \ref metalambda_metaclosure "metaclosure" with the contents `tmpl::_1` and the argument stack from the first apply. This is the result of the inner \ref apply "tmpl::apply". 3. Next the outer \ref apply "tmpl::apply" is evaluated. It creates an argument stack with one collection containing the single argument`Type2`, and proceeds to evaluate the \ref metalambda_metaclosure "metaclosure" created above. [comment]: # (Keep the numbering here in sync with the `parent` example.) 4. Evaluating the \ref metalambda_metaclosure "metaclosure" (see that section below) evaluates the contained `tmpl::_1` with a two-element argument stack: head to tail [(`Type2`), (`Type1`)]. 5. The first (and only) argument (`tmpl::_1`) in the head of the argument stack is `Type2`, which is the result of the \ref metalambda_metaclosure "metaclosure" and the entire expression. \par The primary purposes for `tmpl::defer` are constructing metalambdas to pass to other metafunctions and preventing "speculative" evaluation of a portion of a metalambda that is not valid for some arguments. See the examples below, in particular \ref make_subtracter, \ref multiplication_table, \ref maybe_first, and \ref column_with_zeros. \subsubsection parent Parent expression \par A parent expression is a specialization of `tmpl::parent`. It evaluates its argument (treated as a metalambda) after popping the top entry off the argument stack. This provides access to the captured arguments in a \ref metalambda_metaclosure "metaclosure". \par Example: \snippet Test_TMPLDocumentation.cpp tmpl::parent The creation of the \ref metalambda_metaclosure "metaclosure" here is similar to the example for \ref defer "tmpl::defer", except that the contained metalambda is `tmpl::parent` instead of a plain `tmpl::_1`. The evaluation proceeds as: 1. As in \ref defer "tmpl::defer" example. 2. As in \ref defer "tmpl::defer" example. 3. As in \ref defer "tmpl::defer" example. 4. The \ref metalambda_metaclosure "metaclosure" evaluates the contained `tmpl::parent` with the argument stack [(`Type2`), (`Type1`)]. 5. Evaluating the `tmpl::parent` pops the stack, and so evaluates `tmpl::_1` with the stack [(`Type1`)]. 6. The first (and only) argument (`tmpl::_1`) in the stack's head is now `Type1`, which is the result of the \ref metalambda_metaclosure "metaclosure" and the entire expression. \warning Do not call `tmpl::parent` when the argument stack is empty, i.e., do not attempt to access more sets of captured arguments than have been captured. If you want to prevent evaluation of an expression, use \ref pin "tmpl::pin". \subsubsection metalambda_constant Constant \par A constant metalambda is any type that is not a struct template with only type template parameters, a specialization of \ref bind "tmpl::bind", or a metaclosure. A constant metalambda evaluates to itself. \snippet Test_TMPLDocumentation.cpp metalambda_constant \subsubsection metalambda_metaclosure Metaclosure \par A metaclosure is an opaque type produced by \ref defer "tmpl::defer", containing a metalambda and an argument stack. When a metaclosure is evaluated, it evaluates the packaged metalambda with an argument stack constructed by pushing the head of the current argument stack onto the argument stack stored in the metaclosure. See \ref defer and \ref parent for examples. \subsection Examples \subsubsection evens \par Finds all numbers in a list that are even. \snippet Test_TMPLDocumentation.cpp metafunctions:evens \snippet Test_TMPLDocumentation.cpp metafunctions:evens:asserts \par The \ref filter "tmpl::filter" metafunction takes a metalambda as its second argument. The \ref integral_constant "tmpl::integral_constant"s have non-type template parameters, so they are treated as constant expressions. The \ref math_comparison "tmpl::equal_to" and \ref math_arithmetic "tmpl::modulo" metafunctions are lazy, despite not being in the `tmpl::lazy` namespace. \subsubsection maybe_first \par Returns the first element of a list, or \ref no_such_type_ "tmpl::no_such_type_" if the list is empty. \snippet Test_TMPLDocumentation.cpp metafunctions:maybe_first \snippet Test_TMPLDocumentation.cpp metafunctions:maybe_first:asserts \par In this example, the inner \ref apply "tmpl::apply" call evaluates the \ref if_ "tmpl::if_" statement, returning either a \ref metalambda_metaclosure "metaclosure" or \ref no_such_type_ "tmpl::no_such_type_". The outer \ref apply "tmpl::apply" either evaluates the metaclosure, calling \ref front "tmpl::front", or evaluates \ref no_such_type_ "tmpl::no_such_type_", which is a constant and gives itself. \par The reason for creating a metaclosure is that all the arguments to \ref if_ "tmpl::if_" are always evaluated (it is an ordinary metafunction with no special treatment during evaluation). This is a problem, because, in a naive attempt at this metafunction, if `L` is an empty list `tmpl::front>` would be evaluated for the first branch. To avoid this we use \ref defer "tmpl::defer" to wrap the call to \ref front "tmpl::front" in a metaclosure, which we evaluate only if necessary. \par Note that this metaclosure does not capture anything. `L` is substituted according to normal C++ rules before any Brigand evaluation. This means that the contents of the `tmpl::defer` are, for the first call above, `tmpl::bind>>`. Without the \ref pin "tmpl::pin", the list would be interpreted as a lazy metafunction, resulting in an error because it does not have a `type` type alias. \par The `L` in `tmpl::size` does not need to be protected by a \ref pin "tmpl::pin" because \ref size "tmpl::size" is an eager metafunction, so that expression has been converted to a \ref integral_constant "tmpl::integral_constant" before the metalambda evaluation starts. \subsubsection factorial \par Calculates the factorial using a simple metalambda passed to a \ref fold "tmpl::fold". \snippet Test_TMPLDocumentation.cpp metafunctions:factorial \snippet Test_TMPLDocumentation.cpp metafunctions:factorial:asserts \par A nearly literal rewrite of this into runtime C++ is \snippet Test_TMPLDocumentation.cpp metafunctions:factorial_cpp \par The equivalent of a range-based for loop is easier to express in functional programming (as a fold) than a standard counting for loop. \subsubsection make_subtracter \par Demonstrates the use of captures in metalambdas. \snippet Test_TMPLDocumentation.cpp metafunctions:make_subtracter \snippet Test_TMPLDocumentation.cpp metafunctions:make_subtracter:asserts \par This metafunction returns a \ref metalambda_metaclosure "metaclosure" that subtracts a given number from it's argument. That metaclosure uses both the argument passed to it (`tmpl::_1`, which is 5 in the example) and the value captured at it's creation (`tmpl::parent`, which is 3 in the example). \par (This `make_subtracter` could be implemented more simply as \snippet Test_TMPLDocumentation.cpp metafunctions:make_subtracter_simple but that doesn't demonstrate metaclosures.) \subsubsection multiplication_table \par Constructs a multiplication table. \snippet Test_TMPLDocumentation.cpp metafunctions:multiplication_table \snippet Test_TMPLDocumentation.cpp metafunctions:multiplication_table:asserts \par This demonstrates the use of \ref defer "tmpl::defer" to pass a closure as an argument to a metafunction (\ref transform "tmpl::lazy::transform"), while capturing an argument from the outer context (the metalambda evaluated for the outer \ref transform "tmpl::transform"). This is the use most similar to common uses of the C++ lambda. \par The outer (eager) \ref transform "tmpl::transform" evaluates its second argument as a metalambda. This first evaluates the arguments to the inner \ref transform "tmpl::lazy::transform". The first argument is a \ref list "tmpl::list" of \ref integral_constant "tmpl::integral_constant"s (because the \ref range "tmpl::range" is eager and has already been evaluated). This must be protected by a \ref pin "tmpl::pin" because it looks like a lazy metafunction. The second argument gives a metaclosure, capturing the value from the outer \ref transform "tmpl::transform" (available as `tmpl::parent`). The \ref list "tmpl::list" (without the \ref pin "tmpl::pin", which has already been evaluated) and metaclosure are then passed to the inner \ref transform "tmpl::lazy::transform". \subsubsection column_with_zeros \par Extracts a column from a row-major matrix, extending any short rows with zeros. \snippet Test_TMPLDocumentation.cpp metafunctions:column_with_zeros \snippet Test_TMPLDocumentation.cpp metafunctions:column_with_zeros:asserts \par This example shows another use of \ref defer "tmpl::defer" to avoid evaluating an invalid expression, similar to \ref maybe_first. The use of an \ref args "argument" in the deferred branch makes this case more complicated: a \ref parent "tmpl::parent" expression is used to access arguments from where the \ref defer "tmpl::defer" occurs to avoid having to pass the argument explicitly using the \ref apply "tmpl::apply" call. \par This is the "apply-defer-parent" pattern for lazy evaluation. A \ref parent "tmpl::parent" is placed immediately inside a \ref defer "tmpl::defer" with a (not immediately) surrounding \ref apply "tmpl::apply". The \ref apply "tmpl::apply" and \ref defer "tmpl::defer" collectively add an (empty) element to the head of the argument stack, which is then popped off to restore the original value. This causes the interior metalambda to have the same result it would have had without the \ref defer "tmpl::defer". \subsubsection factorial_recursion \par Again calculates the factorial, but using a recursive algorithm. \snippet Test_TMPLDocumentation.cpp metafunctions:factorial_recursion \snippet Test_TMPLDocumentation.cpp metafunctions:factorial_recursion:asserts \par This is a direct translation of the common definition \f$f(N) = N f(N-1)\f$ for nonzero \f$N\f$, and \f$f(0) = 1\f$. The metalambda is passed a copy of itself as the first argument and the value to take the factorial of as the second. \par This again uses the "apply-defer-parent" pattern to prevent "speculative" evaluation of conditional branches. In this example, speculative evaluation of the branch is invalid because it would recurse infinitely. \subsubsection primes \par Generates a list of prime numbers less than `N` using the sieve of Eratosthenes. This example defines three helper metafunctions. Two, `zero` and `replace_at`, are defined only for clarity's sake and could be inlined. The third, `range_from_types`, is not easily inlinable, and works around Brigand's lack of sequence generating functions without non-type template parameters. \snippet Test_TMPLDocumentation.cpp metafunctions:primes \snippet Test_TMPLDocumentation.cpp metafunctions:primes:asserts \par This is roughly equivalent to the following C++ code with loops converted to fold expressions over ranges. \snippet Test_TMPLDocumentation.cpp metafunctions:primes_cpp \section metafunction_guidelines Guidelines for writing metafunctions \par This section covers a few general guidelines for writing metafunctions in SpECTRE. Some of the Brigand functions mentioned below have specific advice as well. 1. For general metafunctions, write both lazy and eager versions. Follow the STL convention of `foo` being lazy, `foo_t` being eager, and `foo_v` being a constexpr value (if applicable). This does not apply to internal-use or special-purpose metafunctions. \snippet Test_TMPLDocumentation.cpp guidelines:lazy_eager 2. Don't perform unnecessary return-type conversions. We often recommend using STL types over equivalent Brigand types, but if the implementation naturally produces a Brigand type do not do extra work to convert it. \section function_docs Brigand types and functions \par In this section, CamelCase identifiers indicate [type template parameters](https://en.cppreference.com/w/cpp/language/template_parameters#Type_template_parameter) or, occasionally, [template template parameters](https://en.cppreference.com/w/cpp/language/template_parameters#Template_template_parameter). Identifiers in all lowercase indicate [non-type template parameters](https://en.cppreference.com/w/cpp/language/template_parameters#Non-type_template_parameter). Identifiers in [brackets] are optional, and the default value will be identified in the prose description. Identifiers with ellipses... represent zero or more parameters. \par The *head* of a fully specialized class template is the class template itself (e.g., the head of `tmpl::list` is `tmpl::list`). When taken as a metafunction parameter, these are template template parameters and are usually called `Head` below. \par An identifier called `Sequence` must be a full specialization of a class template with no non-type template parameters. Many functions do not make sense on sequences with a fixed length, and these require the head of their sequence arguments to take a variable number of template arguments. In practical applications, sequence arguments will usually be specializations of \ref list "tmpl::list". \par Parameters called `Predicate` must be unary metalambdas returning \ref integral_constant "tmpl::integral_constant"s of `bool` or compatible classes. \par Parameters called `Comparator` must be binary metalambdas returning \ref integral_constant "tmpl::integral_constant"s of `bool` or compatible classes. They must establish a [strict weak ordering](https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings) on the types they will be applied to in the same manner as runtime comparators from the STL. \par Metafunctions documented here are eager unless otherwise noted. In many cases, Brigand provides lazy versions of its metafunctions under the same name in the `tmpl::lazy` namespace. These cases are indicated by the presence of the `HAS_LAZY_VERSION` macro in the usage example. \subsection Containers \par Brigand provides container classes with the sole purpose of wrapping other things. \subsubsection integral_constant integral_constant \par A compile-time value `value` of type `T`. Very similar to std::integral_constant, except that the `constexpr` specifiers on the member functions have been omitted. \snippet Test_TMPLDocumentation.cpp tmpl::integral_constant \par Brigand supplies type aliases for constants of some specific types: \snippet Test_TMPLDocumentation.cpp tmpl::integral_constant::abbreviations \par Most metafunctions that accept integral_constants will accept any type with a `value` static member variable. \par Because of the `type` type alias, integral_constants behave like lazy metafunctions returning themselves. Most lazy metafunctions producing an integral_constant will actually inherit from their result, so `value` will be directly available without needing to go through the `type` alias. \remark Prefer std::integral_constant, except for the convenience wrapper `tmpl::size_t` or when necessary for type equality comparison. \subsubsection list list \par An empty struct templated on a parameter pack, with no additional functionality. \snippet Test_TMPLDocumentation.cpp tmpl::list \par Most metafunctions that operate on lists will work on any struct template. \subsubsection map map \par A collection of key-value \ref pair "tmpl::pair"s with unique keys. See the section on \ref map_operations "operations on maps" for details. \snippet Test_TMPLDocumentation.cpp tmpl::map \par The actual type of a map is unspecified, but it has the same template parameters as a call to `map` that would produce it. \warning Equivalent maps may have different types, depending on the order their keys are stored in internally. \subsubsection pair pair \par A pair of types, with easy access to each type in the pair. \snippet Test_TMPLDocumentation.cpp tmpl::pair \subsubsection set set \par An unordered collection of distinct types. Trying to create a `set` with duplicate entries is an error (but \ref set_insert "tmpl::insert" ignores duplicate entries). See the section on \ref set_operations "operations on sets" for details. \snippet Test_TMPLDocumentation.cpp tmpl::set \par The actual type of a set is unspecified, but it has the same template parameters as a call to `set` that would produce it. \warning Equivalent sets may have different types, depending on the order their elements are stored in internally. \subsubsection type_ type_ \par A struct containing a `type` alias to `T`. \snippet Test_TMPLDocumentation.cpp tmpl::type_ \par When extracting the type, programmers are encouraged to use \ref type_from "tmpl::type_from" to make it clear that the \c \::type that would otherwise appear is not an evaluation of a lazy metafunction. See \ref always "tmpl::always" or \ref identity "tmpl::identity" for similar functionality that is intended for use as a metafunction. \subsection Constants \par Brigand defines a few concrete types and type aliases. \subsubsection empty_base \par An empty struct used by \ref inherit "tmpl::inherit" and \ref inherit_linearly "tmpl::inherit_linearly". Primarily for internal use. \snippet Test_TMPLDocumentation.cpp tmpl::empty_base \subsubsection empty_sequence \par An empty \ref list "tmpl::list". \snippet Test_TMPLDocumentation.cpp tmpl::empty_sequence \remark Prefer just writing `tmpl::list<>`. \subsubsection false_type \par A \ref integral_constant "tmpl::integral_constant" representing `false`. Similar to std::false_type. \snippet Test_TMPLDocumentation.cpp tmpl::false_type \remark Prefer std::false_type. \subsubsection no_such_type_ \par An empty struct returned as the failure case for various searching operations. \snippet Test_TMPLDocumentation.cpp tmpl::no_such_type_ \subsubsection true_type \par A \ref integral_constant "tmpl::integral_constant" representing `true`. Similar to std::true_type. \snippet Test_TMPLDocumentation.cpp tmpl::true_type \remark Prefer std::true_type. \subsection list_constructor Constructor-like functions for lists \par These functions produce \ref list "tmpl::list"s from non-list values. They are often similar to constructors in the STL. \subsubsection filled_list filled_list \par Creates a list containing `n` (passed as an `unsigned int`) of `Entry`. The head of the list defaults to \ref list "tmpl::list". \snippet Test_TMPLDocumentation.cpp tmpl::filled_list \subsubsection integral_list integral_list \par Shorthand for a \ref list "tmpl::list" of \ref integral_constant "tmpl::integral_constant"s of the type `T` with values `n...`. \snippet Test_TMPLDocumentation.cpp tmpl::integral_list \remark Prefer std::integer_sequence when used for pack expansion. Prefer `tmpl::integral_list` when the contents need to be manipulated for more complicated metaprogramming. \subsubsection make_sequence make_sequence \par Produces a list with first element `Start` and length `n` (provided as an `unsigned int`). The remaining elements are obtained by repeated applications of the \ref metalambdas "metalambda" `Next`, defaulting to \ref next "tmpl::next". The head of the sequence can be specified, and defaults to \ref list "tmpl::list". \snippet Test_TMPLDocumentation.cpp tmpl::make_sequence \see \ref range "tmpl::range", \ref repeat "tmpl::repeat" \subsubsection range range \par Produces a \ref list "tmpl::list" of \ref integral_constant "tmpl::integral_constant"s of type `T` representing adjacent ascending integers from `start` to `stop`, including the starting value and excluding the ending value. \snippet Test_TMPLDocumentation.cpp tmpl::range \see \ref reverse_range "tmpl::reverse_range" \subsubsection reverse_range reverse_range \par Produces a \ref list "tmpl::list" of \ref integral_constant "tmpl::integral_constant"s of type `T` representing adjacent descending integers from `start` to `stop`, including the starting value and excluding the ending value. \snippet Test_TMPLDocumentation.cpp tmpl::reverse_range \see \ref range "tmpl::range" \subsection list_query Functions for querying lists \par These tend to be similar to const member functions in the STL and the non-modifying sequence operations in ``. They are most frequently used with \ref list "tmpl::list", but similar classes will also work. \subsubsection all all \par Checks if `Predicate` is true for all elements of `Sequence`. The default predicate checks that the element's `value` is not equal to zero. \snippet Test_TMPLDocumentation.cpp tmpl::all \note The predicate must return the same true value for each element for `all` to return true. This behaviour may differ by compiler, so it can't be relied upon. \snippet Test_TMPLDocumentation.cpp tmpl::all:inhomogeneous \see \ref any "tmpl::any", \ref none "tmpl::none" \subsubsection any any \par Checks if `Predicate` is true for at least one element of `Sequence`. The default predicate checks that the element's `value` is not equal to zero. \snippet Test_TMPLDocumentation.cpp tmpl::any \remark The \ref any "tmpl::any" and \ref none "tmpl::none" metafunctions perform the same tasks as \ref found "tmpl::found" and \ref not_found "tmpl::not_found", but use different algorithms. In general, \ref any "tmpl::any" and \ref none "tmpl::none" are much faster, but \ref found "tmpl::found" and \ref not_found "tmpl::not_found" short-circuit, so they may be preferable with short lists and expensive predicates. \note The predicate must return the same false value for each element for `any` to return false. This behaviour may differ by compiler, so it can't be relied upon. \snippet Test_TMPLDocumentation.cpp tmpl::any:inhomogeneous \see \ref all "tmpl::all", \ref found "tmpl::found", \ref none "tmpl::none" \subsubsection at at \par Retrieves a given element of `Sequence`, similar to `operator[]` of the STL containers. The `Index` is supplied as a \ref integral_constant "tmpl::integral_constant" or similar type. \snippet Test_TMPLDocumentation.cpp tmpl::at \par This operator is \ref map_at "overloaded for maps". \see \ref at_c "tmpl::at_c" \subsubsection at_c at_c \par Retrieves a given element of `Sequence`, similar to `operator[]` of the STL containers. The index `n` is supplied as an `unsigned int`. \snippet Test_TMPLDocumentation.cpp tmpl::at_c \see \ref at "tmpl::at" \subsubsection back back \par Retrieves the last element of `Sequence`. \snippet Test_TMPLDocumentation.cpp tmpl::back \subsubsection count_if count_if \par Returns the number of elements of `Sequence` satisfying `Predicate`. \snippet Test_TMPLDocumentation.cpp tmpl::count_if \subsubsection fold fold \par Performs a [left fold](https://en.wikipedia.org/wiki/Fold_(higher-order_function)), i.e., given a list `Sequence`, initial state `State`, and \ref metalambdas "metalambda" `Functor`, updates the state by calling `Functor` on the state and the first element of `Sequence`, repeats with the second, and so on, returning the final state. \snippet Test_TMPLDocumentation.cpp tmpl::fold \par Brigand provides `tmpl::_state` and `tmpl::_element` aliases to the appropriate \ref args "arguments" for use in folds. \see \ref reverse_fold "tmpl::reverse_fold" \subsubsection found found \par Returns, as a \ref integral_constant "tmpl::integral_constant" of `bool`, whether `Predicate` matches any element of `Sequence`. The default predicate checks that the element's `value` is not equal to zero. \snippet Test_TMPLDocumentation.cpp tmpl::found \remark This function performs the same operation as \ref any "tmpl::any". See \ref any "tmpl::any" for discussion. \see \ref any "tmpl::any", \ref find "tmpl::find", \ref not_found "tmpl::not_found" \subsubsection front front \par Retrieves the first element of `Sequence`. \snippet Test_TMPLDocumentation.cpp tmpl::front \subsubsection index_if \par Finds the index as a `size_t` \ref integral_constant "tmpl::integral_constant" of the first type in `Sequence` satisfying `Predicate`. Returns `NotFound`, defaulting to \ref no_such_type_ "tmpl::no_such_type_" if no elements match. \snippet Test_TMPLDocumentation.cpp tmpl::index_if \subsubsection index_of index_of \par Finds the index as a `size_t` \ref integral_constant "tmpl::integral_constant" of the first occurrence of `T` in `Sequence`. Returns \ref no_such_type_ "tmpl::no_such_type_" if the type is not found. \snippet Test_TMPLDocumentation.cpp tmpl::index_of \subsubsection list_contains list_contains \par Checks whether `T` is contained in `Sequence`, returning a \ref integral_constant "tmpl::integral_constant" of `bool`. \snippet Test_TMPLDocumentation.cpp tmpl::list_contains \note This is not a Brigand metafunction. It is implemented in SpECTRE. \subsubsection none none \par Checks if `Predicate` is false for all elements of `Sequence`. The default predicate checks that the element's `value` is not equal to zero. \snippet Test_TMPLDocumentation.cpp tmpl::none \remark This function performs the same operation as \ref not_found "tmpl::not_found". See \ref any "tmpl::any" for discussion. \note The predicate must return the same false value for each element for `none` to return true. This behaviour may differ by compiler, so it can't be relied upon. \snippet Test_TMPLDocumentation.cpp tmpl::none:inhomogeneous \see \ref all "tmpl::all", \ref any "tmpl::any", \ref not_found "tmpl::not_found" \subsubsection not_found not_found \par Returns, as a \ref integral_constant "tmpl::integral_constant" of `bool`, whether `Predicate` matches no elements of `Sequence`. The default predicate checks that the element's `value` is not equal to zero. \snippet Test_TMPLDocumentation.cpp tmpl::not_found \remark This function performs the same operation as \ref none "tmpl::none". See \ref any "tmpl::any" for discussion. \see \ref find "tmpl::find", \ref found "tmpl::found", \ref none "tmpl::none" \subsubsection size size \par Returns the number of elements in `Sequence` as a \ref integral_constant "tmpl::integral_constant" of type `unsigned int`. \snippet Test_TMPLDocumentation.cpp tmpl::size \see \ref count "tmpl::count" \subsection list_to_list Functions producing lists from other lists \par These tend to be similar to non-const member functions in the STL and the mutating sequence operations in ``, but due to the nature of metaprogramming all return a new list rather than modifying an argument. They are most frequently used with \ref list "tmpl::list", but similar classes will also work. \subsubsection append append \par Concatenates all of its arguments, keeping the head of the first (or \ref list "tmpl::list" if passed no arguments). \snippet Test_TMPLDocumentation.cpp tmpl::append \see \ref join "tmpl::join" \subsubsection clear clear \par Produces a list with the same head as `Sequence` but no elements. \snippet Test_TMPLDocumentation.cpp tmpl::clear \remark If the head is known, prefer writing it explicitly. If the head is irrelevant, write an empty \ref list "tmpl::list". \subsubsection erase erase \par Produces a copy of `Sequence` with the element at index `Index` (passed as a \ref integral_constant "tmpl::integral_constant" or similar type) removed. \snippet Test_TMPLDocumentation.cpp tmpl::erase \par This operator is overloaded \ref map_erase "for maps" and \ref set_erase "for sets". \see \ref erase_c \subsubsection erase_c erase_c \par Produces a copy of `Sequence` with the element at index `n` (passed as an `unsigned int`) removed. \snippet Test_TMPLDocumentation.cpp tmpl::erase_c \subsubsection filter filter \par Removes all types not matching `Predicate` from `Sequence`. \snippet Test_TMPLDocumentation.cpp tmpl::filter \see \ref remove_if "tmpl::remove_if" \subsubsection find find \par Returns a list containing the first element of `Sequence` for which `Predicate` returns true and all subsequent elements. The default predicate checks that the element's `value` is not equal to zero. Returns an empty list if the predicate returns false for all elements. \snippet Test_TMPLDocumentation.cpp tmpl::find \see \ref found "tmpl::found", \ref not_found "tmpl::not_found", \ref reverse_find "tmpl::reverse_find" \subsubsection flatten flatten \par Recursively inlines the contents of elements of `Sequence` that are sequences with the same head. \snippet Test_TMPLDocumentation.cpp tmpl::flatten \see \ref join "tmpl::join" \subsubsection join join \par Combines lists in the same manner as \ref append "tmpl::append", but takes a list of lists instead of multiple arguments. \snippet Test_TMPLDocumentation.cpp tmpl::join \subsubsection list_difference list_difference \par Remove all elements that occur in `Sequence2` from `Sequence1`. \snippet Test_TMPLDocumentation.cpp tmpl::list_difference \note This is not a Brigand metafunction. It is implemented in SpECTRE. \subsubsection merge merge \par Given two sorted lists, returns a sorted list containing the elements of both. A comparator metalambda can be provided, defaulting to \ref math_comparison "tmpl::less". \snippet Test_TMPLDocumentation.cpp tmpl::merge \note If there are equivalent elements, those from the second list are placed earlier. \snippet Test_TMPLDocumentation.cpp tmpl::merge:equiv \see std::merge \subsubsection partition partition \par Returns a \ref pair "tmpl::pair" containing a list of the elements of `Sequence` for which the `Predicate` returns true and a list of the elements of `Sequence` for which the `Predicate` returns false. \snippet Test_TMPLDocumentation.cpp tmpl::partition \see \ref filter "tmpl::filter", \ref remove_if "tmpl::remove_if" \subsubsection pop_back pop_back \par Remove `Count` elements from the end of `Sequence`. The number of elements to remove is supplied as a \ref integral_constant "tmpl::integral_constant" and defaults to 1. \snippet Test_TMPLDocumentation.cpp tmpl::pop_back \subsubsection pop_front pop_front \par Remove `Count` elements from the beginning of `Sequence`. The number of elements to remove is supplied as a \ref integral_constant "tmpl::integral_constant" and defaults to 1. \snippet Test_TMPLDocumentation.cpp tmpl::pop_front \subsubsection push_back push_back \par Appends types `T...` to `Sequence`. \snippet Test_TMPLDocumentation.cpp tmpl::push_back \subsubsection push_front push_front \par Prepends types `T...` to `Sequence`. The order of the prepended items is retained: they are pushed as a unit, not one-by-one. \snippet Test_TMPLDocumentation.cpp tmpl::push_front \subsubsection remove remove \par Removes all occurrences of `T` from `Sequence`. \snippet Test_TMPLDocumentation.cpp tmpl::remove \subsubsection remove_duplicates remove_duplicates \par Remove duplicates from `Sequence`. The first occurrence of each type is kept. \snippet Test_TMPLDocumentation.cpp tmpl::remove_duplicates \note This is not a Brigand metafunction. It is implemented in SpECTRE. \subsubsection remove_if remove_if \par Removes all types matching `Predicate` from `Sequence`. \snippet Test_TMPLDocumentation.cpp tmpl::remove_if \see \ref filter "tmpl::filter" \subsubsection replace replace \par Replaces all occurrences of `Old` in `Sequence` with `New`. \snippet Test_TMPLDocumentation.cpp tmpl::replace \subsubsection replace_if replace_if \par Replaces all types in `Sequence` matching `Predicate` with `T`. \snippet Test_TMPLDocumentation.cpp tmpl::replace_if \subsubsection reverse reverse \par Reverses the order of types in `Sequence`. \snippet Test_TMPLDocumentation.cpp tmpl::reverse \subsubsection reverse_find reverse_find \par Returns a list containing the last element of `Sequence` for which `Predicate` returns true and all preceding elements. The default predicate checks that the element's `value` is not equal to zero. Returns an empty list if the predicate returns false for all elements. \snippet Test_TMPLDocumentation.cpp tmpl::reverse_find \see \ref find "tmpl::find" \subsubsection reverse_fold reverse_fold \par Performs a [right fold](https://en.wikipedia.org/wiki/Fold_(higher-order_function)), i.e., given a list `Sequence`, initial state `State`, and \ref metalambdas "metalambda" `Functor`, updates the state by calling `Functor` on the state and the last element of `Sequence`, repeats with the second to last, and so on, returning the final state. \snippet Test_TMPLDocumentation.cpp tmpl::reverse_fold \par Brigand provides `tmpl::_state` and `tmpl::_element` aliases to the appropriate \ref args "arguments" for use in folds. \see \ref fold "tmpl::fold" \subsubsection sort sort \par Sorts `Sequence` according to `Comparator`, which defaults to \ref math_comparison "tmpl::less". \snippet Test_TMPLDocumentation.cpp tmpl::sort \note The sort is not stable. \snippet Test_TMPLDocumentation.cpp tmpl::sort:equiv \subsubsection split split \par Splits `Sequence` into parts separated by `Delimiter`, discarding empty parts. \snippet Test_TMPLDocumentation.cpp tmpl::split \subsubsection split_at split_at \par Returns a list of two of lists, the first containing the first `Index` (supplied as a \ref integral_constant "tmpl::integral_constant") elements or `Sequence`, and the second containing the remaining elements. \snippet Test_TMPLDocumentation.cpp tmpl::split_at \subsubsection transform transform \par Calls a `Functor` on each element of `Sequence`, collecting the results in a new list. If additional `Sequences...` are supplied, elements from those lists are passed as additional arguments to `Functor`. \snippet Test_TMPLDocumentation.cpp tmpl::transform \subsection map_operations Operations on maps \par Brigand's \ref map "tmpl::map" type can be manipulated by several metafunctions. \par Examples in this section use this map as an example: \snippet Test_TMPLDocumentation.cpp example_map \subsubsection map_at at \par Returns the value associated with `Key` in `Map`. Returns \ref no_such_type_ "tmpl::no_such_type_" if `Key` is not in the map. \snippet Test_TMPLDocumentation.cpp tmpl::at:map \par This operator is \ref at "overloaded for lists". When called on a \ref map "tmpl::map", this is the same as \ref lookup "tmpl::lookup". \subsubsection map_erase erase \par Produces a copy of `Map` with the element with the key `Key` removed. If `Key` is not in the map, returns `Map` unchanged. \snippet Test_TMPLDocumentation.cpp tmpl::erase:map \par This operator is overloaded \ref erase "for lists" and \ref set_erase "for sets". \subsubsection map_has_key has_key \par Returns a \ref integral_constant "tmpl::integral_constant" of `bool` indicating whether `Map` contains the key `Key`. \snippet Test_TMPLDocumentation.cpp tmpl::has_key:map \par This operator is \ref set_has_key "overloaded for sets". \subsubsection map_insert insert \par Returns `Map` with `Pair` added. If the key of `Pair` is already in the map, the map is returned unchanged. \snippet Test_TMPLDocumentation.cpp tmpl::insert:map \par This operator is \ref set_insert "overloaded for sets". \subsubsection keys_as_sequence keys_as_sequence \par Returns the keys from `Map` as a sequence with head `Head`, defaulting to \ref set "tmpl::set". \snippet Test_TMPLDocumentation.cpp tmpl::keys_as_sequence \par If the key-value pairs are required, they can be extracted directly from the template arguments of the \ref map "tmpl::map". \see \ref values_as_sequence "tmpl::values_as_sequence" \subsubsection lookup lookup \par Returns the value associated with `Key` in `Map`. Returns \ref no_such_type_ "tmpl::no_such_type_" if `Key` is not in the map. \snippet Test_TMPLDocumentation.cpp tmpl::lookup \see \ref map_at "tmpl::at" \subsubsection lookup_at lookup_at \par Returns the value associated with `Key` in `Map`, wrapped in a \ref type_ "tmpl::type_". Returns `type_` if `Key` is not in the map. This function has no eager version, but is still in the `tmpl::lazy` namespace. \snippet Test_TMPLDocumentation.cpp tmpl::lookup_at \see \ref lookup "tmpl::lookup" \subsubsection values_as_sequence values_as_sequence \par Returns the values from `Map` as a sequence with head `Head`, defaulting to \ref list "tmpl::list". \snippet Test_TMPLDocumentation.cpp tmpl::values_as_sequence \par If the key-value pairs are required, they can be extracted directly from the template arguments of the \ref map "tmpl::map". \see \ref keys_as_sequence "tmpl::keys_as_sequence" \subsection set_operations Operations on sets \par Brigand's \ref set "tmpl::set" type can be manipulated by several metafunctions. \subsubsection contains contains \par Returns a \ref integral_constant "tmpl::integral_constant" of `bool` indicating whether `Set` contains `T`. \snippet Test_TMPLDocumentation.cpp tmpl::contains \subsubsection set_erase erase \par Produces a copy of `Set` with the element `T` removed. If the element is not in the set, returns the set unchanged. \snippet Test_TMPLDocumentation.cpp tmpl::erase:set \par This operator is overloaded \ref erase "for lists" and \ref map_erase "for maps". \subsubsection set_has_key has_key \par Returns a \ref integral_constant "tmpl::integral_constant" of `bool` indicating whether `Set` contains `T`. \snippet Test_TMPLDocumentation.cpp tmpl::has_key:set \par This operator is \ref map_has_key "overloaded for maps". \subsubsection set_insert insert \par Returns a copy of `Set` containing an additional element `T`. If `T` is already in the set, the set is returned unchanged. \snippet Test_TMPLDocumentation.cpp tmpl::insert:set \par This operator is \ref map_insert "overloaded for maps". \subsection math Mathematical functions \par These perform the same operations at their language counterparts, but on \ref integral_constant "tmpl::integral_constant"s (or anything else with a `value` static member type of type `value_type`). The results inherit from \ref integral_constant "tmpl::integral_constant"s of types noted below. \par These are all lazy metafunctions. \subsubsection math_arithmetic Arithmetic operators \par These operations return classes inheriting from \ref integral_constant "tmpl::integral_constant"s of the same type as the result of the language operator on their arguments. The integral promotion and conversion rules are applied. (Contrast the \ref math_bitwise "bitwise operators".) \snippet Test_TMPLDocumentation.cpp math_arithmetic \par The standard library runtime functors have the same names for std::plus, std::minus, std::divides, and std::negate, but the other two are std::multiplies and std::modulus. \subsubsection math_bitwise Bitwise operators \par These operations return classes inheriting from \ref integral_constant "tmpl::integral_constant"s of the same type as their first argument's `value`. This is *not* generally the same type as the language operator, even when the types of the values of both arguments are the same. (The integer promotion and conversion rules are not applied.) \snippet Test_TMPLDocumentation.cpp math_bitwise \par The standard library runtime functors are called std::bit_not, std::bit_and, std::bit_or, and std::bit_xor. \subsubsection math_comparison Comparison operators \par These operations return classes inheriting from \ref integral_constant "tmpl::integral_constant"s of `bool`. \snippet Test_TMPLDocumentation.cpp math_comparison \par The standard library runtime functors have the same names, such as std::equal_to. \subsubsection math_logical Logical operators \par These operations return classes inheriting from \ref integral_constant "tmpl::integral_constant"s of `bool`. They should only be used on types wrapping `bool`s. The `and_` and `or_` structs can take any number of arguments. \snippet Test_TMPLDocumentation.cpp math_logical \par The standard library runtime functors are called std::logical_and, std::logical_or, and std::logical_not. The xor operation is equivalent to \ref math_comparison "tmpl::not_equal_to". \subsubsection identity identity \par The identity function. Unlike most math functions, this returns the same type as its argument, even if that is not a \ref integral_constant "tmpl::integral_constant". \snippet Test_TMPLDocumentation.cpp tmpl::identity \see \ref always "tmpl::always" \subsubsection max max \par Computes the larger of `T1` and `T2`, returning a \ref integral_constant "tmpl::integral_constant" of the common type of its arguments. \snippet Test_TMPLDocumentation.cpp tmpl::max \subsubsection min min \par Computes the smaller of `T1` and `T2`, returning a \ref integral_constant "tmpl::integral_constant" of the common type of its arguments. \snippet Test_TMPLDocumentation.cpp tmpl::min \subsubsection next next \par Computes `T` plus one, returning a \ref integral_constant "tmpl::integral_constant" of the same type as its argument. \snippet Test_TMPLDocumentation.cpp tmpl::next \subsubsection prev prev \par Computes `T` minus one, returning a \ref integral_constant "tmpl::integral_constant" of the same type as its argument. \snippet Test_TMPLDocumentation.cpp tmpl::prev \subsection misc Miscellaneous functions \par Functions that don't fit into any of the other sections. \subsubsection always always \par A lazy identity function. \snippet Test_TMPLDocumentation.cpp tmpl::always \see \ref identity "tmpl::identity" \subsubsection apply apply \par Calls a \ref metalambdas "metalambda" `Lambda` with arguments `Arguments...`. \snippet Test_TMPLDocumentation.cpp tmpl::apply \subsubsection count count \par Returns the number of template parameters provided as a \ref integral_constant "tmpl::integral_constant" of `unsigned int`. \snippet Test_TMPLDocumentation.cpp tmpl::count \subsubsection conditional_t conditional_t \par Returns `TrueResult` if the `bool` `b` is true, otherwise `FalseResult`. An optimized version of std::conditional_t. \snippet Test_TMPLDocumentation.cpp tmpl::conditional_t \note This is not a Brigand metafunction. It is implemented in SpECTRE. \subsubsection eval_if eval_if \par A lazy metafunction that, if `Condition` has a true `value`, evaluates and returns the result of the lazy metafunction (*not* metalambda) `TrueFunction`, otherwise, evaluates and returns the result of the lazy metafunction `FalseFunction`. \snippet Test_TMPLDocumentation.cpp tmpl::eval_if \par This performs lazy evaluation of conditional branches outside of a metalambda. \subsubsection eval_if_c eval_if_c \par The same as \ref eval_if "tmpl::eval_if", but takes its first argument as a `bool` instead of a type. \snippet Test_TMPLDocumentation.cpp tmpl::eval_if_c \subsubsection has_type has_type \par A lazy metafunction that returns `T` (defaulting to `void`), ignoring its first argument. \snippet Test_TMPLDocumentation.cpp tmpl::has_type \par This can be used to expand a parameter pack to repetitions of the same type. \snippet Test_TMPLDocumentation.cpp tmpl::has_type:pack_expansion \snippet Test_TMPLDocumentation.cpp tmpl::has_type:pack_expansion:asserts \subsubsection if_ if_ \par A lazy metafunction that returns `TrueResult` if the `value` static member value of `Condition` is true, and otherwise `FalseResult`. \snippet Test_TMPLDocumentation.cpp tmpl::if_ \warning The second and third arguments are both evaluated, independent of which is returned. Use \ref defer "tmpl::defer" or \ref eval_if "tmpl::eval_if" if this is undesirable. \subsubsection if_c if_c \par The same as std::conditional. \snippet Test_TMPLDocumentation.cpp tmpl::if_c \subsubsection inherit inherit \par A lazy metafunction that produces a type with all of its template arguments as base classes. All the arguments must be unique. \snippet Test_TMPLDocumentation.cpp tmpl::inherit \remark This task can be performed more simply than the algorithm used by Brigand by directly using pack expansions: \snippet Test_TMPLDocumentation.cpp tmpl::inherit:pack:definitions \snippet Test_TMPLDocumentation.cpp tmpl::inherit:pack:asserts \note The \ref empty_base "tmpl::empty_base" type is used internally as a sentinel. The result may or may not inherit from \ref empty_base "tmpl::empty_base", independently of whether it is supplied as an argument. \subsubsection inherit_linearly inherit_linearly \par Transforms `Sequence` into a linked list. The `NodePattern` must be a class template (*not* a lazy metafunction) instantiated with metalambdas. The function performs a [left fold](https://en.wikipedia.org/wiki/Fold_(higher-order_function)), with the `Root` (defaulting to \ref empty_base "tmpl::empty_base") as the initial state and the transform function evaluating the arguments to the node pattern. \snippet Test_TMPLDocumentation.cpp tmpl::inherit_linearly \remark This function handles its function-like argument differently from any other function in Brigand. Prefer \ref fold "tmpl::fold", which can perform the same task and has a more standard interface. \subsubsection is_set is_set \par Tests if all of its arguments are distinct, producing a \ref integral_constant "tmpl::integral_constant" of `bool`. \snippet Test_TMPLDocumentation.cpp tmpl::is_set \note This is unrelated to the Brigand \ref set "tmpl::set" type. \subsubsection real_ real_ \par Represents a floating point number of type `RealType` at compile time via its internal memory representation. The value is stored as a \ref integral_constant "tmpl::integral_constant" of type `IntType` with value `value` (which must be the same size as `RealType`) and can be extracted at runtime using the conversion operator. Brigand provides the aliases `single_` and `double_` with `RealType` and `IntType` set to appropriate values. \snippet Test_TMPLDocumentation.cpp tmpl::real_ \par There are no compile-time mathematical functions provided for floating point types. They are opaque (or sometimes treated as integers) until runtime. \remark Consider whether you really need to represent floating point values at compile time. \see std::ratio \subsubsection repeat repeat \par Calls a unary eager metafunction `Function` on `Initial`, then on the result of that, then on the result of that, and so on, up to `Count` calls. \snippet Test_TMPLDocumentation.cpp tmpl::repeat \note This function has a lazy version, but it cannot be used in a metalambda because the template template parameter prevents manipulation of the parameter list. \snippet Test_TMPLDocumentation.cpp tmpl::repeat:lazy \see \ref make_sequence "tmpl::make_sequence" \subsubsection sizeof_ sizeof_ \par A lazy metafunction that computes `sizeof` its argument as an `unsigned int` \ref integral_constant "tmpl::integral_constant". \snippet Test_TMPLDocumentation.cpp tmpl::sizeof_ \subsubsection substitute substitute \par Substitutes values from `ArgumentList` for appearances of \ref args "tmpl::args" (but *not* `tmpl::_1` or `tmpl::_2`) appearing in `Pattern`. \snippet Test_TMPLDocumentation.cpp tmpl::substitute \subsubsection type_from type_from \par Extracts the `type` from `T`. \snippet Test_TMPLDocumentation.cpp tmpl::type_from \remark This function will work on any class with a `type` type alias, but, when used outside of a metafunction, it should only be used with \ref type_ "tmpl::type_" for clarity. \subsubsection wrap wrap \par Replaces the head of `Sequence` with `Head`. \snippet Test_TMPLDocumentation.cpp tmpl::wrap \note This function has a lazy version, but it cannot be used in a metalambda because the template template parameter prevents manipulation of the parameter list. \snippet Test_TMPLDocumentation.cpp tmpl::wrap:lazy \subsection runtime Runtime functionality \par Brigand provides a few C++ functions that execute at runtime. \par The examples in this section use the following definition: \snippet Test_TMPLDocumentation.cpp runtime_declarations \subsubsection for_each_args for_each_args(functor, arguments...) \par Calls `functor` on each of `arguments...`, in order. Returns `functor`. \snippet Test_TMPLDocumentation.cpp tmpl::for_each_args:defs \snippet Test_TMPLDocumentation.cpp tmpl::for_each_args \subsubsection for_each for_each(functor) \par Calls `functor` on \ref type_ "tmpl::type_" objects wrapping each type in `Sequence`, in order. Returns `functor`. \snippet Test_TMPLDocumentation.cpp tmpl::for_each:defs \snippet Test_TMPLDocumentation.cpp tmpl::for_each \see \ref type_from "tmpl::type_from" \subsubsection select select(true_result, false_result) \par Returns `true_result` if `Condition`'s `value` member is true, and `false_result` if it is false. \snippet Test_TMPLDocumentation.cpp tmpl::select \subsection external External integration \par Brigand provides metafunctions for interfacing with some types from the standard library and Boost. They usually come in pairs, with `as_X` taking a list and `X_wrapper` taking a parameter pack. This makes `X_wrapper` equivalent to the wrapped class. \remark Avoid the `*_wrapper` functions in favor of using the class directly. \subsubsection boost_integration Boost \par Brigand provides functions to produce the `boost::fusion` types `deque`, `list`, `set`, and `vector`, as well as `boost::variant`. Because we use brigand instead of boost::fusion and because `std::variant` replaces `boost::variant`, these are not available in SpECTRE. \subsubsection stl_integration STL \par Brigand provides functions to produce the STL types std::pair and std::tuple. In addition to the usual functions, Brigand provides `pair_wrapper_`, which is a lazy form of `pair_wrapper`. The pair functions all assert that they have received two types. \snippet Test_TMPLDocumentation.cpp stl_integration \subsubsection make_integral integral_constant \par Brigand provides two functions for converting from std::integral_constant (or a similar class with a `value_type` and a `value`) to \ref integral_constant "tmpl::integral_constant". The lazy metafunction `make_integral` performs this conversion. The `as_integral_list` eager metafunction performs this operation on all elements of a list. \snippet Test_TMPLDocumentation.cpp tmpl::make_integral \warning The standard library std::integer_sequence is not a list of types, and so cannot be used as input to `as_integral_list`. \subsubsection as_list list \par Brigand provides two metafunctions for converting types to Brigand sequences. The more general function, `as_sequence`, is equivalent to \ref wrap "tmpl::wrap". The specialized version, `tmpl::as_list`, produces a \ref list "tmpl::list". \snippet Test_TMPLDocumentation.cpp tmpl::as_list \remark Using `as_list` is often not necessary because most metafunctions operate on arbitrary template classes. \subsubsection as_set set \par Brigand provides the standard two metafunctions for converting types to Brigand \ref set "tmpl::set"s. \snippet Test_TMPLDocumentation.cpp tmpl::as_set \section oddities Bugs/Oddities * \ref push_front and \ref pop_front have lazy versions, but \ref push_back, and \ref pop_back do not. * \ref reverse_range validates its arguments, but \ref range does not. (Probably because the former is called incorrectly more often.) * Brigand inconsistently uses `unsigned int` and `size_t` for size-related things. (Most blatantly, the result of \ref sizeof_ is represented as an `unsigned int`.) * Brigand has a file containing operator overloads for \ref integral_constant ""s, but it is not included by the main brigand header. They work poorly, mostly because it inexplicably puts them all in namespace std where the compiler can't find them. ================================================ FILE: docs/DevGuide/BuildOptimization.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Build Profiling and Optimization {#build_profiling_and_optimization} \tableofcontents # Why is our build so expensive? SpECTRE makes heavy use of compile-time logic, which is responsible for a lot of the nice type-checking, performance, and flexibility the code has to offer. For instance, our central data structure, the \ref DataBoxGroup "DataBox", uses a type list of several "tags" to determine its contents, as well as to automatically propagate dependencies in compute items. This use of compile-time logic, however, has the trade-off of making our builds take longer and use more memory than a similar implementation in runtime logic would. There is good reason to believe that some of these costs are payed back at runtime, because many of our compile-time switches permit the final runtime code to be more efficient or avoid unnecessary computation. There is certainly room for optimization, though, either in finding better compile-time implementations of the algorithms, eliminating expensive template instantiations, or moving inefficient parts to runtime. This guide gives a quick outline of some of the methods that can be used to profile the build and possible pitfalls # Understanding template expenses The cost of compile-time template logic is a bit non-intuitive if you are used to thinking only of runtime performance. The main reason is that the typical unit of 'cost' in a compile-time operation is the number of instantiated types and functions. Re-using a type that has been instantiated elsewhere (in the same translation unit) typically has a very low compile-time cost, where instantiating a type with new template parameters will incur its own cost, plus any new types that it requires in e.g. type aliases or member functions. Consider a Fibonacci calculation at compile-time: ``` template struct Fibonacci { static constexpr size_t value = Fibonacci::value + Fibonacci::value; }; template <> struct Fibonacci<1> { static constexpr size_t value = 1; }; template <> struct Fibonacci<0> { static constexpr size_t value = 1; }; ``` If we were to write the same logic at runtime, the algorithm would be hopelessly inefficient; the recursive calls would cause each call to Fibonacci to make two calls to the same function, resulting in an exponential time algorithm! However, the C++ language will only instantiate unique types, so only N types will be created, giving a linear in compile-time operation. Compile-time lists and list operations frequently appear in SpECTRE, and should be thought of differently from runtime list operations. In compile-time lists, we have no access to true constant-time lookup, speedy algorithms that rely on sorted structures, or more sophisticated data structures (balanced trees, hash tables, etc.). The limitations of compile-time list techniques can cause list operations to be more costly than we could achieve with runtime data structures. Consider a basic version of the compile-time list accessor: ``` template struct list_at; template struct list_at, 0> { using type = ListItem0; }; template struct list_at, Index> { using type = typename list_at, Index - 1>::type; }; ``` Now, to access the Nth item in the list, we need to instantiate \f$O(N)\f$ types. The above implementation is significantly more costly than we would find in practice in template metaprogramming libraries -- in particular, our chosen TMPL backend, [Brigand](https://github.com/edouarda/brigand), manages the task in \f$O(\log(N))\f$ (at least in type instantiation count). Most of the list operations in SpECTRE cannot take advantage of any particular ordering or hashing of the list, so must resort to naive list operations -- so, searching a list (`tmpl::list_contains` or `tmpl::index_of`) is \f$O(N)\f$ cost, `tmpl::remove_duplicates` is \f$O(N^2)\f$, and `tmpl::list_difference` is similarly \f$O(N^2)\f$. So, complicated type logic scales pretty badly with long lists, and improvements can sometimes be made by reducing a list's size or avoiding the more costly list operations when a list is known to be long. # Profiling the build In the current version of SpECTRE, the most expensive builds are the final translation units associated with the executables (particularly the most complicated executables, like Generalized Harmonic and Valencia), which should be unsurprising from the above discussion: it is in these compilation steps that we instantiate the Parallel components, and in turn, all of the \ref DataBoxGroup "DataBox" types that will be used during the evolution. Similarly, a number of tests have now shown that in the current version of SpECTRE (as of early 2021), by far the most expensive part of the build is \ref DataBoxGroup "DataBox" operations and instantiations, and the best build performance gains are available by either reducing the number of \ref DataBoxGroup "DataBox"es that are instantiated, reducing the number of tags (particularly compute tags) stored in the \ref DataBoxGroup "DataBox", or optimizing the implementations of the \ref DataBoxGroup "DataBox" and its utilities. So, generally speaking, profiling should start by focusing on the \ref DataBoxGroup "DataBox", and move to other utilities if it becomes clear that there are other parts of the code that are contributing significantly to the compilation time or memory usage. ## Specialized tests and feature exploration This is simultaneously the most reliable and most labor-intensive strategy for understanding build costs. The procedure is to identify a feature you'd like to profile and create a specialized test for that feature. Then, you can easily include or exclude uses of functions or classes that you want to profile, and compare the relative total cost of building the test executable. You may want to temporarily remove all other source files from the test executable. There are a number of tools for profiling the cost of an individual process, but for compilation, the detailed tools like `perf` or hpctoolkit are unlikely to give useful information about what parts of our code are slow to build. Instead, it's best to just carefully measure the full build of the target in question, and rapidly iterate to include or exclude potentially expensive parts to understand the build costs. There are a lot of tools that can give you the global resource usage information, including the `/proc/$PID/status` file from kernel information, `top`, or tools from the `sysstat` package. The `time` utility is particularly user-friendly, available on ubuntu (and therefore in the SpECTRE build container) via `apt-get install time`. Then, it can be invoked by `/usr/bin/time -v your_command` (note that simply `time` will route to a different alias in the default environment on ubuntu in the container, so the full path `/usr/bin/time` is required). After completion, it will print a readable report of the time and memory usage. One important feature to be aware of in profiling the build by this method is the implicit memoization of many compile-time features. For instance, if feature `A` and `B` both instantiate a class `C` that is expensive to build, you'll see a difference in the build cost when _either_ `A` or `B` are included, but the cost won't be additive - the second feature will just 'reuse' the instantiation from the first. To optimize this type of situation, either `C` must be improved to be less costly to instantiate, or its use must be eliminated from _both_ `A` and `B` -- removing `C` from only one of the classes that use it won't help the build much at all. ## Templight++ Detailed profiling of a C++ build is a surprisingly hard task, and there are few useful tools for getting a good idea for what parts of a compilation are expensive. One tool that can perform some profiling of the build is [templight++](https://github.com/mikael-s-persson/templight). _It is important to note that this tool often produces build profiles that are misleading or incomplete!_ It is included in this guide under the philosophy that a flawed tool can be better than no tool at all in some circumstances, but the templight++ profiles should be taken primarily as a loose guide for features to investigate with more careful follow-up investigations like the above suggestion of specialized tests and feature exploration. The `templight++` build and usage instructions work nicely with the current SpECTRE build system, and the cmake trick suggested by the `templight++` documentation ```bash export CC="/path/to/llvm/build/bin/templight -Xtemplight -profiler\ -Xtemplight -memory" export CXX="/path/to/llvm/build/bin/templight++ -Xtemplight -profiler\ -Xtemplight -memory" ``` works well in SpECTRE. Build profiling with `templight++` are incredibly slow, and seem to produce increasingly misleading data for larger builds, so it is recommended to avoid using the tool for our most expensive evolution executables. Experience indicates that you will likely wait for hours and be disappointed by deeply flawed results. After building a target, you will find along side each `.o` file in the `build/src` tree an additional file that ends with `.trace.pbf`. These are the `templight++` trace files, and (like many performance tool outputs), require post-processing to recover human-readable data. The companion package [templight-tools](https://github.com/mikael-s-persson/templight-tools) can be built to obtain the `templight-convert` utility that converts the templight traces to more managable formats. It is recommended to install and use [KCacheGrind](https://kcachegrind.github.io/html/Home.html) (which does, unfortunately require some KDE libraries, but doesn't require you to use the full KDE window system) to visualize the output -- the larger graphs produced by templight are inefficient to render in the graphviz format. ## Clang profiling With `clang >= 9`, you can generate a flame graph of what the compiler is spending its time on, including specific function instantiations, class instantiations, source file parsing, debug info generation, and function optimization. To do so, add `-ftime-trace` to the `cmake` option `-D CMAKE_CXX_FLAGS` in your `cmake` command for your build. Then, you can simply `make TargetName`. This will produce a `.json` for each `.cpp.o` that was compiled in the directory that the object file is stored. Note that these object and `.json` files are deep within the build directory. You can then load your `.json` of interest into `chrome://tracing`. Because our code base utilizes many templates and some compilation targets instantiate many types, classes, and functions, note that the flame graph for a particular compilation target may be a lot to visually navigate, click through, and analyze at a high level. Because of this, the tool described below can be very useful and more manageable for some analyses. The companion tool to the flame graph generation is the [ClangBuildAnalyzer](https://github.com/aras-p/ClangBuildAnalyzer). This is an open source tool that you can clone and run to give you profiling output similar to when you profile runtime code in that it identifies compilation hot spots for you. It will report things like "Here are the templates/functions that took the longest to instantiate/compile." Note that because many of our types can have very long names due to our templating, some class and function signatures will not fit in the default character limit of what is printed to the terminal. You can adjust the maximum character length printed by creating a `ClangBuildAnalyzer.ini` file in your working directory as described in the [ClangBuildAnalyzer](https://github.com/aras-p/ClangBuildAnalyzer) `readme.md`. ## Clang AST syntax generation There is a nice and poorly documented feature of the `clang++` compiler that it can produce a rough approximation of the collection of C++ template instantiations produced by a particular executable. Adding `-Xclang -ast-print -fsyntax-only` to the `CXX_FLAGS` will cause this information to be printed to stdout, which should probably be redirected to file because it will be an enormous output. Importantly, to the best of our knowledge, this tool has not yet been used to successfully profile any SpECTRE build, but with sufficient post-processing the C++-syntax version of the AST might be useful to determine the number and nature of instantiations produced by a particular piece of code, and might offer some proxy for build performance. For instance, if we put the above `Fibonacci` struct in a source file with: ```cpp int main(int argc, char** argv) { std::cout << Fibonacci<6>::value << "\n"; } ``` and we compile it with ``` clang++-10 -Xclang -ast-print -fsyntax-only -o fib ./fib.cpp >> fib_out ``` we obtain in `fib_out` (after thousands of lines of STL-generated code): ```cpp template struct Fibonacci { static constexpr size_t value = Fibonacci::value + Fibonacci::value; }; template <> struct Fibonacci<6> { static constexpr size_t value = Fibonacci<6UL - 1>::value + Fibonacci<6UL - 2>::value; }; template <> struct Fibonacci<5> { static constexpr size_t value = Fibonacci<5UL - 1>::value + Fibonacci<5UL - 2>::value; }; template <> struct Fibonacci<4> { static constexpr size_t value = Fibonacci<4UL - 1>::value + Fibonacci<4UL - 2>::value; }; template <> struct Fibonacci<3> { static constexpr size_t value = Fibonacci<3UL - 1>::value + Fibonacci<3UL - 2>::value; }; template <> struct Fibonacci<2> { static constexpr size_t value = Fibonacci<2UL - 1>::value + Fibonacci<2UL - 2>::value; }; template <> struct Fibonacci<1> { static constexpr size_t value = 1; }; template <> struct Fibonacci<0> { static constexpr size_t value = 1; }; int main(int argc, char **argv) { std::cout << Fibonacci<6>::value << "\n"; } ``` Which is actually pretty illuminating about what the compiler decided to do in this simple case. Unfortunately, the AST produced by `clang++` in more complicated cases produces extremely large outputs, so realistic cases are likely too large to be usefully human-readable. It may be possible, though, to script post-processing tools to sift through the collections of template instantiations for particular classes to understand specific cases of template logic. ================================================ FILE: docs/DevGuide/CodeReviewGuide.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Code Review Guide {#code_review_guide} \tableofcontents Code must follow the C++ Core Guidelines and the [Google style guide](https://google.github.io/styleguide/cppguide.html). If the Google style guide disagrees with the Core Guidelines, follow the Core Guidelines. Python code must also follow the [Google style guide](https://google.github.io/styleguide/pyguide.html). Here we summarize what we view as the more important portions of the guides. Stylistic Items: * Adhere to [Google style](https://google.github.io/styleguide/cppguide.html). [Can use `clang-format -style=google`][clang_format]. * CamelCase: class names template parameters, file names, and directory names. * snake_case: function, variable, metafunction and metavariable names. * SCREAMING_SNAKE_CASE: macros. * Functions or classes only used internally in a library should be in a namespace named `LibraryOrFile_detail`. For example, `databox_detail`, `Tensor_detail` or `ConstantExpressions_detail`. * Name unused function parameters `/*parameter_name*/` or `/*meta*/` for TMP cases * Type aliases that wrap type traits have a trailing `_t` following the STL * Private member variables have a [trailing underscore][variable_names]. * Do not use [Hungarian notation](https://en.wikipedia.org/wiki/Hungarian_notation), e.g. `double* pd_blah` is bad * Header order: 1. (If a test:) `Framework/TestingFramework.hpp`, followed by one blank line 2. (If a cpp file with a corresponding hpp file:) hpp corresponding to cpp, followed by one blank line 3. STL and externals (in alphabetical order) 4. Blank line 5. SpECTRE includes (in alphabetical order) * Template definitions in header files are separated from the declaration of the class by the following line, which contains exactly 64 equal signs ``` cpp // ================================================================ ``` * File lists in CMake are alphabetical. * No blank lines surrounding Doxygen group comments (// \@{ and // \@}). * Use the [alternative tokens][alternative_tokens] `or`, `and`, and `not` instead of `||`, `&&`, and `!`. * Use C-style Doxygen comments (`/*! ... */`) when using multi-line math, otherwise C-style and C++ style comments are accepted. * Use the `align` environment instead of `eqnarray`. See the [texfaq](https://texfaq.org/FAQ-eqnarray) for an explanation as to why. * Multi-line equations must have a blank Doxygen line before and after the equation. * When addressing requests on a PR, the commit message must start with `fixup` followed by a descriptive message. * All python code must comply with the [black](https://github.com/psf/black) formatting specified by the `pyproject.toml` file. * Imports in Python code must be sorted to comply to the [isort](https://github.com/PyCQA/isort) formatting specified in the `pyproject.toml` file. Code Quality Items: * All code passes Clang and CppCheck static analyzers. For help with these tools see \ref static_analysis_tools "here". * Almost always `auto`, except with expression templates, i.e. `DataVector` * All loops and if statements use braces. * Order of declaration in classes is `public` before `private` and member functions before data. See [Google](https://google.github.io/styleguide/cppguide.html#Declaration_Order). * Prefer return by value over pass-by-mutable-reference except when mutable reference provides superior performance (in practice if you need a mutable reference use `const gsl::not_null` instead of `Type&`). The mutable references must be the first arguments passed to the function. * All commits for performance changes provide quantitative evidence and the tests used to obtain said evidence. * Never include ``, use `Parallel::printf` inside `Parallel/Printf/Printf.hpp` instead, which is safe to use in parallel. * When using charm++ nodelocks include `` instead of ``. * Do not add anything to [the `std` namespace][extending_std]. * Virtual functions are explicitly overridden using the `override` keyword. * `#%pragma once` is to be used for header guards * Prefer range-based for loops * Use `size_t` for positive integers rather than `int`, specifically when looping over containers. This is in compliance with what the STL uses. * Error messages should be helpful. An example of a bad error message is "Size mismatch". Instead this message could read "The number of grid points in the matrix 'F' is not the same as the number of grid points in the determinant.", along with the runtime values of the mentioned quantities if applicable. * Mark immutable objects as `const` * Make classes serializable by writing a `pup` function * If a class stores an object passed into a constructor the object should be taken by-value and `std::move`d into the member variable. * Definitions of function and class templates should be in `.cpp` files with explicit instantiations whenever possible. The macro `GENERATE_EXPLICIT_INSTANTIATIONS` is useful for generating many explicit instantiations. * Functions should not be marked `noexcept` unless it is part of the signature of an overriden function (e.g. the what() function of an exception derived from std::exception). * Variable names in macros must avoid name collisions, e.g. inside the `PARSE_ERROR` macro you would write `double variable_name_avoid_name_collisions_PARSE_ERROR = 0.0;` * Avoid macros if possible. Prefer `constexpr` functions, constexpr variables, and/or template metaprogramming * Explicitly specify `double`s, e.g. `sqrt(2.)` or `sqrt(2.0)` instead of `sqrt(2)`. * When the index of a `Tensor` is known at compile time, use `get(tensor)` instead of the member `get` function. * All necessary header files must be included. In header files, prefer forward declarations if class definitions aren't necessary. * Explicitly make numbers floating point, e.g. `2.` or `2.0` over `2`. * Avoid `mutable` member variables. If you think you really need these, discuss with at least 2 core developers. In a parallel environment `mutable` variables lead to race conditions since multiple threads can mutate a single object by calling a `const` member function. [alternative_tokens]: http://en.cppreference.com/w/cpp/language/operator_alternative [clang_format]: http://clang.llvm.org/docs/ClangFormat.html [extending_std]: http://en.cppreference.com/w/cpp/language/extending_std [variable_names]: https://google.github.io/styleguide/cppguide.html#Variable_Names ================================================ FILE: docs/DevGuide/CompilerLinkerErrors.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Understanding Compiler and Linker Errors {#compiler_and_linker_errors} \tableofcontents # Linker Errors {#understanding_linker_errors} There are a few common mistakes that can lead to linker problems, specifically problems where there is an `undefined reference`. These include: - forgetting to add a `.cpp` file to the list of sources of a library in a `CMakeLists.txt` file - missing an explicit instantiation of a function or class template in a `cpp` file - not including a `tpp` file inside a `cpp` file - the template specialization or function overload has been explicitly disabled via SFINAE (usually through the use of a `requires` clause) - not linking a library (explained below) Possibly the most difficult part of fixing linking errors is understanding what they are trying to tell you. Let's take the following example ``` error: undefined reference to 'Tensor >, brigand::list > > random_unit_normal(gsl::not_null*>, Tensor, brigand::integral_constant >, brigand::list, Tensor_detail::TensorIndexType<3ul, (UpLo)1, Frame::Inertial, (IndexType)0> > > const&)' in lib/libTest_GeneralizedHarmonic.a(Test_UpwindFlux.cpp.o): Test_UpwindFlux.cpp:function (anonymous namespace)::test_upwind_flux_random() ``` We can start by splitting out information about different parts of the error. First, ``` error: undefined reference to ``` tells us that we forgot to add a link dependency for a library or executable. The next relevant part of information is which library (executable) and file the missing function/class was in. This is at the end of the error message (unfortunately, where in the error message can depend on your linker, these examples used `ld.lld` v9): ``` lib/libTest_GeneralizedHarmonic.a(Test_UpwindFlux.cpp.o): Test_UpwindFlux.cpp:function (anonymous namespace)::test_upwind_flux_random() ``` What this means is that the missing link dependency is used in the library `Test_GeneralizedHarmonic`, the file `Test_UpwindFlux.cpp`, and the function `test_upwind_flux_random()`. We have now determined what the linker error is (a missing link dependency), and in which library, file, and function the missing link dependency is used. We now need to understand what the missing link dependency is. Since SpECTRE uses a lot of templates, the missing reference (link dependency) can be quite long. In this case it is: ``` Tensor >, brigand::list > > random_unit_normal(gsl::not_null*>, Tensor, brigand::integral_constant >, brigand::list, Tensor_detail::TensorIndexType<3ul, (UpLo)1, Frame::Inertial, (IndexType)0> > > const&) ``` In order to make this easier to read, it is recommended to run the code through ClangFormat. This can be done by copying the linker output into an empty `cpp` file and running `clang-format -i EMPTY_FILE_WITH_LINKER_OUTPUT`. Keep in mind that ClangFormat will only work if you have only copied the part of the linker output that resembles valid C++. Doing so in this case gives: \code{.cpp} Tensor >, brigand::list > > random_unit_normal( gsl::not_null*>, Tensor, brigand::integral_constant >, brigand::list< Tensor_detail::TensorIndexType<3ul, (UpLo)1, Frame::Inertial, (IndexType)0>, Tensor_detail::TensorIndexType<3ul, (UpLo)1, Frame::Inertial, (IndexType)0> > > const&); \endcode We see that it is the function `random_unit_normal` that isn't found. Now we can search in the code base where than function is defined. Doing a `git grep "random_unit_normal"` points to `tests/Unit/Helpers/DataStructures/RandomUnitNormal.?pp`. Looking at `tests/Unit/Helpers/DataStructures/RandomUnitNormal.hpp` we see that the function `random_unit_normal` is declared there, and looking in the corresponding `cpp` we see `random_unit_normal` is instantiated in the source file. Opening up `tests/Unit/Helpers/DataStructures/CMakeLists.txt` we see that the library name is `DataStructuresHelpers`, and `RandomUnitNormal.cpp` is in the list of sources for the library. Thus, linking `Test_GeneralizedHarmonic` against `DataStructuresHelpers` will resolve our error. To link against a library, you must add it to the `target_link_libraries`. If `random_unit_normal` had been defined in the header file, then the error would've indicated that we did not include the header (or `tpp`) file into `Test_UpwindFlux.cpp`, and so the compiler could not generate an instantiation. In summary: - Identify target with undefined reference, i.e. the file included in a library or executable. - Identify missing source definition (usually a function or static variable). - Find source declaration and definition in repository. - If source definition is in a `cpp` file, make sure it is in the list of sources in the `CMakeLists.txt` in the same directory and that the corresponding library is linked against by the target. If the undefined reference is a template, make sure the required instantiation exists. - If the undefined reference's definition is in a `tpp` file, make sure the `tpp` file is included in the target file. - If the undefined reference's source definition is in an `hpp` file, make sure the specific instantiation is possible (e.g. not forbidden by a `requires` clause) ================================================ FILE: docs/DevGuide/Connectivity.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Visualisation Connectivity {#visualisation_connectivity} \tableofcontents This guide is split into two parts. The first part details what is meant by 'connectivity' and how it is used to visualise SpECTRE simulations in standard visualisation software such as Paraview. The second part details the methodology associated with ExtendConnectivity - a post-processing executable that removes gaps in the default visualisations produced by SpECTRE. # What is Connectivity? SpECTRE simulations are built on a computational grid composed of individual gridpoints. The 'connectivity' is a list added in the output simulation files that instructs visualisation software, namely Paraview, on how to connect these gridpoints to create lines/surfaces/volumes (depending on the dimension of the simulation) as needed. Given these instructions, Paraview interpolates the data over the regions between gridpoints to create line/surface/volume meshes. In general, the connectivity list contains gridpoints in a particular sequence that corresponds to a line/surface/volume mesh in Paraview. These gridpoints are labelled with integers that are based on the order in which they appear in the h5 files output by the simulation. As one might expect, this list is structured differently depending on the dimension of the simulation. The key underlying difference is the size of the smallest connected region. In 1D, our domain is composed of lines so the smallest connected region is a line made up by two points. In 2D, the smallest connected region used by SpECTRE is typically a quadrilateral made up by four points. In 3D, the smallest connected region used by SpECTRE is typically a hexahedron made up by eight points. A visual representation is illusutrated below. (Note: The numbering of points has been chosen arbitrarily. In reality, this numbering is determined based on the order of gridpoints in the h5 file(s)). \image html ConnectivityStructure.png "Basic connectivity in 1D, 2D, and 3D" The figure above shows how connectivity is defined for a region in each dimension. Fig (a) shows the gridpoint structure for these regions and Fig (c) shows how the resulting mesh appears. Fig (b) shows how a connectivity list should be sequenced to create the desired mesh. Then, in 1D, our connectivity list to create the line in (c) would be [1,2]. Similarly, in 2D, our connectivity list would be [1,2,4,3] and in 3D, our list would be [1,2,4,3,5,6,8,7]. (Note that this sequencing is dictated by Paraview's conventions, not SpECTRE's.) The above example illustrates how to connect the smallest connected region in each dimension. The complete connectivity list, detailing how the entire domain mesh is to be created, is made by concatenating individual connectivity lists. Thus, in 1D, Paraview interprets the list [1,2,2,3] in blocks of 2, with the first block [1,2] representing a line between gridpoints 1 and 2, and the second block [2,3] representing a line between gridpoints 2 and 3. This works similarly in the other dimensions. # How does ExtendConnectivity work? ExtendConnectivity is a post-processing algorithm that looks to add more connectivity entries to fill up any gaps in visualisation. These gaps have multiple sources, the largest of which is the fact that SpECTRE does not add connectivity between elements (as defined in \ref domain_concepts "Domain Concepts") by default. This is important in certain simulations where the endpoints of the elements do not overlap (e.g simulations using Gauss quadrature), resulting in gaps between elements in visualisations. ExtendConnectivity looks to fix this problem specifically. **Note:** The remainder of this guide assumes we are working with simulations whose elements don't overlap. ## Neighbours The key idea in understanding how ExtendConnectivity works is understanding how neighbouring elements are categorised and dealt with. The next sections explain the categories of 'face neighbour', 'edge neighbour', and 'corner neighbour' in detail for 1D, 2D, and 3D. ### 3D We shall start in 3D because the categories are most intuitively defined in 3D. The image below shows a typical example of SpECTRE connectivity for a 3D volume element (with h-refinement 1 and p-refinement 2 in each direction), coloured by their neighbour categorisation. \image html DefaultConnectivity3D.png "3D domain with default connectivity" In the above image, the grey cube is our reference element that neighbour elements are defined around. Then, we define any element that, if elements overlapped, would share a face with our reference element to be a 'face neighbour'. By this definition, we can see that our blue cubes in the above image are our face neighbours. The definitions of the other categories are analogous. We define any element that, if elements overlapped, would share an edge to be an 'edge neighbour' and any element that would share a corner to be a 'corner neighbour'. Hence, our red cubes are our edge neighbours and our green cube is our corner neighbour. In general, for a 3D simulation, face neighbours share a 2D region, edge neighbours share a 1D region, and corner neighbours share a 0D region. These categories apply to the element as a whole. Then, after the element is categorised, the gridpoints must be filtered to the particular face, edge, or corner that will be connected with our reference element. Note that edge and corner neighbours require gridpoints from multiple neighbours (e.g. edge neighbours involve connecting four edges - one from the reference element, two from face neighbours, and one from the edge neighbour). Once the correct gridpoints are identified, they are connected as described in the previous section. The neighbour direction in particular determines the ordering of the gridpoints in this sequence. The image below shows the same domain after the missing connectivity has been added, coloured by the type of connectivity added. \image html ExtendedConnectivity3D.png "3D domain with extended connectivity" In this image, the brown cubes are the face neighbour connections, the orange cubes are the edge neighbour connections, and the yellow cube is the corner neighbour connection. The entire process is then repeated for the next element. This example required only one connectivity entry to be added per neighbour since each element was made up of just one cube. At larger p-refinements, an element consists of more cubes and consequently, more connectivity entries are required. For example, if the domain above had a p-refinement of 3 in each dimension instead, face connections would require adding four cubes and edge connections would require two cubes. ### 2D We can now generalise these definitions to other dimensions. The image below shows a typical example of SpECTRE connectivity for a 2D volume element (with h-refinement 1 and p-refinement 2 in each direction), coloured by their neighbour categorisation in the same colours as above. \image html ExtendedConnectivity2D.png "2D domain with extended connectivity" Once again, the grey square is our reference element. We now define our neighbour types to be analogous to the types in 3D but reduced by one dimension. Then, in a 2D simulation, face neighbours share a 1D regions, edge neighbours share a 0D region, and corner neighbours do not exist. In the image above, our face neighbours are once again blue and our edge neighbours are once again red. Once the elements are categorised, the relevant gridpoints are once again filtered and connected according to the 2D structure explained above. In the image, the face connections are coloured brown and the edge connections are coloured orange again. The next element is then made the reference element and the process is repeated to build up the connectivity for the entire domain. ### 1D We display the concepts in 1D for completeness. The image below shows an example of SpECTRE connectivity for a 1D volume element (with h-refinement 1 and p-refinement 2), coloured by their neighbour categorisation in the same colours as above. \image html ExtendedConnectivity1D.png "1D domain with extended connectivity" In this image, the grey line is our reference element. In a 1D simulation, we correspondingly define face neighbours to share a 0D region and both edge and corner neighbours do not exist. Then, in the image above, our face neighbour is once again the blue element and the face connection is coloured brown again. ### Summary * Face Neighbour:
A neighbouring element that shares an overlap region one dimension lower than the dimension of the simulation. * Edge Neighbour:
A neighbouring element that shares an overlap region two dimensions lower than the dimension of the simulation. * Corner Neighbour:
A neighbouring element that shares an overlap region three dimensions lower than the dimension of the simulation. ## Connecting elements with different p-refinements To be added. ================================================ FILE: docs/DevGuide/CreatingExecutables.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Creating Executables {#dev_guide_creating_executables} \tableofcontents There are several different types of executables that can be built: - An executable that uses Charm++ to run in parallel, e.g. `Executables/ParallelInfo` - An executable that does not use Charm++, does not run in parallel, and supplies its own `main`, e.g. `Executables/Examples/HelloWorldNoCharm` - An executable that uses Charm++ to run in parallel but supplies its own `main` - An executable that uses custom compilation or linking flags, e.g. `DebugPreprocessor` - Executables used for evolutions or elliptic solves ### Executable Using Charm++ for Parallelization \ref tutorial_minimal_parallel_executable tutorial describes how to add a new parallel executable. Another simple example of an executable using Charm++ for parallelization is in `src/Executables/Examples/HelloWorld`. In this example, the only additional phase (besides `Initialization` and `Exit`) is `Execute`, and the phases are executed in order. `SingletonHelloWorld` defines a single component `HelloWorld` \snippet SingletonHelloWorld.cpp executable_example_singleton which specifies via the `chare_type` type alias that it is a singleton parallel component which means that only one such object will exist across all processors used by the executable. Each component must define the static function `execute_next_phase` which is executed during the phases (other than `Initialization` and `Exit`) defined in the metavariables struct. In `SingletonHelloWorld`, the `PrintMessage` action is called during the `Execute` phase. \snippet SingletonHelloWorld.cpp executable_example_action The `PrintMessage` action is executed on whatever process the singleton component is created upon, and prints a message. Executables can read in an input file (specified by the `--input-file` argument) that will be parsed when the executable begins. %Options specified in the input file can be used to either place items in the Parallel::GlobalCache (by specifying tags in the `const_global_cache_tags` type alias of the metavariables, component and action structs), to construct items in the db::DataBox of components during initialization (by specifying tags in the `simple_tags_from_options` type alias of action struct), or be passed to the `allocate_array` function of an array component (by specifying tags in the `array_allocation_tags` type alias of the component). `SingletonHelloWorld` specifies a single option \snippet SingletonHelloWorld.cpp executable_example_options which a string specifying a name that will be placed into the constant global cache. The string is fetched when performing the `PrintMessage` action. Items in the constant global cache are stored once per node that the executable runs on. An example input file for `SingletonHelloWorld` can be found in `tests/InputFiles/ExampleExecutables/SingletonHelloWorld.yaml` and shows how to specify the options (lines beginning with a `#` are comments and can be ignored). Furthermore among the included header files \snippet SingletonHelloWorld.cpp executable_example_includes must be the appropriate header for each parallel component type, which in the `SingletonHelloWorld` example is `AlgorithmSingleton.hpp`. Note that these headers are not in the source tree, but are generated automatically when the code is compiled. See [the Parallelization documentation](group__ParallelGroup.html#details) for more details. ### Executable Using Charm++ with Custom main() While this is technically possible, it has not been tested. We recommend using the Charm++ supplied main chare mechanism for the time being. ### Executable Not Using Charm++ An example of an executable that does not use Charm++ for parallelization but still can use all other infrastructure in SpECTRE is in `src/Executables/Examples/HelloWorldNoCharm`. Adding a non-Charm++ executable to SpECTRE mostly follows the standard way of adding an executable using CMake. The only deviation is that the `CMakeLists.txt` file must tell Charm++ not to add a `main()` by passing the link flags `-nomain-module -nomain`. This is done using CMake's `set_target_properties`: ``` set_target_properties( ${EXECUTABLE} PROPERTIES LINK_FLAGS "-nomain-module -nomain" ) ``` To add the executable as a target you must use the `add_spectre_executable` function, which is a light weight wrapper around CMake's `add_executable`. For example, ``` add_spectre_executable( ${EXECUTABLE} EXCLUDE_FROM_ALL # Exclude from calls to `make` without a specified target HelloWorld.cpp ) ``` You can link in any of the SpECTRE libraries by adding them to the `target_link_libraries`, for example: ``` target_link_libraries( ${EXECUTABLE} DataStructures ) ``` We recommend that you add a test that the executable properly runs by adding an input file to `tests/InputFiles` in an appropriate subdirectory. See [`tests/InputFiles/ExampleExecutables/HelloWorldNoCharm.yaml`] (https://github.com/sxs-collaboration/spectre/tree/develop/tests/InputFiles/ ExampleExecutables/HelloWorldNoCharm.yaml) for an example. The input file is passed to the executable using `--input-file path/to/Input.yaml`. In the case of the executable not taking any input file this is just used to generate a test that runs the executable. For these types of executables `main` can take the usual `(int argc, char *argv[])` and parse command line options. Executables not using Charm++ are just standard executables that can link in any of the libraries in SpECTRE. \warning Currently calling `Parallel::abort` results in a segfault deep inside Charm++ code. However, the error messages from `ASSERT` and `ERROR` are still printed. ### Executable With Custom Compilation or Linking Flags Use the CMake function `set_target_properties` to add flags to an executable. To call a completely custom compiler invocation you should use the `add_custom_target` CMake function. The need for the `custom_target` level of control is rare and should generally be avoided since it adds quite a bit of technical debt to the code base. Thus, it is not explained here. If you are certain you need it you can see the `DebugPreprocessor` executable's `CMakeLists.txt` file for an example. ### Executable Used for Evolution or Elliptic Solve Once they are written, see the tutorials specific to evolution and elliptic solves. ================================================ FILE: docs/DevGuide/Databox.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Motivation for SpECTRE's DataBox {#databox_foundations} \tableofcontents # Introduction {#databox_introduction} This page walks the user through the iterative process that led to SpECTRE's DataBox. At each stage, it discusses the advances and challenges that result from each improvement. # Towards SpECTRE's DataBox {#databox_towards_spectres_databox} ## Working without DataBoxes {#databox_working_without_databoxes} In a small C++ program, it is common to use the built-in fundamental types (bool, int, double, etc.) in computations, and to give variable names to objects of these types. For example, a section of a small program may look like this: \snippet Test_DataBoxDocumentation.cpp working_without_databoxes_small_program_1 What changes as our program's size increases in scale? In SpECTRE, one of our driving design goals is modularity. In other words, functionality should be easy to swap in and out as desired. These smaller modules are easier to test, and keep the code flexible. We could wrap our calculation in such a module, which would then allow us to decouple the initial setup of the variables from where they are used in calculations: \snippet Test_DataBoxDocumentation.cpp working_without_databoxes_mass_compute \snippet Test_DataBoxDocumentation.cpp working_without_databoxes_accel_compute Our small program can now be written as: \snippet Test_DataBoxDocumentation.cpp working_without_databoxes_small_program_2 One advantage is immediate: we are free to add other computation modules that are independently testable and reusable. As the number of routines grows, we can even begin to write routines that work on top of existing ones. \snippet Test_DataBoxDocumentation.cpp working_without_databoxes_force_compute While we have made progress, two problems arise. Our first problem is that as the number of quantities grows, it becomes more unwieldy to have to specify each function argument in our routine. The second problem is worse: the arguments passed to functions can be transposed and the program will still compile and run, but produce incorrect output. For example, the following two lines are equally well-formed from the point of view of the program: \snippet Test_DataBoxDocumentation.cpp working_without_databoxes_failed_accel Every time we call `acceleration_compute` we need to make sure we pass in the arguments in the correct order. In large programs where `acceleration_compute` is called many times, it becomes inevitable that the arguments will be accidentally transposed. We can address the two problems described above with a `std::map`, the first container we'll consider in this series. ##A std::map DataBox {#databox_a_std_map_databox} We can encapsulate the variables we use in a `std::map`, and the first half of our small program example now looks like this: \snippet Test_DataBoxDocumentation.cpp std_map_databox_small_program_1 We have not yet taken full advantage of the encapsulation that `std::map` provides. We do so by rewriting our other routines to take only a single argument, i.e. the `std::map` itself: \snippet Test_DataBoxDocumentation.cpp std_map_databox_mass_compute \snippet Test_DataBoxDocumentation.cpp std_map_databox_accel_compute Notice that this solves the problem of having to provide the arguments in the correct order to every function call of `acceleration_compute`: \snippet Test_DataBoxDocumentation.cpp std_map_databox_force_compute Our small program now looks like: \snippet Test_DataBoxDocumentation.cpp std_map_databox_small_program_2 Within each function, we no longer need to worry about passing in the arguments in the correct order. This is a great improvement, but our reliance on proper names does leave us open to the following mistake: ~~~{.c} // returns 0 without emitting an error! return naive_databox["MisspelledKey"]; ~~~ In the above example, the map is asked to return a value given a key that does not exist! As written, however, the program is well-formed and no error is emitted. (In the case of std::map, [a value is created.] (https://en.cppreference.com/w/cpp/container/map/operator_at)) Because the keys are indistinguishable from their type alone, the mistake cannot be caught at compile time. In our example, the mistake won't even be caught at run time. The run time portion of a SpECTRE calculation will typically be much longer (up to thousands of times longer!) than the compile time portion, so it is critical to catch costly mistakes like this as early into the calculation as possible. Although names encoded as `std::string` cannot be distinguished by the compiler, names encoded as types *can* be. This is possible with C++'s static typing, and to take advantage of this we need a container that is *heterogeneous*, that is, capable of holding objects of different types. ## A std::tuple DataBox {#databox_a_std_tuple_databox} A well-documented example of a fixed-size heterogeneous container of types is [std::tuple](https://en.cppreference.com/w/cpp/utility/tuple): \snippet Test_DataBoxDocumentation.cpp std_tuple_databox_1 The contents of the `std_tuple` are obtained using [std::get](https://en.cppreference.com/w/cpp/utility/tuple/get): \snippet Test_DataBoxDocumentation.cpp std_tuple_databox_2 In the above, we can see that we have promoted our keys from different values all of type `std::string` to different types entirely. We are not limited to fundamental types, we are free to make our own structs that serve as keys. These user-created types are called *tags*. As the sole purpose of the tag is to provide the compiler with a type distinguishable from other types, they can be as simple as the following: \snippet Test_DataBoxDocumentation.cpp std_tuple_tags Note that we have now promoted `Velocity`, `Radius`, etc. from being *values* associated with `std::string`s at run time, to *types* distinguishable from other types at compile time. A large portion of SpECTRE is designed with the philosophy of enlisting the help of the compiler in assuring the correctness of our programs. An example of a `std::tuple` making use of these tags might look like: ~~~{.c} // Note: This won't work! std::tuple sophomore_databox = std::make_tuple(4.0, 2.0, 0.5, 10.0); ~~~ Unfortunately, this will not work. The types passed as template parameters to `std::tuple` must also be the types of the arguments passed to `std::make_tuple`. Using a `std::pair`, we could write the above as: \snippet Test_DataBoxDocumentation.cpp std_tuple_small_program_1 What remains is to rewrite our functions to use `std::tuple` instead of `std::map`. Note that since we are now using a heterogeneous container of potentially unknown type, our functions must be templated on the pairs used to create the `sophomore_databox`. Our functions then look like: \snippet Test_DataBoxDocumentation.cpp std_tuple_mass_compute \snippet Test_DataBoxDocumentation.cpp std_tuple_acceleration_compute \snippet Test_DataBoxDocumentation.cpp std_tuple_force_compute Using all these `std::pair`s to get our `std::tuple` to work is a bit cumbersome. There is another way to package together the tagging ability of the struct names with the type information of the values we wish to store. To do this we need to make modifications to both our tags as well as our %Databox implementation. This is what is done in SpECTRE's `tuples::TaggedTuple`, which is an improved implementation of `std::tuple` in terms of both performance and interface. ##A TaggedTuple DataBox {#databox_a_taggedtuple_databox} TaggedTuple is an implementation of a compile time container where the keys are tags. Tags that are compatible with SpECTRE's `tuples::TaggedTuple` must have the type alias `type` in their structs. This type alias carries the type information of the data we wish to store in the databox. `tuples::TaggedTuple` is able to make use of this type information so we won't need auxiliary constructs such as `std::pair` to package this information together anymore. Our new tags now look like: \snippet Test_DataBoxDocumentation.cpp tagged_tuple_tags We are now able to create the `junior_databox` below in the same way we initially wished to create the `sophomore_databox` above: \snippet Test_DataBoxDocumentation.cpp tagged_tuple_databox_1 Our functions similarly simplify: \snippet Test_DataBoxDocumentation.cpp tagged_tuple_mass_compute \snippet Test_DataBoxDocumentation.cpp tagged_tuple_acceleration_compute \snippet Test_DataBoxDocumentation.cpp tagged_tuple_force_compute In each of these iterations of the Databox, we started with initial quantities and computed subsequent quantities. Let us consider again `force_compute`, in which `mass` and `acceleration` are recomputed for every call to `force_compute`. If `Mass` and `Acceleration` were tags somewhow, that is, if we could compute them once, place them in the databox, and get them back out through the use of tags, we could get around this problem. We are now ready to consider SpECTRE's DataBox, which provides the solution to this problem in the form of `ComputeTags`. # SpECTRE's DataBox {#databox_a_proper_databox} A brief description of SpECTRE's DataBox: a TaggedTuple with compute-on-demand. For a detailed description of SpECTRE's DataBox, see the \ref DataBoxGroup "DataBox documentation". ## SimpleTags {#databox_documentation_for_simple_tags} Just as we needed to modify our tags to make them compatible with `TaggedTuple`, we need to again modify them for use with DataBox. Our ordinary tags become SpECTRE's SimpleTags: \snippet Test_DataBoxDocumentation.cpp proper_databox_tags As seen above, SimpleTags have a `type` and a `name` in their struct. When creating tags for use with a DataBox, we must make sure to the tag inherits from one of the existing DataBox tag types such as `db::SimpleTag`. We now create our first DataBox using these `SimpleTags`: \snippet Test_DataBoxDocumentation.cpp refined_databox We can get our quantities out of the DataBox by using `db::get`: \snippet Test_DataBoxDocumentation.cpp refined_databox_get So far, the usage of DataBox has been similar to the usage of TaggedTuple. To address the desire to combine the functionality of tags with the modularity of functions, DataBox provides ComputeTags. ## ComputeTags {#databox_documentation_for_compute_tags} ComputeTags are used to tag functions that are used in conjunction with a DataBox to produce a new quantity. ComputeTags look like: \snippet Test_DataBoxDocumentation.cpp compute_tags ComputeTags inherit from `db::ComputeTag`, and it is convenient to have them additionally inherit from an existing SimpleTag (in this case `Mass`) so that the quantity `MassCompute` can be obtained through the SimpleTag `Mass`. We use the naming convention `TagNameCompute` so that `TagNameCompute` and `TagName` appear next to each other in documentation that lists tags in alphabetical order. We have also added the type alias `argument_tags`, which is necessary in order to refer to the correct tagged quantities in the DataBox. \note The `tmpl::list` used in the type alias is a contiguous container only holding types. That is, there is no variable runtime data associated with it like there is for `std::tuple`, which is a container associating types with values. `tmpl::list`s are useful in situations when one is working with multiple tags at once. Using nested type aliases to pass around information at compile time is a common pattern in SpECTRE. Let us see how we can compute our beloved quantity of mass times acceleration: \snippet Test_DataBoxDocumentation.cpp compute_tags_force_compute And that's it! `db::get` utilizes the `argument_tags` specified in `ForceCompute` to determine which items to get out of the `refined_databox`. With the corresponding quantities in hand, `db::get` passes them as arguments to the `function` specified in `ForceCompute`. This is why every `ComputeTag` must have an `argument_tags` as well as a `function` specified; this is the contract with DataBox they must satisfy in order to enjoy the full benefits of DataBox's generality. ## Mutating DataBox items {#databox_documentation_for_mutate_tags} It is reasonable to expect that in a complicated calculation, we will encounter time-dependent or iteration-dependent variables. As a result, in addition to adding and retrieving items from our DataBox, we also need a way to *mutate* quantities already present in the DataBox. This can be done via `db::mutate_apply` and can look like the following: \note There is an alternative to `db::mutate_apply`, `db::mutate`. See the \ref DataBoxGroup "DataBox documentation" for more details. \snippet Test_DataBoxDocumentation.cpp mutate_tags \snippet Test_DataBoxDocumentation.cpp time_dep_databox \note The `not_null`s here are used to give us the assurance that the pointers `time` and `falling_speed` are not null pointers. Using raw pointers alone, we risk running into segmentation faults if we dereference null pointers. With `not_null`s we instead run into a run time error that tells us what went wrong. For information on the usage of `not_null`, see the documentation for Gsl.hpp. In the above `db::mutate_apply` example, we are changing two values in the DataBox using four values from the DataBox. The mutated quantities must be passed in as `gsl::not_null`s to the lambda. The non-mutated quantities are passed in as const references to the lambda. \note It is critical to guarantee that there is a strict demarcation between pre-`db::mutate` and post-`db::mutate` quantities. `db::mutate` provides this guarantee via a locking mechanism; within one mutate call, all initial pre-mutated quantities are obtained from the DataBox before performing a single mutation. \note The mutate functions described above are the only accepted ways to edit data in the Databox. It is technically possible to use pointers or references to edit data stored in the Databox, but this bypasses the compute tags architecture. All changes to the Databox must be made by the Databox itself via mutate functions. From the above, we can see that the different kinds of tags are provided in two different `tmpl::list`s. The `MutateTags`, also called `ReturnTags`, refer to the quantities in the DataBox we wish to mutate, and the `ArgumentTags` refer to additional quantities we need from the DataBox to complete our computation. We now return to the recurring question of how to make this construction more modular. We have now worked our way up to SpECTRE's DataBox, but as we can see in the above `db::mutate_apply` example, the lambda used to perform the mutation ends up being independent of any tags or template parameters! This means we can factor it out and place it in its own module, where it can be tested independently of the DataBox. # Toward SpECTRE's Actions {#databox_towards_actions} ## Mutators {#databox_documentation_for_mutators} These constructs that exist independently of the DataBox are the precursors to SpECTRE's *Actions*. As they are designed to be used with `db::mutate` and `db::mutate_apply`, we give them the name *Mutators*. Here is the above lambda written as a Mutator-prototype, a struct-with-void-apply: \snippet Test_DataBoxDocumentation.cpp intended_mutation The call to `db::mutate_apply` has now been made much simpler: \snippet Test_DataBoxDocumentation.cpp time_dep_databox2 There is a key step that we take here after this point, to make our struct-with-void-apply into a proper Mutator. As we will see, this addition will allow us to entirely divorce the internal details of `IntendedMutation` from the mechanism through which we update the DataBox. The key step is to add type aliases to `IntendedMutation`: \snippet Test_DataBoxDocumentation.cpp intended_mutation2 We are now able to write our call to `db::mutate_apply` in the following way: \snippet Test_DataBoxDocumentation.cpp time_dep_databox3 As we saw earlier with `QuantityCompute`, we found that we were able to imbue structs with the ability to "read in" types specified in other structs, through the use of templates and member type aliases. This liberated us from having to hard-code in specific types. We notice immediately that `IntendedMutation` is a hard-coded type that we can factor out in favor of a template parameter: \snippet Test_DataBoxDocumentation.cpp my_first_action Note how the `return_tags` and `argument_tags` are used as metavariables and are resolved by the compiler. Our call to `db::mutate_apply` has been fully wrapped and now takes the form: \snippet Test_DataBoxDocumentation.cpp time_dep_databox4 The details of applying Mutators to the DataBox are entirely handled by `MyFirstAction`, with the details of the specific Mutator itself entirely encapsulated in `IntendedMutation`. SpECTRE algorithms are decomposed into Actions which can depend on more things than we have considered here. Feel free to look at the existing \ref ActionsGroup "actions that have been written." The intricacies of Actions at the level that SpECTRE uses them is the subject of a future addition to the \ref dev_guide "Developer's Guide." ================================================ FILE: docs/DevGuide/DebuggingTips.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Tips for debugging an executable {#runtime_errors} Learn how to use a debugger such as gdb. You can debug MPI executables using the `sys::attach_debugger()` function. See the documentation of that function for details. # Useful gdb commands - To break when an exception is thrown `catch throw` - To break on a specific exception type `catch throw std::out_of_range` (This may not work on all compilers or older versions of gdb. In this case you also try setting a breakpoint on the constructor of the exception type, `break std::out_of_range::out_of_range`) - SpECTRE has pretty printing facilities for various custom types. In order to enable these you must add `add-auto-load-safe-path /path/to/spectre/` to your `~/.gdbinit` file. ================================================ FILE: docs/DevGuide/DevGuide.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Developer Guides {#dev_guide} ### Adaptive Mesh Refinement - \subpage dev_guide_amr "Adaptive Mesh Refinement" ### Charm++ Interface - \subpage load_balancing_notes "Load Balancing Notes and Recommendations" ### Continuous Integration Explanations on our automated tests and deployments can be found here. - \subpage dev_guide_automatic_versioning ### CoordinateMap Guide Methods for creating custom coordinate maps are discussed here. - \subpage redistributing_gridpoints "Methods for redistributing gridpoints" ### Developing and Improving Executables - \subpage dev_guide_creating_executables "Executables and how to add them" - \subpage tutorials_parallel - A series of tutorials demonstrating how to write a parallel executable, and explaining some of the metaprogramming that turns user-provided code into a SpECTRE parallel executable - \subpage dev_guide_option_parsing "Option parsing" to get options from input files - \subpage dev_guide_importing "Importing" data from files - \subpage profiling "Profiling" SpECTRE with a variety of different tools - \subpage spectre_writing_python_bindings "Writing Python Bindings" to use SpECTRE C++ classes and functions from within python. - \subpage implementing_vectors "Implementing SpECTRE vectors" a quick how-to for making new generalizations of DataVectors - \subpage compiler_and_linker_errors "How to parse linker and compiler errors" - \subpage static_analysis_tools "Static analysis tools" - \subpage build_profiling_and_optimization - Getting started with improving compilation time and memory use - \subpage runtime_errors "Tips for debugging an executable" ### Foundational Concepts in SpECTRE Designed to give the reader an introduction to SpECTRE's most recurring concepts and patterns. - \subpage databox_foundations "Towards SpECTRE's DataBox" - \subpage protocols "Protocols: metaprogramming interfaces" - \subpage variables_foundations "Using the Variables class" to improve efficiency ### GPU Support Information on how to use and develop GPU support in SpECTRE. - \subpage gpu_support "GPU support" ### General SpECTRE Terminology Terms with SpECTRE-specific meanings are defined here. - \subpage domain_concepts "Domain Concepts" used throughout the code are defined here for reference. - \subpage visualisation_connectivity "Visualisation Connectivity" is defined and explained here for reference. ### Having your Contributions Merged into SpECTRE - \subpage writing_good_dox "Writing good documentation" is key for long term maintainability of the project. - \subpage writing_unit_tests "Writing Unit Tests" to catch bugs and to make sure future changes don't cause your code to regress. - \subpage github_actions_guide "GitHub Actions" is used to test every pull request. - \subpage code_review_guide "Code review guidelines." All code merged into develop must follow these requirements. ### Performance and Optimization - \subpage general_perf_guide "General performance guidelines" ### Technical Documentation for Fluent Developers Assumes a thorough familiarity and fluency in SpECTRE's usage of TMP. - \subpage DataBoxGroup "DataBox" - \subpage observers_infrastructure_dev_guide "Observers infrastructure" - \subpage dev_guide_parallelization_foundations - Parallelization infrastructure components and usage ### Template Metaprogramming (TMP) Explanations for TMP concepts and patterns known to the greater C++ community can be found here. - \subpage sfinae "SFINAE" - \subpage brigand "The Brigand TMP library" ### Writing Tensor Equations - \subpage writing_tensorexpressions "Writing Tensor Equations with TensorExpressions" ================================================ FILE: docs/DevGuide/DomainConcepts.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Domain Concepts {#domain_concepts} \tableofcontents * Computational Domain:
The region of spacetime on which a numerical simulation is performed. * Inertial Coordinate Frame:
A global coordinate frame covering the computational domain that is also the coordinate frame in which the initial (boundary) value problem that is being solved is specified. Denoted by Frame::Inertial. * Logical Coordinate Frame:
The coordinate frame of a reference cell. In the cell the logical coordinates cover the interval \f$[-1, 1]\f$ in each dimension. Currently the logical coordinates are Cartesian. * CoordinateMap "Coordinate Map":
A mapping between two coordinate frames. Coordinate maps are allowed to be time-dependent, as long as the time coordinate itself is unchanged. * Direction:
A logical coordinate axis and a label "Upper" or "Lower" depending on whether the Direction is aligned with or anti-aligned with the logical coordinate axis, respectively. * Block:
The computational domain is partitioned into a set of non-overlapping, distorted reference cells called Blocks. Each Block must have at most one neighboring Block in each Direction. The reference cell is embedded into a subset of the computational domain using a Coordinate Map from the logical frame of the Block to the global inertial frame. Blocks are identified by unique integral values. * Block Logical Coordinate Frame:
The logical coordinate frame of a Block, denoted by Frame::BlockLogical. The only requirement upon the logical coordinate frames of neighboring Blocks is that they have the same Coordinate Map from their logical coordinate frame to the global inertial frame on their shared boundary up to a mapping that swaps or negates the logical coordinate axes. In other words, at each point on their shared boundary, the logical coordinates of the two blocks are equal after possibly applying a permutation and sign flips. * Grid Coordinate Frame:
For time-dependent coordinate maps, it is useful (e.g. for computational efficiency) to split the Coordinate Map from Frame::BlockLogical to Frame::Inertial into a composition of two maps. This is done by introducing an intermediate coordinate frame (denoted by Frame::Grid) such that the mapping from Frame::BlockLogical to Frame::Grid is time-independent, and the mapping from Frame::Grid to Frame::Inertial is time-dependent. * Orientation:
The information of how the Block Logical Coordinates of neighboring Blocks are related. * \ref BlockNeighbors "Block Neighbors":
The identity and Orientation of neighboring Blocks of a given Block. * Element:
A reference cell that is a refined subregion of a Block defined by its Segments in each dimension. The properties of the Element (e.g coordinate map) are inherited from its Block, i.e. it is self-similar to the Block. * Refinement Level:
The number of times a Block is split in half in a given dimension. * Segment:
In each dimension, the specific subset of the block logical coordinate interval \f$[-1, 1]\f$ defined by the Refinement Level and an integer label such that the Segment's interval is \f$[-1 + 2 \frac{i}{N}, -1 + 2 \frac{i+1}{N}]\f$ where \f$i\f$ is the integer label and \f$N = 2^{(\textrm{Refinement Level})}\f$ is the number of segments on the Refinement Level. * Element Logical Coordinate Frame:
The logical coordinate frame of an Element. In each dimension, the Element Logical Coordinates are related to the Block Logical Coordinates by an affine mapping of the interval \f$[-1, 1]\f$ to the interval covered by the Segment in that dimension. * \ref SegmentId "Segment Identifier":
The Refinement Level and an integer labeling a Segment. * \ref ElementId "Element Identifier":
The Block Identifier containing the Element and a Segment Identifier in each dimension. * External Boundary:
A face of a Block or Element that has no neighbor. * Internal Boundary:
A boundary that is not an External Boundary. * Neighbors:
The identities and Orientation of the neighboring Blocks or Elements of a given Block or Element in a particular Direction . * External Boundary Condition:
A prescription for updating the solution on an External Boundary. Each External Boundary of a Block has exactly one External Boundary Condition associated with it. ================================================ FILE: docs/DevGuide/GitHubActions.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # GitHub Actions Continuous Integration {#github_actions_guide} \tableofcontents # Testing SpECTRE with GitHub Actions CI {#github_actions_ci} SpECTRE uses [GitHub Actions](https://github.com/features/actions) for testing the code. Multiple build jobs (described below) are launched each time a pull request is submitted or updated. GitHub Actions will also launch these build jobs each time you push to a branch on your fork of SpECTRE if you enable it. GitHub Actions is also used to deploy releases of the code. For pull requests, you can view the GitHub Actions CI build by clicking on the `Checks` tab. Near the bottom of the `Conversation` tab a summary of the CI results are presented. You can view all of the GitHub Actions runs by clicking on the `Actions` section. ## What is tested {#what-is-tested} The GitHub Actions report lists the build jobs which will each have either a green check mark if it passes, a red `X` if it has failed, or a yellow dot with a circle if the build is in progress. Clicking on a build job will display the log of the build. The following build jobs are launched: * CHECK_COMMITS runs the script `tools/CheckCommits.sh` and fails the build if any casing of the words in the list below is the first word of the commit message. This allows developers to flag their commits with these keywords to indicate that a pull request should not be merged in its current state. - fixup - wip (for work in progress) - fixme - deleteme - rebaseme - testing - rebase * CHECK_FILES runs the script `tools/CheckFiles.sh` (which also runs the script `tools/FileTestDefs.sh`). The checks fail if any of the following are true: - Any file, * contains a line over 80 characters (We allow exceptions for certain file types and inherently long strings like URLs and include lines. See `tools/FileTestDefs.sh` for the full list of exceptions.) * is missing the license line * does not end with a newline * contains a tab character * contains white space at the end of a line * contains a carriage return character - A `c++` header file (i.e., `*.hpp` or `*.tpp`) is missing `#%pragma once` - A `c++` file (i.e., `*.hpp`, `*.tpp`, or `*.cpp`) file, * includes `` (useless when running in parallel) * includes `` (use `` instead) * includes `"Utilities/TmplDebugging.hpp"` (used only for debugging) * includes any non-header `*.cpp` file * contains a `namespace` ending in `_details` (use `_detail`) * contains a `struct TD` or `class TD` (used only for debugging) * contains `std::enable_if` (use `requires` instead) * contains `Ls` (use `List` instead) * contains additional text after `/*!` (does not render correctly in Doxygen) * contains the string `return Py_None;` (bug prone, use `Py_RETURN_NONE` instead) * contains `.ckLocal()` or `.ckLocalBranch()` (use `Parallel::local` or `Parallel::local_branch` instead) - A `c++` test, * uses `TEST_CASE` (use `SPECTRE_TEST_CASE` instead) * uses `Approx` (use `approx` instead) - A `CMakeLists.txt` file in `src`, but not in an Executables or Python-binding directory, * does not list a `C++` file that is present in the directory * lists a `C++` file that is not present in the directory - A `c++` or `python` file contains a `TODO` (case-insensitive) comment In addition, the CHECK_FILES job tests Python formatting, the release workflow, and other tools in `tools/`. * "Check Python formatting" runs the `black` and `isort` formatters over the source code. * RUN_CLANG_TIDY runs clang-tidy on the source code. This is done for both `Release` and `Debug` builds. * TEST_CHECK_FILES runs `tools/CheckFiles.sh --test` which tests the checks performed in the CHECK_FILES build. * The other builds compile the code and run the tests for both `Release` and `Debug` builds, for the `gcc` and `clang` compilers using a Linux OS, and the `AppleClang` compiler for `OS X`. * Verify the documentation builds successfully. Builds of `develop` deploy the documentation to GitHub pages. ## How to perform the checks locally {#perform-checks-locally} Before pushing to GitHub and waiting for GitHub Actions to perform the checks it is useful to perform at least the following tests locally: - **Unit tests:** Perform a `make unit-tests` and then execute `ctest -L Unit` to run all unit tests. As for `make` you can append a `-jN` flag to `ctest` to run in parallel on `N` cores. To run only a subset of the tests you can use one of the other keywords that the tests are labeled with, such as `ctest -L datastructures`. To run only particular tests you can also execute `ctest -R TEST_NAME` instead, where `TEST_NAME` is a regular expression matching the test identifiers such as `Unit.DataStructures.Mesh`. Pass the flag `--output-on-failure` to get output from failed tests. Consult `ctest -h` for further options. To run the input file tests you must build the executables using `make test-executables`. You can then run `ctest -LE unit` to run everything except for the unit tests, or `ctest` to run all tests. - **clang-tidy:** In a clang build directory, run `make clang-tidy FILE=SOURCE_FILE` where `SOURCE_FILE` is a relative or absolute path to a `.cpp` file. To perform this check for all source files that changed in your pull request, `make clang-tidy-hash HASH=UPSTREAM_HEAD` where `UPSTREAM_HEAD` is the hash of the commit that your pull request is based on, usually the `HEAD` of the `upstream/develop` branch. - **Python formatting:** Run `black --check .` and `isort --check-only .` over the repository. You can install these tools with `pip3 install -r support/Python/dev_requirements.txt` - **Documentation:** To render the documentation for the current state of the source tree the command `make doc` (or `make doc-check` to highlight warnings) can be used, placing its result in the `docs` directory in the build tree. Once code has been made into a pull request to GitHub, the documentation can be rendered locally using the `tools/pr-docs` script. To view the documentation, simply open the `index.html` file in the `html` subdirectory in a browser. Some functionality requires a web server (e.g. citation popovers), so just run a `python3 -m http.server` in the `html` directory to enable this. - The `gcc Debug` build runs code coverage for each GitHub Actions build. ## Troubleshooting {#github-actions-troubleshooting} * Occasionally, a build job will fail because of a problem with GitHub Actions (e.g. it times out). On the `Checks` tab you can restart all or only the failed jobs. In the top right corner there's a `Re-run jobs` menu, which also has `Re-run failed jobs`. This button is `Cancel workflow` during the build process. Note that these buttons are only available if you have write access to the repository (core developer status). * GitHub Actions caches some things between builds. Occasionally this may cause a problem leading to strange build failures. For example, inexplicable segfaults on seemingly random tests or `Illegal instruction` failures. We have to be fairly lax with our caching policies, and so the cache can become stale and outdated when a new container is pushed, among other difficult to understand situations. You can rebuild the ccache by going to `Actions`, then select the `Tests` workflow on the left, click the `Run workflow` drop-down menu, and enter `yes` in the input field below the ccache discussion. If clearing the ccache doesn't help, it could be that a Docker image layer is not being updated. GitHub doesn't (yet) have a way to clear the cache, so instead we clobber it to force GitHub to eject all old caches, both ccache and Docker images, along with anything else. To do this go to `Actions`, select the `Clobber Cache` workflow, then run it on develop. This will dump 9.9GB of random data into the cache. The amount is specified in the `ClobberCache.yaml` workflow file and needs to be updated if GitHub increases their cache size. The current cache size limit is 10GB per repository. Note that starting these workflows is only possible if you have write access to the repository (core developer status). ## Precompiled Headers and ccache {#precompiled-headers-ccache} Getting ccache to work with precompiled headers on GitHub Actions is a little challenging. The header to be precompiled is `${SPECTRE_SOURCE_DIR}/tools/SpectrePch.hpp` and is symbolically linked to `${SPECTRE_BUILD_DIR}/SpectrePch.hpp`. The configuration that seems to work is specifying the environment variables: \code{.sh} CCACHE_COMPILERCHECK=content CCACHE_EXTRAFILES="${SPECTRE_SOURCE_DIR}/tools/SpectrePch.hpp" CCACHE_IGNOREHEADERS=\ "${SPECTRE_BUILD_DIR}/SpectrePch.hpp:${SPECTRE_BUILD_DIR}/SpectrePch.hpp.gch" \endcode ## Caching Dependencies on macOS Builds {#caching-mac-os} On macOS builds we cache all of our dependencies, like LIBXSMM and Charm++. These are cached in `$HOME/mac_cache`. Ultimately this saves about 10-12 minutes even when compared to using ccache to cache the object files from building the dependencies. We also cache `$HOME/Library/Caches/Homebrew`, which is where Homebrew keeps the downloaded formulas. By caching the Homebrew bottles we are able to avoid brew formulas building from source because a tarball of the package was not available at the time. ================================================ FILE: docs/DevGuide/GpuSupport.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # GPU support {#gpu_support} \tableofcontents # Overview \warning GPU support is experimental and this page will be updated as the implementation matures. SpECTRE supports GPU acceleration through the [Kokkos](https://github.com/kokkos/kokkos) library. ## Build configuration To enable GPU support, set the CMake option `-D SPECTRE_KOKKOS=ON` when configuring the build. Either point CMake to a Kokkos installation with `-D Kokkos_ROOT=path/to/kokkos` or set `-D SPECTRE_FETCH_MISSING_DEPS=ON` to fetch Kokkos automatically and build it as part of SpECTRE. You also have to select a parallelization backend for Kokkos and possibly more configuration options like the GPU architecture to build for. Read the [Kokkos documentation](https://kokkos.org/kokkos-core-wiki/get-started/configuration-guide.html) for details on how to configure Kokkos. Here's an example for fetching Kokkos automatically and building it as part of SpECTRE with the CUDA backend: ```sh cmake -D SPECTRE_KOKKOS=ON \ -D SPECTRE_FETCH_MISSING_DEPS=ON \ -D Kokkos_ENABLE_CUDA=ON \ ... ``` Here's an example for using an existing Kokkos installation: ```sh cmake -D SPECTRE_KOKKOS=ON \ -D Kokkos_ROOT=path/to/kokkos/build \ -D CMAKE_CXX_COMPILER=path/to/kokkos/bin/nvcc_wrapper \ ... ``` When building Kokkos separately with the CUDA backend, you have to set the following configuration options: - `Kokkos_ENABLE_CUDA_CONSTEXPR=ON` - `Kokkos_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE` ================================================ FILE: docs/DevGuide/ImplementingVectors.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Implementing SpECTRE vectors {#implementing_vectors} \tableofcontents # Overview of SpECTRE Vectors {#general_structure} In SpECTRE, sets of contiguous or related data are stored in specializations of vector data types. The canonical implementation of this is the `DataVector`, which is used for storage of a contiguous sequence of doubles which support a wide variety of mathematical operations and represent data on a grid used during an evolution or elliptic solve. However, we support the ability to easily generate similar vector types which can hold data of a different type (e.g. `std::complex`), or support a different set of mathematical operations. SpECTRE vector classes are derived from the class template `VectorImpl`. The remainder of this brief guide gives a description of the tools for defining additional vector types. For reference, all functions described here can also be found in brief in the Doxygen documentation for VectorImpl.hpp, and a simple reference implementation can be found in DataVector.hpp and DataVector.cpp. # The class definition {#class_definition} SpECTRE vector types inherit from vector types implemented in the high-performance arithmetic library [Blaze](https://bitbucket.org/blaze-lib/blaze). Using inheritance, SpECTRE vectors gracefully make use of the math functions defined for the Blaze types, but can be customized for the specific needs in SpECTRE computations. The trio of template parameters for `VectorImpl` are the type of the stored data (e.g. `double` for `DataVector`), the result type for mathematical operations, and the static size. The result type is used by Blaze to ensure that only compatible vector types are used together in mathematical expressions. For example, a vector representing `double` data on a grid (`DataVector`) cannot be added to a vector representing spectral coefficients (`ModalVector`). This avoids subtle bugs that arise when vector types are unintentionally mixed. In nearly all cases the result type will be the vector type that is being defined, so, for instance, `DataVector` is a derived class of `VectorImpl`. This template pattern is known as the ["Curiously Recurring Template Pattern"](https://en.wikipedia.org/wiki/ Curiously_recurring_template_pattern) (CRTP). The static size is used as an optimization for small vector sizes. If your vector is small, rather than doing heap allocations, it will use stack allocations in order to be efficient. The default static size is set by a global constexpr bool `default_vector_impl_static_size`. For the Blaze system to use the CRTP inheritance appropriately, it requires the specification of separate type traits in the `blaze` namespace. These traits can usually be declared in a standard form, so are abstracted in a macro. For any new vector `MyNewVector`, the pattern that must appear at the beginning of the file (i.e. before the class definition) is: ``` /// \cond class MyNewVector; /// \endcond namespace blaze { DECLARE_GENERAL_VECTOR_BLAZE_TRAITS(MyNewVector); } ``` The class template `VectorImpl` defines various constructors, assignment operators, and iterator generation members. Most of these are inherited from Blaze types, but in addition, the methods `set_data_ref`, and `pup` are defined for use in SpECTRE. All except for the assignment operators and constructors will be implicitly inherited from `VectorImpl`. The assignment and constructors may be inherited calling the following alias code in the vector class definition: ``` using VectorImpl::operator=; using VectorImpl::VectorImpl; ``` Only the mathematical operations supported on the base Blaze types are supported by default. Those operations are determined by the storage type `T` and by the Blaze library. See [blaze-wiki/Vector_Operations](https://bitbucket.org/ blaze-lib/blaze/wiki/Vector%20Operations). # Allowed operator specification {#blaze_definitions} Blaze keeps track of the return type of unary and binary operations using "type trait" structs. These specializations for vector types should be placed in the header file associated with the `VectorImpl` specialization. For `DataVector`, the specializations are defined in `DataStructures/DataVector.hpp`. The presence or absence of template specializations of these structs also determines the set of allowed operations between the vector type and other types. For example, if adding a `double` to a `DataVector` should be allowed and the result should be treated as a `DataVector` for subsequent operations, then the struct `blaze::AddTrait` needs to be defined as follows: ``` namespace blaze { // the `template <>` head tells the compiler that // `AddTrait` is a class template specialization template <> struct AddTrait { // the `Type` alias tells blaze that the result should be treated like a // `DataVector` for any further operations using Type = DataVector; }; } // namespace blaze ``` Note that this only adds support for `DataVector + double`, not `double + DataVector`. To get the latter the following AddTrait specialization must be defined ``` namespace blaze { // the `template <>` head tells the compiler that // `AddTrait` is a class template specialization template <> struct AddTrait { // the `Type` alias tells blaze that the result should be treated like a // `DataVector` for any further operations using Type = DataVector; }; } // namespace blaze ``` Four helper macros are defined to assist with generating the many specializations that binary operations may require. Both of these macros must be put inside the blaze namespace for them to work correctly. The first of these helper macros is `BLAZE_TRAIT_SPECIALIZE_BINARY_TRAIT(VECTOR_TYPE, BLAZE_MATH_TRAIT)`, which will define all of the pairwise operations (`BLAZE_MATH_TRAIT`) for the vector type (`VECTOR_TYPE`) with itself and for the vector type with its `value_type`. This reduces the three specializations similar to the above code blocks to a single line call, ``` namespace blaze { BLAZE_TRAIT_SPECIALIZE_BINARY_TRAIT(DataVector, AddTrait) } // namespace blaze ``` The second helper macro is provided to easily define all of the arithmetic operations that will typically be supported for a vector type with its value type. The macro is `VECTOR_BLAZE_TRAIT_SPECIALIZE_ARITHMETIC_TRAITS(VECTOR_TYPE)`, and defines all of: - `IsVector` to `std::true_type` - `TransposeFlag`, which informs Blaze of the interpretation of the data as a "column" or "row" vector - `AddTrait` for the `VECTOR_TYPE` and its value type (3 Blaze struct specializations) - `SubTrait` for the `VECTOR_TYPE` and its value type (3 Blaze struct specializations) - `MultTrait` for the `VECTOR_TYPE` and its value type (3 Blaze struct specializations) - `DivTrait` for the `VECTOR_TYPE` and its value type (3 Blaze struct specializations) This macro is similarly intended to be used in the `blaze` namespace and can substantially simplify these specializations for new vector types. For instance, the call for `DataVector` is: ``` namespace blaze { VECTOR_BLAZE_TRAIT_SPECIALIZE_ARITHMETIC_TRAITS(DataVector) } // namespace blaze ``` The third helper macro is provided to define a combination of Blaze traits for symmetric operations of a vector type with a second type (which may or may not be a vector type). The macro is `BLAZE_TRAIT_SPECIALIZE_COMPATIBLE_BINARY_TRAIT(VECTOR, COMPATIBLE, TRAIT)`, and defines the appropriate trait for the two combinations `` and ``, and defines the result type to be `VECTOR`. For instance, to support the multiplication of a `ComplexDataVector` with a `DataVector` and have the result be a `ComplexDataVector`, the following macro call should be included in the `blaze` namespace: ``` namespace blaze { BLAZE_TRAIT_SPECIALIZE_COMPATIBLE_BINARY_TRAIT(ComplexDataVector, DataVector, MultTrait); } // namespace blaze ``` Finally, the fourth helper macro is provided to define all of the blaze traits which are considered either unary or binary maps. This comprises most named unary functions (like `sin()` or `sqrt()`) and named binary functions (like `hypot()` and `atan2()`). The macro `VECTOR_BLAZE_TRAIT_SPECIALIZE_ALL_MAP_TRAITS(VECTOR_TYPE)` broadly specializes all blaze-defined maps in which the given `VECTOR_TYPE` as the sole argument (for unary maps) or both arguments (for binary maps). This macro is also intended to be used in the blaze namespace. The call for `DataVector` is: ``` namespace blaze { VECTOR_BLAZE_TRAIT_SPECIALIZE_ALL_MAP_TRAITS(DataVector) } // namespace blaze ``` # Supporting operations for `std::array`s of vectors {#array_vector_definitions} In addition to operations between SpECTRE vectors, it is useful to gracefully handle operations between `std::arrays` of vectors element-wise. There are general macros defined for handling operations between array specializations: `DEFINE_STD_ARRAY_BINOP` and `DEFINE_STD_ARRAY_INPLACE_BINOP` from `Utilities/StdArrayHelpers.hpp`. In addition, there is a macro for rapidly generating addition and subtraction between arrays of vectors and arrays of their data types. The macro `MAKE_STD_ARRAY_VECTOR_BINOPS(VECTOR_TYPE)` will define: - the element-wise `+` and `-` with `std::array` and `std::array` - the element-wise `+` and `-` of either ordering of `std::array` with `std::array` - the `+=` and `-=` of `std::array` with a `std::array` - the `+=` and `-=` of `std::array` with a `std::array`. # Equivalence operators {#Vector_type_equivalence} Equivalence operators are supported by the Blaze type inheritance. The equivalence operator `==` evaluates to true on a pair of vectors if they are the same size and contain the same values, regardless of ownership. # MakeWithValueImpl {#Vector_MakeWithValueImpl} SpECTRE offers the convenience function `make_with_value` for various types. The typical behavior for a SpECTRE vector type is to create a new vector type of the same type and length initialized with the value provided as the second argument in all entries. This behavior may be created by placing the macro `MAKE_WITH_VALUE_IMPL_DEFINITION_FOR(VECTOR_TYPE)` in the .hpp file. Any other specializations of `MakeWithValueImpl` will need to be written manually. # Interoperability with other data types {#Vector_tensor_and_variables} When additional vector types are added, small changes are necessary if they are to be used as the base container type either for `Tensor`s or for `Variables` (a `Variables` contains `Tensor`s), which contain some vector type. In `Tensor.hpp`, there is a `static_assert` which white-lists the possible types that can be used as the storage type in `Tensor`s. Any new vectors must be added to that white-list if they are to be used within `Tensor`s. `Variables` is templated on the storage type of the stored `Tensor`s. However, any new data type should be appropriately tested. New vector types should be tested by invoking new versions of existing testing functions templated on the new vector type, rather than `DataVector`. # Writing tests {#Vector_tests} In addition to the utilities for generating new vector types, there are a number of convenience functions and utilities for easily generating the tests necessary to verify that the vectors function appropriately. These utilities are in `VectorImplTestHelper.hpp`, and documented individually in the TestingFrameworkGroup. Presented here are the salient details for rapidly assembling basic tests for vectors. ## Utility check functions Each of these functions is intended to encapsulate a single frequently used unit test and is templated (in order) on the vector type and the value type to be generated. The default behavior is to uniformly sample values between -100 and 100, but alternative bounds may be passed in via the function arguments. ### `TestHelpers::VectorImpl::vector_test_construct_and_assign()` This function tests a battery of construction and assignment operators for the vector type. ### `TestHelpers::VectorImpl::vector_test_serialize()` This function tests that vector types can be serialized and deserialized, retaining their data. ### `TestHelpers::VectorImpl::vector_test_ref()` This function tests the `set_data_ref` method of sharing data between vectors, and that the appropriate owning flags and move operations are handled correctly. ### `TestHelpers::VectorImpl::vector_test_math_after_move()` Tests several combinations of math operations and ownership before and after use of `std::move`. ### `TestHelpers::VectorImpl::vector_ref_test_size_error()` This function intentionally generates an error when assigning values from one vector to a differently sized, non-owning vector (made non-owning by use of `set_data_ref`). The assertion test which calls this function should search for the string "Must copy/move/assign into same size". Three forms of the test are provided, which are switched between using a value from the enum `RefSizeErrorTestKind` in the first function argument: - `RefSizeErrorTestKind::Copy`: tests that the size error is appropriately generated when copying to a non-owning vector of the wrong size. This has "copy" in the message. - `RefSizeErrorTestKind::ExpressionAssign`: tests that the size error is appropriately generated when assigning the result of a mathematical expression to a non-owning vector of the wrong size. This has "assign" in the message. - `RefSizeErrorTestKind::Move`: tests that the size error is appropriately generated when a vector is `std::move`d into a non-owning vector of the wrong size. This has "move" in the message. ## `TestHelpers::VectorImpl::test_functions_with_vector_arguments()` This is a general function for testing the mathematical operation of vector types with other vector types and/or their base types, with or without various reference wrappers. This may be used to efficiently test the full set of permitted math operations on a vector. See the documentation of `test_functions_with_vector_arguments()` for full usage details. An example simple use case for the math test utility: \snippet Test_DataVector.cpp test_functions_with_vector_arguments_example More use cases of this functionality can be found in `Test_DataVector.cpp`. # Vector storage nuts and bolts {#Vector_storage} Internally, all vector classes inherit from the templated `VectorImpl`, which inherits from a `blaze::CustomVector`. Most of the mathematical operations are supported through the Blaze inheritance, which ensures that the math operations execute the optimized forms in Blaze. Blaze also offers the possibility of restricting operations via `groups` in the `blaze::CustomVector` template arguments. Currently, we do not use the `blaze::GroupTag` functionality to determine available operations for vectors, but in principle this feature could allow us to further simplify our operator choice logic in the SpECTRE vector code. SpECTRE vectors can be either "owning" or "non-owning". If a vector is owning, it allocates and controls the data it has access to, and is responsible for eventually freeing that data when the vector goes out of scope. If the vector is non-owning, it acts as a (possibly complete) "view" of otherwise allocated memory. Non-owning vectors do not manage memory, nor can they change size. The two cases of data ownership cause the underlying data to be handled fairly differently, so we will discuss each in turn. When a SpECTRE vector is constructed as owning, or becomes owning, its memory is allocated in one of two ways. 1. The size of the vector is larger than the `StaticSize` template parameter to `VectorImpl`. In that case, it allocates its own block of memory of appropriate size, and stores a pointer to that memory in a `std::unique_ptr` named `owned_data_`. The `std::unique_ptr` ensures that the SpECTRE vector needs to perform no further direct memory management, and that the memory will be appropriately managed whenever the `std::unique_ptr owned_data_` member is deleted or moved. 2. The size of the vector is less than or equal to the `StaticSize` template. In this case, the data is stored on the stack in a `std::array` member variable called `static_owned_data_`. Since it is on the stack, this doesn't require any memory management by the user. In either case, the base `blaze::CustomVector` must also be told about the pointer, which is always accomplished by calling the protected function `VectorImpl.reset_pointer_vector(const size_t set_size)`, which sets the `blaze::CustomVector` internal pointer to either the pointer obtained by `std::unique_pointer.get()` or the pointer obtained by `std::array.data()` depending on the size of the vector. When a SpECTRE vector is constructed as non-owning by the `VectorImpl(ValueType* start, size_t set_size)` constructor, or becomes non-owning by the `set_data_ref` function, neither the internal `std::unique_ptr` named `owned_data_` nor the internal `std::array` named `static_owned_data_` points to the data represented by the vector and both can be thought of as "inactive" for the purposes of computation and memory management. This behavior is desirable, because otherwise the `std::unique_ptr` would attempt to free memory that is presumed to be also used elsewhere, causing difficult to diagnose memory errors. And we needn't worry about the `std::array` because it's allocated on the stack. The non-owning SpECTRE vector updates the base `blaze::CustomVector` pointer directly by calling `blaze::CustomVector.reset` from the derived class (on itself). ================================================ FILE: docs/DevGuide/ImportingData.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Importing data {#dev_guide_importing} \tableofcontents The `importers` namespace holds functionality for importing data into SpECTRE. We currently support loading volume data files in the same format that is written by the `observers`. ## Importing volume data The `importers::ElementDataReader` parallel component is responsible for loading volume data, interpolating it, and distributing it to elements of one or multiple array parallel components. As a first step, make sure you have added the `importers::ElementDataReader` to your `Metavariables::component_list`. Also make sure you have a `Parallel::Phase` in which you will perform registration with the importer, and another in which you want to load the data. Here's an example for such `Metavariables`: \snippet Test_VolumeDataReaderAlgorithm.hpp metavars To load volume data from a file, write an action in which you invoke `importers::Actions::ReadAllVolumeDataAndDistribute` on the `importers::ElementDataReader`. For simple use cases we provide `importers::Actions::ReadVolumeData`, which can be added to the `phase_dependent_action_list` of your element array and which will generate input-file options for you. Here's an example that will be explained in more detail below: \snippet Test_VolumeDataReaderAlgorithm.hpp import_actions - The `importers::Actions::ReadVolumeData` action specifies input-file options and dispatches to `importers::Actions::ReadAllVolumeDataAndDistribute` on the `importers::ElementDataReader` nodegroup component. It loads the volume data file once per node on its first invocation. Subsequent invocations of these actions, e.g. from all other elements on the node, will do nothing. The data is distributed into the inboxes of all elements on the node under the `importers::Tags::VolumeData` tag using `Parallel::receive_data`. - The `importers::Actions::ReceiveVolumeData` action waits for the volume data to be available and directly moves it into the DataBox. If you wish to verify or post-process the data before populating the DataBox, use your own specialized action in place of `importers::Actions::ReceiveVolumeData`. - You need to register the elements of your array parallel component for receiving volume data. To do so, invoke the `importers::Actions::RegisterWithElementDataReader` action in an earlier phase, as shown in the example above. The parameters passed to `importers::Actions::ReadAllVolumeDataAndDistribute` specify the volume data to load. See the documentation of `importers::Actions::ReadAllVolumeDataAndDistribute` for details. In the example above, we use `importers::Actions::ReadVolumeData` to generate the input-file options for us and place them in an option group: \snippet Test_VolumeDataReaderAlgorithm.hpp option_group This results in a section in the input file that may look like this: \snippet Test_VolumeDataReaderAlgorithm2D.yaml importer_options ================================================ FILE: docs/DevGuide/LoadBalancingNotes.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Notes on SpECTRE load-balancing using Charm++'s built-in load balancers {#load_balancing_notes} \tableofcontents The goal of load-balancing (LB) is to ensure that HPC resources are well-used while performing large inhomogeneous simulations. In 2020-2021, Jordan Moxon and Francois Hebert performed a number of tests using Charm++'s built-in load balancers with SpECTRE. These notes highlight the key points and give (at the bottom) some general recommendations. ### Overview of how LBs work with SpECTRE In late 2020 FH tested Charm's LBs on simple, homogeneous, SpECTRE test cases. These tests reveal the following broad behavior patterns: - Without using any LBs (no LB command-line args, or `+balancer NullLB`), SpECTRE's performance depends sensitively on how the DG elements are distributed over the HPC system. This indicates that communication costs are very important in SpECTRE runs. This statement remains true for more expensive evolution systems like Generalized Harmonic. - Charm's LBs that are not communications aware (e.g., `GreedyLB`, `RefineLB`, ...) all result in low parallel efficiency (20-30%). This is consistent with the understanding that communication costs are large. A good initial distribution of elements over processors will be degraded by these LBs, leading to more complicated communication graph and loss of performance. - Some of Charm's communication-aware LBs perform well: they approach the efficiency of a "manually tuned" initial distribution of elements onto processors. This suggests these LBs do a good job of partitioning the communications graph. In FH's simple tests, the best results were from `RecBipartLB`, which came within 10-20% of a manual initial distribution. However, it is a slow algorithm and is best used infrequently or only a few times near the start of the simulation. Note that at the 2020 Charm++ Workshop, the Charm team recommended that we use `MetisLB`, or that we combined `MetisLB` with `RefineLB` (syntax: `+balancer MetisLB +balancer RefineLB`, which applies the first balancer on the first invocation and the second balancer on all subsequent invocations, to 'polish' the results of the first LB). In practice, this failed for two reasons: - `MetisLB` tends to error with FPEs - When falling back to the pairing of `RecBipartLB` followed by `RefineLB`, the run starts with good performance. However, within a few applications of `RefineLB`, the performance is heavily degraded (down to 20-30% efficiency). It appears that we should stick to the comm-aware LB strategies. ### Contaminated LB measurements on first invocation There is reason to suspect that the Charm load balancing may incorrectly balance the load when applied near the start of some simulations. This is because the 'one-time' setup of the system may involve nontrivial computation, and (e.g. for numeric initial data) communication patterns between components that differ significantly from the patterns during evolution. Then, the first balancer invocation, based partially on the measurements taken during the non-generalizable initialization phase, can give rise to a poorly-chosen balance and injure performance. This is the suspected cause of poor performance that has been noticed in cases of homogeneous load and numeric initial data in Generalized Harmonic tests performed by Geoffrey Lovelace. JM confirmed the problem. It appears that the balance is not similarly degraded when using cases that do not involve numeric initial data -- some basic 2-node re-tests with Generalized Harmonic by JM seem to produce useful balance (improved performance) when not using numeric initial data. This issue has not been investigated to a completely satisfactory conclusion, though the above explanation seems most plausible. In cases for which it appears that the LB data is problematically impacted by the set up of the evolution system, we can try two main strategies to mitigate the problem: - Apply the load balancer at least two times near the start of the simulation, with sufficient gaps to collect useful balancing information. The LB database in Charm is cleared every time a balance is applied, so the later balances during the evolution should be uncontaminated. This strategy has not yet been carefully tested. To do this, use an input file similar to ``` PhaseChangeAndTriggers: - Trigger: Slabs: Specified: Values: [5, 10, 15] PhaseChanges: - VisitAndReturn(LoadBalancing) ``` - Use `LBTurnInstrumentOff` and `LBTurnInstrumentOn` to specifically exclude setup procedures from the LB instrumentation. First attempts indicate that this process might be challenging to accomplish correctly, and may require correspondence with the Charm developers to clarify at what points in the code execution those commands may be used, and precisely how they affect the load-balancing database. A first attempt by JM was to turn instrumentation off during array element construction, then turn instrumentation on for each element during the start of the `Evolve` phase, but that attempt led to a hang of the system, so the utility must have more constraints than were initially apparent. ### Scotch load balancer JM tested `ScotchLB`, and found better performance than with `RecBipartLB`. The margin varied a great deal among the number of nodes used, but at multiple points tested, the runtime was less than 65% of the `RecBipartLB` runtime. The tests were performed with homogeneous load, but starting from the round-robin element distribution. The indication is therefore that `ScotchLB` is very effective at minimizing communication costs. However, in practical applications, JM found that the `ScotchLB` often generates FPEs during the graph partition step and causes the simulation to crash. The issue [charm++ issue #3401](https://github.com/UIUC-PPL/charm/issues/3401) tracks the progress to determine the cause of the problem and fix it in Charm. The source of the problem has largely been identified, but the fix is still pending. `ScotchLB` will likely replace `RecBipartLB` as the most-frequently recommended centralized communication based balancer for SpECTRE once the FPE bugs have been fixed. ### General recommendations #### Homogeneous loads For homogeneous loads, it is likely best to omit load-balancing and just use the z-curve distribution (default) to give a good initial distribution and use that for the entire evolution. This means calling the SpECTRE executable with no LB-related command-line args, or with `+balancer NullLB`. You may find modest gains from using a communication-based load balancer, but likely only from the 'extra' parallel components of the system that cause the load to be not completely homogeneous (e.g., components like the interpolator or horizon finder). If you need a very long evolution or intend to submit a large number of evolutions, it may be worth experimenting to see whether 1-3 applications of `RecBipartLB` (or `ScotchLB` once its bugs are fixed, see above) improve performance for the system, for instance by using the input file: ``` PhaseChangeAndTriggers: - Trigger: Slabs: Specified: Values: [5, 10, 15] PhaseChanges: - VisitAndReturn(LoadBalancing) ``` and command-line args `+balancer RecBipartLB` (or `ScotchLB` when its bugs are fixed). This may be particularly relevant for cases with numeric initial data or other complicated set-up procedures. #### Inhomogeneous loads Based on our experiments, we anticipate that using a load-balancer may significantly improve runtimes with inhomogeneous loads. Our testing on this case is far more sparse, but for SpECTRE executables, it is probably remains true that managing communication costs will be an important goal for the balancer. It is likely worth attempting the evolution with a periodically-applied centralized communication-aware balancer, e.g.: ``` PhaseChangeAndTriggers: - Trigger: Slabs: EvenlySpaced: Interval: 1000 Offset: 5 PhaseChanges: - VisitAndReturn(LoadBalancing) ``` paired with command-line args `+balancer RecBipartLB` (or `ScotchLB` when its bugs are fixed). Important considerations when choosing the interval with which to balance are: - you will want to ensure that the balancer is applied frequently enough to prioritize expensive parts of the simulation before any relevent features 'move' to other elements. For example, if a shock is moving across the simulation domain causing certain elements to be more expensive to compute, you want to balance often enough that the LB 'keeps up' with the movement of the shock. - you will want to avoid balancing so frequently that the synchronization and balancer calculation itself becomes a significant portion of runtime. We have not yet taken much detailed data on using the load-balancers for inhomogeneous loads, so more detailed tests determining their efficacy would be valuable. ================================================ FILE: docs/DevGuide/Observers.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Observers Infrastructure {#observers_infrastructure_dev_guide} \tableofcontents The observers infrastructure works with two parallel components: a group and a nodegroup. We have two types of observations: `Reduction` and `Volume` (see the enum `observers::TypeOfObservation`). `Reduction` data is anything that is written once per time/integral identifier per simulation. Some examples of reduction data are integrals or L2 norms over the entire domain, integrals or L2 norms over part of the domain, and integrals over lower-dimensional surfaces such as apparent horizons or slices through the domain. Volume data is anything that has physical extent, such as any of the evolved variables (or derived quantities thereof) across all or part of the domain, or quantities on lower-dimensional surfaces in the domain (e.g. the rest mass density in the xy-plane). Reduction and volume data both use the group and nodegroup for actually getting the data to disk, but do so in a slightly different manner. ### Reduction Data Reduction data requires combining information from many or all cores of a supercomputer to get a single value. Reductions are tagged by some temporal value, which for hyperbolic systems is the time and for elliptic systems some combination of linear and non-linear iteration count. The reduction data is stored in an object of type `Parallel::ReductionData`, which takes as template parameters a series of `Parallel::ReductionDatum`. A `Parallel::ReductionDatum` takes as template parameters the type of the data and operators that define how data from the different cores are to be combined to a single value. See the paragraphs below for more detail, and the documentation of `Parallel::ReductionDatum` for examples. At the start of a simulation, every component and event that wants to perform a reduction for observation, or will be part of a reduction observation, must register with the `observers::Observer` component. The `observers::Observer` is a group, which means there is one per core. The registration is used so that the `Observer` knows once all data for a specific reduction (both in time and by name/ID) has been contributed. Reduction data is combined on each core as it is contributed by using the binary operator from `Parallel::ReductionDatum`'s second template parameter. Once all the data is collected on the core, it is copied to the local `observers::ObserverWriter` nodegroup, which keeps track of how many of the cores on the node will be contributing to a specific observation, and again combines all the data as it is being contributed. Once all the node's data is collected to the nodegroup, the data is sent to node `0` which combines the reduction data as it arrives using the binary operator from `Parallel::ReductionDatum`'s second template parameter. Using node `0` for collecting the final reduction data is an arbitrary choice, but we are always guaranteed to have a node `0`. Once all the reductions are received on node `0`, the `ObserverWriter` invokes the `InvokeFinal` (third) template parameter on each `Parallel::ReductionDatum` (this is the n-ary) in order to finalize the data before writing. This is used, for example, for dividing by the total number of grid points in an L1 or L2 norm. The reduction data is then written to an HDF5 file whose name is set in the input file using the option `observers::Tags::ReductionFileName`. Specifically, the data is written into an `h5::Dat` subfile since, along with the data, the subfile name must be passed through the reductions. The actions used for registering reductions are `observers::Actions::RegisterEventsWithObservers` and `observers::Actions::RegisterWithObservers`. There is a separate `Registration` phase at the beginning of all simulations where everything must register with the observers. The action `observers::Actions::ContributeReductionData` is used to send data to the `observers::Observer` component in the case where there is a reduction done across an array or subset of an array. If a singleton parallel component or a specific chare needs to write data directly to disk it should use the `observers::ThreadedActions::WriteReductionDataRow` action called on the zeroth element of the `observers::ObserverWriter` component. ### Volume Data Volume data is vaguely defined as anything that has some extent. For example, in a 3d simulation, data on 2d surfaces is still considered volume data for the purposes of observing data. The spectral coefficients can also be written as volume data, though some care must be taken in that case to correctly identify which mode is associated with which terms in the basis function expansion. Whatever component will contribute volume data to be written must register with the `observers::Observer` component (there currently isn't tested support for directly registering with the `observers::ObserverWriter`). This registration is the same as in the reduction data case. Once the observers are registered, data is contributed to the `observers::Observer` component using the `observers::Actions::ContributeVolumeData` action. The data is packed into an `ElementVolumeData` object that carries `TensorComponent`s on a grid. Information on the grid, such as its extents, basis and quadrature, are stored alongside the `TensorComponent`s. Once all the elements on a single core have contributed their volume data to the `observers::Observer` group, the `observers::Observer` group moves its data to the `observers::ObserverWriter` component to be written. We write one file per node, appending the node ID to the HDF5 file name to distinguish between files written by different nodes. The HDF5 file name is specified in the input file using the `observers::Tags::VolumeFileName` option. The data is written into a subfile of the HDF5 file using the `h5::VolumeFile` class. If a singleton parallel component or a specific chare needs to write volume data directly to disk, such as surface data from an apparent horizon, it should use the `observers::ThreadedActions::WriteVolumeData` action called on the zeroth element of the `observers::ObserverWriter` component. For surface data (such as output from horizon finds), this data should be written to a file specified by the `observers::Tags::SurfaceFileName` option. ### Threading and NodeLocks Since the `observers::ObserverWriter` class is a nodegroup, its entry methods can be invoked simultaneously on different cores of the node. However, this can lead to race conditions if care isn't taken. The biggest caution is that the `DataBox` cannot be mutated on one core and simultaneously accessed on another. This is because in order to guarantee a reasonable state for data in the `DataBox`, it must be impossible to perform a `db::get` on a `DataBox` from inside or while a `db::mutate` is being done. What this means in practice is that all entry methods on a nodegroup must put their `DataBox` accesses inside of a `node_lock.lock()` and `node_lock.unlock()` block. To achieve better parallel performance and threading, the amount of work done while the entire node is locked should be minimized. To this end, we have additional locks. One for the HDF5 files because we do not require a threadsafe HDF5 (`observers::Tags::H5FileLock`). We also have locks for the objects mutated when contributing reduction data (`observers::Tags::ReductionDataLock`). ### Future changes - It would be preferable to make the `Observer` and `ObserverWriter` parallel components more general and have them act as the core (node)group. Since any simple actions can be run on them, it should be possible to use them for most, if not all cases where we need a (node)group. ================================================ FILE: docs/DevGuide/OptionParsing.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Option Parsing {#dev_guide_option_parsing} \tableofcontents SpECTRE can read YAML configuration files at runtime to set parameters and choose between classes implementing an interface. %Options are parsed during code initialization and can be used to construct objects placed in the Parallel::GlobalCache and options passed to the parallel components. The types necessary to mark objects for parsing are declared in `Options/Options.hpp`. ## Metadata and options YAML input files begin with a metadata section, terminated by `---`, and followed by the executable options: ```yaml # Metadata here Description: | Briefly describe the configuration and link to papers for details. --- # Options start here ``` The metadata section may also be empty: ```yaml --- --- # Options start here ``` You only need the leading `---` marker if the metadata section is empty. This is YAML's "document start marker" (see the [YAML spec](https://yaml.org/spec/1.2)). Any metadata fields at the beginning of the file also imply the start of a document, so you don't need the first `---` marker. Metadata provide information for tools, whereas options provide information to the executable. See tools like `CheckOutputFiles` for details on the metadata fields that they use. Metadata can also provide information on how to run the input file, such as the name and version of the executable, and a description that may refer to published papers for details on the configuration. Options are defined by the executable and detailed below. ## General option format An option is defined by an "option tag", represented by a `struct`. At minimum, the struct must declare the type of the object to be parsed and provide a brief description of the meaning. The name of the option in the input file defaults to the name of the struct (excluding any template parameters and scope information), but can be overridden by providing a static `name()` function. Several other pieces of information, such as suggestions, limits and grouping, may be provided if desired. This information is all included in the generated help output. If an option has a suggested value, the value is specified in the input file as usual, but a warning will be issued if the specified value does not match the suggestion. Examples: \snippet Options/Test_Options.cpp options_example_scalar_struct \snippet Options/Test_Options.cpp options_example_vector_struct The option type can be any type understood natively by yaml-cpp (fundamentals, `std::string`, and `std::map`, `std::vector`, `std::list`, `std::array`, and `std::pair` of parsable types) and types SpECTRE adds support for. SpECTRE adds `std::unordered_map` (but only with ordered keys), `std::variant` (with alternatives tested in order), and various classes marked as constructible in their declarations. An option tag can be placed in a group by adding a `group` type alias to the struct. The alias should refer to a type that, like option tags, defines a help string and may override a static `name()` function. Example: \snippet Options/Test_Options.cpp options_example_group ## Constructible classes A class that defines `static constexpr Options::String help` and a typelist of option structs `options` can be created by the option parser. When the class is requested, the option parser will parse each of the options in the `options` list, and then supply them to the constructor of the class. A class can use Options::Alternatives to support more than one possible set of options for its creation. (See [Custom parsing](#custom-parsing) below for more general creation mechanisms.) Unlike option descriptions, which should be brief, the class help string has no length limits and should give a description of the class and any necessary discussion of its options beyond what can be described in their individual help strings. Creatable classes must be default constructible and move assignable. The `Options::Context` is an optional argument to the constructor that should be used when the constructor checks for validity of the input. If the input is invalid, `PARSE_ERROR` is used to propagate the error message back through the options ensuring that the error message will have a full backtrace so it is easy for the user to diagnose. Example: \snippet Options/Test_CustomTypeConstruction.cpp class_creation_example Classes may use the Metavariables struct, which is effectively the compile time input file, in their parsing by templating the `options` type alias or by taking the Metavariables as a final argument to the constructor (after the `Options::Context`). Example: \snippet Options/Test_CustomTypeConstruction.cpp class_creation_example_with_metavariables ## Factory The factory interface creates an object of type `std::unique_ptr` containing a pointer to some class derived from `Base`. The list of creatable derived classes is specified in the `factory_creation` struct in the metavariables, which must contain a `factory_classes` type alias that is a `tmpl::map` from base classes to lists of derived classes: \snippet Options/Test_Factory.cpp factory_creation When a `std::unique_ptr` is requested, the factory will expect a single YAML argument specifying the name of the class (as given by a static `name()` function or, lacking that, the actual class name). If the derived class takes no arguments, the name can be given as a YAML string, otherwise it must be given as a single key-value pair, with the key the name of the class. The value portion of this pair is then used to create the requested derived class in the same way as an explicitly constructible class. Examples: \snippet Options/Test_Factory.cpp factory_without_arguments \snippet Options/Test_Factory.cpp factory_with_arguments \anchor custom-parsing ## Custom parsing Occasionally, the requirements imposed by the default creation mechanism are too stringent. In these cases, the construction algorithm can be overridden by providing a specialization of the struct \code{cpp} template struct Options::create_from_yaml { template static T create(const Options::Option& options); }; \endcode The create function can perform any operations required to construct the object. Example of using a specialization to parse an enum: \snippet Options/Test_CustomTypeConstruction.cpp enum_creation_example Note that in the case where the `create` function does *not* need to use the `Metavariables` it is recommended that a general implementation forward to an explicit instantiation with `void` as the `Metavariables` type. The reason for using `void` specialization is to reduce compile time. Since we only need one full implementation of the function independent of what type `Metavariables` is, we should only parse and compile it once. By having a specialization on `void` (or some other non-metavariables type like `NoSuchType`) we can handle the metavariables-independent case efficiently. As a concrete example, the general definition and forward declaration of the `void` specialization in the header file would be: \snippet Options/Test_CustomTypeConstruction.cpp enum_void_creation_header_example while in the `cpp` file the definition of the `void` specialization is: \snippet Options/Test_CustomTypeConstruction.cpp enum_void_creation_cpp_example ================================================ FILE: docs/DevGuide/ParallelExecutable/Concepts.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Parallelization in SpECTRE {#tutorial_parallel_concepts} \tableofcontents This overview describes the concepts and terminology that SpECTRE uses to enable parallelism. This overview is a general discussion with no code examples. Subsequent tutorials will provide a more in-depth exploration of the parallelization infrastructure, including code examples. Unlike many parallel scientific codes which use data-based parallelism, SpECTRE uses task-based parallelism. The classical strategy for parallelism (data-based parallelism) is to assign a portion of the data to processes (or threads) that synchronously execute compute kernels. This is implemented in many codes but it is difficult to design codes with this strategy that will efficiently scale for complex multi-scale, multi-physics workloads. Task-based parallelism provides a solution: Instead of dividing work between parallel processes based on data ownership, there is a set of tasks and their inter-dependencies. Tasks are scheduled and assigned to processes dynamically, providing opportunities for load balancing and minimization of idle threads. By dividing the program into small enough tasks such that you have several tasks per thread, communication time is hidden by interleaving tasks that are ready to be executed with tasks that are waiting for data. In order to implement task-based parallelism, SpECTRE is built on top of the parallel programming framework of the Charm++ library, which is developed by the [Parallel Programming Laboratory](http://charm.cs.illinois.edu/) at the University of Illinois. Charm++ is a mature parallel programming framework that provides intra-node threading and can use a variety of communication interfaces (including MPI) to communicate between nodes. Charm++ has a large user base, which includes users of the cosmological \f$N\f$-body code [ChaNGa](https://github.com/N-BodyShop/changa/wiki/ChaNGa) and of the molecular dynamics code [NAMD](https://www.ks.uiuc.edu/Research/namd/). ## Charm++ basic concepts In order to understand how parallelization works in SpECTRE, it is useful to understand the basic concepts in the design of Charm++. Much of the following is quoted verbatim from the [Charm++ documentation](https://charm.readthedocs.io), interspersed with comments on how SpECTRE interacts with Charm++. > Charm++ is a C++-based parallel programming system, founded on the > migratable-objects programming model, and supported by a novel and > powerful adaptive runtime system. It supports both irregular as well > as regular applications, and can be used to specify task-parallelism > as well as data parallelism in a single application. It automates > dynamic load balancing for task-parallel as well as data-parallel > applications, via separate suites of load-balancing strategies. Via > its message-driven execution model, it supports automatic latency > tolerance, modularity and parallel composition. Charm++ also supports > automatic checkpoint/restart, as well as fault tolerance based on > distributed checkpoints. SpECTRE currently wraps only some of the features of Charm++, primarily the ones that support task-parallelism. We are just beginning our exploration of dynamic load balancing. Coming soon we will utilize automatic checkpoint/restart. At present we do not use Charm++ support for fault tolerance. > The key feature of the migratable-objects programming model is > over-decomposition: The programmer decomposes the program into a > large number of work units and data units, and specifies the > computation in terms of creation of and interactions between these > units, without any direct reference to the processor on which any > unit resides. This empowers the runtime system to assign units to > processors, and to change the assignment at runtime as necessary. SpECTRE's parallelization module is designed to make it easy for users to exploit the migratable-object model by providing a framework to define the units into which a program can be decomposed. > A basic unit of parallel computation in Charm++ programs is a > chare. At its most basic level, it is just a C++ object. A Charm++ > computation consists of a large number of chares distributed on > available processors of the system, and interacting with each other > via asynchronous method invocations. Asynchronously invoking a > method on a remote object can also be thought of as sending a > “message” to it. So, these method invocations are sometimes referred > to as messages. (besides, in the implementation, the method > invocations are packaged as messages anyway). Chares can be created > dynamically. In SpECTRE, we wrap Charm++ chares in struct templates that we call __parallel components__ that represent a collection of distributed objects. We wrap the asynchronous method invocations between the elements of parallel components in struct templates that we call __actions__. Thus, each element of a parallel component can be thought of as a C++ object that exists on one core on the supercomputer, and an action as calling a member function of that object, even if the caller is on another core. > Conceptually, the system maintains a “work-pool” consisting of seeds > for new chares, and messages for existing chares. The Charm++ > runtime system (Charm RTS) may pick multiple items, > non-deterministically, from this pool and execute them, with the > proviso that two different methods cannot be simultaneously > executing on the same chare object (say, on different > processors). Although one can define a reasonable theoretical > operational semantics of Charm++ in this fashion, a more practical > description of execution is useful to understand Charm++. A Charm++ > application’s execution is distributed among Processing Elements > (PEs), which are OS threads or processes depending on the selected > Charm++ build options. On each PE, there is a scheduler operating > with its own private pool of messages. Each instantiated chare has > one PE which is where it currently resides. The pool on each PE > includes messages meant for chares residing on that PE, and seeds > for new chares that are tentatively meant to be instantiated on that > PE. The scheduler picks a message, creates a new chare if the > message is a seed (i.e. a constructor invocation) for a new chare, > and invokes the method specified by the message. When the method > returns control back to the scheduler, it repeats the cycle > (i.e. there is no pre-emptive scheduling of other invocations). It is very important to keep in mind that the actions that are executed on elements of parallel components are done so non-deterministically by the run-time system. Therefore it is the responsibility of the programmer to ensure that actions are not called out of order. This means that if action B must be executed after action A on a given element of a parallel component, the programmer must ensure that either action B is called after the completion of action A (i.e. it is not sufficient that action B is invoked after action A is invoked), or that action B checks that action A has completed before running. > When a chare method executes, it may create method invocations for > other chares. The Charm Runtime System (RTS) locates the PE where > the targeted chare resides, and delivers the invocation to the > scheduler on that PE. In SpECTRE, this is done by one element of a parallel component calling an action on an element of a another parallel component. > Methods of a chare that can be remotely invoked are called entry > methods. Entry methods may take serializable parameters, or a > pointer to a message object. Since chares can be created on remote > processors, obviously some constructor of a chare needs to be an > entry method. Ordinary entry methods are completely non-preemptive- > Charm++ will not interrupt an executing method to start any other > work, and all calls made are asynchronous. In SpECTRE, the struct template that defines a parallel component has taken care of creating the entry methods for the underlying chare, which are then called by invoking actions. > Charm++ provides dynamic seed-based load balancing. Thus location > (processor number) need not be specified while creating a remote > chare. The Charm RTS will then place the remote chare on a suitable > processor. Thus one can imagine chare creation as generating only a > seed for the new chare, which may take root on some specific > processor at a later time. We are just in the process of beginning to explore the load-balancing features of Charm++, but plan to have new elements of parallel components (the wrapped chares) be creatable using actions, without specifying the location on which the new element is created. > Chares can be grouped into collections. The types of collections of > chares supported in Charm++ are: chare-arrays, chare-groups, and > chare-nodegroups, referred to as arrays, groups, and nodegroups > throughout this manual for brevity. A Chare-array is a collection of > an arbitrary number of migratable chares, indexed by some index > type, and mapped to processors according to a user-defined map > group. A group (nodegroup) is a collection of chares, with exactly > one member element on each PE (“node”). Each of SpECTRE's parallel components has a type alias `chare_type` corresponding to whether it is a chare-array, chare-group, or chare-nodegroup. In addition we support a singleton which is essentially a one-element array. > Charm++ does not allow global variables, except readonly > variables. A chare can normally only access its own data > directly. However, each chare is accessible by a globally valid > name. So, one can think of Charm++ as supporting a global object > space. SpECTRE does not use the readonly global variables provided by Charm++. Instead SpECTRE provides a nodegroup called the `GlobalCache` which provides global access to both read-only and writable objects, as well as a way to access every parallel component. > Every Charm++ program must have at least one mainchare. Each > mainchare is created by the system on processor 0 when the Charm++ > program starts up. Execution of a Charm++ program begins with the > Charm RTS constructing all the designated mainchares. For a > mainchare named X, execution starts at constructor X() or X(CkArgMsg > *) which are equivalent. Typically, the mainchare constructor starts > the computation by creating arrays, other chares, and groups. It can > also be used to initialize shared readonly objects. SpECTRE provides a pre-defined mainchare called `Main` that is run when a SpECTRE executable is started. `Main` will create the other parallel components, and initialize items in the `GlobalCache` whose items can be used by any parallel component. > Charm++ program execution is terminated by the CkExit call. Like the > exit system call, CkExit never returns, and it optionally accepts an > integer value to specify the exit code that is returned to the > calling shell. If no exit code is specified, a value of zero > (indicating successful execution) is returned. The Charm RTS ensures > that no more messages are processed and no entry methods are called > after a CkExit. CkExit need not be called on all processors; it is > enough to call it from just one processor at the end of the > computation. SpECTRE wraps `CkExit` with the function `sys::exit`. As no more messages are processed by Charm++ after this call, SpECTRE also defines a special `Exit` phase that is guaranteed to be executed after all messages and entry methods have been processed. > As described so far, the execution of individual Chares is > “reactive”: When method A is invoked the chare executes this code, > and so on. But very often, chares have specific life-cycles, and the > sequence of entry methods they execute can be specified in a > structured manner, while allowing for some localized non-determinism > (e.g. a pair of methods may execute in any order, but when they both > finish, the execution continues in a pre-determined manner, say > executing a 3rd entry method). Charm++ provides a special notation to simplify expression of such control structures, but this requires writing specialized interface files that are parsed by Charm++. SpECTRE does not support this; rather we split the executable into a set of phases. In each phase, each parallel component will execute a user-defined list of actions. > The normal entry methods, being asynchronous, are not allowed to > return any value, and are declared with a void return type. SpECTRE's actions do not return any value to the calling component. Instead when the action is finished it can call another action to send data to an element of any parallel component. > To support asynchronous method invocation and global object space, > the RTS needs to be able to serialize (“marshall”) the parameters, > and be able to generate global “names” for chares. For this purpose, > programmers have to declare the chare classes and the signature of > their entry methods in a special “.ci” file, called an interface > file. Other than the interface file, the rest of a Charm++ program > consists of just normal C++ code. The system generates several > classes based on the declarations in the interface file, including > “Proxy” classes for each chare class. Those familiar with various > component models (such as CORBA) in the distributed computing world > will recognize “proxy” to be a dummy, standin entity that refers to > an actual entity. For each chare type, a “proxy” class exists. The > methods of this “proxy” class correspond to the remote methods of > the actual class, and act as “forwarders”. That is, when one invokes > a method on a proxy to a remote object, the proxy marshalls the > parameters into a message, puts adequate information about the > target chare on the envelope of the message, and forwards it to the > remote object. Individual chares, chare array, groups, node-groups, > as well as the individual elements of these collections have a such > a proxy. Multiple methods for obtaining such proxies are described > in the manual. Proxies for each type of entity in Charm++ have some > differences among the features they support, but the basic syntax > and semantics remain the same - that of invoking methods on the > remote object by invoking methods on proxies. SpECTRE has wrapped all of this functionality in order to make it easier to use. SpECTRE automatically creates the interface files for each parallel component using template metaprogramming. SpECTRE provides proxies for each parallel component that are all held in the `GlobalCache` which is available to every parallel component. In order for actions to be called as entry methods on remote parallel components, the arguments to the function call must be serializable. Charm++ provides the `PUP` framework to serialize objects where `PUP` stands for pack-unpack. Since the PUP framework is used by Charm++ for checkpointing, load-balancing, and passing arguments when calling actions, all user-defined classes with member data must define a `pup` function. > In terms of physical resources, we assume the parallel machine > consists of one or more nodes, where a node is a largest unit over > which cache coherent shared memory is feasible (and therefore, the > maximal set of cores per which a single process can run. Each node > may include one or more processor chips, with shared or private > caches between them. Each chip may contain multiple cores, and each > core may support multiple hardware threads (SMT for example). > Charm++ recognizes two logical entities: a PE (processing element) > and a logical node, or simply “node”. In a Charm++ program, a PE is > a unit of mapping and scheduling: each PE has a scheduler with an > associated pool of messages. Each chare is assumed to reside on one > PE at a time. A logical node is implemented as an OS process. In > non-SMP mode there is no distinction between a PE and a logical > node. Otherwise, a PE takes the form of an OS thread, and a logical > node may contain one or more PEs. Physical nodes may be partitioned > into one or more logical nodes. Since PEs within a logical node > share the same memory address space, the Charm++ runtime system > optimizes communication between them by using shared > memory. Depending on the runtime command-line parameters, a PE may > optionally be associated with a subset of cores or hardware threads. In other words, how Charm++ defines a node and a PE depends upon how Charm++ was installed on a system. The executable `Executables/ParallelInfo` can be used to determine how many nodes and PEs exist for a given Charm++ build and the runtime command-line parameters passed when calling the executable. For more details see the [Charm++ documentation](https://charm.readthedocs.io) and \ref dev_guide_parallelization_foundations. ================================================ FILE: docs/DevGuide/ParallelExecutable/MinimalExecutable.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # The minimal SpECTRE executable {#tutorial_minimal_parallel_executable} \tableofcontents This tutorial will illustrate what is needed to compile the minimal SpECTRE executable that will simply print some useful information about the executable and then exit. Specifically, this tutorial will introduce: - A user-provided `Metavariables`, a C++ struct that is used to specify the metaprogram that is converted into a C++ executable. - how to build a SpECTRE executable - how to run a SpECTRE executable - useful information that can be extracted from all SpECTRE executables - `Main`, the main parallel component that acts as the main function of a C++ executable. In this tutorial, `SPECTRE_ROOT` refers to the directory in which SpECTRE was cloned, and `SPECTRE_BUILD_DIR` refers to the directory in which you built SpECTRE. ### Creating a build target for a parallel executable The first step is to select (or create) a directory (within `SPECTRE_ROOT/src`) that will hold the files from which the executable will be created. For this tutorial we created the directory `ParallelTutorial` in `src/Executables/Examples`. If you create a new directory for the executable, you will need to edit the `CMakeLists.txt` file in its parent directory and add (replacing `ParallelTutorial` with the appropriate directory name) \snippet Examples/CMakeLists.txt add_subdirectory The second step is to edit (or create) the `CMakeLists.txt` file in the executable directory and add a call to `add_spectre_executable` such as: \snippet ParallelTutorial/CMakeLists.txt add_spectre_executable The `add_spectre_executable` just forwards its arguments to CMake's `add_executable`. It works just like `add_executable` in that you pass it a source file that defines your executable. Your source file needs a `CkRegisterMainModule()` function. This is the "main" function of the Charm++ program: \snippet ParallelTutorial/MinimalExecutable.cpp main_function It just calls `Parallel::charmxx::register_main_module()`. This is where SpECTRE code takes over. SpECTRE programs are defined by the `Metavariables` class that is passed to this function. ### Writing the metavariables files The metavariables can be thought of as a compile-time input file that defines what the executable will do: \snippet MinimalExecutable.cpp metavariables_definition The metavariables struct must define a `static constexpr std::array default_phase_order` that is used to define the default order in which phases are executed. In this example the executable will execute the `Initialization` phase followed by the `Exit` phase. The metavariables struct must define a type alias `component_list` that is a `tmpl::list` (a typelist defined in `Utilities/TMPL.hpp`) of the parallel components used by the executable. In this example no parallel components are used. The metavariables struct must define `help`, a `static constexpr Options::String` that will be printed as part of the help message of the executable. (`Options::String` is defined in `Options/Options.hpp`.) ### Building a SpECTRE executable Let `$EXECUTABLE` be the name of the executable (the first argument passed to the `add_spectre_executable` `CMake` function, so in this example `MinimalExample`). Then the executable can be built by running the following command in `$SPECTRE_BUILD_DIR`: ``` make $EXECUTABLE ``` which will produce the executable of the same name in `$SPECTRE_BUILD_DIR/bin`. ### Running a SpECTRE executable To run a SpECTRE executable, run the command: ``` ./$SPECTRE_BUILD_DIR/bin/$EXECUTABLE ``` where `` must include any required command-line options. In the simple example for this tutorial, no command-line options are required. On a laptop, we get the following output: ``` Charm++: standalone mode (not using charmrun) Charm++> Running in Multicore mode: 1 threads Converse/Charm++ Commit ID: v6.8.0-0-ga36028edb CharmLB> Load balancer assumes all CPUs are same. Charm++> Running on 1 unique compute nodes (4-way SMP). Charm++> cpu topology info is gathered in 0.000 seconds. Executing 'some_path/MinimalExample' using 1 processors. Date and time at startup: Fri Oct 25 15:03:05 2019 SpECTRE Build Information: Version: 0.0.0 Compiled on host: kosh-3.local Compiled in directory: some_path/build Source directory is: some_path/parallel_tutorial Compiled on git branch: feature/parallel_tutorial Compiled with git hash: 1f4ab20cbda9ae8072a17df69de9731c43687468 Linked on: Fri Oct 25 13:26:06 2019 Done! Wall time in seconds: 0.004185 Date and time at completion: Fri Oct 25 15:03:05 2019 [Partition 0][Node 0] End of program ``` which includes information that will be printed by every SpECTRE executable on startup and exit. First, there is information provided by `Charm++` that will depend upon how `Charm++` was built. Next you will see information provided by SpECTRE which includes: - the name of the executable - how many processes the executable was run on - the date and time at startup - the version of SpECTRE that was used to compile the executable - where the executable was compiled - which git branch and hash was used to compile the executable - when the executable was linked On exit, the executable will print that it is `Done!`, followed by how the long the executable took to run as timed by the `Charm++` wall-clock timer, and the date and time at completion, followed by any information the `Charm++` provides upon exiting the program. ### Extracting useful information from a SpECTRE executable Every SpECTRE executable comes with a set of command-line options that can be used to obtain useful information about the executable (and for executables expecting an input file, whether or not the input file can be parsed successfully). #### Getting a list of available options To get a list of available options for a SpECTRE executable, run either of the following commands: ``` ./$SPECTRE_BUILD_DIR/bin/$EXECUTABLE --help ./$SPECTRE_BUILD_DIR/bin/$EXECUTABLE -h ``` In the middle of the `Charm++` startup information will now appear a long list of `Charm++` related command-line options which we will ignore for this tutorial. After the SpECTRE startup information, there is now a list of available command-line options: ``` -h [ --help ] Describe program options --check-options Check input file options --dump-source-tree-as arg If specified, then a gzip archive of the source tree is dumped with the specified name. The archive can be expanded using 'tar -xzf ARCHIVE.tar.gz' --dump-paths Dump the PATH, CPATH, LD_LIBRARY_PATH, LIBRARY_PATH, and CMAKE_PREFIX_PATH at compile time. --dump-environment Dump the result of printenv at compile time. --dump-build-info Dump the contents of SpECTRE's BuildInfo.txt --dump-only Exit after dumping requested information. ``` which we will describe in detail below. This is followed by a description of the expected input-file options, which in this example will simply print the `help` string from the metavariables struct, and the statement that there are no options expected: ``` ==== Description of expected options: A minimal executable ``` We will cover input file options in a future tutorial. #### Checking options As the minimal executable in this tutorial expects no input-file options, running the command: ``` ./$SPECTRE_BUILD_DIR/bin/$EXECUTABLE --check-options ``` will print out `No options to check!` and exit the program. See a future tutorial for an example of checking input-file options. #### Dumping the source tree In order to aid in reproducibility, all SpECTRE executables contain a copy of `$SPECTRE_ROOT`. To obtain the source tree as an archive file, run the command: ``` ./$SPECTRE_BUILD_DIR/bin/$EXECUTABLE --dump-source-tree-as SpECTRE ``` which will produce the archive file `SpECTRE.tar.gz` which can be expanded with the command: ``` tar -xzf SpECTRE.tar.gz ``` #### Dumping other information about a SpECTRE executable In addition to dumping the entire source tree there are the following options: - `--dump-paths` will print out various paths from when the executable was compiled - `--dump-environment` will print the results of `printenv` (i.e. all of the environment variables) from when the executable was compiled - `--dump-build-info` will print the contents of SpECTRE's `BuildInfo.txt` which will contain the versions of libraries that SpECTRE linked against, as well as various `CMake` variables Also note that the option `--dump-only` can be used to have the SpECTRE executable terminate immediately after dumping the information. ### Behind the scenes: the main parallel component Every Charm++ executable needs a mainchare. All SpECTRE executables use `Main` (found in `src/Parallel/Main.hpp`) as the mainchare. When a SpECTRE executable is run, the constructor of `Main` that is executed takes the command line options as an argument (as type `CkArgMsg*`). This constructor performs the following operations: - Prints useful startup information - Parses the command line options, performing any requested operations - Parses the input file options, populating a tagged tuple with their values. (This is discussed in more detail in a future tutorial on input file options.) - Creates the `GlobalCache` (a nodegroup chare) that holds objects created from input file options that are stored once per Charm++ node, as well as proxies to all other parallel components. - Creates user-requested non-array parallel components, passing them the proxy to the `GlobalCache` as well as any items they request that can be created from input file options. - Creates empty array user-requested parallel components - Sends the complete list of parallel components to the `GlobalCache`. Once the list of parallel components is sent to the `GlobalCache` on each node, the `Main` member function `allocate_array_components_and_execute_initial_phase` will be executed. This will allocate the elements of the array parallel components by calling the `allocate_array` member function of each component. Then the `start_phase` member function is called on each component, which will execute the phase action list for the `Initialization` phase for each component. Charm++ will execute each phase until it detects that nothing is happening (quiescence detection). As this represents a global synchronization point, the number of phases should be minimized in order to exploit the power of SpECTRE. After each phase, the `execute_next_phase` member function of `Main` will be called. This member function first determines what the next phase is. If the next phase is `Exit`, then some useful information is printed and the program exits gracefully. Otherwise the `execute_next_phase` member function of each parallel component is called. ================================================ FILE: docs/DevGuide/Parallelization.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Parallelization, Charm++, and Core Concepts {#dev_guide_parallelization_foundations} \tableofcontents # Introduction {#dev_guide_parallelization_introduction} SpECTRE builds a layer on top of Charm++ that performs various safety checks and initialization for the user that can otherwise lead to difficult-to-debug undefined behavior. The central concept is what is called a %Parallel Component. A %Parallel Component is a struct with several type aliases that is used by SpECTRE to set up the Charm++ chares and allowed communication patterns. %Parallel Components are input arguments to the compiler, which then writes the parallelization infrastructure that you requested for the executable. There is no restriction on the number of %Parallel Components, though practically it is best to have around 10 at most. Here is an overview of what is described in detail in the sections below: - \ref dev_guide_parallelization_metavariables_class "Metavariables": Provides high-level configuration to the compiler, e.g. the physical system to be simulated. - \ref dev_guide_parallelization_phases_of_execution "Phases": Defines distinct simulation phases separated by a global synchronization point, e.g. `Initialization`, `Evolve` and `Exit`. - \ref dev_guide_parallelization_core_algorithm "Algorithm": In each phase, repeatedly iterates over a list of actions until the current phase ends. - \ref dev_guide_parallelization_parallel_components "Parallel component": Maintains and executes its algorithm. - \ref dev_guide_parallelization_actions "Action": Performs a computational task, e.g. evaluating the right hand side of the time evolution equations. May require data to be received from another action potentially being executed on a different core or node. # The Metavariables Class {#dev_guide_parallelization_metavariables_class} SpECTRE takes a different approach to input options passed to an executable than is common. SpECTRE not only reads an input file at runtime but also has many choices made at compile time. The compile time options are specified by what is referred to as the metavariables. What exactly the metavariables struct specifies depends on the executable, but all metavariables structs must specify the following: - `help`: a `static constexpr Options::String` that will be printed as part of the help message. It should describe the executable and basic usage of it, as well as any non-standard options that must be specified in the metavariables and their current values. An example of a help string for one of the testing executables is: \snippet Test_AlgorithmCore.cpp help_string_example - `component_list`: a `tmpl::list` of the parallel components (described below) that are to be created. Most evolution executables will have the `DgElementArray` parallel component listed. An example of a `component_list` for one of the test executables is: \snippet Test_AlgorithmCore.cpp component_list_example - `using const_global_cache_tags`: a `tmpl::list` of tags that are used to place const items in the GlobalCache. The alias may be omitted if the list is empty. - `using mutable_global_cache_tags`: a `tmpl::list` of tags that are used to place mutable items in the GlobalCache. The alias may be omitted if the list is empty. - `default_phase_order`: an array of Parallel::Phase that must contain at least `Initialization` as the first element and `Exit`as the last element. Phases are described in the next section. There are also several optional members: - `input_file`: a `static constexpr Options::String` that is the default name of the input file that is to be read. This can be overridden at runtime by passing the `--input-file` argument to the executable. - `ignore_unrecognized_command_line_options`: a `static constexpr bool` that defaults to `false`. If set to `true` then unrecognized command line options are ignored. Ignoring unrecognized options is generally only necessary for tests where arguments for the testing framework, [Catch](https://github.com/catchorg/Catch2/), are passed to the executable. # Phases of an Execution {#dev_guide_parallelization_phases_of_execution} Global synchronization points, where all cores wait for each other, are undesirable for scalability reasons. However, they are sometimes inevitable for algorithmic reasons. That is, in order to actually get a correct solution you need to have a global synchronization. SpECTRE executables can have multiple phases, where after each phase a global synchronization occurs. By global synchronization we mean that no parallel components are executing or have more tasks to execute: everything is waiting to be told what tasks to perform next. Every executable must have at least two phases, `Initialization` and `Exit`. The next phase is decided by the member function Parallel::Main::execute_next_phase. Usually the next phase is determined from the `default_phase_order` provided by the metavariables. If more complex decision making is desired, various components can send data to Parallel::Main via the PhaseControl infrastructure. This allows the next Phase to be determined dynamically. Here is an example of a `default_phase_order` member variable: \snippet LinearSolverAlgorithmTestHelpers.hpp default_phase_order_array In contrast, an evolution executable might have phases `Initialization`, `SetInitialData`, `Evolve`, and `Exit`. The first phase that is entered is always `Initialization`. During the `Initialization` phase the `Parallel::GlobalCache` is created, all (node)group components are created, and empty array and singleton components are created. Next, the function `allocate_remaining_components_and_execute_initialization_phase` is called which allocates singleton components and the elements of each array component, and then starts the `Initialization` phase on all parallel components. Once all parallel components' `Initialization` phase is complete, the next phase is determined and the `execute_next_phase` function is called on all the parallel components. At the end of an execution the `Exit` phase has the executable wait to make sure no \ref dev_guide_parallelization_parallel_components "parallel components" are performing or need to perform any more tasks, and then exits. An example where this approach is important is if we are done evolving a system but still need to write data to disk. We do not want to exit the simulation until all data has been written to disk, even though we've reached the final time of the evolution. If we reach the `Exit` phase, but some \ref dev_guide_parallelization_parallel_components "parallel components" have not terminated properly, this means a deadlock has occurred. A deadlock usually implies some error in the order messages have been sent/received. For example, if core 0 was paused and waiting to receive a message from core 1, but core 1 was also paused and waiting to receive a message from core 0, this would be considered a deadlock. We detect deadlocks during the `Exit` phase. All executables have the option to specify a function with the following signature \snippet Test_DetectHangArray.cpp deadlock_analysis_function If this function is specified in the metavariables and a deadlock occurs, this function and all the simple actions in it will run. The information printed during this function call is executable dependent, but it should print enough information for you to determine why the deadlock occurred. If this function isn't specified and a deadlock occurs, a message about how to add this function to your metavariables is printed, but nothing else. After this, the executable aborts. # The Algorithm {#dev_guide_parallelization_core_algorithm} Since most numerical algorithms repeat steps until some criterion such as the final time or convergence is met, SpECTRE's parallel components are designed to do such iterations for the user. An Algorithm executes an ordered list of actions until one of the actions cannot be evaluated, typically because it is waiting on data from elsewhere. When an algorithm can no longer evaluate actions it passively waits by handing control back to Charm++. Once an algorithm receives data, typically done by having another parallel component call the `receive_data` function, the algorithm will try again to execute the next action. If the algorithm is still waiting on more data then the algorithm will again return control to Charm++ and passively wait for more data. This is repeated until all required data is available. The actions that are iterated over by the algorithm are called iterable actions and are described below. Since the action list is phase dependent we refer to them generally as phase-dependent action lists (PDALs, pronounced "pedals"). # Parallel Components {#dev_guide_parallelization_parallel_components} Building off the introduction, a %Parallel Component is essentially a wrapper around Charm++ chares that makes it easy for a user to add parallel objects into their program. Charm++ chares can be confusing to work with which is why we wrap them. Each parallel component runs its own \ref dev_guide_parallelization_core_algorithm "Algorithm". Data can be sent from one parallel component to another and the receiving parallel components' Algorithm will be able to take that data and continue the program. ## 1. Types of Parallel Components {#dev_guide_parallelization_component_types} There are four types of %Parallel Components in SpECTRE: 1. `Parallel::Algorithms::Singleton`s have one object in the entire execution of the program. They are implemented as single element Charm++ chare arrays. Charm++ does offer a distributed object called a singleton, however, we explicitly don't use this for various reasons (see Parallel::Algorithms::Singleton). Henceforth and throughout SpECTRE, a `singleton` will refer to Parallel::Algorithms::Singleton and *not* a Charm++ singleton. 2. `Parallel::Algorithms::Array`s hold zero or more elements, each of which is an object distributed to some core. An array can grow and shrink in size dynamically if need be and can also be bound to another array. A bound array has the same number of elements as the array it is bound to, and elements with the same ID are on the same core. See Charm++'s chare arrays for details. 3. `Parallel::Algorithms::Group`s are arrays with one element per core which are not able to be moved around between cores. These are typically useful for gathering data from elements of a Parallel::Algorithms::Array on their core, and then processing or reducing the data further. See [Charm++'s](http://charm.cs.illinois.edu/help) group chares for details. 4. `Parallel::Algorithms::Nodegroup`s are similar to groups except that there is one element per node. See [parallel component placement](#dev_guide_parallelization_component_placement) for the definition of a cores and nodes. We ensure that all entry method calls done through the Algorithm's `simple_action` and `receive_data` functions are threadsafe. User-controlled threading is possible by calling the entry method member function `threaded_action`, which is like `simple_action` except it passes a node lock to the `Action`'s apply function. Note that unlike `simple_action`s, multiple `threaded_action`s can be executing simultaneously on the same chare, but on different cores of the node. \note Technically there is a fifth type of parallel component called a MainChare which is placed and executed on the global zeroth core. However, there can only be one of these in a executable, it is entirely different from a Singleton, and it is not specifiable by the user so we omit it from the count here. ## 2. Requirements {#dev_guide_parallelization_component_requirements} Each %Parallel Component struct must have the following type aliases: 1. `using chare_type` is set to one of the four \ref dev_guide_parallelization_component_types "types of Parallel Components". 2. `using metavariables` is set to the Metavariables struct that stores the global metavariables. It is often easiest to have the %Parallel Component struct have a template parameter `Metavariables` that is the global metavariables struct. Examples of this technique are given below. 3. `using phase_dependent_action_list` is set to a `tmpl::list` of `Parallel::PhaseActions>` where each `PhaseAction` represents a PDAL that will be executed on the parallel component during the specified phase. The %Actions are executed in the order that they are given in the `tmpl::list`s of the PDALs, but the phases need not be run in linear order. However, `db::DataBox` types are constructed assuming the phases are performed from first in the `phase_dependent_action_list` to the last. Simple actions (described below) can be executed in any phase. If there are no iterable actions in a phase then a `PhaseAction` need not be specified for that phase. However, at least one `PhaseAction`, even if it is empty, must be specified. 4. `using simple_tags_from_options` which is a `tmpl::list` of all the tags that will be inserted into the initial `db::DataBox` of each component. These tags are db::SimpleTag%s that have have a `using option_tags` type alias and a static function `create_from_options` (see the example below). This list can usually be constructed from the initialization actions of the component (i.e. the list of actions in the `PhaseAction` list for the `Initialization` phase) using the helper function `Parallel::get_simple_tags_from_options` (see the examples of components below). Each initialization action may specify a type alias `using simple_tags_from_options` which are a `tmpl::list` of tags that will be fetched from the db::DataBox by the action. 5. `using const_global_cache_tags` is set to a `tmpl::list` of tags that are required by the `allocate_array` function of an array component, or simple actions called on the parallel component. These tags correspond to const items that are stored in the Parallel::GlobalCache (of which there is one copy per Charm++ node). The alias can be omitted if the list is empty. 6. `using mutable_global_cache_tags` is set to a `tmpl::list` of tags that correspond to mutable items that are stored in the Parallel::GlobalCache (of which there is one copy per Charm++ core). The alias can be omitted if the list is empty. 7. `array_allocation_tags` is set to a `tmpl::list` of tags that will be constructed from options and will only be used in the `allocate_array` function of an array component. This type alias is only required for array components. Additionally, each %Parallel Component struct must define a `static constexpr bool checkpoint_data`, indicating whether the DataBox and inbox contents should be preserved in a checkpoint. Setting this to false is intended for organizational components that only store registration data that can be regenerated during the Restart phase. \parblock \note Array parallel components must also specify the type alias `using array_index`, which is set to the type that indexes the %Parallel Component Array. Charm++ allows arrays to be 1 through 6 dimensional or be indexed by a custom type. The Charm++ provided indexes are wrapped as `Parallel::ArrayIndex1D` through `Parallel::ArrayIndex6D`. When writing custom array indices, the [Charm++ manual](http://charm.cs.illinois.edu/help) tells you to write your own `CkArrayIndex`, but we have written a general implementation that provides this functionality (see `Parallel::ArrayIndex`); all that you need to provide is a plain-old-data ([POD](http://en.cppreference.com/w/cpp/concept/PODType)) struct of the size of at most 3 integers. \endparblock \parblock \note Singletons use an `array_index` of type `int`, but users need not specify this. It is already specified in the implementation of a singleton. \endparblock %Parallel array components have a static `allocate_array` function that is used to construct the elements of the array. The signature of the `allocate_array` functions must be: \code static void allocate_array( Parallel::CProxy_GlobalCache& global_cache, const tuples::tagged_tuple_from_typelist& initialization_items, const tuples::tagged_tuple_from_typelist& array_allocation_items, const std::unordered_set& procs_to_ignore); \endcode The `allocate_array` function is called by the Main parallel component when the execution starts and will typically insert elements into array parallel components. If the `allocate_array` function depends upon input options that are not in the GlobalCache, those tags should be added to the `array_allocation_tags` type alias. A TaggedTuple is constructed from this type alias and its input options and is only available in the `allocate_array` function. All other tags that will be constructed from options and used during the %Initialization phase should be placed in the `simple_tags_from_options` type alias. This type alias is a `tmpl::list` of tags which are db::SimpleTag%s that have have a `using option_tags` type alias and a static function `create_from_options`. They only need to be explicitly added to the list if no initialization action has added them to its `simple_tags_from_options` type alias. If you want to ignore specific processors when placing array elements, you can pass in a `std::unordered_set` to `allocate_array` that contains all the processors that shouldn't have array elements on them. The `allocate_array` functions of different array components are called in random order and so it is not safe to have them depend on each other. Each parallel component must also decide what to do in the different phases of the execution. This is controlled by an `execute_next_phase` function with signature: \code static void execute_next_phase( const Parallel::Phase next_phase, const Parallel::CProxy_GlobalCache& global_cache); \endcode Parallel::Main::execute_next_phase` determines the next phase, after which the `execute_next_phase` function of each component gets called. The `execute_next_phase` function determines what the parallel component should do during the next phase. Typically the `execute_next_phase` function should just call `start_phase(phase)` on the parallel component. ## 3. Examples {#dev_guide_parallelization_component_examples} An example of a singleton parallel component is: \snippet Test_AlgorithmParallel.cpp singleton_parallel_component An example of an array parallel component is: \snippet Test_AlgorithmParallel.cpp array_parallel_component There are some parallel components that are common to many executables. - Parallel::GlobalCache (a Parallel::Algorithms::Nodegroup) - DgElementArray (a Parallel::Algorithms::Array) - observers::Observer (a Parallel::Algorithms::Group) - observers::ObserverWriter (a Parallel::Algorithms::Nodegroup) The MutableGlobalCache deserves special mention, which is why is has its own section with instructions on how to use it. See [Mutable items in the GlobalCache](#dev_guide_parallelization_mutable_global_cache). ## 4. Placement {#dev_guide_parallelization_component_placement} The user has some control over where parallel components get placed on the resources it is running on. Here is a figure that illustrates how one may place parallel components. \image html charm_node_structure.png "Parallel component placement." In this example we are running on three (3) nodes that have four (4) cores each. For all our executables, we reserve one core of each node purely for communication purposes. Nothing else is run on this core. Because of this, what Charm++ calls a node, doesn't correspond to a full node on a supercomputer. A charm-node simply corresponds to a collection of cores on a physical node. In our case, a charm-node is represented by the remaining cores on a node not used for communication (i.e. the first charm-node corresponds to cores 1-3 on the first physical node). Also the definition of a charm-core doesn't necessarily have to correspond to an actual core (it could correspond to a hyperthreaded virtual core), however, for our purposes, it does. SpECTRE offers wrappers around Charm++ functions that will tell you the total number of charm-nodes/cores in an executable and what charm-node/core a parallel component is on. (In the following examples, the type `T` is an `int` or a `size_t`) - `Parallel::my_node()` returns the charm-node that the parallel component is on. In the figure, `Sing. 4` would return `2`. - `Parallel::my_proc()` returns the charm-core that the parallel component is on. In the figure, `Sing. 4` would return `6` (*not* `9`). - `Parallel::number_of_nodes()` returns the total number of charm-nodes in an executable. The above figure would have `3` charm-nodes. - `Parallel::number_of_procs()` returns the total number of charm-cores in an executable. The above figure would have `9` charm-cores (*not* `12`). \note For Charm++ SMP (shared memory parallelism) builds, a node corresponds to a collection of cores on a physical node, and a core corresponds to a processor on that physical node. However, for non-SMP builds, nodes and cores are equivalent. All of our builds are done with Charm++ SMP so nodes and cores have their usual definitions. The placement of Groups and Nodegroups are determined by Charm++. This is because a Group is on every charm-core and a Nodegroup is on every charm-node. Even though Nodegroups are one per charm-node, the user can't choose which core is used on the charm-node. They run on the next available charm-core on the charm-node. The Elements of an Array, however, can be placed on specific charm-cores. They are inserted into the Array by using the Charm++ `insert` member function of the CProxy for the Array. The `insert` function is documented in the Charm++ manual. In the Array example in the [Examples](#dev_guide_parallelization_component_examples) section, `array_proxy` is a `CProxy` and so all the documentation for Charm++ array proxies applies. SpECTRE always creates empty arrays with the constructor and requires users to insert however many elements they want and on which charm-cores they want them to be placed. Note that load balancing calls may result in array elements being moved. In a similar fashion, Singletons can also be placed on specific charm-cores. This can be specified in the input file. From an input file, there are two ways to specify where Array/Singleton parallel components can be placed. ```yaml ResourceInfo: AvoidGlobalProc0: true Singletons: AhA: Proc: 12 Exclusive: true AhB: Proc: Auto Exclusive: false ``` First is the `AvoidGlobalProc0` option. This option will tell the program to not put *any* Array Elements or Singletons on the global zeroth charm-core. This core is sometimes used to write data to disk which is typically much slower than the program execution. The second is the `Singletons:` option. You can set the value to `Auto`, and then each singleton will have their proc be chosen automatically and they won't be exclusive. Otherwise, you must specify options for each singleton as in the example above. `AhA` is the `pretty_type::name()` of a Singleton in the program and the user has a choice of which proc to place the Singleton on (`Auto` will let the program decide) and whether to exclude Array Elements or other Singletons from being put on this core. This is useful in case the Singleton does some expensive computation that shouldn't be slowed down by having lots of Array Elements on the same core. In the figure above, `AvoidGlobalProc0` is true, and `Sing. 2` requested to be exclusively on core `2`. # Actions {#dev_guide_parallelization_actions} %Actions are structs with a static `apply` method and come in five variants: simple actions, iterable actions, reduction actions, threaded actions, and local synchronous actions. The signature of `apply` methods differs for the different types of actions, but all types have the same general form. Actions receive a `db::DataBox`, the Parallel::GlobalCache, and their element's index and parallel component, as well as arguments specific to the action type. The `db::DataBox` should be thought of as the member data of the parallel component while the actions are the member functions. The combination of a `db::DataBox` and actions allows building up classes with arbitrary member data and methods using template parameters and invocation of actions. This approach allows us to eliminate the need for users to work with Charm++'s interface files, which can be error prone and difficult to use. The Parallel::GlobalCache is passed to each action so that the action has access to global data and is able to invoke actions on other parallel components. The `ParallelComponent` template parameter is the tag of the parallel component that invoked the action. A proxy to the calling parallel component can then be retrieved from the Parallel::GlobalCache. The remote entry method invocations are slightly different for different types of actions, so they will be discussed below. However, one thing that is disallowed for all actions is calling an action locally from within an action on the same parallel component. Specifically, \snippet Test_AlgorithmNestedApply1.cpp bad_recursive_call Here `Parallel::local()` is a wrapper around `ckLocal()` which is a Charm++ provided method that returns a pointer to the local (currently executing) parallel component. See the [Charm++ manual](http://charm.cs.illinois.edu/help) for more information. However, you are able to queue a new action to be executed later on the same parallel component by getting your own parallel component from the Parallel::GlobalCache (`Parallel::get_parallel_component(cache)`). The difference between the two calls is that by calling an action through the parallel component you will first finish the series of actions you are in, then when they are complete Charm++ will call the next queued action. Array, group, and nodegroup parallel components can have actions invoked in two ways. First is a broadcast where the action is called on all elements of the array: \snippet Test_AlgorithmParallel.cpp broadcast_to_group The second case is invoking an action on a specific array element by using the array element's index. The below example shows how a broadcast would be done manually by looping over all elements in the array: \snippet Test_AlgorithmParallel.cpp call_on_indexed_array Note that in general you will not know what all the elements in the array are and so a broadcast is the correct method of sending data to or invoking an action on all elements of an array parallel component. The `array_index` argument passed to all `apply` methods is the index into the parallel component array. If the parallel component is not an array the value and type of `array_index` is implementation defined and cannot be relied on. ## 1. Simple Actions {#dev_guide_parallelization_simple_actions} Simple actions can be thought of as member functions of remote objects (chares/parallel components). They are the direct analog of entry methods in Charm++ except that the member data is stored in the `db::DataBox` that is passed in as the first argument. A simple action must return void but can use `db::mutate` to change values of items in the `db::DataBox` if the `db::DataBox` is taken as a non-const reference. In some cases you will need specific items to be in the `db::DataBox` otherwise the action won't compile. To restrict which `db::DataBox`es can be passed you should use `requires` in the action's `apply` function template parameter list. For example, \snippet Test_AlgorithmCore.cpp requires_action checks that `CountActionsCalled` is available in the box. Simple actions can be called using a `CProxy` (see the [Charm++ manual](http://charm.cs.illinois.edu/help)), which is retrieved from the Parallel::GlobalCache using the parallel component struct and the `Parallel::get_parallel_component()` function. For example, the action above could be called as \snippet Test_AlgorithmCore.cpp simple_action_call Any arguments after the proxy are passed as additional arguments to the action's `apply` function. ## 2. Iterable Actions {#dev_guide_parallelization_iterable_actions} Iterable actions make up the algorithms described by the PDALs. These actions are executed one after the other until one of them cannot be evaluated. Their `apply` methods signature is \snippet Test_AlgorithmCore.cpp apply_iterative The `ActionList` type is the `tmpl::list` of iterable actions in the current phase. That is, it is equal to the `action_list` type alias in the current PDAL. The `inboxes` is a collection of the tags specified as `tmpl::list`s in the iterable actions' member type aliases `inbox_tags`. This collection represents data received from other chares using the `receive_data` function. Iterable actions can request that the algorithm be paused or halted for the current phase, and control which action in the current PDAL will be executed next. This is all done via the return value from the `apply` function. The `apply` function for iterable actions must return a Parallel::iterable_action_return_t which is a `std::tuple>`. The first element of the tuple controls how algorithm execution continues. See the documentation of `Parallel::AlgorithmExecution` for the meanings of different values of that enum. The second element of the tuple is usually set to `std::nullopt` in order to continue iterating through the algorithm, but can be used to jump to a different action in the current PDAL. Most iterable actions will simply return \snippet Test_AlgorithmParallel.cpp iterable_action_return_continue_next_action An action that pauses the algorithm will return \snippet Test_AlgorithmParallel.cpp return_with_termination After an algorithm has been paused it can be restarted by passing `false` to the `set_terminate` method or by calling `receive_data(..., true)`. Since the order in which messages are received is undefined in most cases the `receive_data(..., true)` call should be used to restart the algorithm. The return value `Parallel::AlgorithmExecution::Retry` deserves special mention. It is intended for use by actions that use data supplied by other parallel objects to indicate that they have not received all of the data they require. The algorithm will stop until an operation that could supply data has occurred and then the action will be retried. An example of waiting because of missing data is \snippet Test_AlgorithmCore.cpp retry_example In order to jump to a specific action, the metafunction `tmpl::index_of` can be used to get an `tmpl::integral_constant` with the value of the index of the element `element` in the typelist `list`. For example, \snippet Test_AlgorithmCore.cpp out_of_order_action The metafunction call `tmpl::index_of::%value` returns a `size_t` whose value is that of the action `iterate_increment_int0` in the PDAL. The indexing of actions in the PDAL starts at `0`. Iterable actions are invoked as part of the algorithm and so the only way to request they be invoked is by having the algorithm run on the parallel component. The algorithm can be explicitly evaluated in a new phase by calling `start_phase(Phase::TheCurrentPhase)`: \snippet Test_AlgorithmCore.cpp start_phase Alternatively, to evaluate the algorithm without changing phases the `perform_algorithm()` method can be used. By passing `true` to `perform_algorithm` the algorithm will be restarted if it was paused. The algorithm is also evaluated by calling the `receive_data` function, either on an entire array or singleton (this does a broadcast), or an on individual element of the array. Here is an example of a broadcast call: \snippet Test_AlgorithmParallel.cpp broadcast_to_group and of calling individual elements: \snippet Test_AlgorithmParallel.cpp call_on_indexed_array The `receive_data` function always takes a `ReceiveTag`, which is set in the actions' `inbox_tags` type aliases. The `inbox_tags` must have two member type aliases, a `temporal_id` which is used to identify when the data was sent, and a `type` which is the type of the data to be stored in the `inboxes`. The types are typically a `std::unordered_map`. In the discussed scenario of waiting for neighboring elements to send their data the `DATA` type would be a `std::unordered_map`. Inbox tags must also specify a `static bool insert_into_inbox()` function. For example, \snippet Test_AlgorithmParallel.cpp int_receive_tag The return value indicates whether `perform_algorithm()` should be called after insertion. This exists primarily to allow the communication logic used with `DgElementArray` to match that used with `DgElementCollection` more closely. It is safe to always return `true`. For common types of `DATA`, such as a `map`, a data structure with an `insert` function, a data structure with a `push_back` function, or copy/move assignment that is used to insert the received data, inserters are available in `Parallel::InboxInserters`. For example, there is `Parallel::InboxInserters::Map` for `map` data structures. The inbox tag can inherit publicly off the inserters to gain the required insertion capabilities: \snippet Test_AlgorithmCore.cpp int receive tag insert Any inbox tag that uses Charm++ messages must also specify a `message_type` type alias which is the object that will be sent. An example is: \snippet Test_AlgorithmMessages.cpp charm message inbox tag The `inbox_tags` type alias for the action is: \snippet Test_AlgorithmParallel.cpp int_receive_tag_list An inbox tag can also optionally specify a static function called `output_inbox` that returns a `std::string`. This function can be used for printing the contents of the inbox in a nice way as the types can sometimes get complicated. You can also use the `Parallel::output_inbox` function to output a specific inbox from all the inboxes. See an above example for the signature of the `output_inbox` function. \warning It is the responsibility of the iterable action to remove data from the inboxes that will no longer be needed. Normally when remote functions are invoked they go through the Charm++ runtime system, which adds some overhead. The `receive_data` function tries to elide the call to the Charm++ RTS for calls into array components. Charm++ refers to these types of remote calls as "inline entry methods". With the Charm++ method of eliding the RTS, the code becomes susceptible to stack overflows because of infinite recursion. The `receive_data` function is limited to at most 64 RTS elided calls, though in practice reaching this limit is rare. When the limit is reached the remote method invocation is done through the RTS instead of being elided. ## 3. Reduction Actions {#dev_guide_parallelization_reduction_actions} Reduction actions are the targets of reducing data over an array. For example, you may want to know the sum of a `int` from every element in the array. You can do this as follows: \snippet Test_AlgorithmReduction.cpp contribute_to_reduction_example This reduces over the parallel component `ArrayParallelComponent`, reduces to the parallel component `SingletonParallelComponent`, and calls the action `ProcessReducedSumOfInts` after the reduction has been performed. The reduction action is: \snippet Test_AlgorithmReduction.cpp reduce_sum_int_action As you can see, the last argument to the `apply` function is of type `int`, and is the reduced value. You can also broadcast the result back to an array, even yourself. For example, \snippet Test_AlgorithmReduction.cpp contribute_to_broadcast_reduction It is often necessary to reduce custom data types, such as `std::vector` or `std::unordered_map`. Charm++ supports such custom reductions, and so does our layer on top of Charm++. Custom reductions require one additional step to calling `contribute_to_reduction`, which is writing a reduction function to reduce the custom data. We provide a generic type that can be used in custom reductions, `Parallel::ReductionData`, which takes a series of `Parallel::ReductionDatum` as template parameters and `ReductionDatum::value_type`s as the arguments to the constructor. Each `ReductionDatum` takes up to four template parameters (two are required). The first is the type of data to reduce, and the second is a binary invokable that is called at each step of the reduction to combine two messages. The last two template parameters are used after the reduction has completed. The third parameter is an n-ary invokable that is called once the reduction is complete, whose first argument is the result of the reduction. The additional arguments can be any `ReductionDatum::value_type` in the `ReductionData` that are before the current one. The fourth template parameter of `ReductionDatum` is used to specify which data should be passed. It is a `std::index_sequence` indexing into the `ReductionData`. \warning All elements of the array must call the same reductions in the same order. It is *defined* behavior to do multiple reductions at once as long as all contribute calls on all array elements occurred in the same order. It is **undefined** behavior if the contribute calls are made in different orders on different array elements. ## 4. Threaded Actions {#dev_guide_parallelization_threaded_actions} Threaded actions are similar to simple actions, with the difference being that multiple threaded actions may be running on the same chare at the same time (potentially in parallel with one simple or reduction action). The `apply` function for a threaded actions has the same signature as that for a simple action, except that it also receives a `NodeLock` intended to control access to the chare's `db::DataBox`. All access to the `db::DataBox`, including read-only access, must occur while the action owns this lock. (Simple and reduction actions implicitly hold the lock for their entire execution.) \snippet Test_AlgorithmNodelock.cpp threaded_action_example Threaded actions can only be run on nodegroup chares. ## 5. Local Synchronous Actions {#dev_guide_parallelization_local_synchronous_actions} There is limited ability to retrieve data held by another parallel component via a direct synchronous call. Unlike the above actions, the invocation of a synchronous action is precisely a call to a member function of another parallel component; therefore, these invocations will run to completion, and return their result before the calling code proceeds in execution. Aside from being synchronous and being able to return data, local synchronous actions behave the same as threaded actions, except that they will only run on the chare of a nodegroup that is on the local node. Local synchronous actions' `apply` functions follow a signature motivated by threaded actions, but take fewer arguments. This may be a bug. Local synchronous actions must specify their return type in a `return_type` type alias. This is to help simplify the logic with the variant `db::DataBox` held by the parallel component. An example of a definition of a local synchronous action: \snippet Test_AlgorithmLocalSyncAction.cpp synchronous_action_example And the corresponding invocation: \snippet Test_AlgorithmLocalSyncAction.cpp synchronous_action_invocation_example \warning Say an action is being run on a component on a node where a mutable item in the GlobalCache is up-to-date. This action then calls another action on a different component on a different node. It is **NOT** guaranteed that this mutable item in the GlobalCache is up-to-date on this new node. It is up to the user to ensure the mutable item is up-to-date on whatever node they run an action on, even if it was up-to-date on the node that sent the message. The \ref dev_guide_parallelization_mutable_global_cache "Mutable items in the GlobalCache" section gives details about mutable GlobalCache items. # Mutable items in the GlobalCache {#dev_guide_parallelization_mutable_global_cache} Most items in the GlobalCache are constant, and are specified by type aliases called `const_global_cache_tags` as described above. However, the GlobalCache can also store mutable items. Because of asynchronous execution, **EXTREME** care must be taken when mutating items in the GlobalCache, as described below. A mutable item can be of any type, as long as that type is something that can be checked for whether it is "up-to-date". Here "up-to-date" means that the item can be safely used (even read-only) without needing to be mutated first. For example, a mutable item might be a function of time that knows the range of times for which it is valid; the mutable item is then deemed up-to-date if it will be called for a time within its range of validity, and it is deemed not up-to-date if it will be called for a time outside its range of validity. Thus the up-to-date status of a mutable item is determined by both the state of the item itself and by the code that wishes to use that item. ## 1. Specification of mutable GlobalCache items Mutable GlobalCache items are specified by a type alias `mutable_global_cache_tags`, which is treated the same way as `const_global_cache_tags` for const items. ## 2. Use of mutable GlobalCache items ### 1. Checking if the item is up-to-date Because execution is asynchronous, any code that uses a mutable item in the GlobalCache must first check whether that item is up-to-date. The information about whether an item is up-to-date is assumed to be stored in the item itself. For example, a mutable object stored in the GlobalCache might have type `std::map` (for some type `T`), and then any code that uses the stored object can check whether an entry exists for a particular `temporal_id`. To avoid race conditions, it is important that up-to-date checks are based on something that is independent of the order of mutation (like a `temporal_id`, and not like checking the size of a vector). To check an item, use the function `Parallel::mutable_cache_item_is_ready`, which returns a bool indicating whether the item is up-to-date. If the item is up-to-date, then it can be used. `Parallel::mutable_cache_item_is_ready` takes a lambda as an argument. This lambda is passed a single argument: a const reference to the item being retrieved. The lambda should determine whether the item is up-to-date. If so, it should return a default_constructed `std::unique_ptr`; if not, it should return a `std::unique_ptr` to a callback function that will be called on the next `Parallel::mutate` of that item. The callback will typically check again if the item is up-to-date and if so will execute some code that gets the item via `Parallel::get`. For the case of iterable actions, `Parallel::mutable_cache_item_is_ready` typically uses the callback `Parallel::PerformAlgorithmCallback`. In the example below, the vector is considered up-to-date if it is non-empty. If the vector is not up-to-date, then when it becomes up-to-date the callback function will be invoked; in this case the callback function re-runs `perform_algorithm()`, which will call the same action again. \snippet Test_AlgorithmGlobalCache.cpp check_mutable_cache_item_is_ready Note that `Parallel::mutable_cache_item_is_ready` is called on the local node and does no parallel communication. ### 2. Retrieving the item The item is retrieved using `Parallel::get` just like for constant items. For example, to retrieve the item `Tags::VectorOfDoubles`: \snippet Test_AlgorithmGlobalCache.cpp retrieve_mutable_cache_item Note that `Parallel::get` is called on the local node and does no parallel communication. Whereas we support getting *non-mutable* items in the GlobalCache from a DataBox via `db::get`, we intentionally do not support `db::get` of *mutable* items in the GlobalCache from a DataBox. The reason is that mutable items should be retrieved only after a `Parallel::mutable_cache_item_is_ready` check, and being able to retrieve a mutable item from a DataBox makes it difficult to enforce that check, especially when automatically-executing compute items are considered. ## 3. Modifying a mutable GlobalCache item To modify a mutable item, pass `Parallel::mutate` two template parameters: the tag to mutate, and a struct with an `apply` function that does the mutating. `Parallel::mutate` takes two arguments: a reference to the local GlobalCache, and a tuple that is passed into the mutator function. For the following example, \snippet Test_AlgorithmGlobalCache.cpp mutate_global_cache_item the mutator function is defined as below: \snippet Test_AlgorithmGlobalCache.cpp mutate_global_cache_item_mutator `Parallel::mutate` broadcasts to every node, where it calls the mutator function and then calls all the callbacks that have been set on that node by `Parallel::mutable_cache_item_is_ready`. The `Parallel::mutate` operation is guaranteed to be thread-safe without any further action by the developer so long as the item being mutated can be mutated in a threadsafe way. See the `Parallel::GlobalCache` docs for more details. # Charm++ Node and Processor Level Initialization Functions {#dev_guide_parallelization_charm_node_processor_level_initialization} Charm++ allows running functions once per core and once per node before the construction of any parallel components. This is commonly used for setting up error handling and enabling floating point exceptions. Other functions could also be run. Which functions are run on each node and core is set by calling `Parallel::charmxx::register_init_node_and_proc` in `CkRegisterMainModule()` with function pointers to the functions to be called. For example: \snippet Test_AlgorithmPhaseControlNodegroup.cpp charm_init_funcs_example ================================================ FILE: docs/DevGuide/PerformanceGuidelines.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # General Performance Guidelines {#general_perf_guide} \tableofcontents Below are some general guidelines for achieving decent performance. - One good measurement is worth more than a million expert opinions. Our testing framework [Catch2](https://github.com/catchorg/Catch2) supports benchmarks, so we encourage you to add benchmarks to your tests. See the [Catch2 benchmarks documentation](https://github.com/catchorg/Catch2/blob/devel/docs/benchmarks.md) for instructions. Essentially, add a `BENCHMARK` to your test case and run the test executable (such as `./bin/Test_LinearOperators`). Note that we skip benchmarks during automated unit testing with `ctest` because benchmarks are only meaningful in a controlled environment (such as a specific machine or architecture). You can keep track of the benchmark results you ran on specific machines in a comment in the test case (until we have a better way of keeping track of benchmark results). Catch2's benchmarking is not as feature-rich as Google Benchmark. We have a `Benchmark` executable that uses Google Benchmark so one can compare different implementations and see how they perform. This executable is only available in release builds. - Reduce memory allocations. On all modern hardware (many core CPUs, GPUs, and FPGAs), memory is almost always the bottleneck. Memory allocations are especially expensive since this is a quasi-serial process: the OS has to manage memory allocations for _all_ running threads and processes. SpECTRE has various classes to optimize this. For example, there are `Variables`, `TempBuffer`, and `DynamicBuffer` that allow making large contiguous memory allocations that are then used for individual tensor components. ================================================ FILE: docs/DevGuide/Profiling.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Profiling {#profiling} \tableofcontents There are a number of tools available for profiling, each with their own strengths and weaknesses. This makes it difficult to recommend one "right" way of analyzing performance using profilers. Instead, one should use a combination of the tools to discover and eliminate performance bottle necks. Common profilers are Charm++ Projections (tracing-based), HPCToolkit (sampling-based, very versatile), Linux perf (sampling-based, command line only), Intel VTune (sampling-based, works well on Intel hardware), AMD uProf (similar to Intel VTune), and Score-P (sampling and tracing, with MPI and pthread interfacing). ## Profiling with HPCToolkit {#profiling_with_hpctoolkit} Follow the HPCToolkit installation instructions at [hpctoolkit.org](http://hpctoolkit.org). The Spack installation seems to work well. Once installed, compile your executable in Release mode with `-D ENABLE_PROFILING=ON -D DEBUG_SYMBOLS=ON` since otherwise you won't be able to get call stacks and source analysis. Using `-D BUILD_SHARED_LIBS=ON` is recommended since it makes HPCToolkit a lot easier to use. You must also use the system allocator, `-D MEMORY_ALLOCATOR=SYSTEM`. We will work from the build directory and perform all runs and performance analysis there. First run HPCToolkit as: ``` hpcrun -t --event CYCLES@f200 ./bin/EXEC --input-file ./Input.yaml +p1 ``` We will profile on one core, but you can profile on multiple cores as well as multiple nodes if using MPI as the Charm++ backend. This will generate a `hpctoolkit-EXEC-measurements` directory. Run ``` hpcstruct -jN ./hpctoolkit-EXEC-measurements ``` where `N` is the number of cores to run on. This will generate a mapping to line numbers, etc. in the measurements directory. \warning Skipping the `hpcstruct` step will make `hprprof` below run extremely slowly. Once the run is complete, run ``` hpcprof hpctoolkit-EXEC-measurements ``` or if HPCToolkit version < 2024, run ``` hpcprof -I /path/to/spectre/src/+ hpctoolkit-EXEC-measurements ``` Note that the `+` is a literal `+` symbol. This will create the directory ``` hpctoolkit-EXEC-database ``` which you can view using ``` hpcviewer ./hpctoolkit-EXEC-database ``` HPCViewer will generally start you in the `Top-down view` (callgraph of callers). You can select `Bottom-up view` (callgraph of callees) to get a different perspective. Whether you want to look at the callgraph of callers or callees depends a bit on the executable, what you're looking to measure, and how you like to think about things. The callees graph can give you a nice overview of what the low-level things taking up a lot of time are, but certainly makes the call stack not look like you would expect. On the right of the callgraphs you will see `CYCLES:Sum (I)` and `CYCLES:Sum (E)`. `I` means time spent _including_ callees, while `E` means time spent in the function itself (exclusive time). Sorting by exclusive gives a good idea of what the hot functions are. Here is a screenshot from HPCViewer: \image html HpcViewerCallees.png "HPCViewer callgraph of callees" You can see that 49.1% of inclusive time is spent in primitive recovery, and the line after the 49.1% function is a function inside the Kastaun recovery scheme. The `__nss_database_lookup` is some system call, e.g. `__memcpy_avx_unaligned_erms` or `__memset_avx2_unaligned_erms`. Looking at the calling code, e.g. `prepare_neighbor_data` gives a good hint as to what's going on. In most cases these are memory copies or memory sets (`std::vector` default initializes its memory, which is bad for performance). The way to fix these bottlenecks is to avoid memory copies and `std::vector` as buffers. HPCToolkit allows you to sample on a variety of different event counters instead of just cycles. Please see the HPCToolkit manual for details. ## Profiling with AMD uProf {#profiling_with_amd_uprof} [AMD uProf](https://developer.amd.com/amd-uprof/) is AMD's sampling-based profiler that makes it relatively easy to do quite a bit of detailed performance analysis. The uProf manual is quite good and extensive, so for the most part the reader is referred to that. However, we will go over some basics for profiling executables and understanding the results. Make sure to compile your executable in Release mode with `-DENABLE_PROFILING=ON -D DEBUG_SYMBOLS=ON` since otherwise you won't be able to get call stacks and source analysis. When you open uProf you may be asked to change the kernel event paranoid level. Once you have uProf open, select `PROFILE` at the top. Specify the application path, options, etc. We will again run on a single core to analyze performance. It's recommended that you set the Core Affinity in AMD uProf so that your application isn't migrated between cores during a profiling run. Then choose `Next` in the lower right corner. Make sure the `CPU Profile Type` is set to `CPU Profile` at the top. We will first do a `Time-based Sampling` run (on the left). This means uProf will interrupt the application every `N` milliseconds and see where the application is. You typically want a few thousand total samples to get something that's reasonably representative of your application. Under the `Advanced %Options` make sure `Enable CSS` (on the right) is enabled (green) and that `Enable FPO` is also enabled. Now click `Start Profile` in the bottom right. Once the profile is complete you will be presented with a summary outlining where your code is spending most of its time. Click `ANALYZE` at the top to get a more detailed view. On the left you can select between a callgraph of callees (Function HotSpots), a callgraph of callers (Call Graph), and a few other views. Below is an example of a result from the same run we used with HPCToolkit above. \image html AmdUprofCallgraph.png "AMD uProf callgraph of callees" Again we see that most of our time is spent in primitive recovery but also that a lot of time is spent copying memory. This was grouped into `__nss_database_lookup` in HPCToolkit. Unfortunately, getting a call stack out of the `memcpy` doesn't always work and so while you know you're spending a lot of time copying memory, it's not so obvious where those copies are occurring. ## Profiling With Charm++ Projections {#profiling_with_projections} To view trace data after a profiling run you must download Charm++'s Projections software from their [website](http://charm.cs.illinois.edu/). If you encounter issues it may be necessary to clone the git repository and build the correct version from scratch. Note that the version of Charm++ used to compile SpECTRE should match the version of Projections used to analyze the trace data. You can collect the trace data on a different machine than the one you will be analyzing the data on. For example, you can collect the data on a supercomputer and analyze it on your desktop or laptop. For profiling you will want to use a production build of Charm++, which means compiling Charm++ with the `--with-production` flag. To enable trace collecting you must build with the `--enable-tracing` flag as well. For example, on a multicore 64-bit Linux machine the build command would be ``` shell ./build LIBS multicore-linux-x86_64 gcc -j8 --with-production --enable-tracing ``` You must build your executable in Release mode as well, specifying `-DCMAKE_BUILD_TYPE=Release` to CMake, as well as ``` -DCHARM_TRACE_PROJECTIONS=ON -DCHARM_TRACE_SUMMARY=ON -DENABLE_PROFILING=ON ``` to enable SpECTRE to use Charm++'s tracing features. ### Running SpECTRE With Trace Output When running SpECTRE you must specify a directory to output trace data into. This is done by adding the command line argument `+traceroot DIR` where `DIR` is the directory to dump the trace data into. Note that `DIR` must already exist, the application will not create it. For example, ```shell ./bin/EXEC --input-file ./Input.yaml +p4 +traceroot ./ExecTraces ``` You might get a warning that Charm++ had to flush the log some number of times during the run. Flushing the log adds overhead to the execution and so affects timing measurements. While Charm++ has the ability to manually flush the log periodically (and therefore exclude the time it takes to flush the log from the trace), we have not yet implemented support for this. For short executable runs you can increase the log size by specifying `+logsize M` when running the executable. The default log size is 1,000,000 (1000000). Note that if you increase the log size too much you will run out of memory/RAM. For more information on runtime options to control trace data see the [Charm++ Projections manual](http://charm.cs.illinois.edu/manuals/html/projections/1.html). ### Visualizing Trace %Data In Projections By default Charm++ records entry method names by using the `PRETTY_FUNCTION` macro. This means entry method names include all class (parallel component) and action template parameter names, including any template parameters of the template parameters. This very quickly leads to incomprehensibly long names that are very difficult to read in the Projections interface. We include a basic Python executable to handle the majority of renames, but the executable supports additional basic (textual find-replace) and regular expression replacements via a JSON file. These additional replacements are useful for making executable-specific renames. The Python executable is `tools/CharmSimplifyTraces.py` and an example replacements file is `tools/CharmTraceReplacements.json`. See the [Charm++ Projections manual](http://charm.cs.illinois.edu/manuals/html/projections/2.html) for details. ## Profiling with Score-P {#profiling_with_scorep} See the [Score-P](https://www.vi-hps.org/projects/score-p/overview/overview.html) website for installation instructions specific to Score-P. To compile SpECTRE with Score-P you must invoke CMake with the environment variable `SCOREP_WRAPPER=off` (do NOT export this variable!) and the `scorep-` compiler wrappers. For example, ```sh SCOREP_WRAPPER=off cmake -DCMAKE_C_COMPILER=scorep-gcc \ -DCMAKE_CXX_COMPILER=scorep-g++ -DCMAKE_Fortran_COMPILER=scorep-gfortran \ -D CMAKE_BUILD_TYPE=Release -D ENABLE_PROFILING=ON \ -D BUILD_DOCS=OFF -D BUILD_PYTHON_BINDINGS=OFF $SPECTRE_HOME ``` where `$SPECTRE_HOME` points to your spectre source tree. You can then compile the executable you want to profile. When running the executable you will need to make sure Score-P has enough memory to be able to function properly. For the EvolveGhSingleBlackHole, Score-P needs 1.5GB of memory. To enable profiling, disable tracing, and use 1.5GB of memory for Score-P, set the environment variables ```sh SCOREP_ENABLE_PROFILING=1 \ SCOREP_ENABLE_TRACING=0 \ SCOREP_TOTAL_MEMORY=1536000000 ``` We also need to use a filter file to keep the data at all manageable and to avoid some currently not understood interaction between Score-P and our option parser. The profile is in `support/Profiling/ScoreP` and named `spectre.flt`. The final command should look something like: ```sh SCOREP_ENABLE_PROFILING=1 SCOREP_ENABLE_TRACING=0 \ SCOREP_TOTAL_MEMORY=1536000000 \ SCOREP_FILTERING_FILE=$SPECTRE_HOME/support/Profiling/ScoreP/spectre.flt \ mpirun -np 2 EvolveGhSingleBlackHole --input-file ./KerrSchild.yaml +ppn 91 ``` Depending on your profile, you might also need to increase the callpath depth by setting ```sh SCOREP_PROFILING_MAX_CALLPATH_DEPTH=150 ``` Once you've successfully run the executable you should have a directory like `scorep-20251006_1732_65976792745157592`. Please see the Score-P documentation for how to analyze the output. ================================================ FILE: docs/DevGuide/Protocols.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Protocols {#protocols} \tableofcontents # Overview of protocols {#protocols_overview} Protocols are a concept we use in SpECTRE to define metaprogramming interfaces. A variation of this concept is built into many languages, so this is a quote from the [Swift documentation](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html): > A protocol defines a blueprint of methods, properties, and other requirements > that suit a particular task or piece of functionality. The protocol can then > be adopted by a class, structure, or enumeration to provide an actual > implementation of those requirements. Any type that satisfies the requirements > of a protocol is said to conform to that protocol. You should define a protocol when you need a template parameter to conform to an interface. Here is an example of a protocol that is adapted from the [Swift documentation](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html): \snippet Utilities/Test_ProtocolHelpers.cpp named_protocol The protocol defines an interface that any type that adopts it must implement. For example, the following class conforms to the protocol we just defined: \snippet Utilities/Test_ProtocolHelpers.cpp named_conformance The class indicates it conforms to the protocol by (publicly) inheriting from `tt::ConformsTo`. Once you have defined a protocol, you can check if a class conforms to it using the `tt::assert_conforms_to` or `tt::conforms_to` metafunctions: \snippet Utilities/Test_ProtocolHelpers.cpp conforms_to Note that checking for protocol conformance is cheap, so you may freely use protocol conformance checks in your code. This is how you can write code that relies on the interface defined by the protocol: \snippet Utilities/Test_ProtocolHelpers.cpp using_named_protocol Checking for protocol conformance here makes it clear that we are expecting a template parameter that exposes the particular interface we have defined in the protocol. Therefore, the author of the protocol and of the code that uses it has explicitly defined (and documented!) the interface they expect. And the developer who consumes the protocol by writing classes that conform to it knows exactly what needs to be implemented. Note that the `tt::conforms_to` metafunction is SFINAE-friendly, so you can use it like this: \snippet Utilities/Test_ProtocolHelpers.cpp protocol_sfinae The `tt::conforms_to` metafunction only checks if the class _indicates_ it conforms to the protocol. Where SFINAE-friendliness is not necessary prefer the `tt::assert_conforms_to` metafunction that triggers static asserts with diagnostic messages to understand why the class does not conform to the protocol. We typically define protocols in a file named `Protocols.hpp` and within a `protocols` namespace, similar to how we write \ref DataBoxTagsGroup "tags" in a `Tags.hpp` file and within a `Tags` namespace. The file should be placed in the directory associated with the code that depends on classes conforming to the protocols. For example, the protocol `Named` in the example above would be placed in directory that also has the `greet` function. # Protocol users: Conforming to a protocol {#protocols_conforming} To indicate a class conforms to a protocol it (publicly) inherits from `tt::ConformsTo`. The class must fulfill all requirements defined by the protocol. The requirements are listed in the protocol's documentation. Any class that indicates it conforms to a protocol must have a unit test to check that it actually does. You can use the `tt::assert_conforms_to` metafunction for the test: \snippet Utilities/Test_ProtocolHelpers.cpp test_protocol_conformance # Protocol authors: Writing a protocol {#protocols_author} To author a new protocol you implement a class that provides a `test` metafunction and detailed documentation. The `test` metafunction takes a single template parameter (typically named `ConformingType`) and checks that it conforms to the requirements laid out in the protocol's documentation. Its purpose is to provide diagnostic messages as compiler errors to understand why a type fails to conform to the protocol. You can use `static_assert`s or trigger standard compiler errors where appropriate. See the protocols defined above for examples. Occasionally, you might be tempted to add template parameters to a protocol. In those situations, add requirements to the protocol instead and retrieve the parameters from the conforming class. The reason for this guideline is that conforming classes will always inherit from `tt::ConformsTo`. Therefore, any template parameters of the protocol must also be template parameters of their conforming classes, which means the protocol can just require and retrieve them. For example, we could be tempted to follow this antipattern: \snippet Utilities/Test_ProtocolHelpers.cpp named_antipattern However, instead of adding template parameters to the protocol we should add a requirement to it: \snippet Utilities/Test_ProtocolHelpers.cpp named_with_type Classes would need to specify the template parameters for any protocols they conform to anyway, if the protocols had any. So they might as well expose them: \snippet Utilities/Test_ProtocolHelpers.cpp person_with_name_type This pattern also allows us to check for protocol conformance first and then add further checks about the types if we wanted to: \snippet Utilities/Test_ProtocolHelpers.cpp example_check_name_type # Protocol authors: Testing a protocol {#protocols_testing} Protocol authors should provide a unit test for their protocol that includes an example implementation of a class that conforms to it. The protocol author should add this example to the documentation of the protocol through a Doxygen snippet. This gives users a convenient way to see how the author intends their interface to be implemented. # Protocols and C++20 "Constraints and concepts" {#protocols_and_constraints} A feature related to protocols is in C++20 and goes under the name of [constraints and concepts](https://en.cppreference.com/w/cpp/language/constraints). Every protocol defines a _concept_, but it defers checking its requirements to the unit tests to save compile time. In other words, protocols provide a way to _indicate_ that a class fulfills a set of requirements, whereas C++20 constraints provide a way to _check_ that a class fulfills a set of requirements. Therefore, the two features complement each other. Once C++20 becomes available in SpECTRE we can either gradually convert our protocols to concepts and use them as constraints directly if we find the impact on compile time negligible, or we can add a concept that checks protocol conformance the same way that `tt::conforms_to_v` currently does (i.e. by checking inheritance). ================================================ FILE: docs/DevGuide/PythonBindings.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Writing Python Bindings {#spectre_writing_python_bindings} \tableofcontents ## CMake and Directory Layout To allow users to analyze output from simulations and take advantage of SpECTRE's data structures and functions in python, bindings must sometimes be written. SpECTRE uses [pybind11](https://pybind11.readthedocs.io/) to aid with generating the bindings. The C++ code for the bindings should generally go in a `Python` subdirectory. For example, the bindings for the DataStructures library would go in `src/DataStructures/Python/`. SpECTRE provides the `spectre_python_add_module` CMake function to make adding a new python module, be it with or without bindings, easy. The python bindings are built only if `-D BUILD_PYTHON_BINDINGS=ON` is passed when invoking cmake (enabled by default). You can specify the Python version, interpreter and libraries used for compiling and testing the bindings by setting the `-D Python_EXECUTABLE` to an absolute path such as `/usr/bin/python3`. The function `spectre_python_add_module` takes as its first argument the module, in our case `DataStructures`. Optionally, a list of `SOURCES` can be passed to the CMake function. If you specify `SOURCES`, you must also specify a `LIBRARY_NAME`. A good `LIBRARY_NAME` is the name of the C++ library for which bindings are being built prefixed with `Py`, e.g. `PyDataStructures`. If the Python module will only consist of Python files, then the `SOURCES` option should not be specified. Python files that should be part of the module can be passed with the keyword `PYTHON_FILES`. Finally, the `MODULE_PATH` named argument can be passed with a string that is the path to where the module should be. For example, `MODULE_PATH "submodule0/submodule1/"` would mean the module is accessed from python using `import spectre.submodule0.submodule1.MODULE_NAME`. Here is a complete example of how to call the `spectre_python_add_module` function: \code spectre_python_add_module( Extra LIBRARY_NAME "PyExtraDataStructures" MODULE_PATH "DataStructures/" SOURCES Bindings.cpp MyCoolDataStructure.cpp PYTHON_FILES CoolPythonDataStructure.py ) \endcode The library that is added has the name `PyExtraDataStructures`. Make sure to call `spectre_python_link_libraries` for every Python module that compiles `SOURCES`. For example, \code spectre_python_link_libraries( PyExtraDataStructures PRIVATE ExtraDataStructures pybind11::module ) \endcode You may also call `spectre_python_add_dependencies` for Python modules that have `SOURCES`, e.g. \code spectre_python_add_dependencies( PyExtraDataStructures PyDataStructures ) \endcode Note that these functions will skip adding or configure any C++ libraries if the `BUILD_PYTHON_BINDINGS` flag is `OFF`. ## Writing Bindings Once a python module has been added you can write the actual bindings. You should structure your bindings directory to reflect the structure of the library you're writing bindings for. For example, say we want bindings for `DataVector` and `Matrix` then we should have one source file for each class's bindings inside `src/DataStructures/Python`. The functions that generate the bindings should be in the `py_bindings` namespace and have a reasonable name such as `bind_datavector`. There should be a file named `Bindings.cpp` which calls all the `bind_*` functions. The `Bindings.cpp` file is quite simple and should `include `, forward declare the `bind_*` functions, and then have a `PYBIND11_MODULE` function. For example, \code{.cpp} #include namespace py = pybind11; namespace py_bindings { void bind_datavector(py::module& m); } // namespace py_bindings PYBIND11_MODULE(_Pybindings, m) { py_bindings::bind_datavector(m); } \endcode Note that the library name is passed to `PYBIND11_MODULE` and is prefixed with an underscore. The underscore is important and the library name must be the same that is passed as `LIBRARY_NAME` to `spectre_python_add_module` (see above). The `DataVector` bindings serve as an example with code comments on how to write bindings for a class. There is also extensive documentation available directly from [pybind11](https://pybind11.readthedocs.io/). If you are binding a library full of similarly structured free functions, such as libraries in `src/PointwiseFunctions/`, you can bind all functions directly in the `Bindings.cpp` file to avoid unnecessary boilerplate code. See `src/PointwiseFunctions/GeneralRelativity/Python/Bindings.cpp` for an example. \note Exceptions should be allowed to propagate through the bindings so that error handling via exceptions is possible from python rather than having the python interpreter being killed with a call to `abort`. ## Testing Python Bindings and Code All the python bindings must be tested. SpECTRE uses the [unittest](https://docs.python.org/3/library/unittest.html) framework provided as part of python. To register a test file with CMake use the SpECTRE-provided function `spectre_add_python_test` passing as the first argument the test name (e.g. `"Unit.DataStructures.Python.DataVector"`), the file as the second argument (e.g. `Test_DataVector.py`), and a semicolon separated list of labels as the last (e.g. `"unit;datastructures;python"`). All the test cases should be in a single class so that the python unit testing framework will run all test functions on a single invocation to avoid startup cost. Below is an example of registering a python test file for bindings: \snippet tests/Unit/DataStructures/CMakeLists.txt example_add_pybindings_test Python code that does not use bindings must also be tested. You can register the test file using the `spectre_add_python_test` CMake function with the same signature as shown above. ## Using The Bindings See \ref spectre_using_python "Using SpECTRE's Python" ## Notes: - All python libraries are dynamic/shared libraries. - Exceptions should be allowed to propagate through the bindings so that error handling via exceptions is possible from python rather than having the python interpreter being killed with a call to `abort`. - All function arguments in Python bindings should be named using `py::arg`. See the Python bindings in `IO/H5/` for examples. Using the named arguments in Python code is optional, but preferred when it makes code more readable. In particular, use the argument names in the tests for the Python bindings so they are being tested as well. ## Guidelines for writing command-line interfaces (CLIs) - List all CLI endpoints in `support/Python/__main__.py`. - Follow the recommendations in the [click](https://click.palletsprojects.com/en/8.1.x/) documentation. - Split your code into free functions that know nothing about the CLI and can just as well be called independently from Python, and the CLI commands that call the functions. Test both. - Take only input files that the script operates on as positional arguments (like H5 data files or YAML input files) and everything else as options. - Choose option names and shorthands consistent with other CLI endpoints in the repository. For example, H5 subfile names are specified with '--subfile-name' / '-d' and output files are specified with '--output' / '-o'. Look at other CLI endpoints before making choices for option names. - Never read or write files to or from "default" locations. Instead, take all input files as arguments and write all output files to locations specified explicitly by the user. This is important so users are not afraid of moving and renaming files, and are not left wondering where the script wrote its output. Examples: - Don't try to read a file like "spectre.out" from the current directory just because it might be there by convention. Instead, add an argument or option like `--out-filename` so the user can specify it. - Don't write a file like "plot.pdf" to the current directory without telling the user. Instead, add an option like `--output` / `-o` for the user to specify explicitly so they know exactly where output is written to. - Operate on files instead of directories when possible. For example, prefer taking many H5 volume data files as arguments instead of the directory that contains them. This helps with operating on H5 files in segments or other subdirectory structures. Passing many files to a script is easy for the user by using a glob (note: don't take the glob as a string argument, take the expanded list of files directly using `click.argument(..., nargs=-1, type=click.Path(...), required=True)`). Note that Click recommends to avoid `required=True` here but to [gracefully degrade to a noop](https://click.palletsprojects.com/en/8.1.x/arguments/#variadic-arguments) instead, but that's confusing for the user. - Never overwrite or delete files without prompting the user or asking them to run with `--force`. - When the user did not specify an option, print possible values for it and return instead of raising an exception. For example, print the subfile names in an H5 file if no subfile name was specified. This allows the user to make selections incrementally. - When the user did not specify an output file, write the output to `sys.stdout` if possible instead of raising an exception. This allows the user to use pipes and chain commands if they want, or add a quick `-o` option to write to a file. - Always use Python's `logging` module over plain `print` statements. This allows the user to control the verbosity. ================================================ FILE: docs/DevGuide/QuickStartDockerVSCode.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Code development quick-start with Docker and Visual Studio Code {#dev_guide_quick_start_docker_vscode} \tableofcontents This page describes how to get started developing SpECTRE on Mac, Linux, or Windows using [Docker](https://docker.com) and the [Visual Studio Code](https://code.visualstudio.com) editor. This is a particularly quick way to get up and running with SpECTRE code development, though of course not the only way. If you prefer setting up your development environment differently, we suggest you read the \ref installation "Installation" page. If you would like to jump right into a working development environment, read on! ## Fork the SpECTRE repository on GitHub The SpECTRE code lives on GitHub in the [sxs-collaboration/spectre](https://github.com/sxs-collaboration/spectre) repository. Developers work on their own copy (or ["fork"](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-forks)) of the repository and contribute back to [sxs-collaboration/spectre](https://github.com/sxs-collaboration/spectre) through [pull requests](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests). Fork the repository to your own account: - [Fork sxs-collaboration/spectre on GitHub](https://github.com/sxs-collaboration/spectre/fork) ## Clone the SpECTRE repository to your computer To work on SpECTRE code you will need a local copy (or "clone") of the repository on your computer. We use SSH to communicate with GitHub, so you need to set up your SSH keys first. Follow GitHub's instructions to generate an SSH key and add it to your GitHub account: - [Generating an SSH key and adding to to GitHub](https://docs.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent) Now you can download the repository via SSH. Navigate to **your fork** of the SpECTRE repository (i.e. the repository at the URL https://github.com/YOURNAME/spectre). Follow GitHub's instructions to clone the repository to your computer, selecting the SSH option: - [Cloning a repository](https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository) \note If you clone the SpECTRE repository using HTTPS instead of SSH, you won't be able to push any changes you make to your fork. You'll still be able to make local changes on your computer, but you won't be able to share your changes with anybody. ## Install Docker On your computer you will need Docker to run the containerized development environment. Install and start Docker: - [Get Docker](https://docs.docker.com/get-docker/) If you're new to Docker, you can read through Docker's [Getting started](https://docs.docker.com/get-started/) documentation to learn about their basic concepts. We will use Docker to download and jump into a prebuilt development environment that has everything installed to compile and run SpECTRE. ## Install Visual Studio Code We will use the Visual Studio Code editor to jump into the containerized development environment, edit code, compile executables and run them. Download and install Visual Studio Code: - [Get Visual Studio Code](https://code.visualstudio.com) Microsoft maintains [extensive documentation](https://code.visualstudio.com/docs) for Visual Studio Code that you can read to get started using the editor. We recommend you take a look through the [Tips and Tricks](https://code.visualstudio.com/docs/getstarted/tips-and-tricks) to get an idea of the editor's features. ## Install the "Remote - Containers" extension Visual Studio Code's "Remote - Containers" extension lets you run the editor in a Docker container. Install the extension: - [Install the "Remote - Containers" extension](vscode:extension/ms-vscode-remote.remote-containers) ## Open the SpECTRE repository in Visual Studio Code Now open the SpECTRE repository that you have cloned to your computer in Visual Studio Code. Depending on your operating system you can select `File > Open`, type `Cmd+O` (macOS) or `Ctrl+O` (Linux or Windows), drag the repository folder onto the Visual Studio Code icon or any other means to open the folder in Visual Studio Code. Now is also time to learn how to use the single most important tool in Visual Studio Code, the command palette. Try it now: Hit `Cmd+P` (macOS) or `Ctrl+P` (Linux or Windows) and start typing the name of any file, for example `QuickStartDockerVSCode.md`. Hit `Enter` to open the file. This is how you can quickly open any file in the repository. Note that the search is fuzzy, so you can type any few letters in the path to the file. In addition to opening files, you can hit `Cmd+Shift+P` (macOS) or `Ctrl+Shift+P` (Linux or Windows) and type the name of any command that Visual Studio Code supports (or parts of it), for example `Preferences: Open User Settings`. ## Reopen the SpECTRE repository in the development container Open the command palette by hitting `Cmd+Shift+P` (macOS) or `Ctrl+Shift+P` (Linux or Windows) and run the command `Remote-Containers: Reopen in container` by starting to type a few letters of this command and then hitting `Enter`. Visual Studio Code will download and run the container and drop you into a fully configured environment where you can proceed to compile and run SpECTRE. This may take a few minutes so just let VSCode run and do it's thing. There may be a `show logs` button somewhere on your screen if you're interested in the details of the download. If you are interested to learn more about how this feature works you can read through the [VS Code documentation on remote containers](https://code.visualstudio.com/docs/remote/containers) and inspect the `.devcontainer/devcontainer.json` file that's included in the SpECTRE repository. \note If you look into the `.devcontainer/devcontainer.json` file, you'll see we are using the `sxscollaboration/spectre:dev` container. We also offer other containers. The `sxscollaboration/spectre:ci` container has more compilers and the `sxscollaboration/spectre:demo` container has a couple pre-built executables. If you'd like to build in a different container, just switch the image name in the json file and reopen in the new container. ## Configure, compile and run SpECTRE With Visual Studio Code running in the development container you can now configure, compile and run SpECTRE with no additional setup. Hit `Cmd+Shift+P` (macOS) or `Ctrl+Shift+P` (Linux or Windows) to open the command palette and run the command `CMake: Select a Kit`. You should see a `Default` kit available. Then, open the command palette again, run `CMake: Select Variant`, and select either `Release` or `Debug`. For this tutorial we recommend using `Release`. If you want to actually develop SpECTRE, the `Debug` option would be better. This specific kit uses `clang` to build SpECTRE along with the Python bindings. Finally, open the command palette once more and run `CMake: Configure` which will now actually run CMake. It will set up a build directory. You can open Visual Studio Code's [integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal) with the keyboard shortcut ``Ctrl+` `` and navigate to the newly created build directory to inspect it: ``` cd build-Default-Debug ``` For compiling and running SpECTRE you can either use Visual Studio Code's CMake integration by looking up further commands in the command palette, or use the terminal. We will be using the terminal from now on. Try compiling an executable, for example: ``` make -j4 ExportCoordinates3D ``` Once the executable has compiled successfully you can try running it: ``` ./bin/ExportCoordinates3D \ --input-file $SPECTRE_HOME/tests/InputFiles/ExportCoordinates/Input3D.yaml ``` This executable produced a volume data file in the `build-Default-Debug` directory that we can visualize in ParaView. Generate an XMF file from the volume data file that ParaView understands: ``` ./bin/spectre generate-xdmf \ --file-prefix ExportCoordinates3DVolume --subfile-name element_data \ --output ExportCoordinates3DVolume ``` Since the build directory is shared with the host file system you can now open ParaView on your computer and load the generated XMF file as described in the \ref tutorial_visualization "visualization tutorial". \note If you wanted to run this executable again, you'd have to first remove the existing `.h5` files, otherwise an error will occur. ## Edit and contribute code to SpECTRE with VS Code You are now ready to code! The other \ref dev_guide "dev guides" will teach you how to write SpECTRE code. Return to the [Visual Studio Code documentation](https://code.visualstudio.com/docs) to learn more about editing code with Visual Studio Code. In particular, the Visual Studio Code documentation can teach you how to use Git to commit your code changes to your repository: - [Git support in Visual Studio Code](https://code.visualstudio.com/docs/editor/versioncontrol#_git-support) SpECTRE code development follows a pull-request model. You can learn more about this process in our contributing guide: - [Contributing to SpECTRE through pull requests](https://spectre-code.org/contributing_to_spectre.html#pull-requests) Visual Studio Code can also help you create and review pull requests: - [Working with pull requests in VS Code](https://code.visualstudio.com/docs/editor/github#_pull-requests) ## Interactively debug a SpECTRE test with VS Code To track down an issue with your code it can be very useful to interactively debug it. First, make sure you have written a test case where the issue occurs. If you have not written a test yet, this is a great time to do it. Refer to the \ref writing_unit_tests "Writing Unit Tests" dev guide to learn how to write tests. To launch the interactive debugger, hit `Cmd+Shift+P` (macOS) or `Ctrl+Shift+P` (Linux or Windows) to open the command palette, run the command `CMake: Set Debug Target` and select your test executable (e.g. `Test_LinearOperators`) Then run the command `CMake: Debug`. The test executable will compile, run and stop on any breakpoints. Follow the Visual Studio Code documentation to learn how to set breakpoints in your code and inspect the state of your variables: - [Debug actions in VS Code](https://code.visualstudio.com/docs/editor/debugging#_debug-actions) ## Real-time collaboration with Live Share You can use the [Live Share](https://docs.microsoft.com/en-us/visualstudio/liveshare/) extension to work together with others and edit code simultaneously. Live Share can be very useful to debug code together. Follow these instructions to share a link to your current Visual Studio Code workspace: - [Live Share Quickstart: Share your first project](https://docs.microsoft.com/en-us/visualstudio/liveshare/quickstart/share) ## Tips and tricks - The [**GitLens extension**](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) is very useful to browse your repository. Select the "Source Control" icon and explore the various panels. - When you build the **documentation** (e.g. with `make doc`), you can open it in a web server within VS Code: ``` python3 -m http.server -d docs/html ``` The web server launches on port 8000 by default, which is being forwarded outside the container, so you can just open http://127.0.0.1:8000 in your browser to view the documentation. - Instead of working in the Docker container, you can use the [Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) extension to **work on a remote machine** such as your local supercomputing cluster. Ask the cluster administrators or users for suggestions concerning installing and running SpECTRE on the particular supercomputer. - You can work with **Jupyter notebooks in Visual Studio Code**. First, install Jupyter and all other Python packages you want to work with in the container: ``` pip3 install jupyter matplotlib ``` Any `.ipynb` notebook files you create or open will be displayed in VS Code's notebook editor. This is very useful for quickly plotting data from SpECTRE runs or using SpECTRE's Python bindings. Refer to the [VS Code documentation on Jupyter support](https://code.visualstudio.com/docs/python/jupyter-support) for more information. - Docker can quickly use up a lot of disk space. From time to time you can "prune" unneeded images and containers to reclaim disk space: - [Prune unused Docker objects](https://docs.docker.com/config/pruning/) When pruning containers, make sure no data is deleted that you care about! ================================================ FILE: docs/DevGuide/RedistributingGridpoints.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Redistributing Gridpoints {#redistributing_gridpoints} \tableofcontents ## Introduction The simplest way to construct a volume map from two parameterized surfaces is by linearly interpolating between them: \f[\vec{x}(\xi,\eta,\zeta) = \frac{1-\zeta}{2}\vec{\sigma}_-(\xi,\eta)+ \frac{1+\zeta}{2}\vec{\sigma}_+(\xi,\eta)\f] In the above example, each surface \f$\vec{\sigma}_+\f$ and \f$\vec{\sigma}_-\f$ is parameterized using the logical coordinates \f$\xi\f$ and \f$\eta\f$, and a third coordinate \f$\zeta\in[-1,1]\f$ is used to interpolate between them. We then distribute gridpoints on this volume by specifying values of the coordinates \f$\xi,\eta,\f$ and \f$\zeta\f$ at which the gridpoints are located. In SpECTRE these values are the locations of the quadrature nodes. The distribution of the gridpoints throughout the volume depends on the parameterization used, and the simplest choice of parameterization does not necessarily lead to the best gridpoint distribution. In this section we discuss situations in which there exist better parameterizations than those obtained by linear interpolation. ## Generalized Logical Coordinates In each of the following examples, we will obtain functions \f$\Xi(\xi), \mathrm{H}(\eta),\f$ and \f$\mathrm{Z}(\zeta)\f$ that give better gridpoint distributions than using the logical coordinates alone. Where possible, we will write the reparameterized map such that the functional form of the map is unchanged when replacing \f$\Xi\f$ with \f$\xi\f$, etc. We therefore refer to \f$\Xi, \mathrm{H},\f$ and \f$\mathrm{Z}\f$ as the *generalized logical coordinates*, as they can also refer to the logical coordinates \f$\xi, \eta,\f$ and \f$\zeta\f$ themselves, when the transformation is the identity. ## Equiangular Maps The mapping for a cubed sphere surface can be easily obtained by taking points that lie on each face of a cube and normalizing them such that they lie on the sphere: \f[\vec{\sigma}_{+z}(\xi,\eta) = \frac{1}{\sqrt{1 + \xi^2 + \eta^2}} \begin{bmatrix} \xi\\ \eta\\ 1\\ \end{bmatrix}\f] In the above example the parameterization used for the upper \f$+z\f$ surface of the cube is linear in \f$\xi\f$ and \f$\eta\f$. However, distances measured on the surface of the sphere are not linear in \f$\xi\f$ and \f$\eta\f$. To see this, one may compute \f$g_{\xi\xi} = |\frac{\partial\vec{x}}{\partial\xi}|^2\f$ to see how distances are measured in terms of \f$\xi\f$: \f[g_{\xi,\xi}|_{\eta=0} = \frac{1}{(1+\xi^2)^2}\f] This metric term demonstrates that a gridpoint distribution uniform in \f$\xi\f$ will end up being compressed near \f$\xi=\pm1\f$. Suppose we reparameterized the surface using the generalized logical coordinate \f$\Xi\in[-1,1]\f$. We would find: \f[g_{\xi,\xi}|_{\eta=0} = \frac{\Xi'^2}{(1+\Xi^2)^2}\f] Ideally, we would like distances measured along a curvilinear surface to be linear in the logical coordinates. We solve the differential equation and obtain: \f[\Xi = \tan(\xi\pi/4)\f] These two parameterizations of the cubed sphere are known as the *equidistant* and *equiangular* central projections of the cube onto the sphere. We now summarize their usage in SpECTRE CoordinateMaps that have `with_equiangular_map` as a specifiable parameter: In the case where `with_equiangular_map` is `true`, we have the equiangular coordinates \f[\textrm{equiangular xi} : \Xi(\xi) = \textrm{tan}(\xi\pi/4)\f] \f[\textrm{equiangular eta} : \mathrm{H}(\eta) = \textrm{tan}(\eta\pi/4)\f] with derivatives \f[\Xi'(\xi) = \frac{\pi}{4}(1+\Xi^2)\f], \f[\mathrm{H}'(\eta) = \frac{\pi}{4}(1+\mathrm{H}^2)\f] In the case where `with_equiangular_map` is `false`, we have the equidistant coordinates \f[ \textrm{equidistant xi} : \Xi = \xi\f] \f[ \textrm{equidistant eta} : \mathrm{H} = \eta\f] with derivatives: \f[\Xi'(\xi) = 1\f] \f[\mathrm{H}'(\eta) = 1\f] ## Projective Maps The mapping for any convex quadrilateral can be obtained by bilinearly interpolating between each vertex \f$\vec{x}_1, \vec{x}_2, \vec{x}_3\f$ and \f$\vec{x}_4\f$: \f[\vec{x}(\xi,\eta) = \frac{(1-\xi)(1-\eta)}{4}\vec{x}_1+ \frac{(1+\xi)(1-\eta)}{4}\vec{x}_2+ \frac{(1-\xi)(1+\eta)}{4}\vec{x}_3+ \frac{(1+\xi)(1+\eta)}{4}\vec{x}_4 \f] In the case of a trapezoid where two of the sides are parallel, it is appropriate to linearly interpolate along the parallel sides. However, linearly interpolating between the two bases results in a less than ideal gridpoint distribution. This happens in the case of SpECTRE's Frustum, where the logical coordinate \f$\zeta\f$ interpolates between the bases. \image html BilinearVProjective.png "Comparison of mappings. (Noah Veltman)" As seen in Veltman's [Warp-Off] (https://bl.ocks.org/veltman/8f5a157276b1dc18ce2fba1bc06dfb48), linear interpolation between the two bases results in a uniformly spaced grid between the bases of the frustum. This causes elements near the smaller base to be longer in the direction normal to the base, and elements near the larger base to be shorter in the direction normal to the base. We desire elements that have roughly equal sizes along each of their dimensions. We can redistribute the gridpoints in the \f$\zeta\f$ direction using a projective map, moving more gridpoints toward the smaller base. We can also see in the figure above that a projective map can be applied incorrectly, leaving elements distorted at the opposite end. From this we can see that it is important to control the degree of projection. We adapt a technique from projective geometry to obtain the desired grid spacing. The heart of the method lies in the fact that objects arranged in a line at equal distances from one another will appear to converge as they approach the horizon. \image html ProjectionOntoPlane.png "Controlling the degree of projection." The above diagram demonstrates how to obtain a nonlinearly parameterized object (seen in red) from a linearly parameterized one (seen in purple). This is done by lifting the linearly parameterized object into a higher spatial dimension \f$w\f$, such that its projection onto the plane remains unchanged. As seen above, \f$w_{\delta}\f$ controls the degree of projection of one end of the object (purple) into a higher spatial dimension \f$w\f$. In projective geometry, these points that exist in the higher dimension are labeled with *homogeneous coordinates* \f$\tilde{x}, \tilde{y}, \tilde{z}, w\f$, to distinguish them from the Cartesian coordinates that label points that exist on the \f$w=1\f$ hyperplane, \f$x,y,z\f$. The resulting grid (seen in red) is obtained by projecting back into the \f$w=1\f$ hyperplane. The Cartesian coordinates are obtained by dividing each homogeneous coordinate of the linearly parameterized object by its respective \f$w\f$ coordinate value. The parametric equation for the purple object seen above in homogeneous coordinates is: \f[\begin{bmatrix}\tilde{x}\\\tilde{y}\\\tilde{z}\\w\\\end{bmatrix}= \frac{1-\zeta}{2}\begin{bmatrix}x_1\\y_1\\z_1\\1\\\end{bmatrix}+ \frac{1+\zeta}{2}\begin{bmatrix}x_2w_{\delta}\\y_2w_{\delta}\\ z_2w_{\delta}\\w_{\delta}\\\end{bmatrix}\f] The equation for the projected red object in Cartesian coordinates is obtained by dividing by w: \f[\vec{x}(\zeta) = \frac{1}{w(\zeta)} \begin{bmatrix} \tilde{x}(\zeta)\\ \tilde{y}(\zeta)\\ \tilde{z}(\zeta)\\ \end{bmatrix}\f] We wish to cast our parametric equation for the surface into the form: \f[\vec{x}(\zeta) = \frac{1-\mathrm{Z}}{2}\vec{x}_1 + \frac{1+\mathrm{Z}}{2}\vec{x}_2\f] for some appropriate choice of auxiliary variable `projective_zeta` \f$ = \mathrm{Z}(\zeta)\f$. We would also like for \f$\mathrm{Z}\f$ to reduce to \f$\zeta\f$ when \f$w_{\delta}\ = 1\f$. Defining the auxiliary variables \f$w_{\pm} := w_{\delta}\pm 1\f$, the desired \f$\mathrm{Z}(\zeta)\f$ is given by: \f[\mathrm{Z} = \frac{w_- + \zeta w_+} {w_+ + \zeta w_-}\f] with derivative: \f[\mathrm{Z}' = \frac{\partial\mathrm{Z}}{\partial \zeta} = \frac{w_+^2 - w_-^2}{(w_+ + \zeta w_-)^2}\f] For SpECTRE CoordinateMaps that have `projective_scale_factor` as a specifiable parameter, the value \f$w_{\delta} = 1\f$ should be supplied in case the user does not want to use projective scaling. If `auto_projective_scale_factor` is set to `true`, the map will compute a value of \f$w_{\delta}\f$ that is appropriate. ================================================ FILE: docs/DevGuide/StaticAnalysis.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Static Analysis Tools {#static_analysis_tools} \tableofcontents SpECTRE code is frequently run through the [Clang Tidy](http://clang.llvm.org/extra/clang-tidy/) static analyzer. Since analyzing a single source file can take over half a minute it is generally not advisable to run clang-tidy over the entire code base. If CMake isn't finding clang-tidy, make sure clang-tidy is installed and that you have chosen clang as your compiler. To analyze a single source file run, for example `make clang-tidy FILE=/path/to/source/src/DataStructures/DataVector.cpp`. To analyze the entire code base run `make clang-tidy-all`. To analyze all changed C++ source files in the commits from `FIRST_HASH` to `HEAD`, run `make clang-tidy-hash HASH=FIRST_HASH`. ================================================ FILE: docs/DevGuide/TensorExpressions.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Writing Tensor Equations with TensorExpressions {#writing_tensorexpressions} \tableofcontents SpECTRE's `TensorExpression`s interface allows you to write tensor equations in SpECTRE in C++ with syntax that resembles tensor index notation. To use it, simply add this include to the top of your file: ``` #include "DataStructures/Tensor/Tensor.hpp" ``` The following guide assumes a basic understanding of the `Tensor` class and \ref tnsr "tnsr" type aliases. **RHS** refers to the right hand side expression that we wish to compute and **LHS** refers to the resulting left hand side tensor that stores the result of computing the RHS expression. # Syntax {#te_syntax} `TensorExpression`s are arithmetic expressions of `Tensor`s that can be evaluated using `tenex::evaluate`. Terms used in the expression may be `Tensor`s or numbers (see [supported types](#te_data_type_support)). As a simple example of how `TensorExpression`s are used, if you would like to raise the index of some `Tensor` `R` with some inverse spacetime metric `Tensor` `g`, i.e. \f$R^c{}_b = R_{ab} g^{ac}\f$, you can compute this with `TensorExpression`s by doing: \snippet Expressions/Test_Examples.cpp te_example_evaluate_lhs_return where `R_up`, `R`, and `g` are rank 2 spacetime `Tensor`s and the `ti::*` variables are `TensorIndex`s representing generic tensor indices. Here is a breakdown of the different parts of this line: - the RHS expression to compute is the argument to \ref tenex::evaluate "evaluate": `R(ti::a, ti::b) * g(ti::A, ti::C)` - the result LHS `Tensor` is `R_up` - the LHS `Tensor`'s indices are the template arguments to \ref tenex::evaluate "evaluate": `ti::C, ti::b` The LHS \ref ::Symmetry "Symmetry" will be deduced from the RHS tensors' symmetries and order of operations. Alternatively, if you already have a LHS `Tensor` variable, you can pass it into the following \ref tenex::evaluate "evaluate" overload, where the LHS `Tensor` provided will be assigned to the result of the RHS expression: \snippet Expressions/Test_Examples.cpp te_example_evaluate_lhs_arg Note that to use this \ref tenex::evaluate "evaluate" overload, the LHS `Tensor` does not need to be previously sized unless the data type is a Blaze vector type (e.g. `DataVector`) *and* the RHS expression contains no `Tensor` terms (see [example](#te_assigning_to_a_number) where sizing is necessary). This overload is useful in a couple cases: - [Specifying the LHS symmetry](#te_specify_lhs_symmetry): One advantage of this overload is that it uses the \ref ::Symmetry "Symmetry" of the provided LHS tensor instead of deducing it from the RHS expression. This enables you to specify the LHS symmetry in cases where the previous \ref tenex::evaluate "evaluate" overload does not deduce the one you want. While the LHS index order in this example (`ti::C, ti::b`) could theoretically be deduced from the index types of `R_up`, we still require specifying them because this isn't the case for all equations and we would like to have a unified interface. See [this example](#te_specify_lhs_symmetry), which demonstrates a case where you might want to specify the LHS symmetry and where the LHS index order would not be deducible. - **[Using spatial and time indices on LHS spacetime indices](#te_spatial_time_index_lhs)** ## Tensor indices {#te_tensor_indices} `TensorIndex`s represent generic tensor indices and are supplied as comma-separated lists in two places: - in parentheses for each tensor in the RHS expression - in the template parameters of \ref tenex::evaluate "evaluate" to specify the order of the LHS result tensor's indices. Each `TensorIndex` takes the form `ti::*` where `*` is a letter that encodes index properties: - Uppercase letters denote upper indices and lowercase letters denote lower indices - Letters `A/a - H/h` indicate spacetime indices, `I/i - N/n` indicate spatial indices, and `T/t` indicates a concrete time index. This is what is currently defined, but more spatial and spacetime indices (letters) can easily be added if needed. Note that there is no precedence or difference between the indices of some type, e.g. `ti::a`, `ti::b`, ... `ti::h` are equivalent The properties of each `TensorIndex` and the `Tensor`'s indices (typelist of \ref SpacetimeIndex "TensorIndexType"s) must be compatible: - valences (being upper or lower indices) must match - if a `Tensor`'s index is spacetime, you can use a spacetime `TensorIndex`, spatial `TensorIndex`, or concrete time `TensorIndex` - if a `Tensor`'s index is spatial, you must use a spatial `TensorIndex` To demonstrate correct and incorrect usage, let's say we have tensors \f$R_{ab}\f$ (two spacetime indices, e.g. type \ref tnsr "tnsr::ab") and \f$S_{ij}\f$ (two spatial indices, e.g. type \ref tnsr "tnsr::ij"): ``` R(ti::c, ti::d) // OK R(ti::c, ti::k) // OK, can use spatial TensorIndex on spacetime index R(ti::c, ti::t) // OK, can use time TensorIndex on spacetime index R(ti::c, ti::D) // ERROR, ti::D is upper but the 2nd index is lower S(ti::j, ti::k) // OK S(ti::a, ti::k) // ERROR, can't use spacetime TensorIndex on a spatial index S(ti::j, ti::t) // ERROR, can't use time TensorIndex on a spatial index ``` # Examples {#te_examples} ## Basic operations {#te_basic_operations} In the following examples: - `R` is type \ref tnsr "tnsr::ab" - `S` is type \ref tnsr "tnsr::ab" - `T` is type \ref Scalar "Scalar" - `U` is type \ref tnsr "tnsr::Ab" - `V` is type \ref tnsr "tnsr::aBC" - `G` is type \ref tnsr "tnsr::a" - `H` is type \ref tnsr "tnsr::A" ### Addition and subtraction {#te_addition_and_subtraction} \f$L_{ab} = R_{ab} + S_{ba}\f$ \snippet Expressions/Test_Examples.cpp te_example_addition \f$L = 1 - T\f$ \snippet Expressions/Test_Examples.cpp te_example_subtraction ### Contraction of a single tensor {#te_contraction} \f$L = U^{a}{}_{a}\f$ \snippet Expressions/Test_Examples.cpp te_example_contraction_to_scalar \f$L^b = V_{a}{}^{ba}\f$ \snippet Expressions/Test_Examples.cpp te_example_contraction_to_tensor ### Inner and outer products {#te_products} \f$L = G_a H^{a}\f$ \snippet Expressions/Test_Examples.cpp te_example_inner_product \f$L_{cb} = T G_a G_c U^{a}{}_{b}\f$ \snippet Expressions/Test_Examples.cpp te_example_inner_and_outer_product ### Division {#te_division} \f$L_a = \frac{G_a}{2}\f$ \snippet Expressions/Test_Examples.cpp te_example_division_by_number \f$L_{ba} = \frac{R_{ab}}{T}\f$ \snippet Expressions/Test_Examples.cpp te_example_division_by_tensor \f$L = \frac{5}{U^{a}{}_{a} + 1}\f$ \snippet Expressions/Test_Examples.cpp te_example_division_by_tensor_expression ### Square root {#te_square_root} \f$L = \sqrt{T}\f$ \snippet Expressions/Test_Examples.cpp te_example_square_root_tensor \f$L = \sqrt{G_a H^a}\f$ \snippet Expressions/Test_Examples.cpp te_example_square_root_inner_product ## More features {#te_more_features} ### Specifying the LHS symmetry {#te_specify_lhs_symmetry} When using the \ref tenex::evaluate "evaluate" overload that returns the LHS `Tensor`, the \ref ::Symmetry "Symmetry" of the LHS `Tensor` will be deduced from the RHS expression. However, in some cases the deduced LHS symmetry may not be what you want. To specify it yourself, you can pass your LHS `Tensor` (that has the desired \ref ::Symmetry "Symmetry") to the \ref tenex::evaluate "evaluate" overload that takes the LHS `Tensor` as the first argument. For example, if we have \f$L_{ab} = R_a R_b\f$, the indices of \f$L\f$ are symmetric. However, when we do: \snippet Expressions/Test_Examples.cpp te_example_deduced_lhs_symmetry_fail the type of `L` will be \ref tnsr "tnsr::ab" because it is not known at compile time that the two vectors in the product are the same. To override the deduced symmetry and make it a symmetric result, we can create a \ref tnsr "tnsr::aa" and pass it into the other overload: \snippet Expressions/Test_Examples.cpp te_example_deduced_lhs_symmetry_force ### Assigning to a number {#te_assigning_to_a_number} You can assign a number (e.g. `double`) to a `Tensor` of any rank to fill all components with that value, e.g. \f$L_{ab} = -1\f$. How you do that is slightly different depending on the underlying data type of your `Tensor`: - When your `Tensor`'s data type is a number type (e.g. `double`, `std::complex`): \snippet Expressions/Test_Examples.cpp te_example_assign_number_to_tensor_of_numbers - When your `Tensor`'s data type is a Blaze vector type (e.g. `DataVector`, `ComplexDataVector`), the `Tensor` must first be sized before calling \ref tenex::evaluate "evaluate" because there is no sizing information (from a `Tensor` component) in the RHS expression: \snippet Expressions/Test_Examples.cpp te_example_assign_number_to_tensor_of_vectors See [supported number types](#te_data_type_support) for the data types that the RHS number can be. ### Using spatial and time indices on RHS spacetime indices {#te_spatial_time_index_rhs} If a `Tensor` has spacetime indices, you can use generic spatial indices and concrete time indices to refer to a subset of the components, as we see in literature. Lapse \f$\alpha\f$ computed from the spacetime metric \f$g_{ab}\f$ and shift \f$\beta^i\f$: \f$\alpha = \sqrt{\beta^i g_{it} - g_{tt}}\f$ \snippet Expressions/Test_Examples.cpp te_example_rhs_spatial_and_time_indices ### Using spatial and time indices on LHS spacetime indices {#te_spatial_time_index_lhs} Related to the previous example, you can also use generic spatial indices and concrete time indices for the spacetime indices of the LHS `Tensor` to assign subsets of the LHS `Tensor`'s components. Spacetime metric \f$g_{ab}\f$ computed from the lapse \f$\alpha\f$, shift \f$\beta^i\f$, and spatial metric \f$\gamma_{ij}\f$: \f$g_{tt} = -\alpha^2 + \beta^m \beta^n \gamma_{mn}\f$ \f$g_{ti} = \gamma_{mi} \beta^m\f$ \f$g_{ij} = \gamma_{ij}\f$ \snippet Expressions/Test_Examples.cpp te_example_lhs_spatial_and_time_indices \parblock \note The above example is for demonstration purposes only. In practice, you would want to avoid repeating computing the reused quantity \f$\beta^i \gamma_{ij}\f$ by e.g. storing the result of the reused quantity in another variable. \endparblock ### Using the LHS Tensor in the RHS expression {#te_using_lhs_tensor_in_rhs} You can use the LHS `Tensor` in the RHS expression to emulate operations like `+=`, `*=`, etc. For example, say you would like to emulate the following: ``` // pseudocode L_ab = R_ab L_ab += 2.0 * S_ba ``` You can emulate the `+=` operation by calling \ref tenex::update "update" instead of \ref tenex::evaluate "evaluate": ``` auto L = tenex::evaluate(R(ti::a, ti::b)); // use the LHS tensor in the RHS tenex::update( make_not_null(&L), L(ti::a, ti::b) + 2.0 * S(ti::b, ti::a)); ``` One limitation is that when using the LHS tensor in the RHS expression, the LHS tensor's index order must be the same on the LHS and RHS. This means that the order of the `TensorIndex` template parameters of \ref tenex::update "update" must match the order of the `TensorIndex` arguments in the parentheses that come after the LHS `Tensor` in the RHS expression. For example, the following is not allowed and will yield a runtime error: ``` // ERROR: index order for L on LHS and RHS is not the same tenex::update( make_not_null(&L), L(ti::b, ti::a) + 2.0 * S(ti::b, ti::a)); ``` \parblock \note It is not advised to use very large RHS expressions with \ref tenex::update "update" because runtime performance does not scale well as the number of operations gets very large. This is because \ref tenex::evaluate "evaluate" breaks up large expressions into smaller ones, but \ref tenex::update "update" cannot. One way around this is to break up the expression and use more than one call to \ref tenex::update "update". \endparblock # Compile time math checks {#te_compile_time_math_checks} For all operations, mathematical legality is checked at compile time. The compiler will catch what is not sound to write on paper, which includes things like no repeated indices, can't divide by a tensor with rank > 0, and that spatial dimensions, frames, valences, index types (spatial or spacetime), and ranks of tensors match where they should. Here are some examples of illegal math that the compiler will catch: ``` tnsr::ab R{}; tnsr::ab S{}; tnsr::ab T{}; tnsr::AB G{}; // ERROR: LHS and RHS indices don't match auto result1 = tenex::evaluate(R(ti::a, ti::b) + S(ti::a, ti::b)); // ERROR: Can't add Tensors with different indices auto result2 = tenex::evaluate(R(ti::a, ti::b) + S(ti::a, ti:c)); // ERROR: Repeated index in the RHS auto result3 = tenex::evaluate(R(ti::a, ti::b) * S(ti::a, ti::c)); // ERROR: Can't add Tensors with different Frame types auto result4 = tenex::evaluate(R(ti::a, ti::b) + T(ti::a, ti::b)); // ERROR: Can't contract indices with different number of spatial dimensions auto result5 = tenex::evaluate(R(ti::a, ti::b) * G(ti::A, ti::B)); // ERROR: Can't divide by a rank > 0 Tensor auto result6 = tenex::evaluate(R(ti::a, ti::b) / S(ti::a, ti::b)); ``` # Support for data types and operations {#te_data_type_and_op_support} ## Data types {#te_data_type_support} The RHS expression may contain a mixture of number terms and `Tensor` terms, e.g. `0.5 * T(ti::a)`. Currently supported data types for number terms: - `double` - `std::complex` Currently supported underlying data types for `Tensor` terms: - `double` - `std::complex` - `DataVector` - `ComplexDataVector` Support for more types can be added. ## Operations {#te_operation_support} It's possible for terms in the RHS expression to have different data types. The mixture of `double`s and `Tensor`s is shown in the [subtraction example](#te_addition_and_subtraction) and the [division examples](#te_division). It's also possible for terms to be a mixture of both real-valued and complex-valued numbers or `Tensor`s. For example, we can compute \f$z^i = x^i + i y*i\f$, where \f$x\f$ and \f$y\f$ are real-valued `Tensor`s, `i` is a `std::complex`, and \f$z\f$ is a complex-valued `Tensor`. \snippet Expressions/Test_Examples.cpp te_example_complex_vector In the above example, a `std::complex` is multiplied by a `Tensor`, which can be thought to have an "intermediate" type `Tensor`, and then a `Tensor` is added to that intermediate `Tensor` to yield the resulting type, `Tensor`. The following table shows the data type that results from performing a binary operation (`+`, `-`, `*`, `/`) between two terms of given data types:
Data types resulting from binary operations between supported TensorExpression operand types
double std::complex<double> Tensor<double> Tensor<std::complex<double>> Tensor<DataVector> Tensor<ComplexDataVector>
double double - - - - -
std::complex<double> std::complex<double> std::complex<double> - - - -
Tensor<double> Tensor<double> Tensor<std::complex<double>> Tensor<double> - - -
Tensor<std::complex<double>> Tensor<std::complex<double>> Tensor<std::complex<double>> Tensor<std::complex<double>> Tensor<std::complex<double>> - -
Tensor<DataVector> Tensor<DataVector> Tensor<ComplexDataVector>* Not supported Not supported Tensor<DataVector> -
Tensor<ComplexDataVector> Tensor<ComplexDataVector> Tensor<ComplexDataVector> Not supported Not supported Tensor<ComplexDataVector> Tensor<ComplexDataVector>
\parblock \note The only binary operation that is supported between `std::complex` and `Tensor` is multiplication. This is because Blaze does not support addition, subtraction, nor division between `std::complex` and `DataVector`. \endparblock ================================================ FILE: docs/DevGuide/Tmp.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # SFINAE {#sfinae} \tableofcontents SFINAE, Substitution Failure Is Not An Error, means that if a deduced template substitution fails, compilation must continue. This can be exploited to make decisions at compile time. See [here](http://nilsdeppe.com/posts/tmpl-part1) for a discussion using `std::enable_if` to remove certain functions from overload resolution or certain template specializations from name lookup. Another method of controlling name lookup resolution is using `std::void_t`. `void_t` is a metafunction from types to `void`, that is ```cpp template using void_t = void; ``` `void_t` is useful when used in combination with `decltype` and `std::declval` to probe if a type has certain members. For example, we can implement a type trait to check if a type `T` is iterable by first have the general definition inherit from `std::false_type` as follows, ```cpp template struct is_iterable : std::false_type {}; ``` Next we will have specialization that uses `void_t` to check if the type `T` has a `begin()` and `end()` function. ```cpp template struct is_iterable().begin(), std::declval().end())>> : std::true_type {}; ``` What is happening here? Well, we use `std::declval` to convert the type `T` to a reference type, which allows us to call member functions inside `decltype` expressions without having to construct an object. First we try to call the member function `begin()` on `std::declval()`, and if that succeeds we throw away the result using the comma operator. Next we try to call `end()` on `std::declval()`, which, if it succeeds we get the return type of using `decltype`. Note that `decltype` is important because we can only call member functions on reference types inside of `decltype`, not just anywhere. Finally, if all this succeeded use `void_t` to metareturn `void`, otherwise the template parameters of `void_t` fail to evaluate and the specialization cannot be resolved during name lookup. We could just as well use ```cpp template struct is_iterable().begin()), decltype(std::declval().end())>> : std::true_type {}; ``` Which of the two implementations of the `is_iterable` is preferred is simply a matter of taste, both behave correctly. If you're reading closely you might wonder why the `void_t` is necessary at all, why not just `decltype(...)`? Well the reason is that since the default template parameter metavalue is `void`, the specialization cannot be resolved during name lookup unless the second template parameter in the specialization is either `void` as well or is explicitly specified when the class template is being invoked. Thus, the clearest implementation probably is ```cpp template > struct is_iterable : std::false_type {}; template struct is_iterable().begin(), std::declval().end())>> : std::true_type {}; ``` You could now also define a helper type alias and constexpr boolean ```cpp template using is_iterable_t = typename is_iterable::type; template constexpr bool is_iterable_v = is_iterable::value; ``` ================================================ FILE: docs/DevGuide/Variables.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Using Variables in SpECTRE {#variables_foundations} # What is a Variables and Why Use Them? Variables are a data structure that hold a contiguous memory block with Tensors pointing to it. Variables temporaries allow you to declare temporary tensors and scalars so that you can do all allocations needed for a computation at one time. Since physical memory is shared between CPU cores, processes can't allocate in parallel since they might try to allocate to the same chunk of memory. As more CPU cores are used, this becomes a bottleneck, slowing down or stopping other processes while memory is being allocated. Using a Variables to allocate all memory needed at once can improve efficiency allowing the computation to operate smoothly and uninterrupted. # Defining a Variables of Temporary Tags To define a Variables, you'll need the TempTensor and Variables headers ```cpp #include "DataStructures/Tags/TempTensor.hpp" #include "DataStructures/Variables.hpp" ``` this will give you access to temporary Scalars and Tensors we'll need to allocate. You can define a Variables that allocates one Scalar with something like this: ```cpp Variables>> temp_buffer{get<0,0>(spatial_metric).size()}; ``` Here, the Variables we've defined `temp_buffer` provides a tmpl::list with a TempScalar inside as the template argument, this will allocate a single temporary scalar. The size and DataType of the TempScalar is deduced by what's inside the {}, you can provide any tensor or std::array with the correct size needed. Now, to use the allocation you've made, you can do: ```cpp auto& useful_scalar = get<::Tags::TempScalar<0>>(temp_buffer); ``` # Real Use Example Now that we've got the basics, using them to allocate multiple Scalars and Tensors is quite easy. For instance, let's say I need to allocate 2 scalars, a spatial vector and 2 lower rank 2 tensors for my function. ```cpp Variables, ::Tags::TempScalar<1>, ::Tags::TempI<0, 3, Frame::Inertial>, ::Tags::Tempij<0, 3, Frame::Inertial>, ::Tags::Tempij<1, 3, Frame::Inertial>>> temp_buffer{get<0,0>(spatial_metric).size()}; ``` Here, when we allocate for the same type of scalar or tensor (rank 2 lower) the way we distinguish multiple allocations is through the number within the <>. Now, to use each individual allocation, we can do something like: ```cpp auto& cool_scalar1 = get<::Tags::TempScalar<0>>(temp_buffer); auto& cool_scalar2 = get<::Tags::TempScalar<1>>(temp_buffer); auto& cool_tensor1 = get<::Tags::Tempij<0, 3, Frame::Inertial>>(temp_buffer); auto& cool_tensor2 = get<::Tags::Tempij<1, 3, Frame::Inertial>>(temp_buffer); ``` # Tips In the interest of reducing memory allocations, there a certain scenarios where you can resuse old allocations that are no longer useful to your computation. To see this, let's say that you're trying to make two unit vectors. You might start by saying you'll need two different vectors (rank 1 upper tensors) and 2 different scalars as the magnitude of each vector. The way we'd allocate for this is by doing: ```cpp Variables, ::Tags::TempScalar<1>, ::Tags::TempI<0, 3, Frame::Inertial>, ::Tags::TempI<1, 3, Frame::Inertial>>> temp_buffer{get<0,0>(spatial_metric).size()}; ``` However, doing this allocates more memory than we actually need. Once we finish calculating the first unit vector, the memory we've allocated for the scalar magnitude of the first vector will just sit there unused. We can reuse the allocation for the TempScalar<0> and use it when calculating the second unit vector without having to allocate another TempScalar. Now, allocating an extra scalar is not very expensive, but when using tensors, the memory required really adds up, so this is just another way to help make SpECTRE a bit more efficient. ================================================ FILE: docs/DevGuide/WritingDox.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Writing Good Documentation {#writing_good_dox} \tableofcontents # Tutorials, Instructions, and Dev Guide {#writing_dox_writing_help} All non-code documentation such as tutorials, installation instructions, and the developer guide is written inside Markdown files such as this one. These files must be placed inside `docs/Tutorials`, `docs/MainSite`, or `docs/DevGuide` according to what they document. Each Markdown file must start with the following line ``` markdown # The title {#the_tag} ``` where `The title` is replaced with your desired title, and `the_tag` with the tag you want to use to reference the Markdown file and documentation. Each main heading of the file starts with a single octothorpe and can have a tag. For example, ``` markdown # My Section {#file_name_my_section} ``` While the `file_name` portion is not necessary, it is useful for reducing the likelihood of reference collisions. You can add a table of contents using the Doxygen command \\tableofcontents. All sections, subsections, subsubsections, etc. are shown in the table of contents if they have a tag, if not they do not appear. # C++ Documentation {#writing_dox_cpp_dox_help} We require you to add Doxygen documentation for any of the following you may have added to the public interface in any hpp file: + classes + structs + enums + functions + namespaces + macros + type aliases Documentation begins on the line immediately above the declaration with either a triple slash `///` or a `/*!`. Examples: \verbatim /// A brief description of the object to be documented /// /// Doxygen comments can be made /// using triple slashes... class ExampleClass{ ... rest of code } \endverbatim \verbatim /*! * \brief A brief description of the object to be documented * * Doxygen comments can also be made * using the "slash-star, star-slash" pattern, in this way. */ class ExampleClass{ ... rest of code } \endverbatim Build your documentation by running `make doc` in your build directory. You can then view it by opening `BUILD_DIR/docs/html/index.html` in a browser and using the file navigator in Doxygen to locate your file. In addition to providing a file directory of all the source files in SpECTRE, Doxygen also conveniently provides two additional organizations of the files, Modules and Namespaces. To ensure that your documentation is easily found from within Doxygen, we recommend that you add any new objects to Modules and any new namespaces to Namespaces. \note The `///` Doxygen syntax does not require a `\brief`, while the C-style `/*!` does. ## Add your object to an existing Module: Within a Doxygen comment, use the Doxygen keyword \verbatim \ingroup \endverbatim followed by the name of the Module (you can find the list of existing Modules in `docs/GroupDefs.hpp`). ## Add a new Module: Within `docs/GroupDefs.hpp`, add the name of your Module (which follows the naming convention "YourNameForModule" followed by "Group") among the rest, taking care to keep the list of Modules in alphabetical order. ## Add a new namespace: In the hpp file in which the namespace is declared for the first time, add a Doxygen comment to the line directly above the namespace. Subsequent files which use this namespace will not need a Doxygen comment. We also strongly encourage you to: ## Put any mathematical expressions in your documentation into LaTeX form: Within a Doxygen comment, begin and conclude your expression with \verbatim \f$ \endverbatim Example: \verbatim \\\ We define \f$ \xi : = \eta^2 \f$ \endverbatim Note that if this expression spans more than one line, your Doxygen comment must of the "slash-star, star-slash" form shown in the previous section. One can also use (within a Doxygen comment) the form \verbatim \f[ expression \f] \endverbatim to put the expression on its own line. We also encourage you to use the latex env `align` for formatting these multiple-line equations. Please prefer the `align` environment over the `eqnarray` environment. See the [texfaq](https://texfaq.org/FAQ-eqnarray) for an explanation as to why. When using out-of-line equations it is important to have a blank Doxygen line above and below the equation so that ClangFormat does not merge the equation with other lines. For example, \verbatim * word word word * * \f{align}{ * a &= b \\ * c &= d * \f} * * word word word \endverbatim prevents ClangFormat from changing the code to \verbatim word word word \f{align}{ a &= b \\ c &= d \f} \endverbatim which may not render properly and makes the source code harder to read. ## Cite publications in your documentation {#writing_dox_citations} When you refer to publications or books in the documentation, add a corresponding entry to `docs/References.bib`. Follow these guidelines when editing `docs/References.bib`: - Ideally, find the publication on [INSPIRE HEP](https://inspirehep.net) and copy its BibTeX entry. - For publications that are not listed on [INSPIRE HEP](https://inspirehep.net), make sure to format the new entry's key in the same style, i.e. `([a-zA-Z]+):([0-9]{4})([a-z]*)`. Good keys are, for instance, `Einstein:1915` or `LVC:2016a`. For books you may omit the year. - Sort the list of BibTeX entries in the file alphabetically by their keys. - Provide open access or preprint information whenever possible. For publications available on [arXiv](https://arxiv.org), for instance, add the following fields (filling in the correct values): ``` archivePrefix = {arXiv}, eprint = {1609.00098}, primaryClass = {astro-ph.HE}, ``` - Provide the `url` field whenever possible. If a DOI has been issued by the publisher, use `https://doi.org/` and also fill the `doi` field of the entry. Else, use the URL provided by the publisher. - Make sure to wrap strings in the BibTeX entries in `{}` when capitalization is important, or when BibTeX keywords should be ignored (e.g. `and` in author lists). - Spell out journal names directly instead of using LaTeX macros such as `\apj` or `\mnras`, since Doxygen does not expand those macros in the generated bibliography. To cite an entry from the `docs/References.bib` file in the documentation, use the Doxygen keyword \verbatim \cite \endverbatim followed by the BibTeX key at the place in the documentation where you want the citation to appear. It will render as a numbered link to the bibliography page. It will also show a popover when hovering over the link, which displays the bibliographic information and provides quick access to the publication. ## Include any pictures that aid in the understanding of your documentation: First, please compress your image to be under 130kB. As most images will be diagrammatical in nature this is certainly achievable! Second, add the directory that will contain your image to the `docs/Images/` directory. Create the appropriate directories such that the directory structure in `docs/Images` matches that of `src` and `tests/Unit`. Finally, include the image by using the Doxygen keyword \verbatim \image html NameOfImage.png \endverbatim in your hpp file. # Python Documentation {#writing_dox_python_dox_help} DocStrings... ================================================ FILE: docs/DevGuide/WritingTests.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Writing Unit Tests {#writing_unit_tests} \tableofcontents Unit tests are placed in the appropriate subdirectory of `tests/Unit`, which mirrors the directory hierarchy of `src`. Typically there should be one test executable for each production code library. For example, we have a `DataStructures` library and a `Test_DataStructures` executable. When adding a new test there are several scenarios that can occur, which are outlined below. - You are adding a new source file to an existing test library:
If you are adding a new source file in a directory that already has a `CMakeLists.txt` simply create the source file, which should be named `Test_ProductionCodeFileBeingTest.cpp` and add that to the `LIBRARY_SOURCES` in the `CMakeLists.txt` file in the same directory you are adding the `cpp` file.
If you are adding a new source file to a library but want to place it in a subdirectory you must first create the subdirectory. To provide a concrete example, say you are adding the directory `TensorEagerMath` to `tests/Unit/DataStructures`. After creating the directory you must add a call to `add_subdirectory(TensorEagerMath)` to `tests/Unit/DataStructures/CMakeLists.txt` *before* the call to `add_test_library` and *after* the `LIBRARY_SOURCES` are set. Next add the file `tests/Unit/DataStructures/TensorEagerMath/CMakeLists.txt`, which should add the new source files by calling `set`, e.g. ``` set(LIBRARY_SOURCES ${LIBRARY_SOURCES} Test_ProductionCodeFileBeingTest.cpp PARENT_SCOPE) ``` The `PARENT_SCOPE` flag tells CMake to make the changes visible in the CMakeLists.txt file that called `add_subdirectory`. You can now add the `Test_ProductionCodeFileBeingTested.cpp` source file. - You are adding a new directory:
If the directory is a new lowest level directory you must add a `add_subdirectory` call to `tests/Unit/CMakeLists.txt`. If it is a new subdirectory you must add a `add_subdirectory` call to the `CMakeLists.txt` file in the directory where you are adding the subdirectory. Next you should read the part on adding a new test library. - You are adding a new test library:
After creating the subdirectory for the new test library you must add a `CMakeLists.txt` file. See `tests/Unit/DataStructures/CMakeLists.txt` for an example of one. The `LIBRARY` and `LIBRARY_SOURCES` variables set the name of the test library and the source files to be compiled into it. The library name should be of the format `Test_ProductionLibraryName`, for example `Test_DataStructures`. The library sources should be only the source files in the current directory. The `add_subdirectory` command can be used to add source files in subdirectories to the same library as is done in `tests/Unit/CMakeLists.txt`. The `CMakeLists.txt` in `tests/Unit/DataStructures/TensorEagerMath` is an example of how to add source files to a library from a subdirectory of the library. Note that the setting of `LIBRARY_SOURCES` here first includes the current `LIBRARY_SOURCES` and at the end specifies `PARENT_SCOPE`. The `PARENT_SCOPE` flag tells CMake to modify the variable in a scope that is visible to the parent directory, i.e. the `CMakeLists.txt` that called `add_subdirectory`.
Finally, in the `CMakeLists.txt` of your new library you must call `add_test_library`. Again, see `tests/Unit/DataStructures/CMakeLists.txt` for an example. The `add_test_library` function adds a test executable with the name of the first argument and the source files of the third argument. Remember to use `target_link_libraries` to link any libraries your test executable uses (see \ref spectre_build_system). All tests must start with ```cpp // Distributed under the MIT License. // See LICENSE.txt for details. #include "Framework/TestingFramework.hpp" ``` The file `tests/Unit/Framework/TestingFramework.hpp` must always be the first include in the test file and must be separated from the STL includes by a blank line. All classes and free functions should be in an anonymous/unnamed namespace, e.g. ```cpp namespace { class MyFreeClass { /* ... */ }; void my_free_function() { /* ... */ } } // namespace ``` This is necessary to avoid symbol redefinition errors during linking. Test cases are added by using the `SPECTRE_TEST_CASE` macro. The first argument to the macro is the test name, e.g. `"Unit.DataStructures.Tensor"`, and the second argument is a list of tags. The tags list is a string where each element is in square brackets. For example, `"[Unit][DataStructures]"`. The tags should only be the type of test, in this case `Unit`, and the library being tested, in this case `DataStructures`. The `SPECTRE_TEST_CASE` macro should be treated as a function, which means that it should be followed by `{ /* test code */ }`. For example, \snippet Test_Tensor.cpp example_spectre_test_case From within a `SPECTRE_TEST_CASE` you are able to do all the things you would normally do in a C++ function, including calling other functions, setting variables, using lambdas, etc. The `CHECK` macro in the above example is provided by [Catch2](https://github.com/catchorg/Catch2) and is used to check conditions. We also provide the `CHECK_ITERABLE_APPROX` macro which checks if two `double`s or two iterable containers of `double`s are approximately equal. `CHECK_ITERABLE_APPROX` is especially useful for comparing `Tensor`s, `DataVector`s, and `Tensor`s since it will iterate over nested containers as well. \warning Catch's `CHECK` statement only prints numbers out to approximately 10 digits at most, so you should generally prefer `CHECK_ITERABLE_APPROX` for checking double precision numbers, unless you want to check that two numbers are bitwise identical. All unit tests must finish within a few seconds, the hard limit is 5, but having unit tests that long is strongly discouraged. They should typically complete in less than half a second. Tests that are longer are often no longer testing a small enough unit of code and should either be split into several unit tests or moved to an integration test. #### Discovering New and Renamed Tests When you add a new test to a source file or rename an existing test the change needs to be discovered by the testing infrastructure. This is done by building the target `rebuild_cache`, e.g. by running `make rebuild_cache`. #### Testing Pointwise Functions Pointwise functions should generally be tested in two different ways. The first is by taking input from an analytic solution and checking that the computed result is correct. The second is to use the random number generation comparison with Python infrastructure. In this approach the C++ function being tested is re-implemented in Python and the results are compared. Please follow these guidelines: - The Python implementation should be in a file with the same name as the source file that is being re-implemented and placed in the same directory as its corresponding `Test_*.cpp` source file. - The functions should have the same names as the C++ functions they re-implement. - If a function does sums over tensor indices then [`numpy.einsum`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.einsum.html) should be used in Python to provide an alternative implementation of the loop structure. - You can import Python functions from other re-implementations in the `tests/Unit/` directory to reduce code duplication. Note that the path you pass to `pypp::SetupLocalPythonEnvironment` determines the directory from which you can import Python modules. Either import modules directly from the `tests/Unit/` directory (e.g. `import PointwiseFunction.GeneralRelativity.Christoffel as christoffel`) or use relative imports like `from . import Christoffel as christoffel`. Don't assume the Python environment is set up in a subdirectory of `tests/Unit/`. It is possible to test C++ functions that return by value and ones that return by `gsl::not_null`. In the latter case, since it is possible to return multiple values, one Python function taking all non-`gsl::not_null` arguments must be supplied for each `gsl::not_null` argument to the C++. To perform the test the `pypp::check_with_random_values()` function must be called. For example, the following checks various C++ functions by calling into `pypp`: \snippet Test_PyppRandomValues.cpp cxx_two_not_null The corresponding Python functions are: \snippet PyppPyTests.py python_two_not_null #### Writing and Fixing Random-Value Based Tests Many tests in SpECTRE make use of randomly generated numbers in order to increase the parameter space covered by the tests. The random number generator is set up using: ```cpp MAKE_GENERATOR(gen); ``` The generator `gen` can then be passed to distribution classes such as `std::uniform_real_distribution` or `UniformCustomDistribution`. Each time the test is run, a different random seed will be used. When writing a test that uses random values, it is good practice to run the test at least \f$10^4\f$ times in order to set any tolerances on checks used in the test. This can be done by using the following command in the build directory (SPECTRE_BUILD_DIR): ``` ctest --repeat-until-fail 10000 -R TEST_NAME ``` where `TEST_NAME` is the test name passed to `SPECTRE_TEST_CASE` (e.g. `Unit.Evolution.Systems.CurvedScalarWave.Characteristics`). If a test case fails when using a random number generated by `MAKE_GENERATOR`, as part of the output from the failed test will be the text ``` Seed is: SEED from FILE_NAME:LINE_NUMBER ``` Note that the output of tests can be found in `SPECTRE_BUILD_DIR/Testing/Temporary/LastTest.log` The failing test case can then be reproduced by changing `MAKE_GENERATOR` call at the provided line in the given file to ```cpp MAKE_GENERATOR(gen, SEED); ``` If the `MAKE_GENERATOR` is within `CheckWithRandomValues.hpp`, the failing test case most likely has occurred within a call to `pypp::check_with_random_values()`. In such a case, additional information should have been printed to help you determine which call to `pypp::check_with_random_values()` has failed. The critical information is the line ``` function: FUNCTION_NAME ``` where `FUNCTION_NAME` should correspond to the third argument of a call to `pypp::check_with_random_values()`. The seed that caused the test to fail can then be passed as an additional argument to `pypp::check_with_random_values()`, where you may also need to pass in the default value of the comparison tolerance. Typically, you will need to adjust a tolerance used in a `CHECK` somewhere in the test in order to get the test to succeed reliably. The function `pypp::check_with_random_values()` takes an argument that specifies the lower and upper bounds of random quantities. Typically these should be chosen to be of order unity in order to decrease the chance of occasionally generating large numbers through multiplications which can cause an error above a reasonable tolerance. #### Testing Failure Cases {#testing_failure_cases} `ASSERT`s and `ERROR`s can be tested with the `CHECK_THROWS_WITH` macro. This macro takes two arguments: the first is either an expression or a lambda that is expected to trigger an exception (which now are thrown by `ASSERT` and `ERROR` (Note: You may need to add `()` wrapping the lambda in order for it to compile.); the second is a Catch Matcher (see [Catch2](https://github.com/catchorg/Catch2) for complete documentation), usually a `Catch::Matchers::ContainsSubstring()` macro that matches a substring of the error message of the thrown exception. When testing `ASSERT`s the `CHECK_THROWS_WITH` should be enclosed between `#%ifdef SPECTRE_DEBUG` and an `#%endif` If the `#%ifdef SPECTRE_DEBUG` block is omitted then compilers will correctly flag the code as being unreachable which results in warnings. Adding the "attribute" `// [[OutputRegex, Regular expression to match]]` before the `SPECTRE_TEST_CASE` macro will force ctest to only pass the particular test if the regular expression is found in the output of the test. In this case, the first line of the test should call the macro `OUTPUT_TEST();`. ### Testing Actions The action testing framework is documented as part of the `ActionTesting` namespace. ## Input file tests We have a suite of input file tests in addition to unit tests. Every input file in the `tests/InputFiles/` directory is added to the test suite automatically. If you don't want your input file tested at all, add the relative input file path to the whitelist in `cmake/AddInputFileTests.cmake`. If the input file is being tested, it must specify the `Executable` it should run with in the input file metadata (above the `---` marker in the input file). Properties of the test are controlled by the `Testing` section in the input file metadata. The following properties are available: - `Check`: Semicolon-separated list of checks, e.g. `parse;execute`. The following checks are available: - `parse`: Just check that the input file passes option parsing. - `execute`: Run the executable. If the input file metadata has an `ExpectedOutput` field, check that these files have been written. See `spectre.tools.CleanOutput` for details. - `execute_check_output`: In additional to `execute`, check the contents of some output files. The checks are defined by the `OutputFileChecks` in the input file metadata. See `spectre.tools.CheckOutputFiles` for details. - `CommandLineArgs` (optional): Additional command-line arguments passed to the executable. - `ExpectedExitCode` (optional): The expected exit code of the executable. Default: `0`. See `Parallel::ExitCode` for possible exit codes. - `Timeout` (optional): Timeout for the test. Default: 2 seconds. - `Priority` (optional): Priority of running this test on CI. Possible values are: `low` (not usually run on CI), `normal` (run at least once on CI), `high` (run always on CI). Default: `normal`. ================================================ FILE: docs/Doxyfile.in ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Last updated for Doxygen 1.9.1 # See https://www.doxygen.nl/manual/config.html # for documentation on the commands in this file. #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = SpECTRE PROJECT_NUMBER = @SPECTRE_VERSION@ OUTPUT_DIRECTORY = @PROJECT_BINARY_DIR@/docs STRIP_FROM_PATH = @PROJECT_SOURCE_DIR@ JAVADOC_AUTOBRIEF = YES MULTILINE_CPP_IS_BRIEF = YES TAB_SIZE = 2 ALIASES = "spectreversion=@SPECTRE_VERSION@" \ "spectredoi=@SPECTRE_DOI@" \ "spectrezenodoid=@SPECTRE_ZENODO_ID@" \ "semantics=

Semantics:" \ "metareturns=

Returns: " \ "return=

Returns: " \ "requires=

Requires: " \ "effects=

Effects: " \ "synchronization=

Synchronization: " \ "postconditions=

Postconditions: " \ "returns=

Returns: " \ "throws=

Throws: " \ "complexity=

Complexity: " \ "remarks=

Remarks: " \ "errorconditions=

Error Conditions: " \ "notes=

Notes: " \ "details=

Details

" \ "usage=

Usage

" \ "example=

Example

" \ "derivedrequires=

Derived Class Requires:" DISTRIBUTE_GROUP_DOC = YES SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = NO EXTRACT_PRIVATE = NO EXTRACT_STATIC = NO EXTRACT_LOCAL_CLASSES = NO # We want to be able to have undocumented members, such as size() that show # up but what they do is rather obvious. WARN_IF_UNDOCUMENTED = NO CASE_SENSE_NAMES = YES GENERATE_TODOLIST = NO GENERATE_TESTLIST = NO GENERATE_BUGLIST = NO STRIP_CODE_COMMENTS = NO SHOW_FILES = NO SHOW_USED_FILES = YES VERBATIM_HEADERS = NO CITE_BIB_FILES = @PROJECT_SOURCE_DIR@/docs/References.bib \ @PROJECT_SOURCE_DIR@/docs/Dependencies.bib #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # Add the documentation pages in the order they should appear in the tree view. # Use `\subpage` within the pages to establish a hierarchy. # - We also pick up notebooks converted to markdown by the # `doc-notebooks-to-markdown` target (see `cmake/SetupDoxygen.cmake` for # details). # - The changelog is generated by CI (see `.github/workflows/Tests.yaml`) INPUT = @PROJECT_SOURCE_DIR@/docs/Installation \ @PROJECT_SOURCE_DIR@/docs/Tutorials \ @PROJECT_SOURCE_DIR@/docs/Examples \ @PROJECT_SOURCE_DIR@/docs/Contributing \ @PROJECT_SOURCE_DIR@/docs/DevGuide \ @PROJECT_SOURCE_DIR@/docs/Gallery.md \ @PROJECT_SOURCE_DIR@/docs/PublicationPolicy.md \ @PROJECT_SOURCE_DIR@/docs/Changelog.md \ @PROJECT_SOURCE_DIR@/docs \ @CMAKE_BINARY_DIR@/docs/tmp/notebooks_md \ @SPECTRE_DOXYGEN_GROUPS@ \ @PROJECT_SOURCE_DIR@/src \ @PROJECT_SOURCE_DIR@/tests/Unit/Framework \ @PROJECT_SOURCE_DIR@/tests/Unit/Helpers USE_MDFILE_AS_MAINPAGE = @PROJECT_SOURCE_DIR@/docs/Main.md # We don't parse cpp files because Doxygen has trouble with some template # expressions and we place documentation in header files anyway. FILE_PATTERNS = *.hpp \ *.md RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXCLUDE_SYMBOLS = charm_init_* \ *detail* \ PUP* \ SPECTRE_TEST_CASE* \ std* \ YAML* EXAMPLE_PATH = @PROJECT_SOURCE_DIR@/tests/ \ @PROJECT_SOURCE_DIR@/src/Executables/Examples/ \ @PROJECT_SOURCE_DIR@/support/DevEnvironments/spack.yaml \ @PROJECT_SOURCE_DIR@/support/Python/dev_requirements.txt \ @PROJECT_SOURCE_DIR@/support/Python/requirements.txt \ @PROJECT_SOURCE_DIR@/citation.bib EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO # Input filters run over content before it is parsed by Doxygen. They are # invoked with a file name as additional argument. We run the following filters: # - Format markdown math for Doxygen. See the documentation in # `markdown-math-filter.pl` for details. INPUT_FILTER = "@PERL_EXECUTABLE@ -0777 -p @PROJECT_SOURCE_DIR@/docs/config/markdown-math-filter.pl" #--------------------------------------------------------------------------- # configuration options related to the output #--------------------------------------------------------------------------- GENERATE_HTML = @SPECTRE_DOX_GENERATE_HTML@ HTML_HEADER = @PROJECT_SOURCE_DIR@/docs/config/header.html HTML_FOOTER = @PROJECT_SOURCE_DIR@/docs/config/footer.html IMAGE_PATH = @PROJECT_SOURCE_DIR@/docs/ \ @CMAKE_BINARY_DIR@/docs/tmp/notebooks_md GENERATE_LATEX = NO GENERATE_RTF = NO GENERATE_XML = @SPECTRE_DOX_GENERATE_XML@ XML_OUTPUT = xml #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES # Macros we actually want to expand during preprocessing EXPAND_AS_DEFINED = MAKE_BINARY_FUNCTIONAL \ MAKE_BINARY_INPLACE_OPERATOR \ MAKE_BINARY_OPERATOR \ MAKE_UNARY_FUNCTIONAL EXPAND_ONLY_PREDEF = YES SEARCH_INCLUDES = YES PREDEFINED = SPECTRE_ALWAYS_INLINE= \ OVERLOADER_CONSTEXPR= \ SPECTRE_DOXYGEN_INVOKED \ SPECTRE_AUTODIFF #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The tag file for cppref can be updated as new features are added to the # standard library and to C++ by cloning # https://github.com/p12tic/cppreference-doc (if that is no longer # available there is a fork available at # https://github.com/nilsdeppe/cppreference-doc), entering the directory # and running `make doc_doxygen`. The up-to-date tag file is place in the # `output` subdirectory and can then be copied into the SpECTRE repo TAGFILES += "@PROJECT_SOURCE_DIR@/docs/config/cppreference-doxygen-web.tag.xml=http://en.cppreference.com/w/" ALLEXTERNALS = NO #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- HAVE_DOT = NO CLASS_GRAPH = NO COLLABORATION_GRAPH = NO GROUP_GRAPHS = NO UML_LOOK = NO TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = NO INCLUDED_BY_GRAPH = NO CALL_GRAPH = NO CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = NO DIRECTORY_GRAPH = NO DOT_IMAGE_FORMAT = svg MAX_DOT_GRAPH_DEPTH = 0 GENERATE_LEGEND = NO #--------------------------------------------------------------------------- # HTML layout file #--------------------------------------------------------------------------- LAYOUT_FILE = @DOXYGEN_LAYOUT_FILE@ HTML_EXTRA_FILES = @PROJECT_SOURCE_DIR@/docs/config/icons/octicons.eot \ @PROJECT_SOURCE_DIR@/docs/config/icons/octicons.svg \ @PROJECT_SOURCE_DIR@/docs/config/icons/octicons.ttf \ @PROJECT_SOURCE_DIR@/docs/config/icons/octicons.woff \ @PROJECT_SOURCE_DIR@/docs/config/octicons.css \ @PROJECT_SOURCE_DIR@/docs/config/doxygen-awesome-fragment-copy-button.js \ @PROJECT_SOURCE_DIR@/docs/config/doxygen-awesome-interactive-toc.js \ @PROJECT_SOURCE_DIR@/docs/config/doxygen-awesome-paragraph-link.js \ @PROJECT_SOURCE_DIR@/docs/config/js/spectre.js \ @PROJECT_SOURCE_DIR@/docs/config/apple-touch-icon.png \ @PROJECT_SOURCE_DIR@/docs/config/favicon-16x16.png \ @PROJECT_SOURCE_DIR@/docs/config/favicon-32x32.png \ @PROJECT_SOURCE_DIR@/docs/config/favicon.ico \ @PROJECT_SOURCE_DIR@/docs/config/safari-pinned-tab.svg \ @PROJECT_SOURCE_DIR@/docs/.nojekyll \ @PROJECT_SOURCE_DIR@/docs/config/MathJax.js \ @PROJECT_SOURCE_DIR@/docs/Images/banner.png \ @PROJECT_SOURCE_DIR@/LICENSE.txt GENERATE_TREEVIEW = YES # This width must correspond to `side-nav-fixed-width` in `custom.css` TREEVIEW_WIDTH = 280 HTML_EXTRA_STYLESHEET = @PROJECT_SOURCE_DIR@/docs/config/doxygen-awesome.css \ @PROJECT_SOURCE_DIR@/docs/config/doxygen-awesome-sidebar-only.css \ @PROJECT_SOURCE_DIR@/docs/config/custom.css HTML_COLORSTYLE_HUE = 209 HTML_COLORSTYLE_SAT = 255 HTML_COLORSTYLE_GAMMA = 113 USE_MATHJAX = YES # MATHJAX_RELPATH ultimately links to docs/config/MathJax.js, which is # copied to docs/html/MathJax.js with the HTML_EXTRA_FILES MATHJAX_RELPATH = ./ # Since Doxygen doesn't support MathJax 3 yet, we configure all the # extensions/packages through the docs/config/MathJax.js file. MATHJAX_EXTENSIONS = MATHJAX_CODEFILE = #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = YES ================================================ FILE: docs/Examples/BbhInitialData/.gitignore ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. *.yaml *.h5 ================================================ FILE: docs/Examples/BbhInitialData/BbhInitialData.ipynb ================================================ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Binary black hole initial data {#example_bbh_id}\n", "\n", "In this example we run the elliptic solver to compute initial data for binary\n", "black holes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Distributed under the MIT License.\n", "# See LICENSE.txt for details.\n", "\n", "# Dependencies:\n", "%pip install numpy matplotlib pandas 'h5py>=3.0.0' ruamel.yaml" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import h5py\n", "import matplotlib.pyplot as plt\n", "import multiprocessing\n", "import numpy as np\n", "import os\n", "import pandas as pd\n", "from ruamel.yaml import YAML\n", "\n", "plt.style.use(\"../plots.mplstyle\")" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "%%bash\n", "# Clean up output files from previous runs\n", "rm -f Bbh*.h5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, make sure you have compiled the `SolveXcts` executable. Put in the path\n", "to your build directory below. Make sure you have compiled in `Release` mode." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "SPECTRE_BUILD_DIR = \"/Users/nlf/Work/spectre/build-Default-Release\"\n", "SPECTRE_HOME = \"/Users/nlf/Projects/spectre/develop\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## Setup input file\n", "\n", "We set up an input file based on the\n", "`tests/InputFiles/Xcts/BinaryBlackHole.yaml` example:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# Load example input file\n", "load_input_file_path = os.path.join(\n", " SPECTRE_HOME, \"tests/InputFiles/Xcts/BinaryBlackHole.yaml\"\n", ")\n", "yaml = YAML()\n", "with open(load_input_file_path, \"r\") as open_input_file:\n", " input_file = yaml.load(open_input_file)\n", "\n", "# Modify example input file\n", "# - Set output file names\n", "input_file[\"Observers\"][\"VolumeFileName\"] = \"BbhVolume\"\n", "input_file[\"Observers\"][\"ReductionFileName\"] = \"BbhReductions\"\n", "\n", "# Write modified input file\n", "with open(\"Bbh.yaml\", \"w\") as open_input_file:\n", " yaml.dump(input_file, open_input_file)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Run executable\n", "\n", "We pass the input file to the `SolveXcts` executable to solve the elliptic\n", "problem. It will take a few minutes to complete on ~10 cores. Adapt the command\n", "below to your system, or run the `SolveXcts` executable with the `Bbh.yaml`\n", "input file manually." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Charm++: standalone mode (not using charmrun)\n", "Charm++> Running in Multicore mode: 12 threads (PEs)\n", "Converse/Charm++ Commit ID: v6.10.2-0-g7bf00fa\n", "Warning> Randomization of virtual memory (ASLR) is turned on in the kernel, thread migration may not work! Run 'echo 0 > /proc/sys/kernel/randomize_va_space' as root to disable it, or try running with '+isomalloc_sync'.\n", "CharmLB> Load balancer assumes all CPUs are same.\n", "Charm++> Running on 1 hosts (12 sockets x 1 cores x 1 PUs = 12-way SMP)\n", "Charm++> cpu topology info is gathered in 0.002 seconds.\n", "\n", "Executing '/Users/nlf/Work/spectre/build-Default-Release/bin/SolveXcts' using 12 processors.\n", "Charm++ startup time in seconds: 3.621687\n", "Date and time at startup: Tue Feb 22 15:08:18 2022\n", "\n", "SpECTRE Build Information:\n", "Version: 2022.02.17\n", "Compiled on host: 98c21919c2ac\n", "Compiled in directory: /Users/nlf/Work/spectre/build-Default-Release\n", "Source directory is: /Users/nlf/Projects/spectre/develop\n", "Compiled on git branch: xcts_input_files\n", "Compiled on git revision: db7100f700b\n", "Linked on: Thu Jan 27 17:45:20 2022\n", "\n", "The following options differ from their suggested values:\n", "\n", "Option parsing completed.\n", "Multigrid level 0 has 232 elements in 54 blocks distributed on 12 procs.\n", "Multigrid level 1 has 54 elements in 54 blocks distributed on 12 procs.\n", "NewtonRaphson initialized with residual: 1.058476e+01\n", "Gmres initialized with residual: 1.058476e+01\n", "Gmres(1) iteration complete. Remaining residual: 2.003738e-01\n", "Gmres(2) iteration complete. Remaining residual: 1.206809e-01\n", "Gmres(3) iteration complete. Remaining residual: 8.694367e-02\n", "Gmres(4) iteration complete. Remaining residual: 7.275577e-02\n", "Gmres(5) iteration complete. Remaining residual: 4.520779e-02\n", "Gmres(6) iteration complete. Remaining residual: 1.464362e-02\n", "Gmres(7) iteration complete. Remaining residual: 6.754772e-03\n", "Gmres has converged in 7 iterations: RelativeResidual - The residual magnitude has decreased to a fraction of 0.001 of its initial value or below (0.00063816).\n", "NewtonRaphson(1) iteration complete (0 globalization steps, step length 1). Remaining residual: 2.865222e+00\n", "Gmres initialized with residual: 2.865222e+00\n", "Gmres(1) iteration complete. Remaining residual: 4.062729e-02\n", "Gmres(2) iteration complete. Remaining residual: 2.455538e-02\n", "Gmres(3) iteration complete. Remaining residual: 1.602018e-02\n", "Gmres(4) iteration complete. Remaining residual: 1.181106e-02\n", "Gmres(5) iteration complete. Remaining residual: 5.591212e-03\n", "Gmres(6) iteration complete. Remaining residual: 2.012421e-03\n", "Gmres has converged in 6 iterations: RelativeResidual - The residual magnitude has decreased to a fraction of 0.001 of its initial value or below (0.000702361).\n", "NewtonRaphson(2) iteration complete (0 globalization steps, step length 1). Remaining residual: 8.164886e-03\n", "Gmres initialized with residual: 8.164886e-03\n", "Gmres(1) iteration complete. Remaining residual: 1.279278e-03\n", "Gmres(2) iteration complete. Remaining residual: 7.680224e-04\n", "Gmres(3) iteration complete. Remaining residual: 6.026001e-04\n", "Gmres(4) iteration complete. Remaining residual: 5.116235e-04\n", "Gmres(5) iteration complete. Remaining residual: 3.771227e-04\n", "Gmres(6) iteration complete. Remaining residual: 1.521095e-04\n", "Gmres(7) iteration complete. Remaining residual: 4.029530e-05\n", "Gmres(8) iteration complete. Remaining residual: 1.632393e-05\n", "Gmres(9) iteration complete. Remaining residual: 5.028700e-06\n", "Gmres has converged in 9 iterations: RelativeResidual - The residual magnitude has decreased to a fraction of 0.001 of its initial value or below (0.000615893).\n", "NewtonRaphson(3) iteration complete (0 globalization steps, step length 1). Remaining residual: 1.690461e-03\n", "Gmres initialized with residual: 1.690461e-03\n", "Gmres(1) iteration complete. Remaining residual: 6.584416e-06\n", "Gmres(2) iteration complete. Remaining residual: 5.651935e-06\n", "Gmres(3) iteration complete. Remaining residual: 5.288583e-06\n", "Gmres(4) iteration complete. Remaining residual: 4.922907e-06\n", "Gmres(5) iteration complete. Remaining residual: 4.250901e-06\n", "Gmres(6) iteration complete. Remaining residual: 1.596286e-06\n", "Gmres has converged in 6 iterations: RelativeResidual - The residual magnitude has decreased to a fraction of 0.001 of its initial value or below (0.00094429).\n", "NewtonRaphson(4) iteration complete (0 globalization steps, step length 1). Remaining residual: 1.606242e-06\n", "Gmres initialized with residual: 1.606242e-06\n", "Gmres(1) iteration complete. Remaining residual: 7.008839e-07\n", "Gmres(2) iteration complete. Remaining residual: 5.285042e-07\n", "Gmres(3) iteration complete. Remaining residual: 4.919028e-07\n", "Gmres(4) iteration complete. Remaining residual: 3.871318e-07\n", "Gmres(5) iteration complete. Remaining residual: 1.603757e-07\n", "Gmres(6) iteration complete. Remaining residual: 2.922369e-08\n", "Gmres(7) iteration complete. Remaining residual: 1.438336e-08\n", "Gmres(8) iteration complete. Remaining residual: 5.271254e-09\n", "Gmres(9) iteration complete. Remaining residual: 2.125873e-09\n", "Gmres(10) iteration complete. Remaining residual: 1.044162e-09\n", "Gmres has converged in 10 iterations: RelativeResidual - The residual magnitude has decreased to a fraction of 0.001 of its initial value or below (0.000650065).\n", "NewtonRaphson(5) iteration complete (0 globalization steps, step length 1). Remaining residual: 1.066508e-09\n", "Gmres initialized with residual: 1.066508e-09\n", "Gmres(1) iteration complete. Remaining residual: 8.000055e-10\n", "Gmres(2) iteration complete. Remaining residual: 5.991477e-10\n", "Gmres(3) iteration complete. Remaining residual: 4.073811e-10\n", "Gmres(4) iteration complete. Remaining residual: 2.559880e-10\n", "Gmres(5) iteration complete. Remaining residual: 1.242268e-10\n", "Gmres(6) iteration complete. Remaining residual: 3.521815e-11\n", "Gmres has converged in 6 iterations: AbsoluteResidual - The residual magnitude has decreased to 1e-10 or below (3.52181e-11).\n", "NewtonRaphson(6) iteration complete (0 globalization steps, step length 1). Remaining residual: 3.589802e-11\n", "NewtonRaphson has converged in 6 iterations: AbsoluteResidual - The residual magnitude has decreased to 1e-10 or below (3.5898e-11).\n", "\n", "Done!\n", "Wall time in seconds: 769.172052\n", "Date and time at completion: Tue Feb 22 15:21:03 2022\n", "\n", "[Partition 0][Node 0] End of program\n" ] } ], "source": [ "NUM_CORES = multiprocessing.cpu_count()\n", "SOLVE_XCTS = os.path.join(SPECTRE_BUILD_DIR, \"bin/SolveXcts\")\n", "!{SOLVE_XCTS} --input-file Bbh.yaml +p {NUM_CORES}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Load initial data into evolutions\n", "\n", "The executable has created H5 output files with volume data and diagnostics:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "BbhReductions.h5 BbhVolume0.h5\n" ] } ], "source": [ "!ls *.h5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The volume data in the `BbhVolume*.h5` files (one per node) can be imported into\n", "evolution executables. It contains the following data:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/ Group\n", "/VolumeData.vol Group\n", "/VolumeData.vol/ObservationId1423324405707320626 Group\n", "/VolumeData.vol/ObservationId1423324405707320626/ConformalFactor Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/ExtrinsicCurvature_xx Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/ExtrinsicCurvature_yx Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/ExtrinsicCurvature_yy Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/ExtrinsicCurvature_zx Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/ExtrinsicCurvature_zy Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/ExtrinsicCurvature_zz Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/HamiltonianConstraint Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/InertialCoordinates_x Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/InertialCoordinates_y Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/InertialCoordinates_z Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/Lapse Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/MomentumConstraint_x Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/MomentumConstraint_y Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/MomentumConstraint_z Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/ShiftExcess_x Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/ShiftExcess_y Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/ShiftExcess_z Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/Shift_x Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/Shift_y Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/Shift_z Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/SpatialMetric_xx Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/SpatialMetric_yx Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/SpatialMetric_yy Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/SpatialMetric_zx Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/SpatialMetric_zy Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/SpatialMetric_zz Dataset {61344}\n", "/VolumeData.vol/ObservationId1423324405707320626/bases Dataset {696}\n", "/VolumeData.vol/ObservationId1423324405707320626/connectivity Dataset {294400}\n", "/VolumeData.vol/ObservationId1423324405707320626/grid_names Dataset {5272}\n", "/VolumeData.vol/ObservationId1423324405707320626/quadratures Dataset {696}\n", "/VolumeData.vol/ObservationId1423324405707320626/total_extents Dataset {696}\n", "/src.tar.gz Dataset {5307433}\n" ] } ], "source": [ "!h5ls -r BbhVolume*.h5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- `Lapse` ($\\alpha$), `Shift` ($\\beta^i$), `SpatialMetric` ($\\gamma_{ij}$) and\n", " `ExtrinsicCurvature` ($K_{ij}$): These quantities solve the Einstein\n", " constraint equations in \"corotating\" coordinates, such that, e.g.,\n", " $\\partial_t K = 0$. The black holes remain approximately at the same\n", " coordinate positions when starting to evolve the initial data in these\n", " coordinates. Note that $\\beta^i \\propto r$ in these coordinates, which can be\n", " large and hence numerically undesireable.\n", "- `ShiftExcess` ($\\beta_\\text{excess}^i$): This shift vector excludes the\n", " rotational part, so it is asymptotically small. Import `ShiftExcess` instead\n", " of `Shift` in an evolution to obtain coordinates in which the black holes are\n", " orbiting. Note that only\n", " \\begin{equation}\n", " \\beta^i = \\beta_\\text{background}^i + \\beta_\\text{excess}^i\n", " \\end{equation}\n", " fulfills all coordinate conditions imposed on the initial data, such as\n", " $\\partial_t K = 0$. The background shift is typically\n", " \\begin{equation}\n", " \\beta_\\text{background}^i = \\epsilon^{ijk} \\Omega^{j} x^k + \\dot{a}_0 x^i\n", " \\text{,}\n", " \\end{equation}\n", " where $\\Omega$ is the orbital angular velocity and $\\dot{a}_0$ is the\n", " expansion parameter.\n", " See the [Xcts::AnalyticData::Binary](https://spectre-code.org/classXcts_1_1AnalyticData_1_1Binary.html)\n", " class for details." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot diagnostics\n", "\n", "We plot the diagnostics in `BbhReductions.h5` to see what happened during the\n", "elliptic solve:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# These routines read the data and process them a bit. You can skip to the plot\n", "# below to see the results.\n", "\n", "\n", "def split_iteration_sequence(data):\n", " left_bounds = np.where(data.index == 0)[0]\n", " right_bounds = list(left_bounds[1:]) + [-1]\n", " return [data.iloc[i:j] for i, j in zip(left_bounds, right_bounds)]\n", "\n", "\n", "def load_dataset(subfile):\n", " legend = subfile.attrs[\"Legend\"]\n", " return pd.DataFrame(data=subfile, columns=legend).set_index(legend[0])\n", "\n", "\n", "with h5py.File(\"BbhReductions.h5\", \"r\") as h5_file:\n", " nonlinear_residuals = load_dataset(h5_file[\"NewtonRaphsonResiduals.dat\"])\n", " all_linear_residuals = split_iteration_sequence(\n", " load_dataset(h5_file[\"GmresResiduals.dat\"])\n", " )" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA04AAAKHCAYAAAC2MBhJAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAABcSAAAXEgFnn9JSAADDlklEQVR4nOzdd1gUV9sG8HvpVbCLohIRAQsoioK9xq7YYlfU2GuCRmOMmqhRo2ISu0SssaLYe1cQDTasiAVsQbDQ+7LfH37My7qLUnZ3Frh/18X1cs7Mzjyrb3BvzplzJDKZTAYiIiIiIiLKkY7YBRAREREREWk7BiciIiIiIqIvYHAiIiIiIiL6AgYnIiIiIiKiL2BwIiIiIiIi+gIGJyIiIiIioi9gcCIiIiIiIvoCBiciIiIiIqIvYHAiIiIiIiL6AgYnIiIiIiKiL2BwIiIiIiIi+gIGJyIiIiIioi9gcCIiIiIiIvoCPbELKMoqVKiAxMREVKlSRexSiIiIiIiKvefPn8PU1BSRkZF5fi1HnNQoMTER6enpYpdBREREREQA0tPTkZiYmK/XcsRJjbJGmu7duydyJUREREREVKtWrXy/liNOREREREREX8DgRERERERE9AUMTkRERERERF/A4ERERERERPQFDE5ERERERERfwOBERERERET0BVyOnIiIiAodmUwGmUwmdhlEJBKJRAKJRKLRezI4ERERkdaTyWSIj49HXFwckpKSIJVKxS6JiERmYGAAc3NzlC5dGrq6umq/H4MTERERabXMzExERkYiNjZW7FKISIukpaXh3bt3SExMRJUqVdQenhiciIiISKvFxsYKoalUqVIwNzeHoaGhxqfpEJH2yMzMRGJiIt68eYOUlBS8e/cO5cqVU+s9GZyIiIhIq3348AEAUK5cOZQuXVrkaohIG+jo6MDCwgIA8Pr1a8THx6s9OHFVPSIiItJaMpkMqampAIASJUqIXA0RaRtTU1MAH6ftqXvBGAYnIiIi0lrZPwhp4uFvIipcdHT+F2cYnIiIiIiIiETG4ERERERERPQFDE5ERERERERfwOBERERERET0BQxORERERIWQRCLJ9V5WmzZtgkQiwdy5c9VbFAEAPD09IZFIcP78+Vy/5vz585BIJPD09FRbXZ+Tn5qLGwYnIiIiIiKiL+AGuEVcWFgYNmzYgPDwcNjY2GDEiBGws7MTuywiIiLSoB49esDNzQ1lypQRu5RiYeHChZgxYwaqVKkidimkQgxORdjGjRsxcuRISKVSoW/p0qXw8fHBsGHDRKyMiIiINMnCwgIWFhZil1FsWFlZwcrKSuwySMU4Va+ICgsLUwhNACCVSjFy5EiEhYWJVBkRERFpWk7POGV/ruXixYto3bo1zM3NUaJECXTu3Bn379/P8ZrHjx9H586dUbZsWRgaGqJatWr4/vvv8e7dO4Vz//vvP/z+++9o0aIFKlWqBAMDA1SoUAE9e/bEv//+q/T6NjY2kEgkkMlkWLFiBZydnWFiYoK6det+8f1mf18nTpxAq1atYGlpCYlEgpiYmHy9h7S0NKxevRqurq4oXbo0TExMYGNjgy5dumDnzp053v9T9+7dg4eHB0qWLAlzc3M0a9YMx48fz/G9tGzZEhKJBOHh4QrHwsPDIZFI0LJlS7n+mJgYrFixAu3bt0fVqlVhaGiI0qVLo0OHDjh16tRn/+woZwxORdSGDRsUQlMWqVQKX19fDVdERERE2urQoUNo3bo1kpKS0KlTJ1hZWeHo0aNo3rw5IiMjFc6fMWMGOnbsiNOnT8Pe3h7dunWDnp4eli9fjkaNGuHNmzdy5x84cADTp0/Hmzdv4OTkhB49eqBixYrw9/dHkyZNcPLkyRxrGzNmDLy8vFCuXDl069YN1apVy/X72r59Ozp27IjExER07NgRrq6uwoIaeX0PAwcOxPjx4xEaGgo3Nzd0794dVapUweXLl7F27dpc1RMcHAw3NzccOHAA1tbW6NKlC5KTk9GpUyfs2bMn1+/rS4KCgjBp0iQ8evQI9vb26NGjB+zt7XHy5Em0b9+enwPziVP1iihlv5XI6fj79+8xZMgQNG7cGI0bN0bz5s2ho8NMTUREhYNMJkNsbKxKr5mQkIBZs2bh33//haurK+bPnw8zMzOVXd/CwiLXK+Jpwh9//IG9e/fCw8MDwMdfsvbt2xd79+7F6tWr8euvvwrn7tmzB4sXL0bt2rXh7++P6tWrA/j49zB37lz8+uuvmDx5stwoTJMmTXD37l3UqlVL7r4nTpxAt27dMG7cOISFhSn9M9m3bx9u3ryp8Nrc8PHxwc6dO9G3b1+5/ry+h2fPnsHPzw9Vq1bF9evXUbp0aeFaKSkpuHnz5hdrkclkGDp0KBISEjB79mz88ssvwrHVq1dj/PjxeX5/ObG3t8eVK1fg5uYm13/z5k20bt0a3333Hb755huV/n+6OGBwKqJsbGxyfTwoKAhHjhzBkSNHULZsWYXfsBAREWmz2NhYlCxZUm3Xv3//PjZv3qzSa3748AGWlpYqvWZB9O/fXwhNAKCrq4sff/wRe/fuxcWLF+XOXbBgAQBgx44dQuAAIEwFPHjwIPz8/PD27VthMYo6deoovW/79u3Rp08f/PPPP7h7967S86ZPn56v0AQAnTt3VghN+XkP0dHRAIB69erJhSYAMDIygru7+xdrOX/+PO7fv49q1aph9uzZcsfGjRuHLVu24OrVq3l+j8p89dVX+OqrrxT669Wrh/Hjx2PBggU4d+4cunbtqpL7FRcMTkXUiBEjsHTpUqXT9XR1dTF8+HChHRgYKHzfuHFjhd/2JCUloVatWnB1dUXjxo0xevRoGBsbq694IiIi0qivv/5aoa9GjRoAPj6flCUqKgq3b9+GnZ0dateurfAaiUSCJk2a4NatW7h+/Trat28vHEtNTcXx48dx7do1REdHIy0tDQBw584dAB+fz1YWnLp165bv96Xstfl5Dw4ODjA1NcWRI0ewZMkSDBw4EBUrVsxTLZcuXQIA9O7dG7q6ugrH+/fvr7LgBHwcNTxz5gwCAwPx33//ITU1FQCE59z5vHveMTgVUXZ2dvDx8cG3336LzMxMoV9XVxd///233JLk3bp1g66uLgIDA9G2bVuFa127dg3h4eEIDw/H8ePHMXHiRIVz4uLiUKJECfW8GSIiIlIra2trhT5zc3MAED5wA/+b6p/TtLrs3r59K3x/584ddOvW7bOPEsTHxyvtL8iS3spem5/3UKJECfj4+GDUqFH44Ycf8MMPP6BGjRpo1aoVBg8ejCZNmnyxltevXwMAqlatqvT4l2YL5cXLly/RpUsX3L59O8dzcvrzppwxOBVhw4YNg7OzM+rXry/0HTt2DO3atZM7r2HDhmjYsGGO18k+IuXm5qbwW5K0tDRUqFAB1tbWaNy4MZYsWYKyZcuq6F0QERF9noWFBT58+KDSa2riGSdtkttnm7N+GVuhQgW50SRlsgKCTCbDN998g/DwcIwZMwZjxoxBtWrVYGZmBolEgpkzZ2LhwoWQyWRKr2NkZJSHd/Ll1+bnPQAfR4Tatm2LAwcO4OTJk7hw4QLWrVuHdevW4fvvv8eyZcvyXWd+Zf/leHbffvstbt++jV69euGHH36Avb09zM3NoaOjg/Xr12P06NE5/nlTzhicijgXFxfY29sjNDQUAIQ5unkxcuRIODo6IjAwEDVr1lQ4fuvWLSQnJyMsLAzPnz/HunXrFM65ceMGqlevzlEpIiJSOYlEovLnhSwtLbFp0yaVXrMoyBqZKlOmTK7/fB4+fIiHDx+iQYMGWLNmjcLxp0+fqrLEL8rPe8hStmxZfPvtt/j2228hk8lw4sQJ9O3bF97e3hg+fPhnn8XK2tcpIiJC6fGc+g0MDAB8DPOfevHihUJfYmIiTp06hfLly2PXrl0Kv/DW9J93UcKl04oBV1dX4fuc9kr4nLJly6JHjx5YsmSJ0o1zr1+/LnzfoEEDGBoayh3PzMxEq1atULJkSdStWxePHj3Kcw1EREQkPmtrazg4OOD+/fu5/vc8azRQ2XTADx8+aHxfofy8B2UkEgk6dOiAzp07A/i4P9PnNGvWDACwd+9epSNFn+4FlSUrcCmrVdmfXWxsLDIzM2FlZaUQmtLT0+Hv7//ZOilnDE7FQPZpePkJTl8yZswYPHv2DP/88w+8vLwUjt+7dw9xcXHIzMzEnTt3lD5MuX//fgQGBiIlJUXl9REREZHq/Pzzz8jMzESvXr1w69YthePv3r2Dj4+P0K5evTp0dHRw9uxZuQUJUlJSMGbMGLx//14TZcvJ63u4efMm9u3bJyxokeX9+/fCgg6VK1f+7D1btmwJBwcHPHnyBPPnz5c7tm7dOly5ckXp61q0aAEAWLZsGZKSkoT+s2fP4o8//lA4v1y5crCwsMDdu3cREBAg9EulUkyfPp2/wC4ATtUrBrKPON24cQMZGRnQ01PdX71EIoGNjU2ODzU+f/4clpaWiImJgbOzs8IccZlMhtGjRyMqKgoGBgY4ffq08FsZIiIi+rxP9+rJLmtamSoNGDAA9+7dw2+//Yb69eujbt26sLW1hUwmw5MnTxASEgIzMzOMHDkSwMcP8iNGjICPjw+cnZ3RunVrGBsb49KlS5BKpfD09NT4tMi8voeIiAj06tULFhYWaNCgASpUqICYmBhcvHgR8fHx6Nq16xeXJNfR0cGmTZvQpk0bzJkzB35+fqhduzYeP36M4OBgjBs3DqtXr1Z4Xf/+/fH7778jMDAQjo6OcHV1xcuXL/Hvv//i+++/x9KlS+XO19PTww8//ICffvoJLVq0QOvWrVGqVClcvXoVb968wfjx47Fq1SrV/WEWIxxxKgbq1q0rBKXk5OQvDiWrWufOnfHu3Tvcu3cPK1euVDj+9OlTREVFAfi40ISjo6PCOatXr8bq1atx69YtZGRkqL1mIiKiwuLq1as5fr18+VIt91ywYAEuXLiAXr16ITIyEvv378e5c+cglUoxduxYHDx4UO78NWvWYNmyZfjqq69w5swZXLp0CW3btkVwcHCOq8ypW17eg5ubG+bPn4/69esjNDQUe/bsQXBwMJycnODr64u9e/fm6p6NGjXClStX0LVrVzx//hwHDx6Enp4eDh06hD59+ih9jbGxMc6cOYP+/fsjPj4eR48ehVQqxa5du3LcNHfmzJnYvHkznJycEBAQgNOnT8PZ2RlBQUFo0KBB3v+wCAAgkXFJDbXJekBQ00FFGRcXF2FX66xlyrXFrVu3MGXKFFy7dg1VqlTBw4cPFc756quvhOVDd+/eneMPFyIiKloyMzOFBY7s7e1zvfobERUPef0ZUZDP5/zpU0wUdIEIdapbty7Onz+P2NhYnDhxQuH469ev5fZ9UDYU/uuvv2LkyJHYuHEjXr16pc5yiYiIiKgYYnAqJtS9QIQq6OvrKx2uz8zMxOTJk+Hq6opq1aopXZVn165d+PvvvzF8+HCcPn1a4TgHVomIiIioILg4RDGRfcTpzp07SE5OhrGxsYgV5Z61tbWwaoyy55s+fPiA+/fvC+3GjRsrnDN16lRcvHgRjRs3Rv/+/T/7IC0RERER0acYnIqJmjVrwtjYGMnJycjIyMCtW7e+uPqLNlK2GqC+vj42bdqEwMBAPHjwANWrV1c458KFC7h+/TqCg4Ph4OCgEJzi4uJgbGwMfX19tdVORERERIUXp+oVE3p6enBxcRHa2jpdLz/MzMwwdOhQrFu3DhcvXoREIpE7npiYKLdHg7IRqd9++w0WFhZo0aIF/vnnH3WXTERERESFDINTMaLNC0Sok5GREYKDg7F69WoMGzYMtWvXVjgnMDAQycnJuHjxIiIjIxWOv3z5Evfu3VO60zcRERERFX0MTsVIYVggQh10dXVRt25djB07Fr6+vtDV1ZU7LpVKERISIrSVjUj5+vqidu3aKFWqFGbPnq32momIiIhIu/AZp2Ik+4hTaGgoYmNjYWFhIWJF2kFXVxdv3rzBjRs3EBAQIDelMUtgYCAAIDY2FgYGBgrHw8LCcPXqVTRp0gQ2NjYK0wWJiIiIqHDjiFMxYmtri5IlSwrt4OBgEavRLoaGhnB3d8fUqVNhaGiocDwlJUXYUE3ZiNSBAwcwePBgVKtWDT179lR7vURERESkWQxOxYhEIkGDBg2EdnGarldQ58+fR0xMDE6fPo1GjRopHM8akQIAR0dHheOhoaGYNm0a9u3bp/QZKiIiIiLSbpyqV8y4urri1KlTABic8src3Bxt2rRReqxatWqoUaMGHj16pHRE6vTp01i6dCmAj38H165d++y9wsLCsGHDBoSHh8PGxgYjRoyAnZ1dwd8EEREREeULg1MxU1xX1lO3pUuXYunSpYiOjoaZmZnC8ewjUk2aNFE4/vjxY4wZMwaNGzdGYmIi/vzzT0ilUrnr+/j4YNiwYep5A0RERET0WQxOxUz2lfVevHiByMhIVKhQQcSKipayZcsq7W/fvj0yMjIQEBCgdETq0qVLOHPmDM6cOaP09VKpFCNHjkTTpk058kREREQkAj7jVMxUrFgRFStWFNocddKMIUOGYNeuXXj58iV69eqlcDz7iFROpFIpfH191VEeEREVQhKJBBKJBJaWloiJiVF6zqJFiyCRSDB37lyN1pbF09MTEokE58+fl+tv2bIlJBIJwsPDRamruJFIJLCxscnTa3L6u9OU/NSsbgxOxRCn64kra3W+7EaNGoXffvtNLtQqw39giIjoU7GxsfD29ha7DKIij8GpGGJw0j6urq748ccfMXjw4M+ep22/eSEiInFJJBIYGRnhzz//xIcPH8QuJ9e2bNmCBw8eoFKlSmKXUiw8ePAgx8cBKPcYnIqhT4OTTCYTsRrKbsSIEdDV1c3xeKdOnTRYDRERaTsdHR2MGjUKcXFxwuqthUGVKlXg4OAAfX19sUspFhwcHGBrayt2GYUeg1MxlH0vp3fv3nH6lxaxs7ODj49PjuFp48aNGq6IiIi03YwZM2BsbIwVK1bg3bt3uX5dUlIS5s2bh9q1a8PY2BgWFhZo3rw5du7cqfR8GxsbSCQSAMDff/8NJycnGBsbo0KFChg9enSOz1kpk9MzTlnPtUilUixevBg1atSAoaEhKleujOnTpyM1NTXH97Jw4ULUq1cPZmZmMDMzg5ubGzZv3qz0/EuXLmHChAlwcnJCyZIlYWxsDAcHB8yYMUPp+zh//jwkEgk8PT0RGRmJb7/9FtbW1tDT08Mff/zxxfeb9b7S0tLw66+/wsHBAYaGhvDw8Mj3e4iIiMDYsWNRo0YNmJiYoFSpUqhVqxZGjx6N0NBQpfdXxtfXF3Xr1hX+LrPeozLh4eGQSCRo2bKl0uNz586FRCLBpk2b5Ppv3bqFH374AfXr10fZsmVhaGiIatWqYdy4cXj9+rXSa2kjBqdiqFSpUqhevbrQ/tKeQqRZw4YNw+3btxWeherZsydWrlwpUlVERMVLWFgYZsyYgX79+mHGjBkICwsTu6QcWVlZYcyYMYiPj8eSJUty9Zr4+Hg0b94cs2fPRlRUFLp06YImTZrg2rVr6N+/PyZPnpzja3/44QeMHz8eVlZW6NixI2QyGdavX49u3bqpbBbLgAEDMH/+fNjb2+Prr79GfHw8fv/9d4wYMULh3KioKLi7u2PmzJmIjIxEixYt0Lx5czx8+BCenp6YOHGiwmumTZuGDRs2wNjYGG3atEGbNm0QFxeHxYsXo2nTpkhISFBaV3R0NFxdXXHkyBG4u7ujY8eOMDExydV7yszMhIeHB37//XfY2tqie/fusLKyytd7ePHiBVxcXLB27VoAH2ektGjRAoaGhvDx8cGVK1dyVdOMGTMwYsQI3L9/H82bN0fz5s1x7NgxNGrUCO/fv8/VNXJj0aJFWL58OQCgadOm6NSpE2QyGdasWYMGDRoUnvAkI7WpWbOmrGbNmmKXoVT//v1lAGQAZF5eXmKXQ0q4uLgIf0eTJk2SSaVSsUsiItI4qVQqu3//vuz+/fsa+zno6+sr09XVFX4GA5Dp6urKfH19NXL/3MqqSyaTySIjI2UmJiYyU1NTWVRUlHDOwoULZQBkc+bMkXvthAkTZABkrVq1ksXFxQn9Dx48kJUrV04GQHbo0CG511StWlUGQFahQgXZw4cPhf7o6GhZ9erVZQBkZ86ckXvN0KFDZQBk586dk+tv0aKFDIDs2bNnCu8JgMzR0VH233//Cf1Pnz6VWVpaygDIHj9+LPeaTp06yQDIJk+eLEtJSRH6IyMjZQ0aNJABkB07dkzuNUePHpXFxMTI9aWkpMhGjRolAyD75Zdf5I6dO3dOqK1Hjx6y5ORkWV5kvbZ69eqyly9fKhzP63uYPXu2DIBswoQJCteKiIhQ+DMCIKtatapc35UrV2QSiURmYWEhu3HjhtAfHx8va926tVBz9r+7Z8+eyQDIWrRoofR9zpkzRwZAtnHjRrn+s2fPyiIjI+X6pFKp7JdffpEBkA0bNkzhWspqViavPyMK8vmcI07FFBeI0H4uLi7C9xkZGUpX4yMiov9JSUlBTEwMYmJikJSUpHA8IyNDOB4bG6v0Gjdu3MDIkSPlNiEH/ref3u3bt4VrpKSkKLw+LS1NOJ7TqIU6lC9fHmPHjkViYiIWL1782XMTExOxYcMG6OjoYPXq1TA3NxeOOTg4YNasWQCAP//8U+nr582bB3t7e6FdpkwZjBkzBgBw8eLFgr4VAMBff/0lt8/kV199hUGDBgH4OM0uy61bt3D06FG4urrC29sbhoaGwrHy5ctj/fr1AIA1a9bIXb9jx46wsLCQ6zM0NMQff/wBPT09HDhwQGldhoaGWLFiBYyMjPL1vhYuXKiwIEZ+3kN0dDQAoG3btgr3qFKlSq6eZ1qzZg1kMhkmT56MevXqCf1mZmZYsWKFMC1TFVq1aoXy5cvL9eno6GD27NmoVKkSDh48qLJ7qRM/iRVT2YPT9evXFf6BIPFl/yF28+ZNhePR0dEMvURE2SxatAglS5ZEyZIlMW7cOIXjwcHBwvHsH/yza9y4cY7/JkqlUvTv31+4hrJnW7Zv3y4c79KlS4HeT15Nnz4dpqamWLNmDd68eZPjedevX0dycjJcXFzg4OCgcDxrhdeAgABkZmYqHP/6668V+mrUqAEA+O+///JbvkBfXx+tWrXK1T1OnjwJAPDw8FD6C8as54WUPZbw6tUrrF27FlOmTMHw4cPh6emJsWPHwsDAIMepmS4uLvleCVAikaBr164K/fl5D/Xr1wcAzJw5E4cPH1Ya4r8kK4D269dP4VjNmjXh7Oyc52t+zrt377Bx40Z4eXlhxIgR8PT0hKenJ9LT0/Hu3TuVTg1UFz2xCyBx1KtXD7q6upBKpUhMTMTDhw9Rq1YtscuibLKPON2+fRtSqVRYNOLevXvo0qUL4uLicPXqVbln1oiIKP+UBYXsEhMTNVRJ3pUtWxbjx4/H77//LvdMyaeynifJabEAS0tLWFhYIDY2Fh8+fEDp0qXljltbWyu8JmvUKqfFG/KiQoUKShdJUnaPrMUlfvrpJ/z00085XvPTYOHt7Y0ZM2YgPT09T7VVqVIlT+dnV65cObnRpCz5eQ+enp44efIkdu/eja5du8LIyAiurq7o0KEDhg8fLjdal5Os/x9UrVpV6XEbGxvcunXri9fJjR07dmDUqFGfHYWNj49HqVKlVHI/dWFwwsffQP31118IDAzEkydP8NNPP2H+/Plil6VWpqamqFWrFkJCQgB8nK7H4KRdnJycoKOjg8zMTCQlJeHRo0dwdHREUlISWrdujaioKABAly5dEBwcDDMzM5ErJiIq/L40LdrU1FRDleTPtGnTsHr1aqxduxY//PBDvq/zuWla6p46npfrZwXdpk2b5nq57aCgIHh5ecHCwgJ//vknWrZsiQoVKgihpmLFijmOnOV3it7nXpuf96Crq4tdu3ZhxowZOHDgAM6ePYurV6/i0qVLWLRoEY4fP47GjRvnu9b8UvaLh4iICHh6egIA/vjjD3Tu3BmVKlWCsbExgI+jvFeuXCkU2+MwOOHjUHRQUBCaNm2Kt2/fil2Oxri6ugrB6dq1a8L/qUk7mJiYwMHBAffv3wfwcd69o6MjTExM8Oeff6J///6QSCQYOXKk1v9DTkSkCTNmzMCUKVMAAAYGBgrHGzRoIGwSm1MwCAwMRMOGDZVO19PV1cWOHTuE39Ar+yA8YMAAYYlpPT3Nf8wqU6YMJk6ciIULF2LhwoWoWLGiwjlZfREREUqvERsbi5iYGBgbG6NkyZJqrbegska/PDw84OXllavX+Pv7AwAWLFiAoUOHyh1LTk7OcSludcnPe8hSr1491KtXD3PnzkVcXBzmzp2L5cuXY8qUKV9cNdnKygrh4eGIiIiAo6OjwnFl///I+u8qp5GjFy9eKPQdPXoUaWlpmDp1qtLVGp8+ffrZOrUJn3ECMHHiRDx69AibNm2CpaWl2OVoDBeI0H7Zp+tlf86pX79+WLRoEfz9/eHl5aXSBziJiAorIyMjWFpawtLSUukS0Xp6esLxTxcGyOLi4qJ0Pz1dXV38/fffcHZ2Fq6hLDgZGBgIx8WaCeDl5QVzc3OsX78er169Ujhev359GBsb4/r160qf5dm2bRsAoEmTJlq/MFG7du0A/C8M5UZWeFY25XDPnj0aH/nIz3tQpkSJEli4cCEkEgnu3r37xfObNWsGANi9e7fCsYcPHyqdplemTBno6enh2bNnyMjIkDuWnp6OCxcuKLzmc3/eFy9e/OzzeNpGu/9r0BBt/6GgLtmD0+3bt1UyL5lUK/sCETdu3JA7Nn36dHTv3l3TJRERFXnDhg3DgwcP5PZxevDgQaGZmVG6dGlMmjQJqamp2LBhg8JxU1NTDB8+HJmZmRg/frzcc1uPHj0SHleYNGmSxmrOr0aNGqFdu3YICAjA+PHjERcXp3DO7du3cfz4caGdtcjEhg0b5J5xun//PqZPn67+oj+Rn/ewdetWpeHo2LFjkMlkqFy58hfvm7US4h9//IHbt28L/YmJiZg4caLSAGlgYAB3d3e8f/8eq1atEvozMjLg5eWFZ8+eKbwm689727Ztcv9fe/XqlVBDYaHRxHD9+nUsWrQIPXv2hLW1NSQSSa5+U56cnIzZs2ejRo0aMDIyQsWKFTF8+HClv0Wh3KtTp44wnzc9PV2Ytkfa49MRp9z8FkybH1wmIios7OzssHDhQuzYsQMLFy6EnZ2d2CXliZeXF0qUKIHk5GSlxxcuXIj69evj1KlTqFatGr755ht07twZzs7OiIyMxKRJk5SuAKeNtm3bhnr16mH16tWoWrUqWrVqhYEDB6JLly6oUqUK6tatKxc6hg0bhgoVKuDQoUOwt7dH37590a5dO9StWxfNmjXLcbEEbXoPe/fuRZ06dVC9enX06NEDAwYMgLu7O3r27AkdHZ1cPavfuHFjTJ06FTExMcLCEn379oWtrS0ePXqU49//7NmzoaOjgylTpqBx48bo2bMnbG1tsWPHDoWpjwDQrVs31KpVC8HBwahevTp69+6NLl26oEaNGihZsqQoz2Lll0aD07x58/Djjz/C398/16EnJSUFrVu3xrx585CQkIDu3bujcuXK2LhxI+rVq1eo5kVqG319fbkRDU7X0z5169YVvo+JiRFW3snJrl278NVXXzEEExEVcyVLlhSe91LG3NwcFy5cwC+//IIyZcrg4MGDuHTpEho0aIDt27fnuIeTNipXrhwCAwPx119/oWbNmrh58yb8/PwQEhKCatWqYcmSJZg6dapwfunSpfHvv/9iwIABSEtLw8GDB/Hq1SvMmzcPO3bsKBTv4fvvv8f48eNhbm6OS5cuwd/fH1FRUejbty+uXr2KPn365Oq+S5YsgY+PDxwdHXH+/HmcP38e7dq1w5UrV3Jc4a5t27Y4ePAgXF1dcePGDVy4cAFubm74999/la7UaGBggEuXLmHs2LEwMjLC4cOH8eDBA0ycOBGnTp2Cvr5+vv7MxCCRaXAi5+LFi5GYmAhXV1e4urrCxsYGqampn/0t+qxZs7BgwQK4u7vj5MmTwnxhb29veHl5oUWLFjh//rxwfkxMzBcf6jMxMclxOUkbGxsMGjRIJavqZa1Sd+/evQJfS10mTZqEFStWAACGDh2KTZs2iVsQKbC1tRV+QeDn54devXopPW/JkiXCCkpVqlTBtWvXFDabIyIqbDIzMxEaGgoAsLe3L7bT64lIubz+jCjI53ONLveS13mjaWlpWLlyJQBg1apVcg9Zfv/999i8eTMuXLiA69evCxuB7dy5E2PHjv3sdT8NW8UZF4jQftlHVm/evJljcKpZs6awfHlCQgLCw8MZnIiIiIhURKt/bRMQEIDY2FjY2trKTSnL0rt3bwDAoUOHhL4xY8ZAJpN99ouh6X+yB6cHDx4gPj5exGpImezPOX26QER2nTt3hre3N2rUqIGgoCA0atRIE+URERERFQtavY9T1gof2T84ZpfVL/bzHDltHPvkyZNcb2Qmlho1aqBEiRKIi4uDTCbDjRs30KJFC7HLomxyWpJcmUmTJuHbb7/lvk5EREREKqbVI07Pnz8HoHzd9+z9OW3gllvR0dHw8/ODn58fkpKS8PDhQ/j5+eHYsWMFum5hoKOjgwYNGghtTtfTPtlHWyMjI3PczRz4uKEjQxMRERGR6mn1iFPWrsTKNrEDIHxALOj0snv37smtPrJ3717s3bsXVatW/eIqZlmvVyankSht4+rqirNnzwLAF3eZJs0rX748KlasiNevXwP4OF2vc+fOuX69VCrF9OnT0atXL7i7u6urTCIiIqIiTatHnDSlZcuWSp+Fyk1oKgq4QIT2yz7q9KXpetnFxcWhW7duWLZsGTw8PIrN/6eJiIiIVE2rg1PWKnpJSUlKj2dt9Glubq6xmoqi7MEpPDwc0dHRIlZDyuR2gYhP3b9/H6dOnQIAREVFYdasWSqvjYiIiKg40OrglLXX0suXL5Uez+oXY4fnoqRy5cooV66c0A4ODhaxGlImLwtEZOfm5ob169cDAHr06IF169apvDYiInWSSCTC91KpVMRKiEgbZWZmCt9n/3mhDlodnJydnQHk/Bv2rH4nJyeN1VQUSSQSNGzYUGhzup72yT5VLzw8HO/fv8/1az09PXHs2DH4+flx4QgiKnQkEgkMDQ0BfJx+TESUXdYMNAMDA7UHJ61eHKJJkyawsLDAkydPcOvWLdStW1fuuJ+fHwCga9euIlRXtLi6uuLw4cMAuECENqpSpQpKlSolBKZbt26hdevWuX59hw4d1FUaEZHalSxZEpGRkYiKikJGRgbMzc1haGio9g9JRKS9MjMzkZiYiDdv3gDQzKM7Wh2cDAwMMGHCBCxYsADjx4/HyZMnhd+Ye3t7IyQkBC1atED9+vVFrrTw+3SBCJlMxn+QtIhEIkG9evVw5swZAB9HW/MSnJR5+/YtwsLCuNIeEWk9CwsLpKSkICYmBu/fv8/TqDsRFX1GRkYoXbq02u+j0eB05MgRzJs3T2inpaUB+PgcRpaff/5ZbqnlWbNm4fTp0wgMDISdnR2aNWuGiIgIXL16FWXLloWvr6/m3kARlj04RUVF4cWLF8IzZqQdXFxc5IJTQTx48ABdunTBu3fvcOXKFTg6OqqiRCIitdDR0UGFChVgamqK+Ph4JCYm8nknIoKBgQHMzc1RunRp6Orqqv1+Gg1O0dHRuHr1qkJ/9r5PV3QzMjLCuXPnsHDhQmzfvh379+9HqVKl4OnpiXnz5uW4OS7lTZkyZWBjYyMsV/3vv/8yOGmZ/C5J/qmUlBS0bdtW2BeqS5cuuHnzJkqUKFHgGomI1EUikaBEiRLCz6qsrUOIqHiSSCQanx0lkfGnjtpkbYCb0wa52qZv377YvXs3AGD69OlYtGiRyBVRdqGhoXBwcADw8YdFXFycsGR/Xvn7+6Nnz56QSCRYvHgxpk6dyqmZREREVOQV5PO5Vq+qR5rFjXC1m52dnRCUZDIZQkJC8n2tHj16wNvbG/v27cO0adMYmoiIiIi+gMGJBNmDU3BwsNy6+CQ+HR0dYYl+oODPOX333Xfw8PAoYFVERERExQODEwlcXFyEkYe4uDg8evRI5IroU9k3wi1ocMpJfHy8Wq5LREREVJgxOJHA3NxcbnU1TtfTPqpaICInu3fvxldffYXr16+r/NpEREREhRmDE8nhc07aLfuI0927d5Gamqqya3t7e6Nv37549+4dunXrhlevXqns2kRERESFHYMTyWnYsKHwPYOT9qlZsyYMDAwAABkZGSpdsdHZ2VnYAyE5ORnPnz9X2bWJiIiICjsGJ5KTfcTp5s2bwibFpB309fVRp04doa3K55zatGmD1atXw87ODlevXoW7u7vKrk1ERERU2DE4kRwnJyfo6+sDAFJTU3H37l2RK6JPZZ+up+rnnEaNGoVbt27Bzs5OpdclIiIiKuwYnEiOoaGh3JLXnK6nfbIvEKGOlfVMTExUfk0iIiKiwo7BiRRwgQjtln3E6fbt25BKpWq9n1QqxbRp03DhwgW13oeIiIhImzE4kQIuEKHd6tSpAx2dj//pJicnIzQ0VG33io+PR/fu3bF06VL07NkTjx8/Vtu9iIiIiLQZgxMpyD7idPfuXSQmJopYDX3KxMREbr8tdW2ECwCPHj3C6dOnAQDv37/HrFmz1HYvIiIiIm3G4EQKHBwcYGpqCgDIzMxUy0arVDDqXCAiu/r162Pz5s0AAA8PD2zYsEFt9yIiIiLSZgxOpEBXVxf169cX2pyup33UvUBEdn379sXp06exd+9eIVATERERFTcMTqQUF4jQbp+OOMlkMrXer02bNsJzVURERETFET8JkVJcIEK71a1bV/g+NjYWz54903gNb9++xcWLFzV+XyIiIiIxMDiRUtlHnB4/foz379+LWA19ysLCAra2tkJb3dP1PvXgwQM0atQInTt3RkhIiEbvTURERCQGBidSysbGBqVLlxbawcHBIlZDymR/zkmTC3ikpqaiffv2ePr0KRISEtC1a1fExMRo7P5EREREYmBwIqUkEgmfc9Jy2Z9z0uSIk6GhIdauXQsdHR1IJBKMHz8eFhYWGrs/ERERkRgYnChHzs7OwvcrV65EVFSUiNXQpz4NTupeICK7Tp06YcWKFdi7dy9++OEHSCQSjd2biIiISAwMTpSjW7duCd9HRkbC1tYWR44cEa8gkpN9ql5UVBT+++8/jd5/3Lhx6NGjh0bvSURERCQWBifK0atXr+TaCQkJ6NKlC3r16oWXL1+KVBVlKVeuHCpVqiS0tWWj4ri4OLFLICIiIlI5BifKUePGjZX279u3D46OjvD29kZGRoaGq6LsNLkRbm74+fnBxsYGgYGBYpdCREREpFIMTpSjZcuWYdSoUahTpw569+4Nd3d34VhCQgK8vLzQoEEDXLlyRcQqizexFohQ5o8//kCfPn3w4cMHeHh4IDw8XNR6iIiIiFSJwYlyZGZmhnXr1iEkJAR79uzB5cuX4evrK7dM+e3bt9G4cWOMHj2aez2JIHtwEnuqXv369aGvrw8ASE9P53ROIiIiKlIYnCjXdHR0MGzYMISGhmLEiBFyx9avXw8HBwds2bJFo6u7FXfZp+pFRETg3bt3otXSrFkz+Pj4wM7ODkFBQWjatKlotRARERGpGoMT5Vnp0qXx999/4/Lly6hdu7bQHx0djaFDh6JVq1Z48OCBiBUWH5UrV5YbAcy+EqIYhg4dipCQENjb24taBxEREZGqMThRvjVp0gQ3btzA77//DhMTE6H/woULcHZ2xsyZM5GUlCRihUWfRCLRugUijIyMxC6BiIiISOUYnKhA9PX1MW3aNDx48ADdu3cX+tPT07Fw4UKUL18eNjY2GDVqFBISEkSstOjSpgUilJFKpZg2bRpOnjwpdilERERE+cbgRCpRpUoV7N+/HwcOHECVKlWE/oSEBERERMDHxwft2rUT9Rmcoir7iJPYC0R8KiEhAT169MDSpUvRp08f3L9/X+ySiIiIiPKFwYlUqlu3brh//z6mT5+ucCwoKAgVK1bEwIEDceHCBS4ioSLZR5wePXqkVSN7T58+xZkzZwB83Bh31qxZIldERERElD8MTqRypqamWLRoEXr37q1wLC0tDdu3b0fLli3h4OCApUuXIjo6WoQqi47q1avDzMwMACCTyXD79m2RK/ofJycn/PPPP5BIJOjWrRu2bNkidklERERE+cLgRGqzceNGjBo1Cvb29qhbty7KlSsnd/zRo0eYNm0aKlWqhH79+uHs2bPIzMwUqdrCS0dHB3Xr1hXa2vack4eHB86ePYt9+/YJAY+IiIiosGFwIrXJ2kD34cOHuHnzJl6+fIl9+/ahQ4cOkEgkwnnp6enYtWsX2rRpA3t7eyxevBhv3rwRsfLCR5s2wlWmZcuW0NXVFbsMIiIionxjcCKN0dfXR48ePXDs2DE8ffoUs2bNQsWKFeXOefz4MWbMmAFra2v06dMHp06d4ihULmjbkuS58fbtW5w9e1bsMoiIiIhyRSLjE/pqU6tWLQDAvXv3RK5Ee2VkZODo0aNYv349jh49qnTBCF1dXVSsWBGDBw9GixYt0LBhQ1haWmq+WC0WEhICZ2dnAICenh4SEhJgaGgoclU5e/jwIbp06YLXr1/j4sWLaNCggdglERERUTFQkM/nDE5qxOCUN8+fP4evry82bNiAly9ffvZce3t7uLm5oVGjRnBzc0OdOnWgp6enoUq1T3p6OszNzZGamgoACA4ORv369UWuSrn09HTY29vj2bNnAAArKyuEhISgTJkyIldGRERERV1BPp9zqh5pjSpVqmDu3Ll49uwZDh06BHNz8xzPDQ0NxebNmzFu3Di4uLigRIkSaNasGaZOnQo/Pz+8ePGiWC13rq+vjzp16ghtbZ6up6+vDx8fHyHoTpo0CaVLlxa5KiIiIqLPK76/oietpaenhy5duqB///5Yv3690F+5cmUkJibi/fv3Cq9JTk7G5cuXcfnyZaGvfPnyMDY2hkwmw9dffw1vb+8ivaqbi4sLgoODAWjnAhHZtWnTBuvWrYOlpSV69uwpdjlEREREX8TgRFpr2bJlAIArV67A3d0dy5Ytg6mpKZ48eYKgoCBcvXoVV69exa1bt5Cenq7w+uwr8/n4+ODDhw/Ys2ePxurXtMK2QMTw4cPFLoGIiIgo1/iMkxrxGSfNSElJwc2bN3H16lUhUIWHhys9d/z48fjll1+K5NSwa9euoVGjRgAAY2NjxMXFFcrnvmJiYrj4BxEREakFn3GiYs3IyAju7u6YMmUKdu7ciWfPniEyMhLt27dXOHfVqlWws7PDihUrlI5SFWZ16tQR9kpKTk5GaGioyBXlnZ+fH2xsbHD+/HmxSyEiIiKSw+BERVL58uXh5+eHkSNHomrVqihRooRw7MOHD5g0aRLq1q2LU6dOiVilahkbG8PR0VFoF4bpetmtXLkSffr0QWxsLHr16oXHjx+LXRIRERGRgMGJiiwzMzOsX78e4eHhiIqKwpIlS+RW6rt//z6+/vprdO/evch8SHdxcRG+1/YFIj7l6uoq7D2VmZmJ169fi1wRERER0f8wOFGxYGhoiKlTpyIsLAwjRoyARCIRjh08eBA1a9bEDz/8gLi4OBGrLLjCtkBEdo0aNcLmzZtRvXp1XLlyBc2bNxe7JCIiIiIBgxMVK+XLl8fff/+N4OBgNG3aVOhPT0/HkiVLYGdnB19fX2RmZopYZf59OuJU2N5H3759cffuXTg4OIhdChEREZEcBicqllxcXHDx4kXs3LkTlStXFvqjoqIwYsQIuLq6yu0JVVjUrVtX+D4uLg7Pnj0Tr5h8ypquR0RERKRNGJyo2JJIJOjbty8ePnyIuXPnwtjYWDh248YNNGvWDJaWlhg6dCgSEhJErDT3SpQogerVqwvtwvackzJSqRTTpk3DwYMHxS6FiIiIijEGJyr2TExMMGfOHISGhqJ///5yx2JjY7FlyxZ89913IlWXd4X5OadPJSQkoEePHli6dCkGDBiA27dvi10SERERFVMMTkT/r3Llyti+fTsuXbokN/oEAAcOHBCpqrzL2tgNALZu3VpoRsuUefHihbCnU2JiImbNmiVuQURERFRsMTgRfaJp06YYNGiQXF90dDROnjwpUkV5c+3aNeH7ly9folmzZkhKShKxovxzdHTEzp07oaOjg65du2L79u1il0RERETFFIMTkRLe3t4YPny43EIFQ4YMwZs3b0SsKnfCw8Pl2rdu3ULNmjUL7TNCnTp1wvnz5+Hv7y+3DxcRERGRJjE4ESlhZmaGDRs24N9//xXC05s3bzBkyBCtX+I7+zLrWSIiItC9e3d0795dIVgVBs2aNYOurq7YZRAREVExxuBE9Bl16tSBt7e30D558iSWLVsmYkVftmzZMowaNQq1atVC3bp15QJH1ma/ixYtQlpamohVFty7d+8KzfRJIiIiKvwkMplMJnYRRVXWQ/r37t0TuRIqCJlMhl69esHf3x8AoKenh4CAADRs2FDkynLn/v37GDduHC5cuCDX7+DggNWrV6NVq1YiVZZ/oaGh6NKlC54/f45z586hcePGYpdEREREhUBBPp9zxInoCyQSCf7++29ho9yMjAz069cPsbGxIleWOzVr1sS5c+ewZcsWlCtXTuh/+PAhWrdujcGDBxeKZ7eyZGRkoGvXrnj8+DHS0tLg4eFRqOonIiKiwonBiSgXSpUqhe3bt0NH5+N/Ms+ePcOYMWNQWAZsJRIJBg8ejIcPH2LcuHGQSCTCsW3btsHe3h6rV6+GVCoVscrc0dPTw4YNG6Cvrw8A+O677+QCIREREZE6MDgR5VLTpk0xd+5cob1z505s3LhRvILyoWTJkli1ahWuXr2K+vXrC/2xsbEYP3483NzcEBwcLGKFudOsWTP4+vpiz549+PHHH+WCIBEREZE68BknNeIzTkWPVCpF27ZthU1ZTUxMEBwcDEdHR3ELywepVIq1a9fip59+kpt2KJFIMHbsWCxYsACWlpbiFUhERESkYnzGiUhDdHV1sW3bNpQuXRoAkJSUhH79+iElJUXkyvJOV1cX48ePx8OHD+U2/JXJZFi9ejXKlCmDpk2b4v379yJWmXcfPnwQuwQiIiIqghiciPKoUqVKclP0QkJCMHXqVBErKpgKFSpg69atOHv2LBwcHIR+qVSKgIAAVK1aFRs3bkRGRoaIVebOvn37YGNjgxMnTohdChERERUxDE5E+dC1a1dMmjRJaK9atQr79+8XryAVaNWqFW7fvo0KFSrI9SckJGD48OGoXbs2du3apbUbAK9Zswa9evVCXFwcvvnmG9y/f1/skoiIiKgIYXAiyqfff/8d9erVE9rDhw/HixcvRKyo4AwMDNCtWzelx0JDQ9GvXz/Uq1cPBw8e1LoVBd3c3GBiYgLg43NaUVFRIldERERERQmDE1E+GRoaYufOnTA1NQXw8dmagQMHFoopbZ+zbNkyjBo1CnXq1EH//v0xYMAAYRl24OPUxO7du8PNzQ2nTp3SmgBVr149/PPPP7Czs0NQUBBatmwpdklERERUhHBVPTXiqnrFw+bNm+Hp6Sm058yZI7dseVHw4MEDzJ07F7t371Y41rx5cyxYsABNmzYVoTJFaWlpMDAwELsMIiIi0kJcVY9IREOGDMHAgQOF9rx583DhwgURK1I9R0dH7Nq1Czdv3kSXLl3kjl28eBHNmjVDx44dtWIPKIYmIiIiUgcGJ3wcMWjQoAEsLS1hamoKFxcX7Ny5U+yyqJCQSCRYs2YNbG1tAQCZmZkYOHAg3r17J3Jlqle3bl0cOnQIV65cQZs2beSOHT9+HK6urujZsyfu3r0rUoWKpFIpfvjhB/j5+YldChERERViDE74+GyKh4cHtm3bhgMHDqBx48bo379/oV8ljTTH3NwcO3fuhL6+PgDg1atXGDZsmNY8/6Nqbm5uOH36NM6ePQt3d3e5Y/7+/qhTpw4sLS3RuXNnuc11NS0hIQG9evXCkiVLMGTIEK0YESMiIqLCic845aBp06awsrLCnj178n0NPuNU/CxbtkxuT6e//voLEydOFLEi9ZPJZDh27BhmzZqFmzdvKhw3MTHBxIkTMXToUDg6Omq0trCwMDRs2BAxMTEAgA4dOuDYsWMarYGIiIi0B59xUoPSpUsjPT1d7DKokPnuu+/QoUMHoT158mR0794dCQkJIlalXhKJBJ06dUJwcDD8/PxgaGgodzwpKQmLFy9GzZo14erqipUrV2psGqOdnR38/Pygp6eHLl26KF3cgoiIiCg3NBqcrl+/jkWLFqFnz56wtraGRCKBRCL54uuSk5Mxe/Zs1KhRA0ZGRqhYsSKGDx+OV69eqbS+jIwMxMXFYdeuXTh16hRGjx6t0utT0aejo4PNmzfD2NgYwMfRmIMHD6Jv374iV6Z+Ojo66NWrF4YMGZLjOcHBwZg4cSKsrKzQo0cP7N+/H2lpaWqtq02bNrh48SL2798Pc3Nztd6LiIiIii6NTtXz8PDAgQMHFPo/V0JKSgpatWqFoKAgWFlZoVmzZggPD8e1a9dQtmxZBAUFoVq1agWuLTIyElZWVgAAXV1drF69GqNGjSrQNTlVr/iytbXF06dP5fr8/PzQq1cvkSrSnISEBHh5eeHKlSuoW7cuateujZ07dyqdxgd8HN3t378/hg4divr16+fqlylERERE+VGQz+caDU6LFy9GYmIiXF1d4erqChsbG6Smpn42OM2aNQsLFiyAu7s7Tp48CTMzMwCAt7c3vLy80KJFC5w/f144PyYmBpGRkZ+tw8TEBFWqVJHry8jIwK1btxAfH4/jx49j+fLl2LFjR4E+6DI4FV+jR4/G+vXr5fp0dHSwYcMGuT2fipM7d+5gy5Yt2LZtW47/jdasWRNDhw7FwIEDUalSJbXW8+7dOwQFBaFz585qvQ8RERFpj0ITnD5lZGT02eCUlpaGcuXKITY2Fjdu3EC9evXkjjs7OyMkJATBwcGoX78+AGDt2rUYO3bsZ+/7adhSZuTIkbhw4QIePXqU+zf0CQan4itr1OXMmTN48eKF3HS0P/74A5MnTxaxOnFlZGTg9OnT2Lx5M/bv34+UlBSl55UsWRI9e/bEH3/8IfzCRFVCQ0PRpUsXhIeH49SpU2jZsqVKr09ERETaqcguDhEQEIDY2FjY2toqhCYA6N27NwDg0KFDQt+YMWMgk8k++/Wl0AR83K/m06lWRLllZmaGdevW4fHjx7h+/ToqVKggHJsyZQp+/fXXIrtU+Zfo6emhQ4cO2LFjByIjI+Hj44OmTZsqnPfhwwds2LABEyZMUOn9MzMz0aNHDzx+/BgZGRno1asXXr9+rdJ7EBERUdGj1cHp9u3bAAAXFxelx7P6Q0JCVH7vwMBA2NjYqPy6VPzUrl0bly5dQtWqVYW+OXPmwMvLq9iGpywWFhb49ttvcenSJTx+/Bhz5swR9sLKsmvXLvz3338qu6eOjg42btwIIyMjAMD3338vPN9IRERElBM9sQv4nOfPnwMArK2tlR7P6o+IiCjQfVq1aoVevXrBwcEBKSkpOHDgALZv367wjEpOsob8PvXkyRPY2toWqDYqGqpXr47Lly+jXbt2ePjwIQBg+fLliI2Nxfr166GrqytyheKztbXF3Llz8erVK/z9999Cf0pKCho3boyTJ0/Czs5OJfdq1KgRtmzZAgDo06ePSq5JRERERZtWB6esvW9MTEyUHjc1NQUAxMfHF+g+zs7OWLFiBV68eAFTU1PUrFkThw4dQpcuXQp0XaLsrK2tcfHiRXTo0AE3btwAAPj6+iI+Ph7btm2DgYGByBVqh+XLl0MikWD//v2Ijo4GAISHh6NJkyY4evQoGjRooJL7MDARERFRXmj1VD1N+eOPPxAaGoqkpCRER0fjwoULeQpN9+7dU/rF0Sb6VNmyZXH27Fk0a9ZM6NuzZw+6d++OpKQkESvTHmZmZli/fj2ioqLg7e0t9EdHR6NVq1Y4deqU2u4dFhaGyZMno1+/fpgxYwbCwsLUdi8iIiIqXLQ6OGWtpJXTB8rExEQA4KaWVKhYWFjg+PHj6Nixo9B3/PhxtG/fHrGxsSJWpn2+++47bNu2DXp6HwfHExIS0LlzZ+zcuVPl99q4cSMcHBzw119/YdeuXVi8eDEcHR2xceNGld+LiIiICh+tDk5Zey29fPlS6fGs/uwP3RMVBiYmJti/f7/cdLHLly+jVatWwvQ0+mjgwIE4fPiwMDU3PT0d/fv3x19//aWye4SFheHbb79FZmamXL9UKsXIkSM58kRERETaHZycnZ0BQHge5FNZ/U5OThqriUhVDAwMsGPHDowYMULou3nzJpo3b57jLwuKq/bt2+Ps2bMoU6aM0Dd58mT89NNPKlmZcMOGDQqhKYtUKoWvry9SUlIwadIkbNu2DY8ePSr2KyISEREVN1odnJo0aQILCws8efIEt27dUjju5+cHAOjatauGKyNSDV1dXfj4+OD7778X+h4+fIimTZtylOMTDRs2xOXLl+VGmH/77TeMHDkSGRkZBbp2eHj4F4/fvn0bK1aswODBg+Hs7FzgexIREVHhotXBycDAQNj8cvz48cIzTQDg7e2NkJAQtGjRAvXr1xerRKICk0gkWLp0KX799VehLyIiAs7OzqhRowZGjx4trDBZ3Nnb2yMwMBB16tQR+jZs2IBevXohOTk539f90p5tNjY2uHbtmtB2cXFR2G9KKpWiVq1a+Oabb7Bs2TLExcXlux4iIiLSPhKZBuebHDlyBPPmzRPa165dg0wmQ6NGjYS+n3/+GZ07dxbaKSkpaNmyJa5evQorKys0a9YMERERuHr1KsqWLYugoCBUq1ZNU28hT7L2d7p3757IlVBh8ddff2Hy5MkK/aNGjcK6detEqEg7xcTEoFu3brh06ZLQ17RpUxw8eBAlS5bM8/XCwsLg6OgIqVSqcExXVxcPHjxAREQEtm3bhmvXrqFDhw5yK/4BwN27d4VAp6uri7i4OIWtFCIiImBtbc19u4iIiERSkM/nGh1xio6OxtWrV4WvrMyWve/TB+ONjIxw7tw5/Pzzz8ID9REREfD09MSNGze0NjQR5cekSZOwadMmhf4rV65ovhgtZmlpiRMnTqB79+5C3+XLl9G8eXO8evUqz9ezs7ODj4+P0kDTrVs32NnZoW3btti0aRPu37+PZcuWKZx39epV4fs6deoohCaZTIYGDRrAwsICLVu25FRMIiKiQkajI07FDUecKL++/vpruf2KOOKkXEZGBsaOHYu///5b6KtSpQpOnDgBBweHPF8vLCwMvr6+OHz4MO7evQsAKF++PCIiImBoaPjZ10ZHR+PixYu4du0aKlSogO+++07u+LNnz+R+0fPu3TuUKlVK7px9+/bBwsJCCFhERESkWgX5fM7gpEYMTpRfCQkJGDRoEJ48eYLGjRtj2bJlwr5mJE8mk2H27NmYP3++0Kerq4tu3bphy5Yt+fpzi46ORuXKlZGamgrg4x5Pnp6eBarz2LFj6Nq1K6RSKezs7PDo0SOFc6pWrYrnz58D+N/eXkRERKQ6DE5aisGJSHNWrFiBSZMmyfX1798f27dvz9f1Ro0aBR8fHwAfp97dvn0bEomkQDUmJSXh5s2biIuLk9sAGQAiIyNhZWUltF++fIlKlSrJnbNgwQJERUWhYcOGaNOmDSpUqFCgeoiIiIobBictxeBEpFnZR2yAj89Ivnv3TuF5o9y4f/++8N8wAJw+fRpt2rRRSZ3KhIaGYvLkybh27RqMjY2VPqvl6OiIhw8fAgC2bt2KQYMGyR3PyMiAnp6e2mokIiIq7ArN4hBEROrUoUMHuXZKSgq+/fbbfG1WW7NmTblRoU9X0VM1e3t7HD9+HO/evcP169cVjsfGxgqhCfi4r9WnJk2ahGrVqqFfv344efKkWuslIiIqbhiciKjIWLZsGUaNGoXSpUsLfTt27FC6Cl5uZN+Y+OjRo3jw4EGBa/wSiUSidAqeRCLBypUrMWTIEDRs2BB2dnYK51y7dg3Pnj3Drl278OzZM4Xj4eHhuHfvntJl14mIiOjzGJyIqMgwMzPDunXrEBkZidatWwv906dPx4kTJ/J8vTZt2shttvvHH3+oosx8KVGiBMaPH4/Nmzfj6tWrCs9bpaSk4Pbt20I7+/54WVatWoXatWujZMmScnvqERER0ZcxOBFRkaOnp4ddu3bBxsYGAJCZmYl+/frh8ePHebqORCKRW1Z8y5YtCnvNaQtDQ0M8efIEe/bswQ8//IDatWsrnHPt2jUAQHx8vNLVBq9fv45Fixbh7NmziIuLU3vNREREhQmDExEVSWXKlMH+/fthbGwMAIiJiYGHhwfi4+PzdJ0BAwagfPnyAD6O6qxdu1bltaqCRCJBlSpV0Lt3byxevFhhkQiZTAapVAodnY8/9pWNSB08eBA//vgj2rRpo7DwBBERUXHH4ERERZazszM2btwotO/du4ehQ4ciMzMz19cwNDTE+PHjhfaqVauE/Z0KE4lEgsuXLyMuLg4XL16Ei4uLwjlZI1KA8mB1+fJlNG7cGFOmTIG/v79a6yUiItI2DE5EVKT17dsXM2bMENr+/v5YsGBBnq4xZswYGBkZAQDevHmDHTt2qLRGTTI1NUWzZs2E95Nd69at0a5dO1hYWChdtS8wMBBXrlzBn3/+iVWrVikcz8jIwNu3b9VSNxERkdgYnIioyJs/f77c0uKzZ8/GwYMHc/36smXLYsiQIULb29s7X0uca7tp06bh5MmTeP/+vdziGlmyj0gpC1Y3b95E2bJlYWtri+HDh6u1ViIiIk1jcCKiIk9XVxfbt2+XW8J70KBBeVpefMqUKcL3d+7cwZkzZ1RZolbR0dGBrq6uQv+sWbPw119/YdCgQUo3A84KVk+fPlX6ZyuVSrF582Y8ePAgT9MliYiItAGDExEVC5aWlti/f7+wmlx8fDy6d++OmJiYXL3e0dFRoxviaqO6deti4sSJ2Lp1q9LglH0XdmUjUqGhofD09ETNmjVRpkwZpKWlqbVeIiIiVWJwIqJio2bNmti2bZvQDgsLw8CBA3O9IWz2DXGPHTumkQ1xC5NVq1YhPDwcu3fvlpvamOXq1avC95UrV4aBgYHccZlMBk9PTyxevBjnzp1jsCIiIq3C4ERExUr37t0xd+5coX306FHMnj07V6/Vpg1xtZFEIkHVqlXRp08f1K9fX+G4vr4+6tSpAx0dHaUjUs+fP8fmzZsxY8YMtG7dWunS8UXx2TIiIiocGJyIqNj5+eef4eHhIbR/++037Nmz54uvk0gkcqNO2rwhrjYaNGgQQkJCEBsbi/nz5ysczz4iZWtri9KlSyucU7t2bTRt2hTff/89Xrx4odZ6iYiIsmNwIqJiR0dHB1u2bEHNmjWFPk9PT4SEhHzxtf379y8UG+JqMzMzM+HPMDtHR0fMnDkTbdq0Qdu2bRWOR0VF4f79+wgICMDy5cuVXvvevXt4//69ymsmIiJicCKiYsnc3BwHDhyApaUlACApKQkeHh549+7dZ19naGiICRMmCO2VK1ciJSVFnaUWG3Xq1MGCBQtw+vRppYE0+3LoVlZWsLa2Vjjnm2++QenSpVGjRg1cunRJrfUSEVHxwuBERMVW9erVsWPHDujofPxR+OzZM/Tt2xcZGRmffV32DXGjoqIK9Ya4hUnbtm2FDXinTp0KiUQidzwuLk5YsCMsLAxly5ZVuMbu3buxZcsWPHz4kEuiExFRnjA4EVGx1qFDByxcuFBonzlzBlZWVhg9ejQSEhKUvqZMmTJyq8YtX76cixZogJGREdzc3DBp0iS5Z82yhIeHC89FWVhYoEaNGgrnLF26FEOHDoWjoyN8fHzUXjMRERUdDE5EVOxNmzYN/fr1E9pv377F+vXr4eXlleNritOGuIWFk5MToqKi8PTpU/j7+wsjiVlSU1Nx69Ytoe3q6qpwjSVLlqB37974/fff5falIiIiYnAiomJPIpFgw4YNwvS7LJcvX87xNY6OjujUqZPQLo4b4mojiUSCr776Cq1atVI4Fh8fj8GDB6N27dowNTWVW1o+y9GjR7F3715Mnz4dJ06cUDiekJCgMJUzLCwMM2bMQL9+/TBjxgyEhYWp7g0REZHWYHAiIgJgYmKCHj16yPU1bdr0s6/5dEPc+/fvq6U2Uo0yZcpgw4YNuHPnDqKjo6Gvry93XCqVIjg4WGgr22vK29sbJUqUQLNmzeDr64uNGzfC0dERixcvxq5du7B48WI4Ojpi48aNan8/RESkWQxORET/b/369ejevTvs7e0xatQoLFu27LPnt27dGk5OTkKbG+IWHsbGxgp9mZmZ2Lp1K2bMmIE2bdqgXr16CudcvXoVycnJuHz5MkJCQjBy5EhIpVK5c6RSKUaOHMmRJyKiIkYi4xPNalOrVi0A4Dx5oiJs8+bN8PT0BPBxqfIXL14oXc2NCj+ZTIZKlSrhv//+A/Bx6fPdu3fneP6MGTPkFh4hIiLxFeTzOUeciIgKoF+/fqhQoQKAj4sPrFmzRuSKSF0kEgmePHmCwMBALF++HOnp6Z89Pzw8XDOFERGRRjA4EREVgKGhIcaPHy+0V61axQ1xizBjY2O4u7tjypQpSpc7z87GxkYzRRERkUYwOBERFRA3xC2eRowYAV1dXaXHJBIJhg8fruGKiIhInRiciIgKqEyZMhg6dKjQHjt2LEaNGpXjBrpUNNjZ2cHHx0dhvyjg40a7dnZ2IlRFRETqwuBERKQC2TfETU1NhY+PD0aMGCFeQaQRw4YNw9atW4W2np4eHjx4ILdUPRERFQ0MTkREKuDg4IASJUrI9e3evRs///wzkpOTRaqKNKFNmzbC9xkZGVxVkYioiGJwIiJSkU830AWA+fPno06dOjh58qQIFZEmlCtXTi40P3r0SMRqiIhIXRiciIhUZOXKlRg1ahSqVq0KU1NTof/Jkydo3749+vXrJ+wBREWHRCKBvb290M4enJ4/f44uXbrgyZMnYpRGREQqxOBERKQiZmZmWLduHcLDwxEZGYmpU6fKrbq2a9cuODg4YPXq1ZBKpSJWSqqWfWnyrOC0b98+ODk54ciRIxg4cOAX930iIiLtxuBERKQGZmZmWLJkCW7cuAE3NzehPy4uDuPHj4e7uztu3rwpYoWkSsqCk1QqRWxsLADg6tWr8Pf3F6U2IiJSDQYnIiI1cnJyQkBAANauXQtLS0uh/99//0WDBg3w3XffIT4+XrwCSSWUBac+ffrA09MT5ubm2Lp1K/r06SNWeUREpAIMTkREaqajo4PRo0fj4cOHGDhwoNCfmZmJP/74A46Ojti3bx9kMpmIVVJBZA9OYWFhyMzMBAD89ddfuH37NgYNGgSJRCJWeUREpAIMTkREGlK+fHls27YNp0+fltsc9dWrV+jVqxe6deuG8PBw8QqkfMv+95mcnIxXr14BAMzNzfHVV1+JVRYREakQgxMRkYa1adMGISEhmDt3LgwMDIT+w4cPo3r16ihTpgw6deqEt2/filgl5YW5uTmsrKyE9peWJE9MTFR3SUREpGIMTkREIjAyMsKcOXNw584duQ1UpVIp3r17h2PHjsHKygoeHh7w8fERRjBIeyl7zulTmZmZ8Pb2xldffcXRRSKiQobBiYhIRDVq1MCpU6ewbds2uaXLASAjIwMHDhzAqFGjYG1tDRcXF/z8888ICgricuZaKDfB6ZtvvoGXlxeio6MxZMgQ/j0SERUiDE5ERCKTSCQYOHAgBg8e/Nnzbt68ifnz58Pd3R0VKlTA0KFDsXv3bsTExGimUPqs3ASnHj16CN8/efKEo05ERIWIntgFEBHRRytWrICBgQGuXLmChg0bokuXLjh79iwOHz6MZ8+eyZ379u1bbNmyBVu2bIGenh7c3NyQnp6ODx8+oEWLFvD29oaZmZlI76R4yk1wGjhwII4cOYKUlBT4+PigdOnSmiqPiIgKSCLj+rdqU6tWLQDAvXv3RK6EiAozmUyGhw8f4siRIzhy5AguXbr0xSleVlZW6N+/P+rXr4/69evDzs4OOjqcZKBODx8+hKOjIwBAV1cXSUlJcot/ZElNTYWBgQGXJyciEkFBPp8zOKkRgxMRqUNMTAxOnjyJw4cP49ixY7lafc/MzAz16tUTglT9+vVRo0YNheeqKP/S0tJgbGws7OH08OFD2Nvbi1wVERFlx+CkpRiciEjdpFIp/v33X4wbNw43b97M02tNTU1Rt25duTDl4ODAMFUA1atXx5MnTwAABw8eRNeuXXP1utTUVDx48AB169ZVY3VERFSQz+d8xomIqBDT1dWFm5sbLl68CC8vLwQEBKBatWpo0qQJ7t69i+vXr+Phw4dQ9juyxMREBAQEICAgQO569vb2WLVqFVq0aMHpZHlUo0YNITh9aS+nLPfu3cOAAQPw4sULhISEwNraWp0lEhFRPjE4EREVAWZmZli3bp3SYwkJCbh16xauX78ufD18+FCYUpadVCrF/fv30apVKzg4OGDIkCEYPHgwP8znUo0aNXDs2DEAuQtOSUlJaNmypTDd0tPTEydPnuTzaEREWog/mYmIijgzMzM0bdoUkydPxpYtW3Dv3j3ExcUhICAAf/31F4YOHQpDQ0OF1z18+BAzZ85ElSpV0K5dO2zduhWJiYkivIPCIzcr62VnYmKCxYsXC21HR0dkZGSopTYiIioYPuOkRnzGiYgKi9GjR2P9+vVfPM/MzAy9e/fG0KFD0bx5c46MfOL06dNo164dAKBixYp49erVF18jk8kwbtw4dO3aFZ06dVJ3iURExRoXh9BSDE5EVFgkJCTAy8sLV65cgbu7OyZOnIh9+/Zhy5YtwjM7n6patSoGDx6MIUOGwM7OTsMVa6fnz5+jatWqQjs+Pp77aRERaREGJy3F4EREhZ1MJkNgYCA2b96MXbt2IS4uTul5DRs2hKGhId6/f48mTZpg2bJlxTIwZGZmwtTUFCkpKQCAGzduoF69eiJXRUREWQry+ZxzLIiIKEcSiQRNmjTB+vXrERkZiR07dqBjx44KU/SuXbuGS5cu4d69e1i/fj28vLxEqlhcOjo6cqNvoaGh+b7WhQsXcOLECVWURUREKsDgREREuWJsbIx+/frh6NGjePnyJZYsWYLatWsrPffSpUsark575HWBiE+lpaVh5syZaNWqFQYNGoTIyEhVlkdERPnE4ERERHlmZWWFqVOnIiQkBDdu3BCmPmR58+YNYmJixClOZAUNThEREfjjjz8gk8nw9u1bjBo1SpXlERFRPjE4ERFRvkkkEtSrVw9BQUFwd3cX+t+/f4/u3bsLz/oUJwUNTnZ2dli2bJnw/ezZs1VWGxER5R+DExERFZiZmRkCAwMxffp0oe/ixYsYMGAApFKpiJVp3qfBKT9rMI0ZMwYrV67EzZs30aBBA1WWR0RE+cTgREREKrNw4UIMGzZMaPv7+2PcuHH5Cg+FVfbgFBsbi+jo6DxfQyKRYPz48TA1NVVlaUREVAAMTkREpDISiQTr169Hly5dhL7169dj7ty54hWlYaVLl0bJkiWFdn6m6xERkfZhcCIiIpXS09PDrl270LhxY6Hv119/xerVq0WsSnMkEgns7e2FtqqCU1xcHDw9PblEORGRSBiciIhI5UxMTHDo0CHUrFlT6JswYQL27NkjYlWaU9AFIj4VHByMunXrYvPmzfD09MzX9D8iIioYBiciIlKLUqVK4cSJE6hcuTIAQCaTYdCgQTh79qzIlamfqoOToaEhXr9+DQCIjIyEt7d3ga9JRER5w+BERERqY21tjRMnTqBUqVIAPm7u6uHhgZs3b4pcmXqpOjjVqVMHixcvho6ODubOnYt58+YV+JpERJQ3DE5ERKRWjo6OOHLkCIyNjQEA8fHx6NChA548eSJyZeqTPTg9fvxYJUuyT5w4Ebdu3cKcOXOgp6dX4OsREVHeMDgREZHaubm5wc/PD7q6ugCAqKgofP3114iMjBS5MvWoXr268H1qaipevHhR4Gvq6OigTp06Bb4OERHlD4MTERFpRKdOneDr6yu0nz59io4dOyIuLk7EqtTD1NQU1tbWQludS5InJiaq7dpERPQ/DE5ERKQxQ4YMwZIlS4T2rVu34OHhgdTUVBGrUg9VP+ekzP79+/HVV1/h3Llzark+ERH9D4MTgE2bNkEikSh8nT9/XuzSiIiKnKlTp8LLy0tonzt3DoMGDVLJc0DaRN3Baf78+ejRoweio6MxePBgvH//XuX3ICKi/2Fwyuby5cu4cuWK8OXi4iJ2SURERdLvv/+OQYMGCW0/Pz9MmjQJMplMxKpUS93BqVOnTtDX1wcAfPjwATdu3FD5PYiI6H+4LE82jRo14kpFREQaoKOjA19fX7x79w7Hjh0DAKxevRrXrl3DuXPnYGZmJnKFBafu4OTi4oIFCxZg165d2L59u9z9iIhI9TjiREREotDX18eePXtQtmxZoS84OBhDhw4VsSrVyR5kwsPD1fIcl5eXFwIDAxmaiIg0QKPB6fr161i0aBF69uwJa2tr4VmiL0lOTsbs2bNRo0YNGBkZoWLFihg+fDhevXql0voqVaoEPT09ODk5wc/PT6XXJiIiRaampnLBCQCOHTtWJJ53srGxEWYxyGQytexbpaOjAwMDA5Vfl4iIFGk0OM2bNw8//vgj/P39cx16UlJS0Lp1a8ybNw8JCQno3r07KleujI0bN6JevXp4+vRpgeuysrLCggULsH37duzfvx+2trbo06cPDhw4UOBrExHR5zVt2lSunZycjDVr1ohUjero6+ujWrVqQludS5JnJ5PJcO3aNY3ci4ioONHoAz3u7u5wcnKCq6srXF1dYWNj88WpC/Pnz0dQUBDc3d1x8uRJYd67t7c3vLy8MHz4cLnV72JiYr64oaKJiQmqVKkitNu3b4/27dsL7S5duqBZs2b47bff0L1793y8UyIiyq1ly5YBAHbv3o2YmBgAwMyZM9GzZ09UrFhRxMoKrkaNGkJg0kRwevPmDUaMGIFjx47hwoULCqGUiIjyTyITcQkjIyMjpKam5riKUlpaGsqVK4fY2FjcuHED9erVkzvu7OyMkJAQBAcHo379+gCAtWvXYuzYsZ+9b4sWLb641PjSpUvx008/FWhOeq1atQAA9+7dy/c1iIiKizdv3sDBwUEIT9988w127dolblEF5OXlBW9vbwDAiBEj8Pfff6v1fk2bNkVAQAAAoGrVqrh9+zYsLCzUek8iosKkIJ/PtXpxiICAAMTGxsLW1lYhNAFA7969AQCHDh0S+saMGQOZTPbZL+7PRESkfcqXL49FixYJ7d27d+P48eMiVlRwmtgENztvb2/o6uoCAGrWrIm0tDS135OIqLjQ6uB0+/ZtAMhxP6Ws/pCQEJXeVyaTwd/fX2lYIyIi9Rk5ciTc3d2F9rhx45CUlCRiRQWj6eDUsGFDLFq0CCtWrMCRI0cUFt4gIqL80+pNi54/fw4AsLa2Vno8qz8iIqJA9+nduzcaNmwIJycnpKam4u+//8aVK1dw8ODBXL0+a8jvU0+ePIGtrW2BaiMiKk50dHSwdu1auLi4QCqV4tmzZ5g/fz5+++03sUvLl+zB6c2bN4iNjVX71LmpU6eq9fpERMWVVo84JSQkAPi4mIMypqamAID4+PgC3adGjRr4+++/0bNnT/Tv3x/v37/H4cOH0aVLlwJdl4iI8s7JyQnff/+90F6yZEmhfVa0YsWKcv+GhYWFiVgNEREVhFYHJ0357bff8OjRIyQlJSEpKQkBAQHo1KlTrl9/7949pV8cbSIiyp85c+agatWqAICMjAyMGTMGmZmZIleVdxKJROPT9ZQJCwvD5s2bRbk3EVFRodXBKWvp8ZzmtycmJgIAzM3NNVYTERGpn6mpKVauXCm0L1++jE2bNolXUAGIGZxkMhn+/vtv1K1bFyNGjOD+TkREBaDVwSlrr6WXL18qPZ7Vn/VbSSIiKjq6dOmCnj17Cu1p06YhOjpaxIryR8zglJiYiPnz5yMpKQlSqRQDBgwo0DYbRETFmVYHJ2dnZwDAjRs3lB7P6ndyctJYTUREpDl//vmnMPvg/fv3mDZtmsgV5Z2YwcnMzAzbtm2Djo4OSpUqhSVLlsDQ0FCjNRARFRVaHZyaNGkCCwsLPHnyBLdu3VI47ufnBwDo2rWrhisjIiJNsLa2xrx584T25s2bC91efJ8GJ03vO9+0aVNs3rwZd+7cQY8ePTR6byKiokSrg5OBgQEmTJgAABg/frzwTBPwcZO/kJAQtGjRAvXr1xerRCIiUrMJEybI7as3ZsyYQjXdzM7OTvg+Pj4eb9680XgNgwYNQsWKFTV+XyKiokSjwenIkSNwc3MTvrJ2NM/ed+TIEbnXzJo1C40aNUJgYCDs7OzQt29fuLm5wcvLC2XLloWvr68m3wIREWmYnp4e1q1bB4lEAgAIDQ3F77//LnJVuVeqVCmUKVNGaIu1sh4RERWMRoNTdHQ0rl69KnxlTVfI3vfpg79GRkY4d+4cfv75Z5iYmGD//v2IiIiAp6cnbty4gWrVqmnyLRARkQhcXV0xfvx4ob1gwQI8fvxYxIryxt7eXvheG4JTRkYGfv31V3h7e4tdChFRoSGRaXqydTFSq1YtACi0GzcSEWmT2NhYODo64r///gMAtGvXDidOnBBGorTZ8OHDsXHjRgAfVwcUc8Ts5cuX6Nu3LwIDA6Gvr4+goCC4uLiIVg8RkSYV5PO5Vj/jRERElMXCwgJ//vmn0D516hR27twpYkW5pw2b4GYxMTHB8+fPAQDp6en46aefRK2HiKiwYHAiIqJCo3fv3ujYsaPQ/u677xATEyNeQbmUPTiFhoaKWMnHZ662bNkCiUSCIUOGYNeuXaLWQ0RUWDA4ERFRoSGRSLBq1SoYGRkBAN68eYMff/xR5Kq+LHtwevLkCTIyMkSsBmjVqhVu3bqFzZs3o0SJEqLWQkRUWDA4ERFRofLVV19h9uzZQnvdunUICgoSsaIvs7W1FZ7FSk9PR0REhMgVcfN4IqK8YnAiIqJCx8vLCzVr1gQAyGQyjB49WvRRnM8xNjZGlSpVhLbYzznlJCkpCZmZmWKXQUSklRiciIio0DEwMMC6deuEdkhIiNzCEdpImxaIUOb69euoV68eVq5cKXYpRERaicGJiIgKpaZNm2LEiBFCe9q0aRg4cCASEhJErCpn2hyc/P394ebmhkePHuGHH37AnTt3xC6JiEjrMDgREVGhtXjxYmGhCJlMhu3bt2PSpEkiV6WcNgenpk2bokyZMgCAtLQ0XLhwQeSKiIi0D4MTEREVWqVLlxY+8Gfx8/NDenq6SBXlTJuDU9myZbFp0yZUqVIFZ8+exYQJE8QuiYhI6zA4ERFRoZZ9XycAiI+Px/Dhw7VukYPswen58+dITk4WsRpF7du3x6NHj9CyZUuxSyEi0koMTkREVKh5e3tj5MiRcvsRbdu2DdOmTYNMJhOxMnlVq1aFvr6+0H78+LGI1ShnaGgodglERFqLwYmIiAo1MzMzrF+/Hm/evEGrVq2Efm9vbyxZskTEyuTp6uqievXqQlvbpuvl5Nq1a1oVQImIxMLgRERERYKRkRH279+PevXqCX3Tp0/Hxo0bRaxKnjY/5/Sp5ORkTJo0CY0aNZJb+p2IqLhicCIioiKjRIkSOHbsGGxtbYW+kSNH4uDBgyJW9T+FKThNmzYNK1asAAB8//33ePDggcgVERGJi8GJiIiKlPLly+PkyZOoUKECAEAqlaJv3764dOmSyJUVruA0a9YsYcVCOzs7kashIhIfgxMRERU51apVw/Hjx4UFI1JSUtC1a1eEhISIWldhCk4VKlSAr68vpkyZgqtXr8LR0VHskoiIRCWR8YlPtalVqxYA4N69eyJXQkRUPF28eBFff/01UlNTAQBWVlYICAjAV199JUo9kZGRsLKyEtrv3r1DqVKlRKmFiKg4Ksjnc444ERFRkdW8eXPs3LkTOjof/7n777//8PXXXyMqKkqUesqXLw9zc3OhHRYWJkodRESUdwxORERUpHl4eMitCvf48WN07NgRcXFxGq9FIpEUqul6yrx79w7Lly/nEuVEVOwwOBERUZH37bff4rfffhPaN27cQI8ePYQpfJpUmIPT2bNn4ezsjO+//16rlnknItIEBiciIioWZsyYgcmTJwvts2fPYtCgQZBKpRqto7AGJ5lMhkWLFuHVq1cAgEmTJiEiIkLkqoiINIfBiYiIigWJRAJvb28MGDBA6PPz88PEiRM1Ou2ssAYniUSCjRs3omTJktDX18cvv/yCypUri10WEZHG6IldABERkabo6Ohg48aNePfuHU6cOAEAWLNmDcqXL485c+ZopIZPg5NMJoNEItHIvQuqUqVK2LFjB8qXL4+6deuKXQ4RkUZxxImIiIoVAwMD7N27F40aNRL65s6di0qVKmH06NFISEhQ6/2zbyablJSE169fq/V+qta+fXuGJiIqlhiciIio2DE1NcWRI0fkNnV9/fo11q9fDy8vL7Xe28LCAuXLlxfahWm6HhFRccbgRERExVLp0qVx4sQJ6Ovry/VfvnxZ7fe2t7cXvi8Kwemff/7BmDFjxC6DiEitGJyIiKjYqly5Mrp16ybXl5SUpPbFIgrrAhGfSkxMxMCBAzFo0CCsW7cO//zzj9glERGpDYMTEREVa5s2bYKbm5vQDg8Px+bNm9V6z6ISnIyMjPDixQuhPXPmTKSlpYlYERGR+jA4ERFRsWZmZoaAgAC0adNG6Js0aRKePXumtnsWleCkq6uLrVu3okSJEmjWrBkuXrwIAwMDscsiIlILBiciIir2dHR0sGnTJlhaWgIA4uPjMXjwYLVtjps9OD19+hTp6elquY8mVK1aFQEBATh37hyqVq0qdjlERGrD4ERERATA2toaa9euFdoBAQFYvHixWu5VrVo16Oh8/Cc4IyMD4eHharmPptSuXRu6urpil0FEpFYMTkRERP+vb9++GDhwoNCeM2cOrl+/rvL7GBoawsbGRmgX5ul6OZFKpUhOTha7DCIilWFwIiIiymblypWoXLkygI+jQYMGDUJSUpLK71NUnnNS5uXLl2jbti3GjRsndilERCrD4ERERJSNpaUltmzZAolEAgB4+PAhpk+frvL7FNXgdPfuXTg5OeH8+fPYtGkTdu/eLXZJREQqweBERET0iZYtW8LLy0tor1y5EsePH1fpPYpqcHJwcJDb4PfMmTMiVkNEpDoMTkRERErMnz8fTk5OQnvYsGF4+/atyq5fVIOTnp4etm3bBisrK2zatEluwQ0iosKMwYmIiEgJQ0ND/PPPPzA0NAQAREZGYvTo0ZDJZCq5fvbg9PLlSyQmJqrkutrA1tYWT58+xdChQ4Upj0REhR2DExERUQ5q166NhQsXCu19+/Zh8+bNKrl25cqVhVAGAI8fP1bJdbWFkZGR2CUQEakUgxMREdFnTJ48GW3atBHakyZNwrNnzwp8XR0dHdjZ2QntojRdLyd3794tUiNrRFS8MDgRERF9ho6ODjZt2gRLS0sAQHx8PAYPHgypVFrga2efrhcaGlrg62mrzMxM/Pnnn2jQoIHcohtERIUJgxMREdEXWFtbyy1yEBAQgMWLFxf4ukV1gYhPbdy4EVOmTEFqairWrVuHAwcOiF0SEVGeMTgRERHlQt++fTFw4EChPWfOHFy/fr1A16xSpYrw/e7duzFs2DCsXr0aAQEBiI+PL9C1tcngwYPh4uICAKhQoQLMzMxEroiIKO8kMlUtD0QKatWqBQC4d++eyJUQEZEqxMTEwMnJCS9evADwcc+i69evw8TEJF/X8/Dw+Ozoi62tLZydnVG3bl3hfytXrlwoV6oLDQ3FnDlzsHLlSpQpU0bscoiomCrI53MGJzVicCIiKnrOnz+P1q1bC8uST5gwAStWrMjXtZycnHDnzp08vaZkyZJwdnaWC1SOjo5cxY6IKBcYnLQUgxMRUdH0ww8/YMmSJUL72LFj6NChQ56vM3r0aKxfv15o16xZEyVLlkRISEiep+rp6+ujUqVKKFeuHMqWLYsyZcqgbNmyOX5fokSJQjlyRURUEAxOWorBiYioaEpNTUWjRo1w+/ZtAB+f27lz506ep6AlJCTAy8sLV65cgbu7O5YtWwYzMzNkZmbi2bNnuH37Nm7duiX87/Pnz1X2HvT19VGqVCmkp6cjLS0NFSpUwNdffw1ra2uUL18e5cqVE77Kly8PY2Njld07S2pqKv766y9MmDBBLdcnIvoUg5OWYnAiIiq67t69iwYNGiA1NRUAUKJECfTt2xfe3t5qW/zgw4cPuH37tvC1Y8cOpKSkqOVenzIzM1MIU5aWlggICMDr16/RtGlTrF69Gubm5rm63sOHDzFgwADcvHkTEydOxF9//aXmd0BExOCktRiciIiKtuXLl+P777+X6xs1ahTWrVunkft/OtWvU6dOGDhwIN6+fYvo6GjhK3v73bt3UNc//YaGhmjcuDHq1KkDJycn1KlTB7Vq1YKpqanCuZ9Odzx9+rTcRsNEROrA4KSlGJyIiIq2zMxMWFhYICEhQeirU6cOQkJCNHL/nKb6fY5UKsWHDx/w9u1b/PDDDzh06JBwrGbNmqhVqxaioqLw5s0bREVF4f379wWqUSKRoHr16nJhysnJCRUrVoS7uztCQkIwduxYLF26NN+rExIR5VZBPp/rqboYIiKi4kJHRwfdu3fHP//8I/S5u7tr7P5mZmZ5Ht3S1dVFmTJlUKZMGWzfvv2LwSs9PR1v374VglTW15s3b7B///4vbtwrk8kQFhaGsLAw7Nu3T+g3NjaGkZERzM3NER8fj8zMzDy9DyIiTeOIkxpxxImIqOjLz6hPUZH9vdetWxd9+/bF48ePERISgjt37uDu3btITk7O1bUGDx6MLVu2qLliIiruOFVPSzE4ERFRcSaVSvHkyRPcuXNHCFMhISF48uSJwrkmJiZ4//49DA0NRaiUiIqLgnw+11F1MURERETAx2mBNWrUQK9evfDLL79g3759ePz4MeLj4+Hh4SF3blJSEkaOHImLFy/Cw8NDWK2QiEhbMDgRERGRRpmZmWHr1q0YOXIkSpYsKfRv3boVLVu2xIEDBzBr1iwRKyQiUsTgRERERBpnZmaG9evXIzIyEi1atBD6s54g+PPPP1W64S8RUUExOBEREZFoDAwMsHfvXlSvXl3ok0gk8PHxQZUqVUSsjIhIHoMTERERiap06dI4dOgQLCwsAHwcdZo5cyZevXolcmVERP/D4ERERESic3BwgJ+fH3R1dQEAr1+/Rrdu3ZCYmChyZUREHzE4ERERkVZo27YtVq5cKbRv3LiBIUOGIDMzE0lJSSJWRkTE4ERERERaZMyYMZg8ebLQ3rdvH+rVq4eWLVsiPT1dxMqIqLhjcCIiIiKtsmzZMnTs2FFoh4SE4N9//8Uvv/wiYlVEVNwxOBEREZFW0dXVxc6dO1GrVi25/gMHDnDUiYhEw+BEREREWqdEiRI4fPgwypQpI/T9999/ePHihYhVEVFxxuBEREREWsnGxgb79++Hvr4+AODdu3fo0qULYmNjRa6MiIojBiciIiLSWk2aNIGvr6/QfvDgAfr27YuMjAwRqyKi4ojBiYiIiLTaoEGD8NNPPwntEydOYPTo0Xj+/LmIVRFRccPgRERERFrv119/Re/evYW2r68vnJyc0LdvX8yYMQNhYWEiVkdExQGDE4CWLVtCIpEo/frvv//ELo+IiKjY09HRwebNm+Ho6Cj0xcbGYvfu3Vi8eDEcHR2xceNGESskoqJOIpPJZGIXIbb79+8jLi5Orm/ChAlIT0/H7du3833drGVU7927V6D6iIiI6KPLly+jWbNmSo/p6uriwYMHsLOz03BVRFRYFOTzuZ6qiymMatasKdf+8OEDQkJCMHfuXHEKIiIiIqUOHz6c4zGpVApfX18sXLhQgxURUXHBqXpK+Pv7Iz09HX379hW7FCIiIsomPDy8QMeJiPJLo8Hp+vXrWLRoEXr27Alra2vhOaIvSU5OxuzZs1GjRg0YGRmhYsWKGD58OF69eqWWOnft2oX69evD1tZWLdcnIiKi/LGxsfns8WfPnkEqlWqmGCIqVjT6jJOHhwcOHDig0P+5ElJSUtCqVSsEBQXBysoKzZo1Q3h4OK5du4ayZcsiKCgI1apVU1mNb9++hZWVFX777TdMmzatQNfiM05ERESqFRYWBkdHx8+Go2bNmuHEiRMwNjbWYGVEVBgUmmec3N3d4eTkBFdXV7i6usLGxgapqamffc38+fMRFBQEd3d3nDx5EmZmZgAAb29veHl5Yfjw4Th//rxwfkxMDCIjIz97TRMTE1SpUkXpsb179yIjIwPffPNN3t4cERERqZ2dnR18fHwwcuTIHMPTpUuXMGrUKGzdulXD1RFRUSbqqnpGRkZITU3NccQpLS0N5cqVQ2xsLG7cuIF69erJHXd2dkZISAiCg4NRv359AMDatWsxduzYz963RYsWcmEruzZt2iApKQlXrlzJ+xv6BEeciIiI1CMsLAy+vr4IDw+HjY0NqlSpggkTJiAzMxMAYGZmhpMnT8Ld3V3kSolImxSaEae8CggIQGxsLGxtbRVCEwD07t0bISEhOHTokBCcxowZgzFjxuTrfm/evMGFCxewdOnSAtVNRERE6mVnZ6ewel6VKlXQvXt3SKVSJCQkoH379jh58iTc3NxEqpKIihKtDk5Zeyi5uLgoPZ7VHxISopL7+fn5ITMzE3369MnT67KS66eePHnCBSaIiIg0pHPnzjh06BA8PDyQlpaG+Ph4ITzVq1cPBgYGYpdIRIWYVi9H/vz5cwCAtbW10uNZ/RERESq5365du9C0aVNUqlRJJdcjIiIizerYsSP8/f2FkBQXF4e2bdvC3t4emzZtErc4IirUtHrEKSEhAcDHxRyUMTU1BQDEx8cX+F6vX7/G5cuXsWLFijy/Nqc5kjmNRBEREZH6dOrUCXv37kXPnj2Rnp6OhIQEJCQkYNiwYXj58iVmzZoldolEVAhpdXDSpIoVKwoPlBIREVHh1qVLFyE8ZWRkCP1v3rwRsSoiKsy0eqpe1tLjSUlJSo8nJiYCAMzNzTVWExERERUOXbt2xd69e6Gn97/fE2/duhXXr18XsSoiKqy0Ojhl7bX08uVLpcez+qtWraqxmoiIiKjw6NatG/z8/KCrqwsAiI2NRbt27XDjxg2RKyOiwkarg5OzszMA5PjDLavfyclJYzURERFR4dK9e3fs2bNHGHn68OED2rZti5s3b+LYsWN48uSJyBUSUWGg1cGpSZMmsLCwwJMnT3Dr1i2F435+fgA+DsUTERER5aRHjx7YtWuXXHhq1KgROnfujDp16uDChQsiV0hE2k6rg5OBgQEmTJgAABg/frzwTBMAeHt7IyQkBC1atBA2vyUiIiLKSc+ePbFz505h2l56ejpkMhmSk5PRvn17REdHi1whEWkziUwmk2nqZkeOHMG8efOE9rVr1yCTydCoUSOh7+eff0bnzp2FdkpKClq2bImrV6/CysoKzZo1Q0REBK5evYqyZcsiKCgI1apV09RbyJOs5chzWq6ciIiING/Pnj345ptvFPoNDQ3RqVMn9OvXD507dxa2PSGioqMgn881OuIUHR2Nq1evCl9ZmS1736e/7TEyMsK5c+fw888/w8TEBPv370dERAQ8PT1x48YNrQ1NREREpJ369OmDr7/+WqE/NTUV/v7+6Nu3L8qVK4f+/fvjwIEDSE1NFaFKItI2Gh1xKm444kRERKSdEhIS8P333+P06dMwNDTEmzdv8OHDB6XnlihRAj169EC/fv3Qpk0b6Ovra7haIlKVgnw+Z3BSIwYnIiKiwiE9PR2nT5/Gzp074e/vj/j4eKXnlS5dGr169UK/fv3QvHlz4XkpIiocGJy0FIMTERFR4bNo0SL8+OOPAAAdHR1kZmYqPU9PTw9ly5aFm5sbKlWqhHLlyqFcuXIoX7683PdmZmaQSCSafAtElIOCfD7X+/IpRERERMWDTCZDcHCw0HZ2dsbkyZNx4MABHD16VO55p4yMDPz333/w9/f/7DWNjIzkAlXJkiVx9+5dREVFoVmzZvDx8YG5ubna3hMRqQZHnNSII05ERESFj1QqxeTJk3H06FFcuXIF5cuXBwDExsbiwIEDmDBhQo5T+fKjRIkSGDp0KDp37owWLVrAyMhIZdcmInmcqqelGJyIiIgKJ5lMhvfv36N06dIKx0aPHo3169cLbVdXVzRu3BhRUVF48+YNoqKiEBUVhbdv3+Y4zS8nJiYmaN26NTp37oxOnTqhSpUqBX4vRPQ/nKpHREREpEISiURpaHr79i3c3NwAAFeuXIG7uzuWLVsGMzMzhXOlUinevXsnBKmsULVp0ybcunVL6X2TkpJw+PBhHD58GABQu3ZtdOrUCZ06dULjxo25oh+RiDjipEYccSIiIio6kpKS0KZNGwQFBWH27NmYO3duvhZ9SEhIgJeXF65cuQInJyc0atQIZ86cwenTp5GYmJjj6ywsLPD111+jc+fO6NChgzCFkIhyj1P1tBSDExERUdExatQo+Pj4CO2DBw+ia9euKrt+amoqLl68iKNHj+LIkSMICwv77PlmZmbo3r071q5dq3TEi4gUMThpKQYnIiKiouP58+fo0KEDHjx4gNGjR2PNmjVqXWY8LCwMx44dw5EjR3D+/HmkpaUpPW/IkCHYvHmz2uogKkoYnLQUgxMREVHR8uHDByxfvhyzZ8+Gnp7mHhVPTEzEmTNncPToUfj6+iI9PV04ZmxsjMjISJQoUUJj9RAVVgxOWorBiYiIqPhIS0uDgYGB2u/z6ZRBAGjZsiWOHj0KY2Njtd+fqDAryOdzHVUXQ0RERFTcBAUFoXr16ggKClL7vby9vTFy5Ei5Vf/Onz+Pvn37yo1EEZFqMTgRERERFcCjR4/QpUsXvHjxAq1bt8ahQ4fUej8zMzOsX78eUVFRGDJkiNB/6NAheHp65nnvKCLKHQYnIiIiogK4f/8+4uLiAHzcu0lTK9zp6Ohgw4YN8PDwEPq2b9+OiRMngk9iEKkegxMRERFRAXh4eOD48eOwtLTE5s2b0apVK43dW09PDzt27EDr1q2FvtWrV+Pnn3/WWA1ExQWDExEREVEBtW7dGk+ePEG/fv00fm8jIyPs378fjRo1EvoWLFiApUuXarwWoqKMwYmIiIhIBUqVKqW039fXF/Hx8Wq9t7m5OY4ePYratWsLfdOmTVNYfY+I8o/BiYiIiEhN/vzzT4wYMQItW7ZEZGSkWu9VqlQpnDx5EtWqVRP6Ro8ejd27d6v1vkTFBYMTERERkRoEBgbiu+++AwDcuHEDY8aMUfs9rayscPr0aVSsWBEAIJPJMGjQIBw/flzt9yYq6hiciIiIiNTAzc0NU6ZMAQBUqVIFq1ev1sh9v/rqK5w8eVKYOpieno6ePXvi8uXLGrk/UVHF4ERERESkBjo6OvD29saKFStw/PhxYRRIE2rVqoXjx48LS6MnJyejc+fOuHnzpsZqICpqGJyIiIiI1GjChAlwdHRU6E9NTVXrfV1dXXHo0CEYGhoCAOLi4tC+fXuEhoaq9b5ERRWDExEREZGGJScno02bNvjxxx/Vullty5YtsWfPHujq6gIAoqOj0a5dOzx//lxt9yQqqhiciIiIiDRIKpVi0KBBCAgIwKJFizBkyBBkZGSo7X5du3bF5s2bIZFIAAAvXryAk5MTatasidGjRyMhIUFt9yYqSvTELoCIiIioOImJiUFYWJjQNjIyEkaE1GXgwIGIjY3F+PHjAQCxsbGIjY3FgwcPAADr1q1T6/2JigIGJyIiIiINKl26NC5dugQPDw+YmJhgzZo1wmiQOo0bNw4xMTH46aef5PqvXLmi9nsTFQWcqkdERESkYRYWFjh+/Dh2794NPT3N/R77xx9/RI0aNeT6GjVqpLH7ExVmDE5EREREIjA0NISpqalC/7///ouAgAC13FMikWDv3r1yI1yurq5quRdRUcPgRERERKQlHj9+jM6dO6Nt27bw9/dXyz1q166NIUOGCG1vb29IpVK13IuoKGFwIiIiItICUqkUPXr0QHR0NFJSUtC/f3+8fv1aLff68ccfhVGn0NBQ7N27Vy33ISpKGJyIiIiItICuri5WrVoFS0tLAMDff/+NihUrquVe9vb2+Oabb4T2/PnzkZmZqZZ7ERUVDE5EREREWqJ58+a4fPkyVq9ejUGDBqn1XjNnzhS+v3PnDg4fPqzW+xEVdgxORERERFqkVq1aGDt2rNJjqampKruPk5MTunfvLrTnz58PmUymsusTFTUMTkRERESFwKpVq9CwYUO8evVKZdfMvqfTv//+i1OnTqns2kRFDYMTERERkZbz9/fHxIkTERISAnd3dzx48EAl13V1dUX79u2F9oIFC1RyXaKiiMGJiIiISMvdvHlTmEYnk8lgbm6usmvPmjVL+P7ixYu4ePGiyq5NVJQwOBERERFpuV9//RUrVqxAqVKlcPz4cVhbW6vs2k2bNkWLFi2ENkediJRjcCIiIiIqBCZMmIDHjx+jVq1aKr929lGnkydP4tq1ayq/B1Fhx+BEREREVEiULFlSoS8lJQVr1qwp0D5Mbdq0QaNGjYQ2R52IFDE4ERERERVSmZmZGDp0KMaNG4eBAwfme7lyiUQiN+p08OBB3L59W1VlEhUJDE5EREREhdTy5cuxe/duAMDOnTuxYsWKfF+rc+fOcHZ2Ftq//fZbgesjKkoYnIiIiIgKqZEjR6Jt27YAgPbt22Py5Mn5vtano0579uzBw4cPC1wjUVHB4ERERERUSJUoUQJHjhzB3LlzsWfPHujr6xfoej179oSjoyOAj8ueL1y4UBVlEhUJDE5EREREhZiBgQHmzJmjdG+nvD7zpKOjg5kzZwrtf/75B0+fPi1wjURFAYMTERERURH07Nkz1KhRA7t27crT6/r164dq1aoBAKRSKRYvXqyO8ogKHQYnIiIioiLm7du36NChA54/f45+/frhjz/+yPVr9fT08OOPPwrtjRs34uXLl2qokqhwYXAiIiIiKmKeP3+Ot2/fCm1LS8s8vX7IkCGwtrYGAKSnp2Pp0qWqLI+oUGJwIiIiIipiXFxcEBgYCBsbG8ybNw+enp55er2BgQGmT58utNevX483b96ouEqiwoXBiYiIiKgIsre3x82bN/HTTz/l6/UjRoxA+fLlAQDJyclYvny5KssjKnQYnIiIiIiKKEtLS0gkEoX+3bt348WLF599rbGxMaZOnSq0V61ahffv36u8RqLCgsGJiIiIqBg5dOgQ+vfvD3d3d9y5c+ez544ZMwalSpUCACQkJOCvv/7SRIlEWonBiYiIiKiYePXqFfr164fMzEzhe6lUmuP5ZmZmmDJlitD+888/ERcXp4FKibQPgxMRERFRMVGpUiV4e3tDR0cHJUqUwI4dO6Crq/vZ10ycOBElSpQAAMTExGD16tWaKJVI6zA4ERERERUjo0ePhr+/P/z9/eHk5PTF8y0tLTFhwgShvWzZMiQmJqqzRCKtxOBEREREVMx069YNrVu3VuhPS0tTOnVvypQpMDExAfBxc10fHx+110ikbRiciIiIiAiZmZnw9PREv379kJKSInesbNmyGDNmjNBesmSJwjlERR2DExERERFhxowZ2LFjB/z8/PD1118jNjZW7riXlxcMDAwAAK9fv0a7du2QkJAgRqlEomBwIiIiIirm0tPTcffuXaFtaGgIY2NjuXMqVqyI6tWrC+3Lly/jm2++0ViNRGJjcCIiIiIq5vT19XHgwAEMGzYMzs7O2Lt3rzC6lF1mZqZc+9ixY1i3bp2myiQSFYMTEREREUFfXx8bNmzAhQsXhOXHP9W8eXOFvjFjxmDatGkKoYqoqNETuwAiIiIi0g4SiQQWFhYK/REREQgKCsKyZcsAAGfPnsXr16+RlJQEAFi6dCmePn2KrVu3CqvvERU1HHEiIiIiohy9f/8eHTt2RL9+/bBq1SqsXbsWYWFhCA0NhbOzs3Devn370KpVK7x580bEaonUh8GJiIiIiHL07bff4sGDBwA+rrwXGBgIALC2tsalS5fQqVMn4dxr166hUaNGuH//vii1EqkTgxMRERER5Wjx4sWwtbUFAMyePRtNmjQRjpmbm+PAgQMYN26c0BcREYHGjRvjzJkzGq+VSJ0YnIiIiIgoR3Z2dggMDMTChQsxd+5cheN6enpYuXIlli9fDolEAgCIjY1Fhw4d4Ovrq+FqidSHwYmIiIiIPqtcuXKYMWOGEIyyS0lJgUQiwZQpU7Bv3z5h/6eMjAyMGDECM2fO5Ip7VCQwOBERERFRvhw9ehQ1atTArVu3AAAeHh64ePEiKlSoIJyzcOFCDBgwACkpKSJVSaQaDE7/b/Xq1bC1tYWRkRGcnZ1x+PBhsUsiIiIi0lrBwcHo06cPXrx4gWbNmgnPNDVo0ABBQUGoXbu2cO6uXbvQpk0bREdHi1UuUYExOAHYtm0bJk6ciIEDB+LgwYNwcXFBjx49EBQUJHZpRERERFopNDQUqampQrt06dLC91WrVsXly5fRrl07oS8wMBBubm4IDQ3VaJ1EqiKRyWQysYsQW40aNdCiRQv4+PgIfQ0bNkSZMmVw9OjRfF+3Vq1aAIB79+4VuEYiIiIibXPs2DEMGDAAu3fvlgtJWdLT0zF+/Hi5z1glS5aEv78/WrRooclSiQAU7PN5sR9xSkpKwuPHjxX+Y2/Tpg3OnDkj95sUIiIiIvqfjh07Ijw8XGloAgB9fX2sW7cOv//+u9D34cMHtGzZEh06dEBCQoKmSiUqMI0Gp+vXr2PRokXo2bMnrK2tIZFIlK7O8qnk5GTMnj0bNWrUgJGRESpWrIjhw4fj1atXBa4pJSUFMpkMBgYGcv2GhoZIS0vDs2fPCnwPIiIioqLKwsJCoU8mk2HFihVISkqCRCLBtGnTsGfPHujq6grnnDhxAp6enhqslKhgNBqc5s2bhx9//BH+/v65Dj0pKSlo3bo15s2bh4SEBHTv3h2VK1fGxo0bUa9ePTx9+rRANZUqVQolS5bEv//+K9ef1X7//n2Brk9ERERU3Pz000+YNGkS2rRpg7dv3wIAevfuDRsbG7nzDh48yAUjqNDQ0+TN3N3d4eTkBFdXV7i6usLGxuaLU+Hmz5+PoKAguLu74+TJkzAzMwMAeHt7w8vLC8OHD8f58+eF82NiYhAZGfnZa5qYmKBKlSpCe/To0Vi5ciXc3d3RpEkT7Ny5EydPngQA6OgU+9mMRERERLl2+PBhLFy4EAAQFBSE6dOnY8OGDQA+Pgrx5MkT4dz09HT07t0bp06dUpj9Q6RtRF0cwsjICKmpqciphLS0NJQrVw6xsbG4ceMG6tWrJ3fc2dkZISEhCA4ORv369QEAa9euxdixYz973xYtWsiFrcTERAwcOBAHDhwAAFSqVAnffvstfvnlFzx79kzhtyO5xcUhiIiIqLjJyMjA+PHjsX79etSuXRuXLl2CpaUlACAhIQFeXl44dOgQ/vvvP+E1o0ePxpo1a3L1CAdRQRTZxSECAgIQGxsLW1tbhdAEfBzyBYBDhw4JfWPGjIFMJvvsV/bQBACmpqbYv38/Xr9+jbt37+LZs2cwNzdHuXLl8h2aiIiIiIojPT09rF27FsuXL8exY8eE0AQAZmZmWLduHV69eoUhQ4YI/evWrcOaNWtEqJYo9zQ6VS+vbt++DQBwcXFRejyrPyQkRCX3s7KygpWVFVJTU7Fx48ZcP7CYlVw/9eTJE9ja2qqkNiIiIqLCQiKRYMqUKUqPpaSkwMjICOvWrUNoaCiuXr0KAJg0aRIcHBzQunVrDVZKlHtaPeL0/PlzAIC1tbXS41n9ERERBbrPwYMHsXbtWpw7dw7//PMPmjZtioyMDMycObNA1yUiIiKi/4mJiUHDhg2xYMECGBoawt/fHxUrVgQASKVS9OnTp8ALfxGpi1aPOGWt7W9iYqL0uKmpKQAgPj6+QPfR1dXFypUr8eTJE5iZmaFr165YtGiR0uU1lclpjmROI1FERERExU1qaio8PDxw584d3LlzBy9evMCaNWtw4MABNGvWDCkpKXj//j26deuGwMBAlChRQuySieRo9YiTpnTu3Bl3795FcnIyoqOj4evri3LlyoldFhEREVGR8e7dO7kFIUqXLg2JRIIGDRrA19dX6L937x4GDRqEzMxMMcokypFWB6espceTkpKUHk9MTAQAmJuba6wmIiIiIsq7ihUrIiAgAO7u7hgyZAjmz58vHOvfvz9+/PFHoX3o0CH8/PPPYpRJlCOtnqqXtdfSy5cvlR7P6q9atarGaiIiIvq/9u47LIpr/x/4e+kgCCqIigpKMRcUBexgsPeKFTSKoEajxlhi9MYSQ270auCamMQEjCVRMLFrrPGqqCAWvJYYFWygWEBsVGnn94e/na+bXVjqLuX9eh6fxz3nzJzPzM7s8tmZOYeISsfS0hJHjx6Fnp6e0tDjX3zxBf78809ptOQvv/wSLVu2hK+vrzZCJVJSqa84tW7dGgBw8eJFlfXycldXV43FRERERESlZ2JionKy22PHjmHOnDlwdnaWygICAhAbG6vJ8IgKVakTJ09PT5ibm+P27du4dOmSUv327dsBAIMGDdJwZERERERUXi5evIhhw4Zh4MCBmDt3LurWrQvgzdDlQ4YMUXg2ikhbKnXiZGBggBkzZgAApk+fLj3TBAAhISG4cuUKvL294eHhoa0QiYiIiKgM5KPtpaenIyMjA3PmzMGGDRugq6sLAEhKSsKwYcOQnZ2t5UipptNo4rR//3507NhR+peTkwMACmX79+9XWGbRokXo0KEDoqOj4ejoiNGjR6Njx46YO3curKysFEZhISIiIqKqxdDQEOvWrYOpqSl0dXURERGBwYMH4+uvv5banD17FlOnToUQQouRUk2n0cEhUlJSpNmh3/Z2WUpKikKdkZERjh8/juXLlyM8PBy7d+9G3bp14e/vj6CgoEInxyUiIiKiqqF37944efIkrl+/jn79+gEAPvjgA1y5cgWhoaEAgE2bNsHV1RVz5szRZqhUg8kEU/cKI58At7AJcomIiIiocDk5OejRowdOnz4NANDR0cHvv/8uJVdEJVWWv88r9TNORERERFRzGRgYoEOHDtIofAUFBRgzZgxu3Lih5cioJmLiRERERESVUmhoKIKDg5GTkyPN+/Tq1Su0bt0a/v7+SE9P13KEVJMwcSIiIiKiSumvv/6S/m9jYyP9PycnB5s2bcKsWbO0ERbVUEyciIiIiKhS+s9//oMVK1bAxsYGUVFRsLa2Vqjftm0bcnNztRQd1TRMnIiIiIioUpLJZPjkk0/w119/oWnTphg8eLBCfVpaGqZMmcJhykkjmDgRERERUaVWu3ZtAEBISAgmT54svQaAjRs34p///Ke2QqMahIkTEREREVUJpqamCA0Nxf3792FhYSGVr1ixAqtXr9ZaXFQzMHEiIiIioiplxYoVePHihULZ7NmzsWXLFu0ERDUCEyciIiIiqlLmzZsHLy8vAECtWrWkcn9/fxw5ckRbYVE1x8SJiIiIiKqUunXr4o8//kBQUBBiYmJgaWkJAMjLy4OPjw/OnTun5QipOmLiRERERERVjpGRERYtWoSWLVviwIED0pWnjIwM9O/fHzdv3tRyhFTdMHEiIiIioiqtXbt22LVrF/T19QEAqamp6NKlCx4+fKjlyKg6YeJERERERFVer169EBwcLL1OSUlB+/btlQaRICotJk5EREREVC24ubnByMhIep2UlITBgwcjKytLi1FRdcHEiYiIiIiqBS8vL5w9exampqZS2alTp+Dn54e8vDwtRkbVARMnIiIiIqo2XF1d8eDBAwQEBEhlu3fvxrRp0yCE0GJkVNUxcSIiIiKiasXc3Bw//vgjBg0aJJWtW7cOgwYNwuPHj7UYGVVlTJyIiIiIqNrR09PD1q1b4enpKZXt378fLi4uHKqcSoWJExERERFVSyYmJti3bx8cHByksmfPnsHV1RVTpkxBenq6FqOjqoaJExERERFVW3Xq1MGJEydgYWEhleXk5CAsLAxz587VXmBU5TBxIiIiIqJqzcbGBmfOnIFMJlMo37lzJwoKCrQUFVU1TJyIiIiIqNp755134OPjo1D29OlTjBw5EqmpqRxxj9Ri4kRERERENcLGjRsxduxYhUlyd+7cCXt7e4wePRo5OTlajI4qOyZORERERFQjmJqaYvPmzUhOTkb//v2l8pcvX2Lbtm3o1q0bMjMztRghVWZMnIiIiIioRjEzM8OePXswadIkhfLz588jOjpaS1FRZcfEiYiIiIhqHD09PYSGhuLf//63VJabm4t+/fph06ZNWoyMKismTkRERERUI8lkMsyfPx/btm2TnnvKy8uDv78/lixZwgEjSAETJyIiIiKq0UaMGIHIyEjUr19fKgsKCsLAgQOxbds2LUZGlQkTJyIiIiKq8dq3b4+YmBj84x//kMoOHDiAUaNGKdzORzWXnrYDICIiIiKqDJo1a4aoqCj4+PjgxIkTUvmCBQtQr1493Lp1C/fu3YOdnR0CAwPh6OiovWBJ42SCN29WGBcXFwDAtWvXtBwJERERERVXTk4ORo0ahT179hTaRldXF2FhYZg4caIGI6OyKsvf57xVj4iIiIjoLQYGBti1axc+/vjjQtvk5+dj8uTJiI+P12BkpE1MnIiIiIiI/kYmk2HlypUYNGhQoW3y8/Px/fffazAq0iYmTkREREREhTAxMSmy/ptvvsGwYcPw22+/ITMzU0NRkTYwcSIiIiIiKoSdnV2R9QUFBdi9ezdGjx4Na2trvPfeezhw4AByc3M1EyBpDBMnIiIiIqJCBAYGQldXt1ht09PTsXnzZgwYMAANGzbE1KlTcfLkSRQUFFRwlKQJTJyIiIiIiArh6OiIsLAwlcnTwoULcejQIYwfPx5mZmYKdampqfjxxx/h7e0NW1tbzJs3DxcvXgQHtK66OBx5BeJw5ERERETVQ3x8PNavXy/N4/Tee+/B2dlZqs/KysL+/fsRHh6OAwcO4PXr1yrXY2BggFatWiEsLAxubm6aCp/+v7L8fc7EqQIxcSIiIiKqOXJycjBs2DCMHTsWubm5CA8Px9GjRwu9Vc/DwwN+fn4YPXo0bGxsNBxtzcR5nIiIiIiItEgIgRkzZuDAgQMYN24ckpKScOjQITx8+BBr1qxROTpfbGws5s6diyZNmqB79+5Yt24dnj9/roXoqTiYOBERERERlVFiYiK2bt0K4E0SFRcXBwCwtrbGjBkzMG7cuEKXFULg+PHjmDx5MqytrTF06FD8+uuvHN68kuGtehWIt+oRERER1Rx//fUXBg8eDCsrKxw/fhxGRkZSXXp6OubOnYszZ86gU6dOCAwMxJ49exAeHo579+6pXJ+pqSmGDh0KPz8/9OzZE/r6+hrakuqLzzhVUkyciIiIiGqW1NRU5OXlwdrauljthRA4e/YswsPD8euvvyI5OVllu3r16sHa2ho5OTno3r07goODYWpqWp6h1whMnCopJk5EREREBADnz5/HjRs38N577xXaJi8vD8eOHUN4eDh27tyJtLS0Qtv269cP+/fvh0wmq4hwqy0ODkFEREREVEk9evQIQ4cOxfjx4zF//nzk5+erbKenp4fevXtj48aNePLkCbZv3w4fHx8YGhoqtT148CDc3NywdetW5OXlVfQmEJg4ERERERFVqClTpuDhw4cAgJCQEFy+fFntMsbGxhg+fDh27NiBJ0+ewNvbW6nN5cuX4evrixYtWuCHH35AVlZWucdO/4eJExERERFRBVqzZg1atWoFAPjmm2/g7u5eouXNzc3x+++/Y8qUKWjevDmaNm2qUH/nzh1MmzYNdnZ2WL58OV68eFFeodNb+IxTBeIzTkREREQEAGlpadi6dSsmT55cLuu7evUqVq5ciYiICKVb/8zMzDB16lR89NFHaNSoUbn0V13wGSciIiIiokrMzMys0KTp1KlTKOm1jFatWuGXX37BrVu3MGPGDIWhz9PS0rBq1So0a9YMU6ZMQXx8fJlipzeYOBERERERacn69evx7rvv4v3330dOTk6Jl7ezs8OaNWuQkJCARYsWwcLCQqrLyclBWFgYWrRogVGjRiE2NrYcI695mDgREREREWlBdHQ0pk6dCgAICwvDrFmzSr2u+vXrIygoCImJiQgODla4RU8IgW3btqFt27awtbXFhQsXyhx7TcTEiYiIiIhIC5o3bw4PDw8AbxKfhQsXlnmdZmZmmDNnDu7cuYOffvoJLVq0UKhPTExE+/btMXPmTDx9+rTM/dUkTJyIiIiIiLSgQYMGOH78OCZNmoRdu3YpjZZXFoaGhggICMC1a9eU1iuEwLfffgsHBwcEBwfj9evX5dZvdcbEiYiIiIhIS4yMjBAWFobOnTsr1aWnp5d40Ii/09XVRd++fVXWvXz5EvPmzYOLiwt27txZ5r6qOyZORERERESVTE5ODgYMGIAxY8YgMzOzTOsKDg7GlClT0KpVKwQGBuKLL75A7dq1pfrbt29j+PDh6Nq1KweQKALncapAnMeJiIiIiEpKCIFp06bhxx9/BAC4u7vj2LFjMDc3L7c+UlJS8Nlnn+HHH39Umgdq/Pjx+Ne//oXGjRuXW3+VBedxIiIiIiKqJnJycnD79m3ptYuLi8IVovJgZWWF7777DleuXEH//v0V6n7++Wc4OTlh6dKlyMjIKNd+qzImTkRERERElYihoSEOHjyIWbNmoWPHjggNDYVMJquQvpydnbF//34cPnwYLVu2lMqzsrLw+eefw9HRERs3bkRBQUGF9F+V8Fa9CsRb9YiIiIioLLKysmBsbKyRvvLy8rB+/XosXrwYycnJCnX16tWDubk5evbsieDgYJiammokpvLGW/WIiIiIiKohVUlTbGwshg8fjpcvX5ZrX3p6epgyZQri4+OxcOFCGBoaSnWpqam4c+cOQkNDMWfOnHLtt6pg4kREREREVEU8evQIQ4YMwc6dO9GhQwfExcWVex+1a9fGl19+iRs3bmDMmDFK9b/++iuysrLKvd/KjokTEREREVEVsXbtWiQlJQEAbt26hfv371dYX3Z2doiIiMCQIUMUyl+9eoXu3bsjJSWlwvqujJg4ERERERFVEZ999hmWLFkCAFi9ejV69OhR4X1u3rwZEydOhJmZmVQWExODzp0749atWxXef2XBwSEqEAeHICIiIqKKcOHCBXh4eFTYaHuq5OXlYcaMGdL8UgBgaWmJffv2oWPHjhqLoyw4OAQRERERUQ3Stm1blUnTDz/8oDQiXnnR09PD2rVrsXz5cqns6dOn6NatG3bt2lUhfVYmTJyIiIiIiKqBjRs3Ytq0aWjXrh0uX75cIX3IZDIsWLAAmzdvhr6+PgAgOzsbw4cPx5o1ayqkz8qCiRMRERERURUXHx+P999/HwCQmJiI6dOnoyKfyBk7diwOHz4Mc3NzAIAQAh9++CHmzp1bbSfLrfaJ04ULFzB+/Hg4ODhAJpNh0aJFpWpDRERERFRZOTg4YMWKFdDR0YGVlRW2bNlS4c8/devWDVFRUWjSpIlUFhISgtGjRyM7O7tC+9aGap84RUVFISYmBl5eXlJGXJo2RERERESVlUwmw+zZs3HgwAHs3LkTtra2GunXxcUFMTExaNOmjVS2fft29OzZE6mpqRqJQVOqfeI0c+ZMxMXFYePGjbCwsCh1GyIiIiKiyq5Pnz7w8vJSKk9NTUViYmKF9NmoUSOcPHkSffr0kcqioqLg6emJO3fuVEif2lDtEycdHfWbWJw2RERERERVUW5uLkaMGIF27dohKiqqQvowMzPDvn37EBAQIJXdvHkTnTp1wvnz5yukT00rt4whNjYWK1asgI+PDxo3bgyZTFas+yqzsrKwZMkSODk5wcjICI0aNUJAQIA0IzIREREREZXerFmzcOLECSQnJ6Nbt264cuVKhfSjr6+PdevW4fPPP5fKkpOT0bVrV+zbt69C+tSkckucgoKCsHDhQuzatavYSU92dja6d++OoKAgpKenY8iQIWjSpAk2bNgANze3anVpj4iIiIhIG9q1aycNHT569Gi0atWqwvqSyWRYvHgxNm7cCD09PQBAZmYmBg8eDBsbG7z//vtIT0+vsP4rkl55rahTp05wdXVFu3bt0K5dO9jZ2eH169dFLvPFF18gJiYGnTp1wpEjR2BqagrgzWgcc+fORUBAAE6cOCG1f/HiBR4/flzkOk1MTNC0adMybw8RERERUXUwceJEODk54d///jfCwsIqfLQ9AJgwYQJsbGzg4+ODtLQ0AMDDhw8RGhoKIQRCQ0MrPIbyVm6J0yeffFKi9jk5Ofj2228BAN99952UNAHAnDlzsGnTJkRGRiI2NhYeHh4AgK1bt2LatGlFrtfb21sh2SIiIiIiquk8PT2xd+9elXXZ2dkwMjIq9z579uyJ06dPw8PDA3l5eVL5mTNnyr0vTdDaqAhRUVF4+fIl7O3t4ebmplQ/YsQIAFC4H3Lq1KkQQhT5j0kTEREREVHxXLx4Ec2bN8fhw4crZP2urq4YPXq0Qlnnzp0rpK+KVm5XnErq8uXLAAB3d3eV9fLyinp4rTy5uLioLL99+zbs7e01HA0RERERkXqPHz/GkCFD8OjRI/Tv3x/ffvut2ru7SuOHH36Avr4+YmJi8O677yI4OLjc+9AErSVO8nHkGzdurLJeXp6QkFCmflJSUhAZGQngzYNpN27cwPbt21GrVi3069ev2G2IiIiIiKqTa9eu4dmzZwDeDOrg6OhYIf2Ymppiw4YNFbJuTdJa4iQfTcPExERlfa1atQBAepistK5du4aRI0dKr3fs2IEdO3bA1tYW9+7dK3YbdX2oUtiVKCIiIiIibevRoweioqIwZMgQzJs3Dz179tR2SJWa1hInTenatSuEEGVuQ0RERERU3bRp0wZXr16FmZmZtkOp9LQ2OIR8FL3MzEyV9RkZGQDAN5GIiIiIqALVrl1b5RDlS5YswbZt27QQUeWktcRJPtfSgwcPVNbLy21tbTUWExERERERAT///DOCgoIwatQoLF26FAUFBdoOSeu0lji1bt0awJshEFWRl7u6umosJiIiIiKimi4zM1Nhjtbdu3cjOztbixFVDlpLnDw9PWFubo7bt2/j0qVLSvXbt28HAAwaNEjDkRERERER1VwmJiaIjIxEixYtYGlpiT179hQ6oFtNorXEycDAADNmzAAATJ8+XXqmCQBCQkJw5coVeHt7w8PDQ1shEhERERHVSE5OTjh79iyOHDkCOzs7bYdTKZTbqHr79+9HUFCQ9DonJwcA0LFjR6ls8eLFGDBggPR60aJFOHr0KKKjo+Ho6IguXbogISEBZ8+ehZWVFdavX19e4RERERERUQmYm5vDzc1NqTw1NRWHDh3C2LFjtRCV9pRb4pSSkoKzZ88qlb9dlpKSolBnZGSE48ePY/ny5QgPD8fu3btRt25d+Pv7IygoqNDJcYmIiIiISPNyc3MxatQoHDt2DOfOnUNwcDD09Kr9DEcAAJngBEYVRj4BbmET5BIRERERVSX//Oc/sXz5cun1li1b4Ofnp8WISqYsf59r7RknIiIiIiKqWqZNmwZ3d3cAgJ+fH3x9fbUckeYwcSIiIiIiomJp0qQJTp06hcWLF2PdunUqJ86trpg4ERERERFRsZmYmODzzz+HsbGxUl1cXByq65NATJyIiIiIiKjMLl26BDc3N/j7+1fLCXOZOBERERERUZk8efIEgwcPRmZmJn7++Wf4+PhoO6Ryx8SJiIiIiIjKREdHB82aNZP+/9FHH2k3oApQMwZdJyIiIiKiCmNlZYU//vgDM2fOxD/+8Q/07t1bqouPj8dPP/2Ee/fuwc7ODoGBgXB0dNRitKXDeZwqEOdxIiIiIqKaRJ5ayEfb27BhAyZPnoz8/Hypja6uLsLCwjBx4kSNx8d5nIiIiIiISOtkMpmUNMXHxyslTQCQn5+PyZMnIz4+XhshlhoTJyIiIiIiKnc//fSTUtIkl5+fj/Xr12s4orJh4kREREREROXu3r17ZaqvbJg4ERERERFRubOzsytTfWXDxImIiIiIiMpdYGAgdHV1Vdbp6uoiICBAwxGVDRMnIiIiIiIqd46OjggLC1NKnnR1dbFu3boqNyQ553EiIiIiIqIKMXHiRHh5eWH9+vXSPE4BAQFVLmkCmDgREREREVEFcnR0xPLly7UdRpnxVj0iIiIiIiI1mDgRERERERGpwcSJiIiIiIhIDSZOREREREREajBxIiIiIiIiUoOJExERERERkRpMnIiIiIiIiNRg4kRERERERKQGEyciIiIiIiI1mDgRERERERGpwcSJiIiIiIhIDSZOREREREREajBxIiIiIiIiUoOJExERERERkRpMnIiIiIiIiNRg4kRERERERKQGEyciIiIiIiI1mDgRERERERGpIRNCCG0HUV2ZmZkhNzcX9vb22g6FiIiIiKjGu337NvT19ZGWllbiZXnFqQLVqlUL+vr62g4Dt2/fxu3bt7UdBpUQ3zft4H6n0uBxox3c76RpPOZKr7LsO319fdSqVatUy/KKUw3g4uICALh27ZqWI6GS4PumHdzvVBo8brSD+500jcdc6VWHfccrTkRERERERGowcSIiIiIiIlKDiRMREREREZEaTJyIiIiIiIjUYOJERERERESkBkfVIyIiIiIiUoNXnIiIiIiIiNRg4kRERERERKQGEyciIiIiIiI1mDgRERERERGpwcSJiIiIiIhIDSZOREREREREajBxIiIiIiIiUoOJUzWVlZWFJUuWwMnJCUZGRmjUqBECAgKQlJSk7dCoECdOnIBMJlP77/PPP9d2qFVSbGwsVqxYAR8fHzRu3Fjan4XZu3cvJkyYgFatWsHS0hL6+vqoX78++vfvj99//12DkZO2ZGZmYvfu3QgMDESLFi1gZGSEWrVqoXXr1vj888+Rnp6u0L6goACnTp3C/Pnz4eHhATMzMxgaGsLe3h5Tp07F3bt3tbQlVUtJ97vcw4cPMWPGDDg4OMDQ0BAmJiZwdXXF0qVLkZaWpuGtoKooJCQEPj4+cHR0hLm5OQwNDWFra4vx48fj6tWrKpfhcacsNTUV9evXh0wmg4ODg8o2VfU7lhPgVkPZ2dno1q0bYmJi0LBhQ3Tp0gX37t3DuXPnYGVlhZiYGDRv3lzbYdLf3LhxAytWrFBZl5+fj82bNwMAjh07hm7dumkytGph6NCh2LNnj1J5YR+BI0aMwM6dO+Hi4oKmTZvCzMwM9+7dw9mzZwEACxcuxJdfflmhMZN2rVu3DpMnTwYA/OMf/0DLli3x6tUrREdHIy0tDe+88w4iIyNRv359AMCtW7fg6OgIAGjQoAHat28PXV1dnDt3DklJSTAzM8OBAwfg5eWltW2qCkq63wEgPj4enp6eSElJgZ2dHdzd3ZGdnY3o6Gi8ePECzs7OiI6Ohrm5ubY2i6oAS0tLZGRkwNXVFTY2NgCAa9euIS4uDvr6+ti5cycGDhwotedxp5q/vz9+/vlnCCFgb2+PW7duKbWpst+xgqqdTz/9VAAQnTp1EmlpaVJ5cHCwACC8vb21FxyVyoEDBwQA0aRJE1FQUKDtcKqkFStWiMWLF4u9e/eKR48eCUNDQ1HUR+DFixfF06dPlcpjYmKEqampkMlk4sqVKxUZMmnZxo0bxZQpU8Rff/2lUP7w4UPh5uYmAAhfX1+p/NatW6JXr17iv//9r8J5mp2dLfz9/QUA0bRpU5GTk6OxbaiKSrrfhRBi2LBhAoD44IMPRF5enlT+4sUL0bFjRwFALFmyRCPxU9V1+vRpkZWVpVT+3XffCQDC2tpa5ObmSuU87pQdPXpUABBTpkwRAIS9vb3KdlX1O5aJUzXz+vVrYW5uLgCIixcvKtW7uroKAOLChQtaiI5Ky8/PTwAQCxYs0HYo1Ya6xKkogYGBAoD4+uuvyzkqqiqio6MFAGFoaChev36ttn1mZqb02XzixAkNRFg9Fbbf69WrJwCIR48eKS2zc+dOAUD069dPk6FSNWNvby8AiMuXL0tlPO4UZWZmCnt7e+Hs7Czi4uKKTJyKUpm/Y/mMUzUTFRWFly9fwt7eHm5ubkr1I0aMAADs27dP06FRKWVkZEi3mL333ntajoYAQF9fHwBgYGCg5UhIW1q3bg0AeP36NVJTU9W2NzY2hpOTE4A3z0RQ6RS23w0NDdUuW69evQqLi6o/VZ/7PO4ULVu2DHfu3MEPP/wg7a/SqMzfsUycqpnLly8DANzd3VXWy8uvXLmisZiobHbu3ImMjAy4ubnB2dlZ2+HUeFevXsWvv/4KfX199OrVS9vhkJbcuXMHwJsv+Lp166ptX1BQgISEBABvnn+i0ilsv/fu3RsAEBQUhPz8fKn85cuXWLlyJQAgICBAg5FSdfLLL7/g5s2bcHR0lJ5jBHjcve3KlSsIDg7GxIkT0aVLl1Kvp7J/x+ppOwAqX4mJiQCAxo0bq6yXl8u/wKnykw8KwatN2rFv3z7s2LEDubm5SExMRHR0NPT19REWFgZ7e3tth0da8vXXXwMA+vbtW6xfnSMiIpCcnAwrKyt07ty5osOrtgrb78uXL0dsbCy+//57HDhwAB4eHsjOzkZUVBSMjIywefNmDqpDxbZq1Spcu3YNGRkZuH79Oq5du4ZGjRohIiICurq6Ujsed28UFBRg0qRJsLCwkBLG4qpy37HavleQytfkyZMFAPHpp5+qrI+PjxcAhKOjo4Yjo9J4+PCh0NXVFbq6uirvoabSK+4zTkFBQQKA9M/Y2FiEhoaK/Px8DURJldH+/fuFTCYT+vr64tKlS2rbJyYmCktLSwFArF27VgMRVk/q9ntqaqro3bu3wvkKQPj4+Ijr169rIWKqqnr06KFwDNna2orIyEiVbXncCbF69WoBQGzYsEEqu3v3brGecapq37G8VY+oEouIiEB+fj569erF23u0ZNGiRRBCICsrC1evXsXEiRMxZcoUDBkyBDk5OdoOjzTsxo0bGDduHIQQWLVqlfTMTWEyMjLg4+ODp0+fYujQoZg6daqGIq1e1O33K1euoHXr1rh58yb27NmD58+f48GDB1i9ejUOHjwIT09P3Lx5U0vRU1Vz9OhRCCHw/PlznDx5Eo6OjvD29sa//vUvhXY87t7c6bRo0SJ4e3vD39+/xMtXue9YraZtVO5mz54tAIjZs2errL906ZIAINzd3TUcGZWGfOjdLVu2aDuUaqcso+rNnDlTABBfffVVOUdFldmDBw+Era2tACDmzJmjtn1OTo7o16+fACC8vLxEZmamBqKsftTt95ycHOHo6Ch0dHREbGysUr18Ko5Ro0ZpIlyqhnJycoSHh4eQyWTi3LlzUhmPOyEGDhwoDAwMlK6uFfeKkyqV+TuWV5yqmaZNmwIAHjx4oLJeXm5ra6uxmKh0rl+/jv/9738wNTXF0KFDtR0OvUX+vJmqCXWpenr27Bl69+6NhIQETJw4EV999VWR7QsKCjBhwgQcPHgQbdq0wb59+2BsbKyhaKuP4uz3mJgYxMfHo1mzZioHRho5ciQA4OTJkxUeL1VP+vr6GD16NIQQ0qjEPO7e+P3332FiYoKpU6eia9eu0r8xY8YAAJKSkqSyx48fF2udlfk7loNDVDPy2xcuXryosl5e7urqqrGYqHR++eUXAICPjw9MTEy0HA29zdLSEgCQkpKi5UhIE9LT09GvXz/89ddf8PHxQVhYGGQyWZHLzJw5ExEREXBycsLhw4dhYWGhmWCrkeLud/kPgubm5irXIy9//vx5xQVL1d7fP/d53P2fFy9eIDIyUmVddna2VJednV2s9VXm71hecapmPD09YW5ujtu3b+PSpUtK9du3bwcADBo0SMORUUkIIRAeHg6Ao+lVRvIvgUo54g+Vq9evX2PIkCE4d+4c+vTpozSqliqLFi3C999/j6ZNm+KPP/5A/fr1NRRt9VGS/S5//vPmzZtIS0tTqj9//jwAwM7OrsLiperv75/7PO7eEEKo/Hf37l0Ab/aXvKy4+6JSf8dq6x5BqjiffvqpACA6d+4s0tPTpXL5/bbe3t7aC46KJTIyUgAQNjY2lXZkmaquqGeckpOTRWhoqMjIyFCqO3LkiLCyshIAxPbt2ys6TNKivLw8MWzYMAFAdOnSReXx8HchISECgGjQoIGIi4vTQJTVT0n3e1ZWlqhfv74AIMaPHy+ys7OluqSkJNGqVasiR5slEkKI06dPi4MHDyp95+bk5IhvvvlG6OjoCGNjY5GYmCiE4HGnTlHPOFXl71iZEEJoI2GjipOdnY2uXbvi7NmzaNiwIbp06YKEhAScPXsWVlZWiImJQfPmzbUdJhVhypQpCAsLw8cff1ziORFItf379yMoKEh6fe7cOQgh0KFDB6ls8eLFGDBgAO7du4dmzZrBxMQEHh4eaNy4MTIyMhAXF4cbN24AAGbPno2QkBCNbwdpztdff42PPvoIADBs2DDUrl1bZbuvvvoKlpaWuHTpEtzd3SGEQKdOneDk5KSy/aRJk+Dl5VVRYVd5Jd3vALB7926MHDkSeXl5sLGxQdu2bZGVlYUzZ84gLS0N7u7uiIyMhKmpqaY2g6qYjRs3YuLEibC0tISHhwfq1auHp0+f4urVq3j06BGMjIywadMmjBo1SlqGx13h5N+j9vb2uHXrlsq6Kvkdq928jSpKZmamWLx4sbC3txcGBgaiQYMGwt/fX9y/f1/boZEa2dnZok6dOgKAuHz5srbDqTY2bNigNM/G3//J56DIyMgQK1euFP379xe2trbC2NhYGBoaCjs7OzFmzBhx/PhxrW4LacbSpUvVHjMAxN27d4UQQhw/frxY7d+e64SUlXS/y128eFH4+fmJxo0bC319fVGrVi3Rpk0b8eWXX3JEQ1Lrzp074p///Kfw9PQUDRs2lI4hFxcXMXPmTBEfH69yOR53qhV1xakqf8fyihMREREREZEaHByCiIiIiIhIDSZOREREREREajBxIiIiIiIiUoOJExERERERkRpMnIiIiIiIiNRg4kRERERERKQGEyciIiIiIiI1mDgRERERERGpwcSJiIiIiIhIDSZOREREREREajBxIiIiIiIiUoOJExFpVUZGBkJCQtCtWzdYW1vDwMAAderUQadOnbBkyRIkJiZqO8RyI5PJYGdnV+H9nDhxAjKZDP7+/hXeV0l89tlnkMlk2Lhxo0K5v78/ZDIZTpw4oZW4qpN79+5BJpOha9eu2g6lxLp27QqZTIZ79+5pO5QKsXHjRshkMnz22WfaDoWISomJExFpTXR0NBwcHDB37lycO3cOLVu2xIgRI9C5c2fcvn0bQUFBcHJywtGjR7UdaqVSWAJCVB1p6geHsuIPAETVn562AyCimunSpUvo0aMHsrOz8cknn2Dx4sWoVauWVF9QUIDdu3dj/vz5ePDggRYjrXrat2+P69evw9zcXNuhFMvy5cuxYMECNG3aVNuhkBb9/PPPyMzMhI2NjbZDqRDDhg1Dx44dYWlpqe1QiKiUmDgRkcYJIfDee+8hOzsbn332GZYuXarURkdHBz4+PujRowfu37+vhSirLhMTE7zzzjvaDqPYGjZsiIYNG2o7DNKy6p44m5ubV5kfM4hINd6qR0Qad+jQIfz5559o3LgxPv300yLbmpubo2XLltLrop6DKOz5jrdvbYuNjUW/fv1gYWGBunXrYtSoUdIVrYyMDMyfPx92dnYwMjJCy5YtsX37dqV+1D2rUJJnNYQQiIiIwJgxY+Dk5IRatWrBzMwM7du3x/fff4+CggKF9nZ2dli2bBkAYOLEiZDJZNI/+S1Cqp5x+vDDDyGTybB27dpCY/Hw8IBMJsOVK1cUyu/fv48ZM2bA3t4eRkZGqFu3LgYOHIjo6Gi121cchd3iZGdnB5lMBgBYt24dXF1dYWxsjAYNGuD999/HixcvVK4vLy8Pa9euRadOnVC7dm0YGxujTZs2WL16NfLy8pTaX7p0CfPnz4eHhwesrKxgaGiI5s2b44MPPsDDhw+V2r99nL169Qpz5sxBs2bNoK+vj48++kjt9qakpGDBggVwdnaGqakpzM3N4eTkhPHjx+PcuXNK7f/66y+MHTsWDRs2hIGBAWxsbDB+/HjcvHlTbV8AEBISAplMhk8++aTQNsOHD4dMJsPevXsVyp89e4aFCxfC2dkZxsbGMDc3R/fu3fH7778rraOs++Xv5438PAOAhIQEhWP97+d4ZmYmli9fDjc3N5iamsLU1BQdO3bEpk2bVPYlv/0vJycHn3/+Od555x0YGhpi6NChAIDs7Gz89NNPGDJkCJo3bw5jY2NYWFjg3XffxdatW1WuT95Xt27dFGL9+/ao+tzIzMxEUFAQWrZsKe3nwvoCSn9uEFHZ8IoTEWnc/v37AQAjR46Enp7mPobOnj2LqVOnomXLlujTpw8uXryIbdu24fLlyzh37hx69eqFhIQEvPvuu3j69CkiIyMxatQoHDx4EH369KmQmF6/fg0/Pz/Uq1cPzs7OcHd3R2pqKqKjozF9+nScO3dO4VmmESNG4OjRo7h8+TI8PT3h4OAg1TVo0KDQfsaOHYs1a9YgPDwc06ZNU6q/ceMGLl68iFatWsHV1VUqP3PmDAYMGIDnz5+jRYsWGDBgAFJSUnD48GEcOnQIW7ZswejRo8tnZxRi/vz5+Prrr9G1a1c4ODggKioKoaGhuH79OiIjI6U/IAEgKysLAwYMwPHjx1G3bl107NgRRkZGOHv2LGbPno3jx49j165d0NH5v98NV6xYgR07dsDV1RVeXl4A3iRTa9euxe7du3HhwgU0atRIKa6srCx4e3sjISEB3t7ecHd3R506dYrclrS0NHTo0AF3795FkyZN0KtXL+jp6SExMRFbt25F8+bN0b59e6n9f//7XwwaNAhZWVlwc3ND165dcePGDfzyyy/YtWsXDhw4gC5duhTZ55gxY/Dxxx9j69atWLFihcL+AoCXL19i//79qFevHvr16yeVx8XFoWfPnrh//z7s7OzQp08fpKWlISYmBoMGDcKqVaswb968ctkvqjg4OGDChAnYtGkTatWqhREjRkh1b19RTU5ORq9evXDlyhU0aNAA3t7eEEIgOjoa/v7+uHDhAtasWaO0/oKCAgwdOhQnT56Et7c3XF1dUa9ePQBvksBJkyahUaNGaNGiBdq3b4/Hjx8jOjoap06dwo0bNxQSoAkTJuD06dO4ffs2+vTpo3AumpqaFrmdaWlp6NatG2JjY2FlZYWBAwciIyMDx44dw6lTp3DmzBl8/fXXKpctyblBROVAEBFpmKenpwAgfvnllxIv6+3tLQCIu3fvKtXdvXtXABDe3t4K5UuXLhUABACxdu1aqTwnJ0f07NlTABDOzs6ie/fuIj09Xapft26dACDeffddhfVt2LBBABBLly4tUYwAhK2trUJZbm6u2LVrl8jJyVEoT05OFm3bthUARGRkpMrt2bBhg8r+jx8/LgCICRMmKJQ7ODgImUwmEhISlJZZtGiRACBWrFghlb18+VI0bNhQ6Orqis2bNyu0P3/+vKhTp44wNTUVycnJKuP4u8LinjBhggAgjh8/rlBua2srAIgGDRqIGzduSOUpKSnCwcFBABD//e9/FZb54IMPBAAxevRo8eLFC6n81atXon///krHgBBCHDt2TDx+/FihLD8/XyxbtkwAEBMnTlSokx9nAESnTp3E8+fPi7X9Qgixfv16AUAMHjxY5OfnK9QlJyeLq1evSq/T09OFtbW1ACC+/fZbhbYhISECgGjcuLHIyspSiu3v50CPHj0EAHHy5EmlmOTH+dSpU6WyvLw80apVKwFArFy5UiHW+Ph40axZM6Grq6sQb1n2ixAlO2/eJn9fZ82aJbKzs6Xyx48fS+fQwYMHldYJQDg4OIgHDx4orfPp06fijz/+EAUFBQrld+7cEXZ2dkJHR0cpzsKOY7nCPjdmzJghAIhu3bqJV69eSeXXr18X9evXFwDEvn37FJYpzblBRGXHW/WISONSU1MBAFZWVhrt18vLC1OnTpVe6+vrY+bMmQDeXHFZu3atwgAV/v7+sLS0xJkzZ5Cbm1shMenp6WHo0KHQ19dXKLeyssLy5csBAHv27CmXvsaOHQshBMLDw5XqwsPDIZPJ4OfnJ5WtX78ejx49wkcffYSxY8cqtG/bti0WL16M9PR0bN68uVziK0xQUBBatGghvba0tJTex5MnT0rlycnJCAsLQ5MmTbBhwwaF50nMzMzw008/wcDAQOl2RflQ+G/T0dHBkiVLYGNjo3T72tu++eYbWFhYFHtbUlJSAADdu3dXuOoFvHnP374t9bfffsOTJ0/QqVMnTJ8+XaHt7Nmz4eHhgQcPHmDHjh1q+x03bhwAYMuWLUp18rK33+N9+/bh6tWrGD58OD7++GOFWB0cHBAcHIz8/HyEhYWp7K+k+6W0Ll26hAMHDqBdu3YICQmBoaGhVGdtbY3Q0FAAKPQW1eXLl6scjKJevXro2bOn0hWbZs2a4dNPP0VBQQH27dtX5vgzMjLw008/QUdHB99//z3MzMykunfeeQeLFi0CgEKvOBX33CCi8sFb9Yioxujdu7dSWfPmzQG8eWbAyclJoU5XVxe2traIjY3F06dPK3QAg0uXLuHIkSNISEhAZmYmhBBIS0sDAMTHx5dLH2PHjsWyZcsQHh6OBQsWSOVnzpzBnTt34O3tjSZNmkjlR44cAQD4+PioXJ/8FjFVz+WUJ1Xvm/y9evTokVR24sQJ5Obmom/fvjA2NlZapkGDBnB0dMTVq1eRlZWl0CY1NRV79+7Fn3/+iRcvXiA/Px8AkJubi9TUVDx79gx169ZVWF/Dhg3Rtm3bEm2Lh4cHAGDVqlWwtrbGgAEDFP5YftupU6cAQClplRs3bhxiY2Nx6tSpQtvI+fj4YNq0adi+fTvWrFkjJepJSUmIjIyEnZ0dPD09pfZlee9Ls19KSx7n0KFDlRJRANIzT6rilMlkGDRoUJHrP336NE6cOIGkpCRkZ2dDCCEdc+VxXsbGxiIrKwtt27ZVOaDLe++9hw8//BBRUVEoKChQ2sbinhtEVD6YOBGRxsmfI5D/+q4pqn5Zlj9/UNgQyPL6169fV0hMOTk58Pf3R0RERKFt5AlUWTk6OqJdu3Y4f/48rl69ilatWgFQfcUBgPRQ+9t/UKvy9OnTcomvMI0bN1Yqkycbb78v8njDwsIKvRIi9+zZM+k9j4iIwJQpU5Cenl5o+7S0NKXEqTSjwPXo0QOzZ8/G6tWr4evrCz09Pbi7u6NXr14ICAiQEnkA0sAUhc1hJC9PSkpS22/t2rUxaNAgbNu2DYcOHZIShoiICBQUFMDPz0/h6op8X44dO7bIpEzVe6/J0fHkcX766adFDjSTnZ2tVFa/fn2FK1Rve/nyJXx8fHDs2LFC11ke56W699jCwgLm5uZ4+fIlnj9/Ln12yhX33CCi8sHEiYg0rk2bNoiKisLFixelW4jKw99HoPs7Vb9IF6euvON4W0hICCIiItCqVSusXLlSepBeX18fcXFxaNGiBYQQ5RbbuHHjcP78eYSHh2P58uXIy8vDb7/9BkNDQ4WH79/ejhEjRijcwvh3FT30eXHfG3m8bdq0QevWrYtsK/+DOSEhQRp9cPXq1RgwYABsbGykq1GdO3fGmTNnVL4HRkZGxd0EBSEhIXj//fexZ88eHD16FFFRUTh37hxWrlyJiIgIDB8+vFjrKemD/+PGjcO2bdsQHh4uJU6FJc3yfdm3b1+l2xjfpmpOotLul9KQx+nl5QV7e/sSLVtUnJ988gmOHTsGb29vLFu2DC1btoSFhQV0dXVx5MgR9OnTp1zPy6IU9T6X5+cWEanHxImING7AgAH47rvvsG3bNqxcubJEI+sZGBgAgMqrA5qa76moGEoax65duwC8+eXfxcVFoe7OnTuljLBwo0ePxpw5cxAREYEvv/wSR44cQUpKCoYNG6Y08lnjxo1x8+ZNLFiwQLrFrDKT//ru5eWlchQ1VQ4cOICcnBzMmzcPs2bNUqqviPcAAFq0aIH58+dj/vz5yM7OxrfffouPP/4Y06ZNkxIn+Uh+CQkJKtchv9pS3Alj+/Xrh7p162Lv3r1IT09HYmIiLl26BDc3Nzg7Oyu0le/LSZMmFTuR0wZ5nEOHDsXcuXPLbb27du2Crq4u9u7di9q1ayvUlecxoe49fvnyJV68eAFjY+NSjUxIROWLP1UQkcb17dsXLi4uePDgAf71r38V2fbVq1e4du2a9Fr+nFFcXJxS2z/++KN8Ay1EUTHExcUhMTGx2Ot6/vw5ANW33Pz2228ql5EnbqrmJFLH2toaPXv2REJCAqKiogq94gAAvXr1AvB/yV1l161bN+jq6uL3338v9mAeRe3/kydP4smTJ+UaoypGRkaYN28eGjZsiJSUFCQnJwP4v+eICruNUz4oh7rhyOX09fUxcuRIZGZmYvfu3VXmvdfX1y/0WK+oOJ8/f47atWsrJU1A+Z6XHh4eMDY2RmxsrMpnpuTvsaenJ68uEVUCPAuJSONkMhk2b94MIyMjfPbZZ1i4cCEyMjIU2gghsHfvXrRt2xbnz5+Xyr29vQEAwcHByMzMlMqPHTuG1atXayT+du3awcTEBAcPHkRsbKxU/vTpU0yaNKlEt+rJH+T+4YcfFMq3b9+On3/+WeUy8l+pizsB6t/Jb48MDQ3Fnj17YG5ujoEDByq1e//991G/fn2sXLkSoaGhStuVl5eHw4cP488//yxVHOXNxsYGAQEBuHfvHnx9fVUmPbdu3VIYhU6+/zdv3qxwDCYlJSmMwFhedu/ejZiYGKXy2NhYPHnyBKamptJodKNGjYK1tTVOnz4tjQ4n98033+DChQuwsbEp0RWht0fXi4iIgI6ODnx9fZXaDR8+HM7OztiyZQuCgoKUnpcRQiAqKgpRUVHF7ru0GjVqhCdPnqic1LVDhw7o1asXoqKiMH36dLx69UqpzeXLl3Ho0KES9enk5ITnz5/j119/VSj/z3/+g+PHjxcaJ1Cy87JWrVoICAhAQUEBpk+frnAMxsXF4YsvvgDwZgJrIqoEtDcSOhHVdKdPn5bmqTExMRE9evQQfn5+YsCAAVK5kZGROHr0qLRMZmamaNGihQAgmjZtKoYPHy46dOggdHR0xLx584qcx0nVvEeFzXsjV9jcMkuWLJHi69Onj+jbt6+oU6eO6Ny5s+jUqVOx56OJjIwUurq6AoDw8PAQvr6+0twzhW1PUlKSMDIyErq6uqJv374iICBABAYGSvO5FDaPk1xaWpowMTGR5rIJDAxU2U4IIc6cOSMsLS0FANGkSRPRr18/4efnJ7p37y4sLCwEALFr165Cl39baedxUqWwbczMzBS9evUSAEStWrWEp6en8PX1FYMHD5bmtxkyZIjU/vXr18LFxUWaE2f48OFiwIABwsTERHTu3Fl07txZ6b1Ud8wUZdasWQKAsLGxEQMHDhR+fn6ia9eu0jEQHBys0P7o0aPC2NhY4fhwc3MTAISpqanSvEzqYisoKJD2KwDRo0ePQmONi4sTzZo1EwBE/fr1Rc+ePYWfn5/o3bu3NL/Qf/7zn3LZL0IUfq7NnDlTABDNmjUTY8eOFYGBgWLlypVS/ZMnT6R9YmFhIbp27Sp9jjRp0kSa4+ltqs7Ft23evFnaR126dBG+vr7C2dlZ6OjoiNmzZ6s89i5cuCBkMpkwMjISQ4YMEYGBgSIwMFA8ffpUCFH4PE6vXr0SHh4e0n4eOXKk6N+/vzAyMhIAxIcffqgUX2nODSIqOyZORKRVaWlp4quvvhLe3t7CyspK6OnpCQsLC9GhQwexdOlScf/+faVlHjx4IHx9fUWdOnWEsbGxaNu2rdi2bZvaCXDLM3EqKCgQq1atEg4ODkJfX180btxYzJ07V2RkZJR4Is8zZ86I7t27izp16ggzMzPRuXNnsWPHjiJjO3z4sPD09BSmpqbSH3jyxKM4fzj5+vpKyx07dqzQdkII8ejRIzF//nzh4uIiTExMhImJibC3txdDhgwRGzduFGlpaUUuL6eJxEmIN5O3btq0SXTv3l3UrVtX6Ovri0aNGolOnTqJZcuWiZs3byq0f/bsmZg2bZqws7MThoaGonnz5uKTTz4p9L0sS4Lwv//9T8ydO1e0a9dO1K9fXxgaGgpbW1sxaNAghR8I3vbnn38KX19fYW1tLfT19UXDhg3FuHHjFCY+LUlsCxculN779evXFxnvixcvxBdffCHc3d2FqampMDIyEnZ2dqJPnz7iu+++EykpKSXquyiFnTfp6elixowZokmTJkJPT09lH1lZWeKbb74RnTt3Fubm5sLAwEA0adJEeHt7i1WrVil9jqhLnIQQYv/+/aJjx47CzMxMWFhYiJ49e4oTJ04Ueext2bJFuLu7S8nu29tT1MTZ6enpYtmyZcLZ2VkYGhoKMzMz4eXlJcLDw1XGxsSJSDtkQmhoWBgiIiIiIqIqis84ERERERERqcHEiYiIiIiISA0mTkRERERERGowcSIiIiIiIlKDiRMREREREZEaTJyIiIiIiIjUYOJERERERESkBhMnIiIiIiIiNZg4ERERERERqcHEiYiIiIiISA0mTkRERERERGowcSIiIiIiIlKDiRMREREREZEaTJyIiIiIiIjUYOJERERERESkBhMnIiIiIiIiNZg4ERERERERqcHEiYiIiIiISI3/B2y1UM+tdTzGAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Plot linear residuals\n", "n = 0\n", "lin_label = \"Linear residual\"\n", "for linear_residuals in all_linear_residuals:\n", " plt.semilogy(\n", " linear_residuals.index + n,\n", " linear_residuals[\"Residual\"]\n", " / all_linear_residuals[0][\"Residual\"].iloc[0],\n", " color=\"black\",\n", " label=lin_label,\n", " marker=\".\",\n", " markersize=2.5,\n", " zorder=30,\n", " )\n", " n += len(linear_residuals) - 1\n", " lin_label = None\n", "\n", "# Plot nonlinear residuals\n", "nonlin_xticks = [0] + list(\n", " np.cumsum([len(l) - 1 for l in all_linear_residuals])\n", ")\n", "plt.semilogy(\n", " nonlin_xticks,\n", " nonlinear_residuals[\"Residual\"] / nonlinear_residuals[\"Residual\"].iloc[0],\n", " color=\"black\",\n", " ls=\"dotted\",\n", " marker=\".\",\n", " label=\"Nonlinear residual\",\n", " zorder=40,\n", ")\n", "plt.xticks(nonlin_xticks)\n", "xticks = (\n", " range(len(all_linear_residuals))\n", " if nonlinear_residuals is None\n", " else nonlin_xticks\n", ")\n", "\n", "plt.xlabel(\"Cumulative linear solver iteration\")\n", "plt.legend();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The plot shows the convergence of the nonlinear solver (dotted line), along with\n", "the convergence of the linear solver that runs in each nonlinear iteration\n", "(solid line). A few things to note:\n", "\n", "- The residual converges down to almost machine precision, but that doesn't\n", " reflect the discretization error of the solution. It only shows that we have\n", " solved the discretized problem very accurately. To get an idea of the\n", " discretization error we would have to look at quantities such as constraint\n", " norms.\n", "- The Newton-Raphson nonlinear solver converges slowly at first, and then begins\n", " to converge quadratically once we are closer to the solution and hence the\n", " linearization is more accurate.\n", "- The linear solver needs only a few steps to converge, which is a feature of\n", " our multigrid-Schwarz preconditioner.\n", "\n", "You can read more about the elliptic solver in this paper:\n", "\n", "- N. L. Vu _et al_., A scalable elliptic solver with task-based parallelism for\n", " the SpECTRE numerical relativity code (2022),\n", " [arXiv:2111.06767](https://arxiv.org/abs/2111.06767)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "interpreter": { "hash": "5c837ee96a6a314af6ca82ef816f2b1d9c1a2b96687b8bdeaa8036bfb18cb0dc" }, "kernelspec": { "display_name": "Python 3.9.10 ('spectre')", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.10" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 } ================================================ FILE: docs/Examples/Examples.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Examples {#examples} - \subpage example_bbh_id ================================================ FILE: docs/Examples/plots.mplstyle ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Matplotlib style suitable for notebooks that get rendered in our documentation # # These settings configure matplotlib plots so they look good in our online # documentation, and have a consistent style. In a notebook, or when plotting # in a script, apply the style like this: # # import matplotlib.pyplot as plt # plt.style.use('path/to/plots.mplstyle') figure.dpi: 150 figure.facecolor: white ================================================ FILE: docs/Gallery.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond \cond NEVER Instructions for adding images or videos: 1. Send your media files to a SpECTRE core dev (see CONTRIBUTING.md for details and communication channels). They will place the files in this public Google Drive folder: https://drive.google.com/drive/folders/1xvLplF_pPlkADGfgFNaW_ByVATFv61m- 2. Open the media files in Google Drive and get their file IDs. To do this, select [...] > Open in new window > Copy the in the URL of the form https://drive.google.com/file/d//view. 3. Add a section to this page. - Embed images like this: Replace with the width you want your image to have on the page. Google Drive will automatically provide an image of this size. - Embed videos like this: \htmlonly \endhtmlonly 4. Open a pull request to contribute your changes (see CONTRIBUTING.md for details). \endcond # Gallery {#gallery} This page highlights some visualizations of SpECTRE simulations. \note We're always happy to feature images and videos created by the SpECTRE community on this page. See [this page on GitHub](https://github.com/sxs-collaboration/spectre/blob/develop/docs/Gallery.md) for instructions. ## Binary black hole mergers {#gallery_bbh} SpECTRE can simulate black holes that orbit each other and eventually merge, emitting gravitational waves. SpECTRE uses the Generalized Harmonic formulation of Einstein's equations of general relativity to solve this problem. Since we expect the solution of Einstein's equations to be smooth for the BBH problem, we represent our solution using the Discontinuous Galerkin (DG) method because of its ability to represent smooth functions to high accuracy. Also, DG allows SpECTRE to parallelize the BBH problem. Publications: - Lovelace, Nelli, et al. (2024). Simulating binary black hole mergers using discontinuous Galerkin methods. \cite Lovelace2024wra \htmlonly
Apparent horizons of an equal mass non-spinning BBH. The colorful surface represents the lapse value in the equatorial plane and the arrows depict the shift vector. Image credit: Alex Carpenter, CSUF
\endhtmlonly \htmlonly
Overview of a binary black hole simulation in SpECTRE. Upper left panel: computational grid and shape of black hole horizons during merger. A common horizon has formed (blue) that envelops the two original horizons (black). Upper right panel: trajectories of the black holes until merger. This inspiral is 18 orbits long and approximately circular. Bottom panel: gravitational waveform extracted with CCE (see below). Image credit: Geoffrey Lovelace, CSUF
\endhtmlonly ## Binary black hole initial data SpECTRE can generate initial data to start simulations of merging black holes. This problem involves solving the elliptic constraint sector of the Einstein equations for a slice of spacetime that contains two black holes with the requested parameters. SpECTRE uses the \ref ::Xcts "XCTS" formulation with a non-conformally-flat background defined by the \ref ::Xcts::AnalyticData::Binary "superposed" \ref gr::Solutions::KerrSchild "Kerr-Schild" formalism to reach high spins. Black holes are represented by excisions and \ref ::Xcts::BoundaryConditions::ApparentHorizon "boundary conditions". Publications: - Vu et al. (2022). A scalable elliptic solver with task-based parallelism for the SpECTRE numerical relativity code. \cite Vu2021coj - Vu (2024). A discontinuous Galerkin scheme for elliptic equations on extremely stretched grids. \cite Vu2024cgf \htmlonly
An initial slice of spacetime containing two black holes in orbit around each other. Shown is the lapse variable. The two black holes are represented as boundary conditions on excised regions of the computational domain. Image credit: Nils Vu, Caltech
\endhtmlonly ## Cauchy-characteristic evolution (CCE) {#gallery_cce} SpECTRE implements a novel Cauchy-characteristic evolution (CCE) system for extracting gravitational waveforms from our simulations. It evolves the Einstein equations on null slices to infinity, which is more accurate than extrapolation and allows us to extract the gravitational memory effect. The CCE waveform extraction is publicly available as a standalone module. Tutorial: - \ref tutorial_cce Publications: - Moxon et al. (2023). SpECTRE Cauchy-characteristic evolution system for rapid, precise waveform extraction. \cite Moxon2021gbv - Moxon et al. (2020). Improved Cauchy-characteristic evolution system for high-precision numerical relativity waveforms. \cite Moxon2020gha ## Binary neutron star mergers SpECTRE can simulate merging neutron stars and other general-relativistic magneto-hydrodynamic (GRMHD) problems with dynamic gravity. Our DG-FD hybrid scheme accelerates smooth regions of the grid with high-order spectral methods (see \ref gallery_dgfd). Publications: - Deppe et al. (2024). Binary neutron star mergers using a discontinuous Galerkin-finite difference hybrid method. \cite Deppe2024ckt \htmlonly
Simulation of two merging neutron stars. The colors show density contours. Video credit: Nils Vu, Caltech
\endhtmlonly ## Curved and moving meshes with control systems Our computational domains in SpECTRE are designed to adapt to the geometry of the problems we want to solve. They can be curved, e.g. to wrap around excision regions in binary black hole problems (see \ref gallery_bbh) or to resolve the wavezone in binary neutron star merger. They can also rotate and deform in time using control systems, which reactively adjust coordinate maps to track the position and shape of the black hole excisions or neutron stars. ## Adaptive mesh refinement Our discontinuous Galerkin methods allow two types of mesh refinement: splitting elements in half along any dimension (h-refinement) or increasing their polynomial expansion order (p-refinement). The former allows us to distribute computational cost to supercomputers, while the latter allows us to use these resources efficiently by decreasing the numerical error exponentially with the number of grid points where the solution is smooth. Our adaptive mesh refinement technology decides which type of refinement to apply in each region of the domain. ## DG-FD hybrid method {#gallery_dgfd} Our hydrodynamical simulations use a discontinuous Galerkin-finite difference (DG-FD) hybrid method: smooth regions of the simulation are evolved with an efficient DG scheme and non-smooth regions fall back to a robust FD method. Shocks and discontinuities on the grid are tracked with a troubled-cell indicator (TCI) to switch between DG and FD. This approach accelerates our simulations by reducing the computational resources spent on smooth regions of the grid, e.g. when evolving inspiral binary neutron stars and their gravitational radiation. Publications: - Deppe et al. (2022). A high-order shock capturing discontinuous Galerkin-finite difference hybrid method for GRMHD. \cite Deppe2021ada - Deppe et al. (2022). Simulating magnetized neutron stars with discontinuous Galerkin methods. \cite Deppe2021bhi \htmlonly
Simulation of the Kelvin-Helmholtz instability (KHI). Squares indicate cells that have switched to a finite-difference method. They track shocks and discontinuities in the solution. The rest of the domain uses an efficient DG method. Video credit: Nils Deppe, Cornell University
\endhtmlonly ## Binary black holes in scalar Gauss-Bonnet gravity SpECTRE can generate initial data for binary black holes in scalar Gauss-Bonnet gravity, evolve the modified Einstein equations, and extract the gravitational and scalar radiation. Publications: - Nee et al. (2024). Quasistationary hair for binary black hole initial data in scalar Gauss-Bonnet gravity \cite Nee2024bur - Lara et al. (2024). Scalarization of isolated black holes in scalar Gauss-Bonnet theory in the fixing-the-equations approach. \cite Lara2024rwa \htmlonly
Binary black hole initial data in scalar Gauss-Bonnet gravity, in a configuration where the two black holes have opposite charge. The scalar field is solved such that it is in equilibrium with the gravity background, minimizing initial transients in the evolution and giving control over the simulation parameters. Image credit: Peter James Nee, MPI for Gravitational Physics Potsdam, Germany
\endhtmlonly ## Thermal noise in gravitational wave detectors We have applied the SpECTRE technology to an interdisciplinary problem, simulating the Brownian thermal noise in the mirrors of interferometric gravitational-wave detectors at unprecedented accuracy. It uses the SpECTRE elliptic solver \cite Vu2021coj to solve an elasticity problem, which connects to the thermal noise problem through the fluctuation dissipation theorem. Publications: - Vu et al. (2024). High-accuracy numerical models of Brownian thermal noise in thin mirror coatings. \cite Vu2023thn ================================================ FILE: docs/GroupDefs.hpp ================================================ // Distributed under the MIT License. // See LICENSE.txt for details. /// \file /// Defines all group definitions #pragma once /*! * \defgroup ActionsGroup Actions * \brief A collection of steps used in algorithms. */ /*! * \defgroup AderGroup ADER * \brief Functions and classes needed for ADER (Arbitrary high-order using * DERivatives) time integration */ /*! * \defgroup AmrGroup Adaptive Mesh Refinement * \brief Functions and classes specific to hp-adaptive mesh refinement. */ /*! * \defgroup AnalyticDataGroup Analytic Data * \brief Analytic data used to specify (for example) initial data to the * equations implemented in \ref EvolutionSystemsGroup. */ /*! * \defgroup AnalyticSolutionsGroup Analytic Solutions * \brief Analytic solutions to the equations implemented in \ref * EvolutionSystemsGroup and \ref EllipticSystemsGroup. */ /*! * \defgroup BoundaryConditionsGroup Boundary Conditions * A collection of boundary conditions used for evolutions. */ /*! * \defgroup CharmExtensionsGroup Charm++ Extensions * \brief Classes and functions used to make Charm++ easier and safer to use. */ /*! * \defgroup ComputationalDomainGroup Computational Domain * \brief The building blocks used to describe the computational domain. * * ### Description * The VolumeDim-dimensional computational Domain is constructed from a set of * non-overlapping Block%s. Each Block is a distorted VolumeDim-dimensional * hypercube. Each codimension-1 boundary of a Block is either part of the * external boundary of the computational domain, or is identical to a boundary * of one other Block. Each Block is subdivided into one or more Element%s * that may be changed dynamically if AMR is enabled. */ /*! * \defgroup ConservativeGroup Conservative System Evolution * \brief Contains generic functions used for evolving conservative * systems. */ /*! * \defgroup ConstantExpressionsGroup Constant Expressions * \brief Contains an assortment of constexpr functions * * ### Description * Contains an assortment of constexpr functions that are useful for * metaprogramming, or efficient mathematical computations, such as * exponentiating to an integer power, where the power is known at compile * time. */ /*! * \defgroup ControlSystemGroup Control System * \brief Contains control system elements * * The control system manages the time-dependent mapping between frames, such as * the fixed computational frame (grid frame) and the inertial frame. The * time-dependent parameters of the mapping are adjusted by a feedback control * system in order to follow the dynamical evolution of objects such as horizons * of black holes or surfaces of neutron stars. For example, in binary black * hole simulations the map is typically a composition of maps that include * translation, rotation, scaling, shape, etc. * Each map under the governance of the control system has an associated * time-dependent map parameter \f$\lambda(t)\f$ that is a piecewise Nth order * polynomial. At discrete times (called reset times), the control system resets * the Nth time derivative of \f$\lambda(t)\f$ to a new constant value, in order * to minimize an error function \f$Q(t)\f$ that is specific to each map. At * each reset time, the Nth derivative of \f$\lambda(t)\f$ is set to a function * \f$U(t)\f$, called the control signal, that is determined by \f$Q(t)\f$ and * its time derivatives and time integral. Note that \f$\lambda(t)\f$, * \f$U(t)\f$, and \f$Q(t)\f$ can be vectors. * * The key components of the control system are: * - FunctionsOfTime: each map has an associated FunctionOfTime that represents * the map parameter \f$\lambda(t)\f$ and relevant time derivatives. * - ControlError: each map has an associated ControlError that computes * the error, \f$Q(t)\f$. Note that for each map, \f$Q(t)\f$ is defined to * follow the convention that \f$dQ = -d \lambda\f$ as \f$Q \rightarrow 0\f$. * - Averager: an averager can be used to average out the noise in the 'raw' * \f$Q(t)\f$ returned by the ControlError. * - Controller: the map controller computes the control signal \f$U(t)\f$ from * \f$Q(t)\f$ and its time integral and time derivatives. * The control is accomplished by setting the Nth derivative of * \f$\lambda(t)\f$ to \f$U(t)\f$. Two common controllers are PID * (proportional/integral/derivative) * \f[U(t) = a_{0}\int_{t_{0}}^{t} Q(t') dt'+a_{1}Q(t)+a_{2}\frac{dQ}{dt}\f] * or * PND (proportional/N derivatives) * \f[ U(t) = \sum_{k=0}^{N} a_{k} \frac{d^kQ}{dt^k} \f] * The coefficients \f$ a_{k} \f$ in the computation of \f$U(t)\f$ are chosen * at each time such that the error \f$Q(t)\f$ will be critically damped * on a timescale of \f$\tau\f$ (the damping time), * i.e. \f$Q(t) \propto e^{-t/\tau}\f$. * - TimescaleTuner: each map has a TimescaleTuner that dynamically adjusts * the damping timescale \f$\tau\f$ appropriately to keep the error \f$Q(t)\f$ * within some specified error bounds. Note that the reset time interval, * \f$\Delta t\f$, is a constant fraction of this damping timescale, * i.e. \f$\Delta t = \alpha \tau\f$ (empirically, we have found * \f$\alpha=0.3\f$ to be a good choice). * * * For additional details describing our control system approach, see * \cite Hemberger2012jz. */ /*! * \defgroup CoordinateMapsGroup Coordinate Maps * \brief Functions for mapping coordinates between different frames * * Coordinate maps provide the maps themselves, the inverse maps, along * with the Jacobian and inverse Jacobian of the maps. */ /*! * \defgroup CoordMapsTimeDependentGroup Coordinate Maps, Time-dependent * \brief Functions for mapping time-dependent coordinates between different * frames * * Coordinate maps provide the maps themselves, the inverse maps, the Jacobian * and inverse Jacobian of the maps, and the frame velocity (time derivative of * the map) */ /*! * \defgroup DataBoxGroup DataBox * \brief Documentation, functions, metafunctions, and classes necessary for * using DataBox * * DataBox is a heterogeneous compile-time associative container with lazy * evaluation of functions. DataBox can not only store data, but can also store * functions that depend on other data inside the DataBox. The functions will be * evaluated when the data they return is requested. The result is cached, and * if a dependency of the function is modified the cache is invalidated. * * #### Simple and Compute Tags and Their Items * * The compile-time keys are `struct`s called tags, while the values are called * items. Tags are quite minimal, containing only the information necessary to * store the data and evaluate functions. There are two different types of tags * that a DataBox can hold: simple tags and compute tags. Simple tags are for * data that is inserted into the DataBox at the time of creation, while compute * tags are for data that will be computed from a function when the compute item * is retrieved. If a compute item is never retrieved from the DataBox then it * is never evaluated. * * Simple tags must have a member type alias `type` that is the type of the data * to be stored and a `static std::string name()` method that returns the name * of the tag. Simple tags must inherit from `db::SimpleTag`. * * Compute tags must also have a `static std::string name()` method that returns * the name of the tag, but they cannot have a `type` type alias. Instead, * compute tags must have a static member function or static member function * pointer named `function`. `function` can be a function template if necessary. * The `function` must take all its arguments by `const` reference. The * arguments to the function are retrieved using tags from the DataBox that the * compute tag is in. The tags for the arguments are set in the member type * alias `argument_tags`, which must be a `tmpl::list` of the tags corresponding * to each argument. Note that the order of the tags in the `argument_list` is * the order that they will be passed to the function. Compute tags must inherit * from `db::ComputeTag`. * * Here is an example of a simple tag: * * \snippet Test_DataBox.cpp databox_tag_example * * and an example of a compute tag with a function pointer: * * \snippet Test_DataBox.cpp databox_mutating_compute_item_tag * * If the compute item's tag is inline then the compute item is of the form: * * \snippet Test_DataBox.cpp compute_item_tag_function * * Compute tags can also have their functions be overloaded on the type of its * arguments: * * \snippet Test_DataBox.cpp overload_compute_tag_type * * or be overloaded on the number of arguments: * * \snippet Test_DataBox.cpp overload_compute_tag_number_of_args * * Compute tag function templates are implemented as follows: * * \snippet Test_DataBox.cpp overload_compute_tag_template * * Finally, overloading, function templates, and variadic functions can be * combined to produce extremely generic compute tags. The below compute tag * takes as template parameters a parameter pack of integers, which is used to * specify several of the arguments. The function is overloaded for the single * argument case, and a variadic function template is provided for the multiple * arguments case. Note that in practice few compute tags will be this complex. * * #### Subitems and Prefix Tags * * A simple or compute tag might also hold a collection of data, such as a * container of `Tensor`s. In many cases you will want to be able to retrieve * individual elements of the collection from the DataBox without having to * first retrieve the collection. The infrastructure that allows for this is * called *Subitems*. The subitems of the parent tag must refer to a subset of * the data inside the parent tag, e.g. one `Tensor` in the collection. If the * parent tag is `Parent` and the subitems tags are `Sub<0>, Sub<1>`, then when * `Parent` is added to the DataBox, so are `Sub<0>` and `Sub<1>`. This means * the retrieval mechanisms described below will work on `Parent`, `Sub<0>`, and * `Sub<1>`. * * Subitems specify requirements on the tags they act on. For example, there * could be a requirement that all tags with a certain type are to be treated as * a Subitems. Let's say that the `Parent` tag holds a `Variables`, and * `Variables` can be used with the Subitems infrastructure to add the nested * `Tensor`s. Then all tags that hold a `Variables` will have their subitems * added into the DataBox. To add a new type as a subitem the `db::Subitems` * struct must be specialized. See the documentation of `db::Subitems` for more * details. * * The DataBox also supports *prefix tags*, which are commonly used for items * that are related to a different item by some operation. Specifically, say * you have a tag `MyTensor` and you want to also have the time derivative of * `MyTensor`, then you can use the prefix tag `dt` to get `dt`. The * benefit of a prefix tag over, say, a separate tag `dtMyTensor` is that prefix * tags can be added and removed by the compute tags acting on the original tag. * Prefix tags can also be composed, so a second time derivative would be * `dt>`. The net result of the prefix tags infrastructure is that * the compute tag that returns `dt` only needs to know its input * tags, it knows how to name its output based off that. In addition to the * normal things a simple or a compute tag must hold, prefix tags must have a * nested type alias `tag`, which is the tag being prefixed. Prefix tags must * also inherit from `db::PrefixTag` in addition to inheriting from * `db::SimpleTag` or `db::ComputeTag`. * * #### Creating a DataBox * * You should never call the constructor of a DataBox directly. DataBox * construction is quite complicated and the helper function `db::create` * should be used instead. `db::create` is used to construct a * new DataBox. It takes two typelists as explicit template parameters, the * first being a list of the simple tags to add and the second being a list of * compute tags to add. If no compute tags are being added then only the simple * tags list must be specified. The tags lists should be passed as * `db::create, * db::AddComputeTags>`. The arguments to `db::create` are the * initial values of the simple tags and must be passed in the same order as the * tags in the `db::AddSimpleTags` list. If the type of an argument passed to * `db::create` does not match the type of the corresponding simple tag a static * assertion will trigger. Here is an example of how to use `db::create`: * * \snippet Test_DataBox.cpp create_databox * * #### Accessing and Mutating Items * * To retrieve an item from a DataBox use the `db::get` function. `db::get` * will always return a `const` reference to the object stored in the DataBox * and will also have full type information available. This means you are able * to use `const auto&` when retrieving tags from the DataBox. For example, * \snippet Test_DataBox.cpp using_db_get * * If you want to mutate the value of a simple item in the DataBox use * `db::mutate`. Any compute item that depends on the mutated item will have its * cached value invalidated and be recomputed the next time it is retrieved from * the DataBox. `db::mutate` takes a parameter pack of tags to mutate as * explicit template parameters, a `gsl::not_null` of the DataBox whose items * will be mutated, an invokable, and extra arguments to forward to the * invokable. The invokable takes the arguments passed from the DataBox by * `const gsl::not_null` while the extra arguments are forwarded to the * invokable. The invokable is not allowed to retrieve anything from the * DataBox, so any items must be passed as extra arguments using `db::get` to * retrieve them. For example, * * \snippet Test_DataBox.cpp databox_mutate_example * * In addition to retrieving items using `db::get` and mutating them using * `db::mutate`, there is a facility to invoke an invokable with tags from the * DataBox. `db::apply` takes a `tmpl::list` of tags as an explicit template * parameter, will retrieve all the tags from the DataBox passed in and then * invoke the invokable with the items in the tag list. Similarly, * `db::mutate_apply` invokes the invokable but allows for mutating some of * the tags. See the documentation of `db::apply` and `db::mutate_apply` for * examples of how to use them. * */ /*! * \defgroup DataBoxTagsGroup DataBox Tags * \brief Structures and metafunctions for labeling the contents of DataBoxes */ /*! * \defgroup DataStructuresGroup Data Structures * \brief Various useful data structures used in SpECTRE */ /*! * \defgroup DgSubcellGroup DG-Subcell * \brief Functions and classes specific to the discontinuous Galerkin method * supplemented with a finite volume or finite difference subcell limiter. Can * also be thought of as a DG-FD hybrid method. */ /*! * \defgroup DiscontinuousGalerkinGroup Discontinuous Galerkin * \brief Functions and classes specific to the Discontinuous Galerkin * algorithm. */ /*! * \defgroup EllipticSystemsGroup Elliptic Systems * \brief All available elliptic systems */ /*! * \defgroup EquationsOfStateGroup Equations of State * \brief The various available equations of state */ /*! * \defgroup ErrorHandlingGroup Error Handling * Macros and functions used for handling errors */ /*! * \defgroup EventsAndTriggersGroup Events and Triggers * \brief Classes and functions related to events and triggers */ /*! * \defgroup EvolutionSystemsGroup Evolution Systems * \brief All available evolution systems and information on how to implement * evolution systems * * \details Actions and parallel components may require an evolution system to * expose the following types: * * - `volume_dim`: The number of spatial dimensions * - `variables_tag`: The evolved variables to compute DG volume contributions * and fluxes for. * - `compute_time_derivative`: A struct that computes the bulk contribution to * the DG discretization of the time derivative. Must expose a `tmpl::list` of * `argument_tags` and a static `apply` function that takes the following * arguments in this order: * - First, the types of the tensors in * `db::add_tag_prefix` * (which represent the time derivatives of the variables) as not-null pointers. * - The types of the `argument_tags` as constant references. * * Actions and parallel components may also require the Metavariables to expose * the following types: * * - `system`: See above. * - `temporal_id`: A DataBox tag that identifies steps in the algorithm. * Generally use `Tags::TimeStepId`. */ /*! * \defgroup ExecutablesGroup Executables * \brief A list of executables and how to use them * * * * * * * * * * * * * *
Executable Name Description
\ref ParallelInfoExecutablePage "ParallelInfo" Executable for checking number of nodes, cores, etc.
ExportEquationOfStateForRotNS Exports a 1d equation of state in a table format that the RotNS fortran * code can read in.
*/ /*! * \defgroup FileSystemGroup File System * \brief A light-weight file system library. */ /*! * \defgroup FiniteDifferenceGroup Finite Difference * \brief Functions needed for (conservative) finite difference methods. */ /*! * \defgroup GeneralRelativityGroup General Relativity * \brief Contains functions used in General Relativistic simulations */ /*! * \defgroup HDF5Group HDF5 * \brief Functions and classes for manipulating HDF5 files */ /*! * \defgroup InitializationGroup Initialization * \brief Actions and metafunctions used for initialization of parallel * components. */ /*! * \defgroup LimitersGroup Limiters * \brief Limiters to control shocks and surfaces in the solution. */ /*! * \defgroup LinearSolverGroup Linear Solver * \brief Algorithms to solve linear systems of equations * * \details In a way, the linear solver is for elliptic systems what time * stepping is for the evolution code. This is because the DG scheme for an * elliptic system reduces to a linear system of equations of the type * \f$Ax=b\f$, where \f$A\f$ is a global matrix representing the DG * discretization of the problem. Since this is one equation for each node in * the computational domain it becomes unfeasible to numerically invert the * global matrix \f$A\f$. Instead, we solve the problem iteratively so that we * never need to construct \f$A\f$ globally but only need \f$Ax\f$ that can be * evaluated locally by virtue of the DG formulation. This action of the * operator is what we have to supply in each step of the iterative algorithms * implemented here. It is where most of the computational cost goes and usually * involves computing a volume contribution for each element and communicating * fluxes with neighboring elements. Since the iterative algorithms typically * scale badly with increasing grid size, a preconditioner \f$P\f$ is needed * in order to make \f$P^{-1}A\f$ easier to invert. * * \note The smallest possible residual magnitude the linear solver can reach is * the product between the machine epsilon and the condition number of the * linear operator that is being inverted. Smaller residuals are numerical * artifacts. Requiring an absolute or relative residual below this limit will * likely make the linear solver run until it reaches its maximum number of * iterations. * * \note Remember that when the linear operator \f$A\f$ corresponds to a PDE * discretization, decreasing the linear solver residual below the * discretization error will not improve the numerical solution any further. * I.e. the error \f$e_k=x_k-x_\mathrm{analytic}\f$ to an analytic solution * will be dominated by the linear solver residual at first, but even if the * discretization \f$Ax_k=b\f$ was exactly solved after some iteration \f$k\f$, * the discretization residual * \f$Ae_k=b-Ax_\mathrm{analytic}=r_\mathrm{discretization}\f$ would still * remain. Therefore, ideally choose the absolute or relative residual criteria * based on an estimate of the discretization residual. * * In the iterative algorithms we usually don't work with the physical field * \f$x\f$ directly. Instead we need to apply the operator to an internal * variable defined by the respective algorithm. This variable is exposed as the * `LinearSolver::Tags::Operand` prefix, and the algorithm expects that the * computed operator action is written into * `db::add_tag_prefix>` in each step. */ /// \defgroup LoggingGroup Logging /// \brief Functions for logging progress of running code /// \defgroup MathFunctionsGroup Math Functions /// \brief Useful analytic functions /*! * \defgroup NumericalAlgorithmsGroup Numerical Algorithms * \brief Generic numerical algorithms */ /*! * \defgroup NumericalFluxesGroup Numerical Fluxes * \brief The set of available numerical fluxes */ /*! * \defgroup ObserversGroup Observers * \brief Observing/writing data to disk. */ /*! * \defgroup OptionGroupsGroup Option Groups * \brief Tags used for grouping input file options. * * An \ref OptionTagsGroup "option tag" can be placed in a group with other * option tags to give the input file more structure. To assign a group to an * option tag, set its `group` type alias to a struct that provides a help * string and may override a static `name()` function: * * \snippet Test_Options.cpp options_example_group * * A number of commonly used groups are listed here. * * See also the \ref dev_guide_option_parsing "option parsing guide". */ /*! * \defgroup OptionParsingGroup Option Parsing * Things related to parsing YAML input files. */ /*! * \defgroup OptionTagsGroup Option Tags * \brief Tags used for options parsed from the input file. * * These can be stored in the GlobalCache or passed to the `initialize` * function of a parallel component. */ /*! * \defgroup ParallelGroup Parallelization * \brief Functions, classes and documentation related to parallelization and * Charm++ * * See * \ref dev_guide_parallelization_foundations "Parallelization infrastructure" * for details. */ /*! * \defgroup PeoGroup Performance, Efficiency, and Optimizations * \brief Classes and functions useful for performance optimizations. */ /*! * \defgroup PrettyTypeGroup Pretty Type * \brief Pretty printing of types */ /*! * \defgroup ProtocolsGroup Protocols * \brief Classes that define metaprogramming interfaces * * See the \ref protocols section of the dev guide for details. */ /*! * \defgroup PythonBindingsGroup Python Bindings * \brief Classes and functions useful when writing python bindings. * * See the \ref spectre_writing_python_bindings "Writing Python Bindings" * section of the dev guide for details on how to write python bindings. */ /*! * \defgroup SpecialRelativityGroup Special Relativity * \brief Contains functions used in special relativity calculations */ /*! * \defgroup SpectralGroup Spectral * Things related to spectral transformations. */ // Note: this group is ordered by how it appears in the rendered Doxygen pages // (i.e., "Spin-weighted..."), rather than the group's name (i.e., "Swsh..."). /*! * \defgroup SwshGroup Spin-weighted spherical harmonics * Utilities, tags, and metafunctions for using and manipulating spin-weighted * spherical harmonics */ /*! * \defgroup SurfacesGroup Surfaces * Things related to surfaces. */ /*! * \defgroup TensorGroup Tensor * Tensor use documentation. */ /*! * \defgroup TensorExpressionsGroup Tensor Expressions * Tensor Expressions allow writing expressions of * tensors in a way similar to what is used with pen and paper. * * Tensor expressions are implemented using (smart) expression templates. This * allows a domain specific language making expressions such as * \code * auto T = evaluate(F(Indices::_b, * Indices::_a)); * \endcode * possible. */ /*! * \defgroup TestingFrameworkGroup Testing Framework * \brief Classes, functions, macros, and instructions for developing tests * * \details * * SpECTRE uses the testing framework * [Catch](https://github.com/philsquared/Catch). Catch supports a variety of * different styles of tests including BDD and fixture tests. The file * `cmake/SpectreAddCatchTests.cmake` parses the source files and adds the found * tests to ctest with the correct properties specified by tags and attributes. * * ### Usage * * To run the tests, type `ctest` in the build directory. You can specify * a regex to match the test name using `ctest -R Unit.Blah`, or run all * tests with a certain tag using `ctest -L tag`. * * ### Comparing double-precision results * * To compare two floating-point numbers that may differ by round-off, use the * helper object `approx`. This is an instance of Catch's comparison class * `Approx` in which the relative tolerance for comparisons is set to roughly * \f$10^{-14}\f$ (i.e. `std::numeric_limits::%epsilon()*100`). * When possible, we recommend using `approx` for fuzzy comparisons as follows: * \example * \snippet Test_TestingFramework.cpp approx_default * * For checks that need more control over the precision (e.g. an algorithm in * which round-off errors accumulate to a higher level), we recommend using * the `approx` helper with a one-time tolerance adjustment. A comment * should explain the reason for the adjustment: * \example * \snippet Test_TestingFramework.cpp approx_single_custom * * For tests in which the same precision adjustment is re-used many times, a new * helper object can be created from Catch's `Approx` with a custom precision: * \example * \snippet Test_TestingFramework.cpp approx_new_custom * * Note: We provide the `approx` object because Catch's `Approx` defaults to a * very loose tolerance (`std::numeric_limits::%epsilon()*100`, or * roughly \f$10^{-5}\f$ relative error), and so is poorly-suited to checking * many numerical algorithms that rely on double-precision accuracy. By * providing a tighter tolerance with `approx`, we avoid having to redefine the * tolerance in every test. * * ### Attributes * * Attributes allow you to modify properties of the test. Attributes are * specified as follows: * \code * // [[TimeOut, 10]] * // [[OutputRegex, The error message expected from the test]] * SPECTRE_TEST_CASE("Unit.Blah", "[Unit]") { * \endcode * * Available attributes are: * * * * * * * * * * * * * *
Attribute Description
TimeOut override the default timeout and set the timeout to N seconds. This * should be set very sparingly since unit tests are designed to be * short. If your test is too long you should consider testing smaller * portions of the code if possible, or writing an integration test instead. *
OutputRegex * When testing failure modes the exact error message must be tested, not * just that the test failed. Since the string passed is a regular * expression you must escape any regex tokens. For example, to match * `some (word) and` you must specify the string `some \(word\) and`. * If your error message contains a newline, you can match it using the * dot operator `.`, which matches any character. *
* * ### Debugging Tests in GDB or LLDB * * Several tests fail intentionally at the executable level to test error * handling like ASSERT statements in the code. CTest is aware of which * should fail and passes them. If you want to debug an individual test * in a debugger you must specify the name of the test as the first argument to * the test executable. For example, if you want to debug the "Unit.Gradient" * test: Launch the debugger, for example if you're using LLDB then run `lldb * ./bin/Test_LinearOperators`. Then run the test with `run Unit.Gradient` * inside the debugger. */ /*! * \defgroup TimeGroup Time * \brief Code related to the representation of time during simulations. * * The time covered by a simulation is divided up into a sequence of * adjacent, non-overlapping (except at endpoints) intervals referred * to as "slabs". The boundaries between slabs can be placed at * arbitrary times. Slabs, as represented in the code as the Slab * class, provide comparison operators comparing slabs agreeing with * the definition as a sequence of intervals. Slabs that do not * jointly belong to any such sequence should not be compared. * * The specific time is represented by the Time class, which encodes * the slab containing the time and the fraction of the slab that has * elapsed as an exact rational. Times are comparable according to * their natural time ordering, except for times belonging to * incomparable slabs. * * Differences in time within a slab are represented as exact * fractions of that slab by the TimeDelta class. TimeDeltas are only * meaningful within a single slab, with the exception that the ratio * of objects with different slabs may be taken, resulting in an * inexact floating-point result. Longer intervals of time are * represented using floating-point values. */ /*! * \defgroup TimeSteppersGroup Time Steppers * A collection of ODE integrators primarily used for time stepping. */ /*! * \defgroup TypeTraitsGroup Type Traits * A collection of useful type traits, including C++14 and C++17 additions to * the standard library. */ /*! * \defgroup UtilitiesGroup Utilities * \brief A collection of useful classes, functions and metafunctions. */ /*! * \defgroup VariableFixingGroup Variable Fixing * \brief A collection of different variable fixers ranging in sophistication. * * Build-up of numerical error can cause physical quantities to evolve * toward non-physical values. For example, pressure and density may become * negative. This will subsequently lead to failures in numerical inversion * schemes to recover the corresponding convervative values. A rough fix that * enforces physical quantities stay physical is to simply change them by hand * when needed. This can be done at various degrees of sophistication, but in * general the fixed quantities make up a negligible amount of the physics of * the simulation; a rough fix is vastly preferred to a simulation that fails * to complete due to nonphysical quantities. */ ================================================ FILE: docs/Images/Tutorials/make_multicube_figures.py ================================================ #!/usr/bin/env python # Distributed under the MIT License. # See LICENSE.txt for details. import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D from mpl_toolkits.mplot3d.art3d import Poly3DCollection plt.rcParams["figure.figsize"] = (4, 4) plt.rcParams["font.size"] = 10 # higher-quality fonts, but much slower to render: # plt.rcParams['font.serif'] = 'Computer Modern' # plt.rcParams['text.usetex'] = True def draw_basis_vectors( ax, x_origin, label_permutation=[0, 1, 2], flip_vector=[False, False, False], use_greek_labels=True, ): from matplotlib.patches import FancyArrowPatch from mpl_toolkits.mplot3d import proj3d class Arrow3D(FancyArrowPatch): def __init__(self, xs, ys, zs, *args, **kwargs): FancyArrowPatch.__init__(self, (0, 0), (0, 0), *args, **kwargs) self._verts3d = xs, ys, zs def draw(self, renderer): xs3d, ys3d, zs3d = self._verts3d xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M) self.set_positions((xs[0], ys[0]), (xs[1], ys[1])) FancyArrowPatch.draw(self, renderer) length = 0.3 labels = ( [r"$\xi$", r"$\eta$", r"$\zeta$"] if use_greek_labels else ["$x$", "$y$", "$z$"] ) arrow_props = dict( mutation_scale=10, arrowstyle="-|>", color="k", shrinkA=0, shrinkB=0 ) x0, y0, z0 = [ x_origin[i] + (length if flip_vector[i] else 0.0) for i in range(3) ] dx, dy, dz = [length * (-1.0 if flip_vector[i] else 1.0) for i in range(3)] ax.add_artist(Arrow3D([x0, x0 + dx], [y0, y0], [z0, z0], **arrow_props)) ax.add_artist(Arrow3D([x0, x0], [y0, y0 + dy], [z0, z0], **arrow_props)) ax.add_artist(Arrow3D([x0, x0], [y0, y0], [z0, z0 + dz], **arrow_props)) dxt, dyt, dzt = [ -length - 0.15 if flip_vector[i] else length + 0.05 for i in range(3) ] dyt = dyt - (0.15 if flip_vector[1] else 0.0) ax.text(x0 + dxt, y0, z0, labels[label_permutation[0]]) ax.text(x0, y0 + dyt, z0, labels[label_permutation[1]]) ax.text(x0, y0, z0 + dzt, labels[label_permutation[2]]) def draw_polygon_collection(ax, polygons, face_colors, edge_colors): collection = Poly3DCollection(polygons) collection.set_color(face_colors) collection.set_edgecolor(edge_colors) collection.set_linewidth(0.6) ax.add_collection3d(collection) def quad(p, i, j, k, l): return [p[i], p[j], p[k], p[l]] def cube(p, index_start, strides): sx, sy, sz = strides def quad_x_normal(i): return quad(p, i, i + sy, i + sy + sz, i + sz) def quad_y_normal(i): return quad(p, i, i + sx, i + sx + sz, i + sz) def quad_z_normal(i): return quad(p, i, i + sx, i + sx + sy, i + sy) quad_lower_x = quad_x_normal(index_start) quad_upper_x = quad_x_normal(index_start + sx) quad_lower_y = quad_y_normal(index_start) quad_upper_y = quad_y_normal(index_start + sy) quad_lower_z = quad_z_normal(index_start) quad_upper_z = quad_z_normal(index_start + sz) return [ quad_lower_x, quad_upper_x, quad_lower_y, quad_upper_y, quad_lower_z, quad_upper_z, ] def black_color(mean_xyz): return "k" class CubeManager: def __init__(self, point_list, strides, edge_color_function=black_color): self._points = point_list self._strides = strides self._ecf = edge_color_function self.quads = [] self.face_colors = [] self.edge_colors = [] def add_cube(self, start_index, these_faces_transparent=[]): c = cube(self._points, start_index, self._strides) self.quads.extend(c) clear = (1, 1, 1, 0) white_semi_transparent = (1, 1, 1, 0.75) self.face_colors.extend( [ ( clear if face in these_faces_transparent else white_semi_transparent ) for face in range(6) ] ) self.edge_colors.extend( [self._ecf(np.average(face, axis=0)) for face in c] ) def one_cube_figure(): p = np.array([[x, y, z] for z in [0, 1] for y in [0, 1] for x in [0, 1]]) cubes = CubeManager(p, strides=[1, 2, 4]) cubes.add_cube(0) fig = plt.figure() ax = Axes3D(fig) ax.set_aspect("equal") ax.set_axis_off() ax.set_xlim(-0.5, 1.5) ax.set_ylim(-0.5, 1.5) ax.set_zlim(-0.5, 1.5) draw_polygon_collection( ax, cubes.quads, cubes.face_colors, cubes.edge_colors ) draw_basis_vectors(ax, [0.1, 0.1, 0.1]) for i in range(p.shape[0]): # shift labels of upper-y face to avoid overlaps shift_y = -0.25 if p[i, 1] < 0.5 else 0.1 ax.text(p[i, 0], p[i, 1] + shift_y, p[i, 2], "$" + str(i) + "$") fig.savefig("onecube_numbered.png") def two_cube_figures(): p = np.array([[x, y, z] for z in [0, 1] for y in [0, 1] for x in [0, 1, 2]]) cubes = CubeManager(p, strides=[1, 3, 6]) cubes.add_cube(0, [1]) cubes.add_cube(1, [0]) fig = plt.figure() ax = Axes3D(fig) ax.set_aspect("equal") ax.set_axis_off() ax.set_xlim(0.0, 2.0) ax.set_ylim(-0.5, 1.5) ax.set_zlim(-0.5, 1.5) draw_polygon_collection( ax, cubes.quads, cubes.face_colors, cubes.edge_colors ) draw_basis_vectors(ax, [0.1, 0.1, 0.1]) draw_basis_vectors(ax, [1.1, 0.1, 0.1], label_permutation=[2, 0, 1]) fig.savefig("twocubes.png") for i in range(p.shape[0]): # shift labels of upper-y face to avoid overlaps shift_y = -0.25 if p[i, 1] < 0.5 else 0.1 ax.text(p[i, 0], p[i, 1] + shift_y, p[i, 2], "$" + str(i) + "$") fig.savefig("twocubes_numbered.png") def eight_cube_figures(): p = np.array( [[x, y, z] for z in [0, 1, 2] for y in [0, 1, 2] for x in [0, 1, 2]] ) def red_black_blue(mean_xyz): r = max(1.0 - mean_xyz[1], 0.0) b = max(mean_xyz[1] - 1.0, 0.0) return [r, 0.0, b] cubes = CubeManager( p, strides=[1, 3, 9], edge_color_function=red_black_blue ) cubes.add_cube(0, [1, 3, 5]) cubes.add_cube(1, [0, 3, 5]) cubes.add_cube(3, [1, 2, 5]) cubes.add_cube(4, [0, 2, 5]) cubes.add_cube(9, [1, 3, 4]) cubes.add_cube(10, [0, 3, 4]) cubes.add_cube(12, [1, 2, 4]) cubes.add_cube(13, [0, 2, 4]) fig = plt.figure() ax = Axes3D(fig) ax.set_aspect("equal") ax.set_axis_off() ax.set_xlim(0.0, 2.0) ax.set_ylim(0.0, 2.0) ax.set_zlim(0.0, 2.0) draw_polygon_collection( ax, cubes.quads, cubes.face_colors, cubes.edge_colors ) fig.savefig("eightcubes.png") draw_basis_vectors(ax, [0.55, -0.75, 0.0], use_greek_labels=False) for i in range(p.shape[0]): # shift labels on each y=constant surface, to reduce overlaps shift = [0.0, 0.0, 0.0] if p[i, 1] == 0.0: shift[0] = -0.05 shift[1] = -0.3 elif p[i, 1] == 1.0: shift[0] = 0.02 shift[2] = -0.2 else: shift[1] = 0.1 # this label needs additional manual tweaking if i == 15: shift[0] = -0.2 shift[1] = -0.1 # reduce R,B components so colors aren't too bright textcolor = red_black_blue(p[i]) textcolor[0] /= 1.5 textcolor[2] /= 1.5 ax.text( p[i, 0] + shift[0], p[i, 1] + shift[1], p[i, 2] + shift[2], "$" + str(i) + "$", color=textcolor, ) fig.savefig("eightcubes_numbered.png") def eight_cube_rotated_exploded_figure(): p = np.array( [ [x, y, z] for z in [0, 1, 2, 3] for y in [0, 1, 2, 3] for x in [0, 1, 2, 3] ] ) def red_black_blue(mean_xyz): y_normalization = 1.5 r = max(1.0 - mean_xyz[1] / y_normalization, 0.0) b = max(mean_xyz[1] / y_normalization - 1.0, 0.0) return [r, 0.0, b] cubes = CubeManager( p, strides=[1, 4, 16], edge_color_function=red_black_blue ) cubes.add_cube(0) cubes.add_cube(2) cubes.add_cube(8) cubes.add_cube(10) cubes.add_cube(32) cubes.add_cube(34) cubes.add_cube(40) cubes.add_cube(42) fig = plt.figure() ax = Axes3D(fig) ax.set_aspect("equal") ax.set_axis_off() ax.set_xlim(0.0, 3.0) ax.set_ylim(0.0, 3.0) ax.set_zlim(0.0, 3.0) draw_polygon_collection( ax, cubes.quads, cubes.face_colors, cubes.edge_colors ) draw_basis_vectors(ax, [1.0, -0.8, 0.0], use_greek_labels=False) draw_basis_vectors(ax, [0.17, 0.17, 0.25]) draw_basis_vectors( ax, [2.17, 0.17, 0.25], label_permutation=[2, 1, 0], flip_vector=[False, False, True], ) draw_basis_vectors( ax, [0.17, 2.17, 0.45], label_permutation=[0, 2, 1], flip_vector=[False, False, True], ) draw_basis_vectors( ax, [2.17, 2.17, 0.3], label_permutation=[2, 0, 1], flip_vector=[False, True, True], ) draw_basis_vectors( ax, [0.17, 0.17, 2.25], label_permutation=[1, 0, 2], flip_vector=[False, True, False], ) draw_basis_vectors( ax, [2.17, 0.17, 2.25], label_permutation=[1, 2, 0], flip_vector=[False, True, True], ) draw_basis_vectors( ax, [0.17, 2.17, 2.3], label_permutation=[2, 0, 1], flip_vector=[False, True, True], ) draw_basis_vectors(ax, [2.17, 2.17, 2.45]) fig.savefig("eightcubes_rotated_exploded.png") def tesseract_figure(): p = np.array( [ [x, y, z] for z in [0, 1, 2, 3, 4] for y in [0, 1, 2, 3] for x in [0, 1, 2, 3] ] ) def red_black_blue(mean_xyz): # note: the tesseract is a bigger domain, so mean_xyz values can be # larger. the factor of 1.5 normalizes R,B values back into [0,1]. y_normalization = 1.5 r = max(1.0 - mean_xyz[1] / y_normalization, 0.0) b = max(mean_xyz[1] / y_normalization - 1.0, 0.0) return [r, 0.0, b] cubes = CubeManager( p, strides=[1, 4, 16], edge_color_function=red_black_blue ) cubes.add_cube(5, [5]) cubes.add_cube(21, [4, 5]) cubes.add_cube(33, [3]) cubes.add_cube(36, [1]) cubes.add_cube(38, [0]) cubes.add_cube(41, [2]) cubes.add_cube(53, [4]) # also draw the back 3 sides of the bounding box box_quads = np.array( [quad(p, 0, 12, 76, 64), quad(p, 12, 15, 79, 76), quad(p, 0, 3, 15, 12)] ) fig = plt.figure(figsize=(6, 6)) ax = Axes3D(fig) ax.set_aspect("equal") ax.set_axis_off() ax.set_xlim(-0.5, 3.5) ax.set_ylim(-0.5, 3.5) ax.set_zlim(0.0, 4.0) # draw bounding box first, else matplotlib gets the layer ordering wrong draw_polygon_collection(ax, box_quads, "white", "lightgrey") draw_polygon_collection( ax, cubes.quads, cubes.face_colors, cubes.edge_colors ) # these are the visible points on the tesseract points_to_label = [ 5, 6, 10, 21, 22, 26, 36, 33, 34, 38, 39, 43, 52, 49, 50, 53, 54, 55, 56, 58, 59, 62, 69, 70, 73, 74, ] # these are the points we want to show from the bounding box points_to_label.extend([0, 3, 15, 64, 76, 79]) for i in points_to_label: # shift labels on each y=constant surface, to reduce overlaps shift = [0.0, 0.0, 0.0] if p[i, 1] == 0.0 or p[i, 1] == 1.0: shift[0] = -0.07 shift[1] = -0.37 else: shift[1] = 0.1 # specific individual corrections at complex tesseract corners if i == 38: shift[2] = 0.27 elif i == 39: shift[0] = 0.15 shift[1] = -0.2 elif i == 53: shift[0] = 0.24 elif i == 54: shift[0] = 0.24 elif i == 58: shift[2] = -0.3 elif i == 69: shift[2] = 0.15 # reduce R,B components so colors aren't too bright textcolor = red_black_blue(p[i]) textcolor[0] /= 1.5 textcolor[2] /= 1.5 ax.text( p[i, 0] + shift[0], p[i, 1] + shift[1], p[i, 2] + shift[2], "$" + str(i) + "$", color=textcolor, ) fig.savefig("tesseract_numbered.png") one_cube_figure() two_cube_figures() eight_cube_figures() eight_cube_rotated_exploded_figure() tesseract_figure() ================================================ FILE: docs/Installation/BuildSystem.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Build System - CMake {#spectre_build_system} \tableofcontents SpECTRE uses [CMake](https://cmake.org/) for the build system. In this guide we'll outline how to configure SpECTRE and describe some [commonly used CMake flags](#common_cmake_flags). We'll also go over how to [add new source files](#adding_source_files), [libraries](#adding_libraries), [unit tests](#adding_unit_tests), [executables](#adding_executables), and [external dependencies](#adding_external_dependencies). # Configuring The command to configure SpECTRE will look like this ``` cmake -D FLAG1=OPT1 ... -D FLAGN=OPTN ``` where `FLAG{1..N}` are CMake flags that are detailed in the section on [commonly used CMake flags](#common_cmake_flags). CMake will look in your `$PATH` environment variable for all of the [build dependencies](installation.html#build_dependencies) and will use the first one it finds that satisfies the requirements. However, if a dependency is not in your `$PATH`, there are multiple versions of a dependency, or you just want to customize your configuration, you'll have to tell CMake which dependency you want to use and where it is using CMake flags. To that end, even though the [commonly used CMake flags](#common_cmake_flags) section has a more detailed list of the flags available, the following list has the *most common* CMake flags you'll need to customize your configuration (e.g. compilers, charm, build type, and library types): - CMAKE_C_COMPILER - CMAKE_CXX_COMPILER - CMAKE_Fortran_COMPILER - CHARM_ROOT - CMAKE_BUILD_TYPE - BUILD_SHARED_LIBS \note If you are on a cluster, take a look at the [installation on clusters](installation_on_clusters.html) instructions. If you are on a cluster we support, we will already have an environment setup and an easy way for you to configure the build without having to specify flags yourself. ## Commonly Used CMake flags {#common_cmake_flags} The following are common flags used to control building SpECTRE with CMake (in alphabetical order): - ASAN - Whether or not to turn on the address sanitizer compile flags (`-fsanitize=address`) (default is `OFF`) - BLAZE_USE_ALWAYS_INLINE - Force Blaze inlining (default is `ON`) - If disabled or if the platform is unable to 100% guarantee inlining, falls back to `BLAZE_USE_STRONG_INLINE` (see below) - Forced inlining reduces function call overhead, and so generally reduces runtime. However, it does increase compile time and compile memory usage. It is also easier to use a debugger when forced inlining is disabled. If you are encountering debugger messages like `function inlined`, then forced inlining should be disabled. - BLAZE_USE_STRONG_INLINE - Increase the likelihood of Blaze inlining (default is `ON`) - Strong inlining reduces function call overhead, and so generally reduces runtime. However, it does increase compile time and compile memory usage. It is also easier to use a debugger when strong inlining is disabled. If you are encountering debugger messages like `function inlined`, then strong inlining should be disabled. - BOOTSTRAP_PY_DEPS and BOOTSTRAP_PY_DEV_DEPS - Install missing Python dependencies into the build directory, as listed in `support/Python/requirements.txt` and `support/Python/dev_requirements.txt`, respectively. This is an alternative to creating a Python environment and installing the packages yourself. If you run into problems with packages like h5py, numpy or scipy you can/should still install them yourself to make sure they use the correct HDF5, BLAS, etc. (default is `OFF`) - BUILD_DOCS - Enable building documentation. (default is `ON`) - BUILD_PYTHON_BINDINGS - Build python libraries to call SpECTRE C++ code from python (default is `ON`) - BUILD_SHARED_LIBS - Whether shared libraries are built instead of static libraries (default is `OFF`) - BUILD_TESTING - Enable building tests. (default is `ON`) - CHARM_ROOT - The path to the build directory of `Charm++` - CHARM_TRACE_PROJECTIONS - Enables tracing with Charm++ projections. Specifically, enables the link flag `-tracemode projections`. (default is `OFF`) - CHARM_TRACE_SUMMARY - Enables trace summaries with Charm++ projections. Specifically, enables the link flag `-tracemode summary`. (default is `OFF`) - CMAKE_BUILD_TYPE - Sets the build type. Common options: - `Debug` (the default if the flag is not specified): sets flags that trigger additional error checking - `Release` - CMAKE_C_COMPILER - The `C` compiler used (defaults to whatever is determined by `CMake/Modules/CMakeDetermineCCompiler.cmake`, usually `cc`) - CMAKE_C_FLAGS - Additional flags passed to the `C` compiler. - CMAKE_CXX_COMPILER - The `C++` compiler used (defaults to whatever is determined by `CMake/Modules/CMakeDetermineCXXCompiler.cmake`, usually `c++`) - CMAKE_CXX_FLAGS - Additional flags passed to the `C++` compiler. - CMAKE_Fortran_COMPILER - The `Fortran` compiler used (defaults to whatever is determined by `CMake/Modules/CMakeDetermineFortranCompiler.cmake`) - CMAKE_Fortran_FLAGS - Additional flags passed to the `Fortran` compiler. - CMAKE_INSTALL_PREFIX - Location where the `install` target copies executables, libraries, etc. Make sure to set this variable before you `install`, or a default location such as `/usr/local` is used. - CMAKE_RUNTIME_OUTPUT_DIRECTORY - Sets the directory where the library and executables are placed. By default libraries end up in `/lib` and executables in `/bin`. - COVERAGE - Enable code coverage with GCOV and LCOV (default `OFF`) - DEBUG_SYMBOLS - Whether or not to use debug symbols (default is `ON`) - Disabling debug symbols will reduce compile time and total size of the build directory. - DOCS_ONLY - Build _only_ documentation (default is `OFF`). Requires `BUILD_DOCS=ON`. - ENABLE_OPENMP - Enable OpenMP parallelization in some parts of the code, such as Python bindings and interpolating volume data files. Note that simulations do not typically use OpenMP parallelization, so this flag only applies to tools. - ENABLE_PARAVIEW - Try to find ParaView to enable 3D rendering tools (default is `OFF`) - ENABLE_PROFILING - Enables various options to make profiling SpECTRE easier (default is `OFF`) - ENABLE_PYTHON - Enables Python. (default is `ON`) - Set to `OFF` for a minimal build on systems without a recent Python installation. Warning: Many things will not work!! - Note: Even when disabled, a minimal Python installation (Python ≥ 2.7) is still required. - BUILD_PYTHON_BINDINGS, BUILD_TESTING, BUILD_DOCS should be `OFF`. - ENABLE_WARNINGS - Whether or not warning flags are enabled (default is `ON`) - FUKA_ROOT - Set to a path to a [FUKA](https://bitbucket.org/fukaws/fuka) installation to enable loading FUKA initial data into SpECTRE. Can be the FUKA repository root or the directory where `libkadath.a` was installed. Also requires FFTW to be installed (see FUKA docs on dependencies). - GSL_STATIC - If set, then the GNU Scientific Library is statically linked. - KEEP_FRAME_POINTER - Whether to keep the frame pointer. Needed for profiling or other cases where you need to be able to figure out what the call stack is. (default is `OFF`) - MACHINE - Select a machine that we know how to run on, such as a particular supercomputer. A file named MACHINE.yaml must exist in support/Machines and a submit script template named MACHINE.sh must exist in support/SubmitScripts. - MEMORY_ALLOCATOR - Set which memory allocator to use. If there are unexplained segfaults or other memory issues, it would be worth setting `MEMORY_ALLOCATOR=SYSTEM` to see if that resolves the issue. It could be the case that different third-party libraries accidentally end up using different allocators, which is undefined behavior and will result in complete chaos. (default is `JEMALLOC`) - PY_DEV_MODE - Enable development mode for the Python package, meaning that Python files are symlinked rather than copied to the build directory. Allows to edit and test Python code much easier, in particular when it uses compiled Python bindings, but doesn't replace CMake placeholders in the Python code such as the project version. (default is `OFF`) - SPEC_ROOT - Set to a path to a SpEC installation (the SpEC repository root) to link in SpEC libraries. In particular, the SpEC::Exporter library is linked in and enables loading SpEC data into SpECTRE. See \ref installation for details. - SPECTRE_AUTODIFF - Enable automatic differentation (default is `OFF`). This is required for computing Hessians. - SPECTRE_DEBUG - Defines `SPECTRE_DEBUG` macro to enable `ASSERT`s and other debug checks so they can be used in Release builds. That is, you get sanity checks and compiler optimizations. You cannot disable the checks in Debug builds, so this option has no effect in Debug builds. (default is `OFF` in release) - SPECTRE_DEBUG_Og - Compile Debug builds with `-Og` instead of the default `-O0`. `-Og` is specifically designed to preserve debuggability while enabling optimizations that do not interfere with source-level debugging. Has no effect when `SPECTRE_OPTIMIZE_SIZE=ON` (which uses `-Oz`). (default is `ON`) - SPECTRE_NAN_INIT - Defines `SPECTRE_NAN_INIT` macro to initialize memory to NaN in various places to catch use of uninitialized values. (default is the value of `SPECTRE_DEBUG`, or `ON` in Debug builds) - SPECTRE_OPTIMIZE_SIZE - Optimize for executable size instead of speed (adds the `-Oz` compiler flag). The default is `OFF`, unless on Apple Silicon machines, where the default is `ON`. This is because of a bug in macOS on Apple Silicon, which means executables larger than 2GB in size cannot run. Disabling this option on Apple Silicon can improve debugging tests (which are small enough so the bug does not affect them). - SPECTRE_FETCH_MISSING_DEPS - Download missing dependencies and build them alongside the SpECTRE source. (default is `OFF`) - SPECTRE_Fortran_STATIC_LIBS (default: `OFF`) - Use static version of `libgfortran` and `libquadmath`. - SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY - Minimum priority of input file tests to run. Possible values are: `low` (not usually run on CI), `normal` (run at least once on CI), `high` (run always on CI). (default is `normal`) - SPECTRE_KOKKOS (default: `OFF`) - Enable Kokkos support. You must have Kokkos installed and detectable. - SPECTRE_LTO - Enable link-time optimization if the compiler supports it. - SPECTRE_LTO_CORES - Specifies the number of cores to use for parallelizing LTO. Must be a positive integer or "auto". This is only available when `SPECTRE_LTO=ON` and the compiler supports LTO. - SPECTRE_TEST_RUNNER - Run test executables through a wrapper. This might be `charmrun`, for example. (default is to not use one) - SPECTRE_TEST_TIMEOUT_FACTOR (and specific overrides SPECTRE_X_TEST_TIMEOUT_FACTOR for X one of UNIT, STANDALONE, INPUT_FILE, or PYTHON) - Multiply the timeout for the respective set of tests by this factor (default is `1`). - This is useful to run tests on slower machines. - SPECTRE_USE_ALWAYS_INLINE - Force SpECTRE inlining (default is `ON`) - Forced inlining reduces function call overhead, and so generally reduces runtime. However, it does increase compile time and compile memory usage. It is also easier to use a debugger when forced inlining is disabled. If you are encountering debugger messages like `function inlined`, then forced inlining should be disabled. - STRIP_SYMBOLS - Whether or not to strip all symbols (default is `OFF`) - If enabled strips all extraneous symbols from libraries and executables, further reducing the size of them. - STUB_EXECUTABLE_OBJECT_FILES - Replace object files from executables after linking with empty stubs (default is `OFF`) - This is useful for drastically reducing the build size in CI, but since the object files are replaced with empty stubs will generally cause linking problems if used during development. - STUB_LIBRARY_OBJECT_FILES - Replace object files from libraries after linking with empty stubs (default is `OFF`) - This is useful for drastically reducing the build size in CI, but since the object files are replaced with empty stubs will generally cause linking problems if used during development. - UBSAN_INTEGER - Whether or not to turn on the undefined behavior sanitizer [unsigned integer overflow](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) flag (`-fsanitize=integer`) (default is `OFF`) - UBSAN_UNDEFINED - Whether or not to turn on the undefined behavior sanitizer [undefined behavior](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) compile flags (`-fsanitize=undefined`) (default is `OFF`) - UNIT_TESTS_IN_TEST_EXECUTABLES - Whether to build the `unit-tests` target as part of the `test-executables` target. This is used to build only the non-unit tests in the CI build that doesn't use the PCH. (default is `ON`) - USE_CCACHE - Use ccache to cache build output so that rebuilding parts of the source tree is faster. The cache will use up space on disk, with the default being around 2-5GB. If you are performing a one time build to test something specific you should consider disabling ccache in order to avoid removing cached files that may be useful in other builds. (default is `ON`) - USE_FORMALINE - Write the source tree into HDF5 files written to disk in order to increase reproducibility of results. (default is `ON`) - USE_GIT_HOOKS - Use git hooks to perform some sanity checks so that small goofs are caught before they are committed. These checks are particularly useful because they also run automatically on \ref github_actions_guide "CI" and must pass before pull requests are merged. (default is `ON`) - USE_LD - Override the automatically chosen linker. The options are `ld`, `gold`, and `lld`. (default is `OFF`) - USE_PCH - Whether or not to use pre-compiled headers (default is `ON`) - USE_SLEEF - Whether to use [Sleef](https://github.com/shibatch/sleef) with Blaze to vectorize addition math functions like `sin`, `cos`, and `exp`. (default is `OFF`) - \note Blaze isn't tested super thoroughly across different architectures so there's unfortunately no guarantee that Blaze+Sleef will work everywhere. - USE_XSIMD - Whether to use [xsimd](https://github.com/xtensor-stack/xsimd) with Blaze to vectorize addition math functions like `sin`, `cos`, and `exp`. Defines the macro `SPECTRE_USE_XSIMD`, which can be check to enable manual vectorization where necessary. (default is `ON`) ## CMake targets To see all possible build targets, once you configure SpECTRE run ``` make list ``` This will be a long list of all libraries, test executables, simulation executables, and custom build targets. The custom targets that are available to build with `make` or `ninja` are: - unit-tests - Build unit tests, which you can run with `ctest -L unit`. Available if `BUILD_TESTING` is `ON` (the default). - test-executables - Build all tests, including executables, so you can run all tests with `ctest`. Available if `BUILD_TESTING` is `ON` (the default). To compile `test-executables` you may have to reduce the number of cores you build on in parallel to avoid running out of memory. - all-pybindings - Build Python bindings. See \ref spectre_using_python for details. - cli - Same as all-pybindings - install - Install targets that have been built to the `CMAKE_INSTALL_PREFIX`. Doesn't try to build anything else. # Editing the build system \note When editing `CMakeLists.txt` files, it is conventional to indent multiline commands by two spaces (except for the first line), and to separate most commands by blank lines. ## Adding Source Files {#adding_source_files} SpECTRE organizes source files into subdirectories of `src` that are compiled into libraries. To add a new source file `FILE.cpp` to an existing library in `src/PATH/DIR`, just edit `src/PATH/DIR/CMakeLists.txt` and add `FILE.cpp` to the list of files in ``` spectre_target_sources( ${LIBRARY} PRIVATE ) ``` such that the resulting `` is in alphabetical order. ## Adding Header Files {#adding_header_files} Similarly to [adding new source files](#adding_source_files), you can add a new header file `FILE.hpp` to a library by editing the `CMakeLists.txt` in that directory and adding `FILE.hpp` to the list of files in ``` spectre_target_headers( ${LIBRARY} INCLUDE_DIRECTORY ${CMAKE_SOURCE_DIR}/src HEADERS ) ``` \note Any `.tpp` files also go in this list of header files. ## Adding Libraries {#adding_libraries} To add a source file `FILE.cpp` that is compiled into a new library `LIB` in a directory `src/PATH/DIR` (either in a new directory, or in an existing directory that either does not have a `CMakeLists.txt` file, or does not create a library in the existing `CMakeLists.txt`): - Create (if necessary) a `CMakeLists.txt` file in `DIR`, with the following two lines at the top: ``` # Distributed under the MIT License. # See LICENSE.txt for details. ``` - In the parent directory (i.e. `src/PATH`), (if necessary) add the following line to its `CMakeLists.txt` file (if necessary, recursively do the previous step and this one until you reach a `CMakeLists.txt` that adds the appropriate subdirectory): ``` add_subdirectory(DIR) ``` If there are already other `add_subdirectory()` lines in the file, place the new one so that the subdirectories are in alphabetical order. - Add the line: ``` set(LIBRARY LIB) ``` where convention is that `LIB` = `DIR`. As library names must be unique, this is not always possible, in which case the convention is to prepend the parent directory to `DIR`. - Add the lines ``` add_spectre_library(${LIBRARY}) spectre_target_sources( ${LIBRARY} PRIVATE FILE.cpp ) spectre_target_headers( ${LIBRARY} INCLUDE_DIRECTORY ${CMAKE_SOURCE_DIR}/src HEADERS FILE.hpp ) target_link_libraries( ${LIBRARY} PUBLIC PRIVATE INTERFACE ) ``` where each `` is an alphabetized list of libraries of the form ``` SomeLibrary SomeOtherLibrary YetAnotherLibrary ``` The libraries listed under `INTERFACE` are those included in at least one `.hpp` file in `LIB` but never used in any `.cpp` files in `LIB`. The libraries listed under `PRIVATE` are used in at least one `.cpp` file in `LIB` but not in any `.hpp` file in `LIB`. The libraries listed under `PUBLIC` are used in at least one `.hpp` file and at least one `.cpp` file in `LIB`. Note that a library counts as being used in a `.cpp` file if the corresponding `.hpp` file includes it. In other words, list a dependency as `PRIVATE` if it is needed only to compile the library, but not for including headers. List a dependency as `INTERFACE` if it is not needed to compile the library, but is needed for including headers. List a dependency as `PUBLIC` if it is needed for both. \note If your library only contains header files, you must specify `INTERFACE` like so in the `add_spectre_library(${LIBRARY} INTERFACE)` function. You should also omit the `spectre_target_sources` lines as well. ## Adding Unit Tests {#adding_unit_tests} We use the [Catch](https://github.com/philsquared/Catch) testing framework for unit tests. All unit tests are housed in `tests/Unit` with subdirectories for each subdirectory of `src`. Add the `cpp` file to the appropriate subdirectory and also to the `CMakeLists.txt` in that subdirectory. Inside the source file you can create a new test by adding a `SPECTRE_TEST_CASE("Unit.Dir.Component", "[Unit][Dir][Tag]")`. The `[Tag]` is optional and you can have more than one, but the tags should be used quite sparingly. The purpose of the tags is to be able to run all unit tests or all tests of a particular set of components, e.g. `ctest -L Data` to run all tests inside the `Data` directory. Please see \ref writing_unit_tests "writing unit tests", other unit tests and the [Catch documentation](https://github.com/philsquared/Catch) for more help on writing tests. Unit tests should take as short a time as possible, with a goal of less than two seconds. Please also limit the number of distinct cases (by using `SECTION`s). You can check the unit test coverage of your code by installing all the optional components and then running `make unit-test-coverage` (after re-running CMake). This will create the directory `BUILD_DIR/docs/html/unit-test-coverage/` which is where the coverage information is located. Open the `index.html` file in your browser and make sure that your tests are indeed checking all lines of your code. Your pull requests might not be merged until your line coverage is over 90% (we are aiming for 100% line coverage wherever possible). Unreachable lines of code can be excluded from coverage analysis by adding the inline comment `LCOV_EXCL_LINE` or a block can be excluded using `LCOV_EXCL_START` and `LCOV_EXCL_STOP`. However, this should be used extremely sparingly since unreachable code paths should be removed from the code base altogether. ## Adding Executables {#adding_executables} All general executables are found in `src/Executables`, while those for specific evolution (elliptic) systems are found in `src/Evolution/Executables` (`src/Elliptic/Executables`). See \ref dev_guide_creating_executables "how to create executables". ## Adding External Dependencies {#adding_external_dependencies} To add an external dependency, first add a `SetupDEPENDENCY.cmake` file to the `cmake` directory. If CMake does not already support `find_package` for the library you're adding you can write your own `FindDEPENDENCY.cmake` file. The `SetupDEPENDENCY.cmake` file must then be included in the root `spectre/CMakeLists.txt`. Be sure to test both that setting `LIBRARY_ROOT` works correctly for your library, and also that if the library is required that CMake fails gracefully if the library is not found. # Dependencies ## Checking Dependencies Getting dependencies of libraries correct is quite difficult. SpECTRE offers the CMake function `check_spectre_libs_dependencies`, defined in `cmake/SpectreCheckDependencies.cmake`, to check the dependencies for all libraries in the `libs` target. Individual target dependencies can be checked using the `check_target_dependencies` CMake function defined in `cmake/SpectreCheckTargetDependencies.cmake`. Please see those functions in the source tree for more details on how to use them. ## Formaline SpECTRE's implementation of Formaline is based on, but distinct in implementation from, the [original design](https://github.com/hypercott/formaline) which embeds an archive of the source tree into the executable. The original design creates a C/C++ file with a function that returns an array/vector of `char`s (a byte stream). However, this results in a very large source file (50MB or more), which is very slow to compile and ends up more than doubling the link time. Instead, SpECTRE's Formaline implementation uses the linker `ld` to encode a file into an object, which means rather than creating a large source file, we can directly encode the source tree archive into the binary at the linking stage. Most of SpECTRE's Formaline is implemented inside the `tools/WrapExecutableLinker.sh` script. Function declarations are provided in `Utilities/Formaline.hpp` and a small function that writes the source file to disk is defined in `Utilities/Formaline.cpp`. The first Formaline-related thing done in `WrapExecutableLinker.sh` is to archive everything in the source directory tracked by git. Once the archive is created we run `ld -r -b binary -o object.o src.tar.gz` (with unique names for `object.o` and `src.tar.gz` for each executable that is built to avoid name collisions) to generate an object file with the source file encoded from `_binary_src_tar_gz_start` to `_binary_src_tar_gz_end`. Next we write a C++ source file that defines a function `get_archive` to convert the byte stream into a `std::vector`. We also encode the output of `printenv`, the various `PATH` environment variables, and the CMake generated `BuildInfo.txt` file into the source file. Finally, the generated source file is built during the linking phase and the object file containing the source archive is linked into the executable. To further aid in reproducibility, the `printenv` output and `BuildInfo.txt` contents are written to HDF5 files as part of the `h5::Header` object. The archive of the source tree is written using the `h5::SourceArchive` object and can be extracted by running ``` h5dump -d /src.tar.gz -b LE -o src.tar.gz /path/to/hdf5/file.h5 ``` # Using Kokkos Kokkos support is still extremely experimental, but can be enabled by passing `-D SPECTRE_KOKKOS=ON` to CMake. You must pass additional CMake flags that Kokkos will use to configure itself. For example, to enable CUDA support you must pass `-D Kokkos_ENABLE_CUDA=ON`. See the [Kokkos documentation](https://kokkos.org/kokkos-core-wiki/keywords.html) for details. ## Nvidia Compiler If you are using CUDA to compile for Nvidia GPUs but do not have the target GPU on the system you are compiling on then you must also tell CMake what CUDA architecture to use. You can do this by passing `-D CMAKE_CUDA_ARCHITECTURES=80` to CMake. You must choose the architecture that will be compatible with the GPU you plan to use. Note that this is actually called the compute capability version by Nvidia and can be viewed [here](https://developer.nvidia.com/cuda-gpus). ================================================ FILE: docs/Installation/Installation.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Installation {#installation} \tableofcontents This page details how to install SpECTRE on personal machines and on clusters that have no official support (yet). - For details on installing SpECTRE on a number of clusters that we support please refer to: \subpage installation_on_clusters - For configuring SpECTRE please refer to: \subpage spectre_build_system - For instructions on installing SpECTRE on Apple Silicon Macs please refer to: \subpage installation_on_apple_silicon - For information on our versioning scheme and public releases please refer to: \subpage versioning_and_releases ### Running containerized releases #### CLI Entrypoint A quick way to run the code without installing anything at all is with our containerized releases: ``` docker run sxscollaboration/spectre --help ``` You can also use [Apptainer/Singularity](https://apptainer.org) instead of Docker, which works better on computing clusters and is more convenient because it shares the host's file system: ``` apptainer run docker://sxscollaboration/spectre --help ``` The entrypoint to this container is the SpECTRE \ref tutorial_cli "command-line interface (CLI)". For example, you can generate initial data for a simulation of merging black holes and plot the result like this: ``` apptainer run docker://sxscollaboration/spectre bbh generate-id \ -q 1 --chi-A 0 0 0 --chi-B 0 0 0 -D 16 -w 0.015 -a 0 -o ./bbh_id apptainer run docker://sxscollaboration/spectre plot slice \ bbh_id/BbhVolume*.h5 -C 0,0,0 -n 0,0,1 -u 0,1,0 -X 24 24 \ -y ConformalFactor -o plot.pdf ``` The containers currently have precompiled code only for Linux x86_64 platforms, and only have a limited set of executables precompiled. The supported features available in the precompiled containers are: - Generating initial data - Running CCE (see \ref tutorial_cce) - Running Python support code with the SpECTRE CLI (see \ref tutorial_cli) #### Starting a container {#start_deploy_container} If you'd rather use an image to start a container, you can run ``` docker run --name spectre -i --entrypoint /bin/bash -t sxscollaboration/spectre:deploy ``` \note The `--entrypoint /bin/bash` is important so you don't run the CLI. ### Running static binaries Another way of running the code without installing anything is with our precompiled static binaries, which are published on GitHub: - Releases with precompiled executables: https://github.com/sxs-collaboration/spectre/releases These are currently compiled only for Linux x86_64 platforms and for Intel Haswell architecture, so they should be compatible with machines newer than mid 2013. We only publish a limited set of precompiled static binaries that are useful as stand-alone tools, such as the CCE executables (see \ref tutorial_cce). ### Quick-start guide for code development with Docker and Visual Studio Code If you're new to writing code for SpECTRE and would like to jump right into a working development environment, a good place to start is our \subpage dev_guide_quick_start_docker_vscode. ### Quick-start installation {#quick_start_install} The easiest way of installing SpECTRE natively on a new machine is this: 1. Collect dependencies. You need a C++ compiler (GCC or Clang), CMake, BLAS/LAPACK, Boost, GSL, HDF5, and Python installed. For details on these required dependencies see \ref build_dependencies. On many computing clusters they are available as modules. On personal machines you can install them with a package manager. 2. Clone the SpECTRE repository: ```sh git clone git@github.com:sxs-collaboration/spectre.git export SPECTRE_HOME=$PWD/spectre ``` 3. Install Charm++: ```sh git clone https://github.com/UIUC-PPL/charm cd charm git checkout v8.0.0 ./build charm++ --with-production --build-shared --disable-tls export CHARM_ROOT=$PWD/ ``` Choose the `` from [this list in the Charm++ documentation](https://github.com/charmplusplus/charm?tab=readme-ov-file#how-to-choose-a-version). For example, choose `multicore-linux-x86_64` on a Linux laptop, `multicore-darwin-arm8` on an Apple Silicon laptop, and `mpi-linux-x86_64` on a standard computing cluster (you will also need MPI for this). See \ref building-charm for details. 4. Configure and build SpECTRE: ```sh cd $SPECTRE_HOME mkdir build cd build cmake \ -D CMAKE_C_COMPILER= \ -D CMAKE_CXX_COMPILER= \ -D CMAKE_Fortran_COMPILER=gfortran \ -D CMAKE_BUILD_TYPE= \ -D CHARM_ROOT=$CHARM_ROOT \ -D SPECTRE_FETCH_MISSING_DEPS=ON \ -D MEMORY_ALLOCATOR=SYSTEM \ $SPECTRE_HOME ``` See \ref building-spectre for details and \ref common_cmake_flags for a list of possible configuration options. For example, set `-D ENABLE_OPENMP=ON` to enable OpenMP-parallelization for the exporter library. Now you can compile executables (again, see \ref building-spectre for details). For example: ```sh make -j12 cli make -j12 BundledExporter ``` ### Installation with Spack You can also install SpECTRE with the [Spack](https://github.com/spack/spack) package manager: ```sh git clone https://github.com/spack/spack source ./spack/share/spack/setup-env.sh spack compiler find spack external find spack install spectre executables=ExportCoordinates3D \ ^charmpp backend=multicore ``` You probably want to customize your installation, e.g., to select a particular version of SpECTRE, the executables you want to install, additional options such as Python bindings, or the Charm++ backend. You can display all possible options with: ```sh spack info spectre # or charmpp, etc. ``` Refer to the [Spack documentation](https://spack.readthedocs.io/en/latest/) for more information. \warning We have not found the Spack installation particularly stable since the Spack package manager is still in development. ## Detailed installation instructions This remainder of this page details the installation procedure for SpECTRE. ### Dependencies {#build_dependencies} \note You don't need to install any of these dependencies by hand if you use a container or follow the \ref quick_start_install. #### Required: * [GCC](https://gcc.gnu.org/) 10.0 or later, [Clang](https://clang.llvm.org/) 13.0 or later (see [here](https://apt.llvm.org/) for how to get newer versions of clang through apt), or AppleClang 13.0.0 or later * [CMake](https://cmake.org/) 3.18.0 or later * [Git](https://git-scm.com/) * BLAS & LAPACK (e.g. [OpenBLAS](http://www.openblas.net)) * [Boost](http://www.boost.org/) 1.60.0 or later * [GSL](https://www.gnu.org/software/gsl/) \cite Gsl * [GNU make](https://www.gnu.org/software/make/) * [HDF5](https://support.hdfgroup.org/HDF5/) (non-mpi version on macOS) \cite Hdf5 * [Python](https://www.python.org/) 3.8 or later. * [Charm++](http://charm.cs.illinois.edu/) 7.0.0, or later (8 preferred). See also \ref building-charm. \cite Charmpp1 \cite Charmpp2 \cite Charmpp3 The following dependencies will be fetched automatically if you set `SPECTRE_FETCH_MISSING_DEPS=ON`: * [Blaze](https://bitbucket.org/blaze-lib/blaze/overview) v3.8. When installing manually, it can be beneficial to install Blaze with CMake so some configuration options are determined automatically, such as cache sizes. \cite Blaze1 \cite Blaze2 * [Catch2](https://github.com/catchorg/Catch2) 3.4.0 or later. You can also install Catch2 from your package manager or do a standard CMake build and installation (as detailed in the [Catch2 docs](https://github.com/catchorg/Catch2/blob/devel/docs/cmake-integration.md#installing-catch2-from-git-repository)). Compile with `CMAKE_POSITION_INDEPENDENT_CODE=ON`. * [LIBXSMM](https://github.com/libxsmm/libxsmm) version 1.16.1 or later. Some configurations of LIBXSMM build incorrectly against pthreads, causing ``undefined reference to 'pthread_yield'`` when building SpECTRE. It is unclear what conditions trigger the problem, but it is fixed in versions newer than 1.17. (As of this writing, there are no newer releases and affected systems must build from git.) \cite Libxsmm * [yaml-cpp](https://github.com/jbeder/yaml-cpp) version 0.7.0 or later. Building with shared library support is recommended when installing from source. \cite Yamlcpp * Python dependencies listed in `support/Python/requirements.txt`. Install with `pip3 install -r support/Python/requirements.txt`. Make sure you are working in a [Python venv](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment) before installing packages. Alternatively, you can set `BOOTSTRAP_PY_DEPS=ON` when configuring a build with CMake to install missing Python packages into the build directory automatically.
\include support/Python/requirements.txt
#### Optional: * [Pybind11](https://pybind11.readthedocs.io) 2.7.0 or later for SpECTRE Python bindings. Included in `support/Python/requirements.txt`. \cite Pybind11 * [jemalloc](https://github.com/jemalloc/jemalloc) * [Doxygen](https://www.doxygen.nl/index.html) 1.9.1 to 1.9.6 — to generate documentation * Python dev dependencies listed in `support/Python/dev_requirements.txt` — for documentation pre- and post-processing, formatting code, etc. Install with `pip3 install -r support/Python/dev_requirements.txt`. Make sure you are working in a [Python venv](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment) before installing packages.
\include support/Python/dev_requirements.txt
* [Kokkos](https://github.com/kokkos/kokkos) (experimental) - for GPU support. See \ref gpu_support for details. * [Google Benchmark](https://github.com/google/benchmark) - to do microbenchmarking inside the SpECTRE framework. v1.2 or newer is required * [LCOV](http://ltp.sourceforge.net/coverage/lcov.php) and [gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html) — to check code test coverage * [PAPI](http://icl.utk.edu/papi/) — to access hardware performance counters * [ClangFormat](https://clang.llvm.org/docs/ClangFormat.html) — to format C++ code in a clear and consistent fashion * [Clang-Tidy](http://clang.llvm.org/extra/clang-tidy/) — to "lint" C++ code * [Scotch](https://gitlab.inria.fr/scotch/scotch) - to build the `ScotchLB` graph partition based load balancer in charm++. * [ffmpeg](https://www.ffmpeg.org/) - for animating 1d simulations with matplotlib * [xsimd](https://github.com/xtensor-stack/xsimd) 11.0.1 or newer - for manual vectorization * [autodiff](https://github.com/autodiff/autodiff/) commit cc2aa5726fdbb258d097f87b97da3d1022f8394e or newer - for automatic differentiation * [libbacktrace](https://github.com/ianlancetaylor/libbacktrace) - to show source files and line numbers in backtraces of errors and asserts. Available by default on many systems, so you may not have to install it at all. The CMake configuration will tell you if you have libbacktrace installed. * [ParaView](https://www.paraview.org/) - for visualization \cite Paraview1 \cite Paraview2 . Make sure your ParaView installation uses the same (major and minor) version of Python as the rest of the build. * [SpEC](https://www.black-holes.org/code/SpEC.html) - to load SpEC data. Compile the exporter in SpEC's `Support/ApplyObservers/Exporter/` directory (see the `Makefile` in that directory). Also make sure to compile SpEC with the same compiler and MPI as SpECTRE to avoid compatibility issues. #### Bundled: * [Brigand](https://github.com/edouarda/brigand) * [libsharp](https://github.com/Libsharp/libsharp) \cite Libsharp ## Clone the SpECTRE repository First, clone the [SpECTRE repository](https://github.com/sxs-collaboration/spectre) to a directory of your choice. In the following we will refer to it as SPECTRE_ROOT. You may `git clone` from GitHub, in which case SPECTRE_ROOT will be `/spectre`. That is, inside SPECTRE_ROOT are `docs`, `src`, `support`, `tests` etc. You can also download the source and extract them to your desired working directory, making sure not to leave out hidden files when you `cp` or `mv` the source files. ## Using Docker to obtain a SpECTRE environment {#docker_install} A [Docker](https://www.docker.com/) image is available from [DockerHub](https://hub.docker.com/r/sxscollaboration/spectre/) and can be used to build SpECTRE on a personal machine. **Note**: If you have SELinux active on your system you must figure out how to enable sharing files with the host OS. If you receive errors that you do not have permission to access a shared directory it is likely that your system has SELinux enabled. One option is to disable SELinux at the expense of reducing the security of your system. To build with the Docker image: 1. Install [Docker-Desktop](https://docs.docker.com/get-docker/). For Linux, if you want to be able to run the following steps without `sudo`, follow the [post-installation-guide](https://docs.docker.com/engine/install/linux-postinstall/) to add a non-root user. 2. Retrieve the Docker image (you may need `sudo` in front of this command) ``` docker pull sxscollaboration/spectre:dev ``` 3. Start the Docker container (you may need `sudo`) ``` docker run -v $SPECTRE_ROOT/:$SPECTRE_ROOT/ --name spectre_dev \ -i -t sxscollaboration/spectre:dev /bin/bash ``` - `-v $SPECTRE_ROOT/:$SPECTRE_ROOT/` binds the directory `$SPECTRE_ROOT` (which is an environment variable you must set up or just use the actual path) outside the container to `$SPECTRE_ROOT` inside the container. In this way, files in the `$SPECTRE_ROOT` on your host system (outside the container) become accessible within the container through the directory SPECTRE_ROOT inside the container. If you wonder why the same SPECTRE_ROOT needs to be used for both inside and outside the container, which is why `$SPECTRE_ROOT` is repeated in the command above with separated by a colon, please see one of the notes below regarding `-v` flag. - The `--name spectre_dev` is optional. If you don't name your container, docker will generate an arbitrary name. - On macOS you can significantly increase the performance of file system operations by appending the flag `:delegated` to `-v`, e.g. `-v $SPECTRE_ROOT/:$SPECTRE_ROOT/:delegated` (see https://docs.docker.com/docker-for-mac/osxfs-caching/). - The `-i` flag is for interactive mode, which will drop you into the container. - It can be useful to expose a port to the host so you can run servers such as [Jupyter](https://jupyter.org/index.html) for accessing the Python bindings (see \ref spectre_using_python) or a Python web server to view the documentation. To do so, append the `-p` option, e.g. `-p 8000:8000`. You will end up in a bash shell in the docker container, as root (you need to be root). Within the container, the files in `$SPECTRE_ROOT` are available and Charm++ is installed in `/work/charm_7_0_0`. For the following steps, stay inside the docker container as root. 4. Proceed with [building SpECTRE](#building-spectre). **Notes:** * Everything in your build directory is owned by root, and is accessible only within the container. * You should edit source files in SPECTRE_ROOT in a separate terminal outside the container, and use the container only for compiling and running the code. * If you exit the container (e.g. ctrl-d), your compilation directories are still saved, as are any other changes to the container that you have made. To restart the container, try the following commands (you may need `sudo`): 1. `docker ps -a`, to list all containers with their CONTAINER_IDs and CONTAINER_NAMEs, 2. `docker start -i CONTAINER_NAME` or `docker start -i CONTAINER_ID`, to restart your container (above, the CONTAINER_NAME was spectre_dev). * When the Docker container gets updated, you can stop it with `docker stop CONTAINER_NAME`, remove it with `docker rm CONTAINER_NAME` and then start at step 2 above to run it again. * You can run more than one shell in the same container, for instance one shell for compiling with gcc and another for compiling with clang. To add a new shell, run `docker exec -it CONTAINER_NAME /bin/bash` (or `docker exec -it CONTAINER_ID /bin/bash`) from a terminal outside the container. * In step 4 above, technically docker allows you to say `-v $SPECTRE_ROOT/:/my/new/path` to map `$SPECTRE_ROOT` outside the container to any path you want inside the container, but **do not do this**. Compiling inside the container sets up git hooks in SPECTRE_ROOT that contain hardcoded pathnames to SPECTRE_ROOT *as seen from inside the container*. So if your source paths inside and outside the container are different, commands like `git commit` run *from outside the container* will die with `No such file or directory`. * If you want to use Docker within VSCode, take a look at our [quick start guide](../DevGuide/QuickStartDockerVSCode.md) for using Docker with VSCode. ## Using Singularity to obtain a SpECTRE environment [Singularity](https://sylabs.io) is a container alternative to Docker with better security and nicer integration. To build SpECTRE with Singularity you must: 1. Build [Singularity](https://sylabs.io) and add it to your `$PATH` 2. `cd` to the directory where you want to store the SpECTRE Singularity image, source, and build directories, let's call it WORKDIR. The WORKDIR must be somewhere in your home directory. If this does not work for you, follow the Singularity instructions on setting up additional [bind points](https://sylabs.io/guides/3.7/user-guide/bind_paths_and_mounts.html) (version 3.7. For other versions, see the [docs](https://sylabs.io/docs/)). Once inside the WORKDIR, clone SpECTRE into `WORKDIR/SPECTRE_ROOT`. 3. Run `sudo singularity build spectre.img docker://sxscollaboration/spectre:dev`. You can also use spectre:ci instead of spectre:dev if you want more compilers installed. If you get the error message that `makesquashfs` did not have enough space to create the image you need to set a different `SINGULARITY_TMPDIR`. This can be done by running: `sudo SINGULARITY_TMPDIR=/path/to/new/tmp singularity build spectre.img docker://sxscollaboration/spectre:dev`. Normally `SINGULARITY_TMPDIR` is `/tmp`, but building the image will temporarily need almost 8GB of space. You can control where Singularity stores the downloaded image files from DockerHub by specifying the `SINGULARITY_CACHEDIR` environment variable. The default is `$HOME/.singularity/`. Note that `$HOME` is `/root` when running using `sudo`. 4. To start the container run `singularity shell spectre.img` and you will be dropped into a bash shell. 5. Proceed with [building SpECTRE](#building-spectre). **Notes:** - You should edit source files in SPECTRE_ROOT in a separate terminal outside the container, and use the container only for compiling and running the code. - If you don't have the same Python version in your environment outside the container as the version inside the container, this will create problems with git hooks. The Singularity container uses python3.8 by default. Thus, it is up to the user to ensure that they are using the same Python version inside and outside the container. To use a different Python version in the container add `-D Python_EXECUTABLE=/path/to/python` to the cmake command where `/path/to/python` is usually `/usr/bin/pythonX` and `X` is the version you want. - Unlike Docker, Singularity does not keep the state between runs. However, it shares the home directory with the host OS so you should do all your work somewhere in your home directory. - To run more than one container just do `singularity shell spectre.img` in another terminal. - Since the data you modify lives on the host OS there is no need to worry about losing any data, needing to clean up old containers, or sharing data between containers and the host. ## Using Spack to set up a SpECTRE environment SpECTRE's dependencies can be installed with [Spack](https://github.com/spack/spack), a package manager tailored for HPC use. [Install Spack](https://spack.readthedocs.io/en/latest/getting_started.html) by cloning it into `SPACK_DIR` (a directory of your choice). Then, enable Spack's shell support with `source SPACK_DIR/share/spack/setup-env.sh`. Consider adding this line to your `.bash_profile`, `.bashrc`, or similar. Refer to [Spack's getting started guide](https://spack.readthedocs.io/en/latest/getting_started.html) for more information. Once you have Spack installed, one way to install the SpECTRE dependencies is with a [Spack environment](https://spack.readthedocs.io/en/latest/environments.html): \include support/DevEnvironments/spack.yaml You can also install the Spack packages listed in the environment file above with a plain `spack install` if you prefer. **Notes:** - Spack allows very flexible configurations and we recommended you read the [documentation](https://spack.readthedocs.io) if you require features such as packages installed with different compilers. - For security, it is good practice to make Spack [use the system's OpenSSL](https://spack.readthedocs.io/en/latest/getting_started.html#openssl) rather than allow it to install a new copy. - To avoid reinstalling lots of system-provided packages with Spack, use the `spack external find` feature and the `--reuse` flag to `spack concretize` (or `spack install`). You can also install some of the dependencies with your system's package manager in advance, e.g., with `apt` or `brew`. If they are not picked up by `spack external find` automatically, register them with Spack manually. See the [Spack documentation on external packages](https://spack.readthedocs.io/en/latest/build_settings.html#external-packages) for details. - Spack works well with a module environment, such as [LMod](https://github.com/TACC/Lmod). See the [Spack documentation on modules](https://spack.readthedocs.io/en/latest/module_file_support.html) for details. ## Building Charm++ {#building-charm} If you are not using a container, haven't installed Charm++ with Spack, or want to install Charm++ manually for other reasons, follow the installation instructions in the [Charm++ repository](https://github.com/UIUC-PPL/charm) and in their [documentation](https://charm.readthedocs.io/en/latest/quickstart.html#installing-charm). Here are a few notes: - Once you cloned the [Charm++ repository](https://github.com/UIUC-PPL/charm), run `git checkout v8.0.0` to switch to a supported, stable release of Charm++. - Apply the appropriate patch (if there is one) for the version from `${SPECTRE_ROOT}/support/Charm`. For example, if you have Charm++ v7.0.0 then the patch will be `v7.0.0.patch`. - Choose the `LIBS` target to compile. This is needed so that we can support the more sophisticated load balancers in SpECTRE executables. - On a personal machine the correct target architecture is likely `multicore-linux-x86_64`, or `multicore-darwin-x86_64` on macOS. On an HPC system the correct Charm++ target architecture depends on the machine's inter-node communication architecture. It might take some experimenting to figure out which Charm++ configuration provides the best performance. - Compile Charm++ with support for shared libraries by appending the option `--build-shared` to the `./build` command or pass `BUILD_SHARED=ON` to the CMake configuration (see the [Charm++ installation instructions](https://github.com/UIUC-PPL/charm#building-dynamic-libraries)). - Passing the `--disable-tls` option to `build` or `-D DISABLE_TLS=ON` to cmake is required for SpECTRE's Python bindings to work. - When compiling Charm++ you can specify the compiler using, for example, ``` ./build LIBS ARCH clang ``` ## Building SpECTRE {#building-spectre} Once you have set up your development environment you can compile SpECTRE. Follow these steps: 1. Create a build directory where you would like to compile SpECTRE. In the Docker container you could create, e.g., `/work/spectre-build`. It can be useful to add a descriptive label to the name of the build directory since you may create more later, e.g., `build-clang-Debug`. Then, `cd` into the build directory. 2. Determine the location of your Charm++ installation. In the Docker container it is `/work/charm_7_0_0/multicore-linux-x86_64-gcc` for GCC builds and `/work/charm_7_0_0/mpi-linux-x86_64-smp-clang` for clang builds. For Spack installations you can determine it with `spack location --install-dir charmpp`. We refer to the install directory as `CHARM_ROOT` below. 3. In your new SpECTRE build directory, configure the build with CMake: ``` cmake -D CHARM_ROOT=$CHARM_ROOT SPECTRE_ROOT ``` Add options to the `cmake` command to configure the build, select compilers, etc. For instance, to build with clang you may run: ``` cmake -D CMAKE_CXX_COMPILER=clang++ \ -D CMAKE_C_COMPILER=clang \ -D CMAKE_Fortran_COMPILER=gfortran \ -D CHARM_ROOT=$CHARM_ROOT \ SPECTRE_ROOT ``` See \ref common_cmake_flags for documentation on possible configuration options. 4. When cmake configuration is done, you are ready to build target executables. - You can see the list of available targets by running `make list` (or `ninja list` if you are using the Ninja generator) or by using tab completion. Compile targets with `make -jN TARGET` (or `ninja -jN TARGET`), where `N` is the number of cores to build on in parallel (e.g. `-j4`). Note that the Ninja generator allows you to compile individual source files too. - Compile the `unit-tests` target and run `ctest -L unit` to run unit tests. Compile `test-executables` and run `ctest` to run all tests, including executables. To compile `test-executables` you may have to reduce the number of cores you build on in parallel to avoid running out of memory. - To use the command-line interface (CLI), compile the `cli` target (see \ref tutorial_cli). - To use the Python bindings, compile the `all-pybindings` target (see \ref spectre_using_python). ## Code Coverage Analysis For any coverage analysis you will need to have LCOV installed on the system. For documentation coverage analysis you will also need to install [coverxygen](https://github.com/psycofdj/coverxygen) and for test coverage analysis [gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html). If you have these installed (which is already done if you are using the docker container), you can look at code coverage as follows: 1. On a gcc build, pass `-D COVERAGE=ON` to `cmake` 2. `make unit-test-coverage` 3. The output is in `docs/html/unit-test-coverage`. ================================================ FILE: docs/Installation/InstallationOnAppleSilicon.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond ## Installing SpECTRE on Apple Silicon {#installation_on_apple_silicon} \tableofcontents The following instructions show how to install SpECTRE and its dependencies on Apple Silicon Macs. Apple Silicon is an arm64 architecture, in contrast to the x86-64 architecture that SpECTRE usually targets. These instructions will result in an Apple Silicon native build of SpECTRE. \note Floating-point exception trapping is not currently supported on Apple Silicon. ### 0. Install the xcode command-line tools. Install the xcode command-line tools, which include the clang compiler, etc. Run the following command in the terminal: ``` xcode-select --install ``` ### 1. Clone spectre Clone the SpECTRE repository in a directory of your choice: ```sh git clone git@github.com:sxs-collaboration/spectre.git export SPECTRE_HOME=$PWD/spectre ``` ### 2. Install python dependencies Spectre depends on python and some python packages. There are different ways to install an arm64-native python stack. The following instructions show how to do this using the Python 3 interpreter bundled with macOS. ```sh cd $SPECTRE_HOME # Create a Python environment python3 -m venv ./env --upgrade-deps # Activate the Python environment . ./env/bin/activate # Install Python packages pip install -r support/Python/requirements.txt \ -r support/Python/dev_requirements.txt # Optionally install additional packages you might want, like Jupyter pip install jupyterlab ``` ### 3. Install dependencies with Homebrew Most of spectre's dependencies can be installed using the [Homebrew](https://brew.sh) package manager. First, if you haven't already, install Homebrew by following the instructions on the [Homebrew](https://brew.sh) homepage. Then, run the following to install a Fortran compiler and other dependencies: ``` brew install gcc autoconf automake ccache cmake brew install boost catch2 doxygen gsl hdf5 openblas yaml-cpp xsimd ``` \note We use OpenBLAS instead of Apple's Accelerate framework here because Accelerate fails to reach the same floating point accuracy as OpenBLAS in some of our tests (specifically partial derivatives). ### 4. Install remaining dependencies Here, install the remaining dependencies that cannot be installed with Homebrew. You can install them from source manually, or use the [Spack](https://github.com/spack/spack) package manager (see below). #### Install manually ```sh export SPECTRE_DEPS_ROOT=$HOME/apps mkdir -p $SPECTRE_DEPS_ROOT cd $SPECTRE_DEPS_ROOT # Install Charm++ git clone https://github.com/UIUC-PPL/charm pushd charm git checkout v8.0.0 ./build charm++ multicore-darwin-arm8 --with-production -g3 -j --build-shared \ --disable-tls popd # The following dependencies are optional! They will be installed in the build # directory automatically if needed in the next step. You can install them # manually like this if you want control over where or how they are installed. # If you don't care, you can skip ahead. # Install Blaze mkdir blaze pushd blaze curl -L https://bitbucket.org/blaze-lib/blaze/downloads/blaze-3.8.tar.gz \ > blaze-3.8.tar.gz tar -xf blaze-3.8.tar.gz mv blaze-3.8 include popd # Install libxsmm # Need master branch of libxsmm to support Apple Silicon git clone https://github.com/libxsmm/libxsmm.git pushd libxsmm make popd ``` #### Install with Spack ```sh # Download spack cd ~ git clone -c feature.manyFiles=true https://github.com/spack/spack.git cd spack # Switch to latest release git checkout releases/latest # Load shell support . ./share/spack/setup-env.sh # Find some system packages so we don't have to install them all from source spack external find # Install dependencies spack install \ charmpp@7.0.0: +shared backend=multicore build-target=charm++ \ blaze@3.8.2 ~blas ~lapack smp=none \ libxsmm@1.16.1: \ ``` ### 5. Configure and build SpECTRE Create a build directory in a location of your choice, e.g. ```sh cd $SPECTRE_HOME mkdir build cd build ``` Next, configure SpECTRE using the following CMake command. If you installed dependencies with Spack, you can use `spack find -p` to retrieve the root directories of the packages and replace them in the command below. You only need to specify `LIBXSMM_ROOT` and `BLAZE_ROOT` if you installed those packages yourself above. The option `SPECTRE_FETCH_MISSING_DEPS` will take care of downloading these if you haven't installed them above. ```sh cmake \ -D CMAKE_C_COMPILER=clang \ -D CMAKE_CXX_COMPILER=clang++ \ -D CMAKE_Fortran_COMPILER=gfortran \ -D CMAKE_BUILD_TYPE=Debug \ -D BUILD_SHARED_LIBS=ON \ -D MEMORY_ALLOCATOR=SYSTEM \ -D CHARM_ROOT=${SPECTRE_DEPS_ROOT}/charm/multicore-darwin-arm8 \ -D SPECTRE_FETCH_MISSING_DEPS=ON \ -D SPECTRE_TEST_TIMEOUT_FACTOR=5 \ -D BLAS_ROOT=$(brew --prefix openblas) \ -D LAPACK_ROOT=$(brew --prefix openblas) \ -D LIBXSMM_ROOT=${SPECTRE_DEPS_ROOT}/libxsmm/ \ -D BLAZE_ROOT=${SPECTRE_DEPS_ROOT}/blaze/ \ .. ``` Finally, build and test SpECTRE. E.g., on a Mac with 10 cores, ```sh make -j10 unit-tests make -j10 test-executables ctest --output-on-failure -j10 ``` Optionally, to install the python bindings in your python environment, ```sh make -j10 all-pybindings pip install -e ${SPECTRE_HOME}/build/bin/python ``` ================================================ FILE: docs/Installation/InstallationOnClusters.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Installation on Clusters {#installation_on_clusters} \tableofcontents The installation instructions are the same for most systems because we use shell scripts to set up the environment for each supercomputer. We describe the generic installation instructions once, and only note special instructions if necessary for the particular system. If you have already built SpECTRE and just want to load the modules, source the shell file for your system and run `spectre_load_modules`. \note Sample submit scripts for some systems are available in `support/SubmitScripts`. ## General Instructions 1. Run `export SPECTRE_HOME=/path/to/where/you/want/to/clone` 2. Clone SpECTRE using `git clone SPECTRE_URL $SPECTRE_HOME` where the `SPECTRE_URL` is the GitHub url you want to use to clone the repo. 3. Run `cd $SPECTRE_HOME && mkdir build && cd build` 4. Run `. $SPECTRE_HOME/support/Environments/SYSTEM_TO_RUN_ON_gcc.sh`, where `SYSTEM_TO_RUN_ON` is replaced by the name of the system as described in the relevant section below. 5. If you haven't already installed the dependencies, run `export SPECTRE_DEPS=/path/to/where/you/want/the/deps` Then run `spectre_setup_modules $SPECTRE_DEPS`. This will take a while to finish. Near the end the command will tell you how to make the modules available by providing a `module use` command. Make sure you are providing an absolute path to `spectre_setup_modules`. 6. Run `module use $SPECTRE_DEPS/modules` 7. Run `spectre_run_cmake`, if you get module loading errors run `spectre_unload_modules` and try running `spectre_run_cmake` again. CMake should set up successfully. 8. Build the targets you are interested in by running, e.g. `make -j4 test-executables` ## Anvil at Purdue University You should build and run tests on a compute node. You can get a compute node by running ``` sinteractive -N1 -n 20 -p debug -t 60:00 ``` Avoid running `module purge` because this also removes various default modules that are necessary for proper operation. Instead, use `module restore`. Currently the tests can only be run in serial, e.g. `ctest -j1` because all the MPI jobs end up being launched on the same core. ## Frontera at TACC Follow the general instructions, using `frontera` for `SYSTEM_TO_RUN_ON`. Processes running on the head nodes have restrictions on memory use that will prevent linking the main executables. It is better to compile on an interactive node. Interactive nodes can be requested with the `idev` command. For unknown reasons, incremental builds work poorly on frontera. Running `make` will often unnecessarily recompile SpECTRE libraries. ## CaltechHPC at Caltech Cluster documentation: https://www.hpc.caltech.edu Follow the general instructions, using `caltech_hpc` for `SYSTEM_TO_RUN_ON`, except you don't need to install any dependencies, so you can skip step 5 and step 6. There are multiple types of compute nodes on CaltechHPC, which are listed on https://www.hpc.caltech.edu/resources. We compile SpECTRE to be compatible with all of them. When you go to build, you will need to get an interactive node (login nodes limit the amount of memory accessible to individual users, to below the amount necessary to build SpECTRE). Slurm commands are listed on https://www.hpc.caltech.edu/documentation/slurm-commands. For example to ensure you get an entire node to build on, use the following command: ``` srun [--reservation=sxs_standing] [--constraint=skylake/cascadelake/icelake] \ -t 02:00:00 -N 1 --exclusive -D . --pty /bin/bash ``` If you are part of the SXS collaboration, you can use our reserved nodes by specifying `--reservation=sxs_standing`. Our reserved nodes are currently cascadelake nodes with 56 cores each. If you want to use another type of node you can specify a `--constraint`. However, note that the reservation flag won't work for nodes other than cascadelake. Be sure to re-source the correct environment files once you get the interactive node shell. ## Ocean at Fullerton Follow the general instructions, using `ocean` for `SYSTEM_TO_RUN_ON`, you do not need to install any dependencies, so you can skip steps 5 and 6. ## Mbot at Cornell Follow steps 1-3 of the general instructions. The only modules you need to load on `mbot` are `gcc/11.4.0 spectre-deps`. This will load everything you need, including LLVM/Clang. You can source the environment file by running `. $SPECTRE_HOME/support/Environments/mbot.sh` and load the modules using `spectre_load_modules`. This offers two functions, `spectre_run_cmake_gcc` and `spectre_run_cmake_clang` for the different compilers. These both default to `Release` mode. If you are developing code, please use either `spectre_run_cmake_clang -D CMAKE_BUILD_TYPE=Debug` or `spectre_run_cmake_clang -D SPECTRE_DEBUG=ON` (you can also use gcc). The second command with `SPECTRE_DEBUG=ON` enables sanity checks and optimizations. This means it can be used in production-level runs to ensure there aren't any subtle bugs that might only arise after a decently long simulation. ## Sonic at ICTS-TIFR Cluster documentation: https://it.icts.res.in/docs/sonic-cluster 1. Clone the spectre source code and set `SPECTRE_HOME` to point it. 2. Create a directory for building SpECTRE (`SPECTRE_BUILD`). 3. Setup the software environment ``` . /mnt/pfs/vaishak.p/soft/modules-5.2.0/init/bash ``` Add these lines to your `.bashrc` and source it if you would like to make it persistent. 4. Source the `$SPECTRE_HOME/support/Environments/Sonic.sh` script. 5. Build SpECTRE by changing to `$SPECTRE_BUILD` and using one of the variants of the `spectre_run_cmake` commands. This by default compiles SpECTRE in Release mode, without debug symbols and LTO, and with system malloc. If you wish to compile in debug mode, with LTO/JEMALLOC, or other options, simply suffix the additional cmake flags to the command. 6. Use `make` to build your targets. ================================================ FILE: docs/Installation/VersioningAndReleases.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Versioning and releases {#versioning_and_releases} \tableofcontents # Version format We employ a date-based versioning scheme with the format `YYYY.0M.0D[.TWEAK]`, where `YYYY` is the year, `0M` the zero-padded month and `0D` the zero-padded day of the month when the version is released. If additional versions are released on a single day, the `TWEAK` component enumerates them. For example, the first version released on May 4th, 2021 carries the name `2021.05.04`. Additional versions released on May 4th, 2021 would carry the names `2021.05.04.1`, `2021.05.04.2`, etc. The reason we use a date-based versioning scheme over, for example, semantic versioning is to avoid implying a notion of compatibility between releases (see section below). # Guarantees and non-guarantees of releases Each release is **guaranteed** to pass all automated tests laid out in the \ref github_actions_guide "guide on automated tests". We provide **no guarantee** that releases satisfy any notion of "compatibility" with each other. In particular, the interface of any C++ library, Python module or executable may change between releases. When writing code for SpECTRE we recommend regularly rebasing on the latest `develop` branch of the [`sxs-collaboration/spectre`](https://github.com/sxs-collaboration/spectre) repository and aiming to contribute your code upstream by following our \ref contributing_to_spectre "contributing guide" in a timely manner. That said, we make an effort to retain compatibility between releases for the following aspects of the code: - Simulation data: We try to ensure that data produced by a release remains compatible with future releases, in the sense that the data can be read, processed or converted to newer formats. - Python bindings: We try to offer deprecation warnings when changing the Python interfaces so developers of external packages that use the Python bindings have time to update their packages. We may establish guarantees for specific interfaces related to these aspects. These guarantees will be defined in the documentation of the respective interface. We explicitly provide **no guarantee** that input files remain compatible with executables built on different releases. Instead, we try to make input files as explicit as possible by not supporting default values, so simulations don't continue with subtly changed parameters part way through. We try to reflect changes that would affect running simulations in the input files, so they can (and often must) be reviewed before the simulation continues. Please note that low-level changes or bugs may always alter results, so be advised to stick with a particular compiled executable if a high level of reproducibility is crucial for your project. # Schedule We typically publish a release at the beginning of each month, and may publish additional releases irregularly. If a major bug is discovered and fixed we will likely create an unscheduled release. # How to find releases You can find all releases on GitHub: - [sxs-collaboration/spectre releases on GitHub](https://github.com/sxs-collaboration/spectre/releases) Each release is tagged with the version name and prefixed `v` in the repository. For example, this is how you can obtain the source code for the `2020.12.07` release: ```sh git clone -b v2020.12.07 https://github.com/sxs-collaboration/spectre ``` The latest release is always available on the `release` branch. This is how you can obtain the source code for the latest release: ```sh git clone -b release https://github.com/sxs-collaboration/spectre ``` ================================================ FILE: docs/Main.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond \mainpage Introduction \tableofcontents \htmlonly

license Standard Build Status codecov

\endhtmlonly # What is SpECTRE? {#intro_sec} SpECTRE is an open-source code for multi-scale, multi-physics problems in astrophysics and gravitational physics. It is based on high-order spectral finite element methods and massive parallelism. In the future, we hope that it can be applied to problems across discipline boundaries in fluid dynamics, geoscience, plasma physics, nuclear physics, and engineering. It runs at petascale and is designed for future exascale computers. SpECTRE is being developed in support of our collaborative Simulating eXtreme Spacetimes (SXS) research program into the multi-messenger astrophysics of black hole neutron star mergers, core-collapse supernovae, and gamma-ray bursts. ## Gallery For an overview of some of SpECTRE's features and some simulations performed with SpECTRE, visit the gallery: - Gallery: https://spectre-code.org/gallery ## Citing SpECTRE Please cite SpECTRE in any publications that make use of its code or data. Cite the latest version that you use in your publication. The DOI for this version is: - DOI: [\spectredoi](https://doi.org/\spectredoi) You can cite this BibTeX entry in your publication: \include citation.bib To aid reproducibility of your scientific results with SpECTRE, we recommend you keep track of the version(s) you used and report this information in your publication. We also recommend you supply the YAML input files and, if appropriate, any additional C++ code you wrote to compile SpECTRE executables as supplemental material to the publication. See our [publication policy](https://spectre-code.org/publication_policies.html) for more information. ## Navigating the Documentation {#navigate_documentation_sec} The SpECTRE documentation is organized into tutorials, developer guides, groups of related code, namespaces, and files for easier navigation. These can all be accessed by links in the menu bar at the top. - For instructions on **installing SpECTRE** on personal computers and clusters consult the \ref installation "Installation" and \ref installation_on_clusters "Installation on clusters" pages, respectively. See the \ref spectre_build_system "build system" page for how to configure SpECTRE. - If you are looking to **run simulations with SpECTRE** we recommend starting with the \ref tutorials "User Tutorials". The tutorials are designed to get users up and running with a simulation, as well as analyzing and visualizing the output. - For people looking to **contribute to SpECTRE** there are tutorials on the \ref dev_guide "Dev Guide" page. For instance, the dev guide details the \ref code_review_guide "code review guidelines", how to \ref writing_unit_tests "write unit tests", how to \ref writing_good_dox "write documentation", and also provides information about C++ and the philosophy behind SpECTRE development. - The [Code modules](modules.html) section contains groups of related code (managed through doxygen groups). For example, there is a group for all the data structures we use, a group for utility functions and classes, as well as groups for coordinate maps, domain creation, and many others. The [Code modules](modules.html) are designed to help developers discover existing functionality so that things are not re-implemented several times. - You can also get an overview of the code base by namespace by visiting the [Namespaces](namespaces.html) section. - To browse all files in the repository you can visit the [GitHub repository](https://github.com/sxs-collaboration/spectre) directly. ## Logos and visuals {#logos_and_visuals} You can find logos and other visuals (e.g. to put on slides) in various formats, colors, and sizes here: - [Logos and visuals](https://drive.google.com/drive/folders/1GEvVrXNqlGojr3NBf7RMFo6BzFmf9Ww7?usp=share_link) ================================================ FILE: docs/PublicationPolicy.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Publication policies {#publication_policies} SpECTRE is an open-source code that is developed and maintained by the [Simulating eXtreme Spacetimes (SXS) collaboration](https://black-holes.org). We ask all authors of scientific publications that make use of SpECTRE's code or data to follow the citation guidelines laid out in the section \ref citing. An additional set of guidelines, laid out in the section \ref sxs_publication_policies applies to publications by members of the SXS collaboration. ## Citing SpECTRE {#citing} Please cite SpECTRE in any publications that make use of its code or data. Cite the latest version that you use in your publication. The DOI for this version is: - DOI: [\spectredoi](https://doi.org/\spectredoi) You can cite this BibTeX entry in your publication: \include citation.bib To aid reproducibility of your scientific results with SpECTRE, we recommend you keep track of the version(s) you used and report this information in your publication. We also recommend you supply the YAML input files and, if appropriate, any additional C++ code you wrote to compile SpECTRE executables as supplemental material to the publication. ## Policies that apply to SXS publications {#sxs_publication_policies} These policies apply to all "science papers" by members of the SXS collaboration that make use of SpECTRE’s code or data, as defined by the [SXS policies](https://github.com/sxs-collaboration/WelcomeToSXS/blob/master/SxsPolicies.md). Our publication policies have the goal that contributions to SpECTRE gain value in academia. For SpECTRE to be successful, it must be worth a junior researcher's time to contribute to the code. Contributions are already partially acknowledged through authorship on the DOI, as laid out in the `Metadata.yaml` file. However, authorship on the DOI alone doesn’t hold enough value in academia to make code contributions worthwhile that have no immediate science paper associated with them, but that enable science papers down the line. Therefore, our policies have the purpose to grant authorship rights on science papers to the developers of code that enabled them. ### Guidelines for SXS paper authors - If you're a member of the SXS collaboration and use SpECTRE for your paper, you should probably include a list of SpECTRE developers as co-authors per the [SXS policies](https://github.com/sxs-collaboration/WelcomeToSXS/blob/master/SxsPolicies.md). - To obtain the list of co-authors, reach out to any of the people listed in the [SpECTRE core developers](https://github.com/orgs/sxs-collaboration/teams/spectre-core-devs/members) team on GitHub. Do this as early as possible, e.g., when you are setting up a paper repository to share early drafts and results with other co-authors. To contact the SpECTRE core developers, use a communication channel of your choice. Here are a few possibilities: - Send a message on Slack. - Knock on their office door. - Send an email to one of the core developers, or to [core-devs@spectre-code.org](mailto:core-devs@spectre-code.org). Possible wording of the email: > Dear SpECTRE core devs, > > I am / we are preparing a paper on [title or topic]. I am / we are using > SpECTRE in this way: > > - [Describe your use of SpECTRE briefly, e.g. as a bulleted list. Mention > which parts of SpECTRE you are using in particular, e.g. the initial > data solver, the evolution scheme, the wave extraction, etc.] > > Claims of the paper: > > - [Summarize the main claims you make in the paper. In particular, does > the paper make any claims about physics?] > > Please respond with the list of co-authors to include in the paper. > > Best regards, > [you] If you already have a draft or outline of your paper available, please feel free to attach it, to give the core developers a better idea of the ways you are using SpECTRE. The core developers will discuss among themselves, following the guidelines listed below, and will get back to you with a list of co-authors and their contributions. In the spirit of transparency within the collaboration the core developers will also share your description of the paper and the suggested list of co-authors with the [spectre-devel@black-holes.org](mailto:spectre-devel@black-holes.org) mailing list. - Please make the paper draft available to all co-authors as early as possible, e.g, by sharing access to a Git repository. This allows the co-authors to contribute their technical expertise to the SpECTRE-related part of the paper, and it also makes them aware of the ongoing work, in the spirit of transparency and collaboration within SXS. ## Guidelines to decide who has authorship rights on SXS science papers that use SpECTRE - A contribution to SpECTRE on the order of ~500 lines of code or more should earn you authorship rights on the first science paper that uses the feature. Major contributions, such as writing a full evolution system, earns you authorship rights on the first three science papers that use the feature. "Using the feature" means the code contributes to the result of the paper, either obviously like a new coordinate map in the domain, or in a more subtle way like an optimization that made the simulation run faster. - Core developers earn authorship rights to all science papers that use SpECTRE for their infrastructure contributions. - In case of controversy, contact any person who you feel comfortable raising your concern with, such as one of the core developers, a member of the [executive committee](https://github.com/sxs-collaboration/WelcomeToSXS/blob/master/SxsPolicies.md#executive-committee), or the [ombudsperson](https://github.com/sxs-collaboration/WelcomeToSXS/blob/master/SxsPolicies.md#ombudsperson). ================================================ FILE: docs/References.bib ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # When editing this file, please follow the guidelines in # https://spectre-code.org/writing_good_dox.html#writing_dox_citations. @article{Alcubierre2003pc, author = "Alcubierre, Miguel and others", title = "{Toward standard testbeds for numerical relativity}", journal = "Class. Quant. Grav.", volume = "21", year = "2004", number = "2", pages = "589-613", url = "https://doi.org/10.1088/0264-9381/21/2/019", doi = "10.1088/0264-9381/21/2/019", eprint = "gr-qc/0305023", archivePrefix = "arXiv", primaryClass = "gr-qc", reportNumber = "AEI-2003-041", SLACcitation = "%%CITATION = GR-QC/0305023;%%" } @article{Alic2012, author = {Daniela Alic and Philipp Moesta and Luciano Rezzolla and Olindo Zanotti and Jos{\'{e}} Luis Jaramillo}, doi = {10.1088/0004-637x/754/1/36}, journal = {The Astrophysical Journal}, number = {1}, pages = {36}, publisher = {American Astronomical Society}, title = {Accurate Simulations of Binary Black Hole Mergers in Force-free Electrodynamics}, url = {https://doi.org/10.1088%2F0004-637x%2F754%2F1%2F36}, volume = {754}, year = 2012 } @article{Anton2006, author = {Luis Antón and Olindo Zanotti and Juan A. Miralles and José M. Martí and José M. Ibáñez and José A. Font and José A. Pons}, doi = {10.1086/498238}, journal = {The Astrophysical Journal}, month = {jan}, pages = {296}, title = {Numerical 3+1 General Relativistic Magnetohydrodynamics: A Local Characteristic Approach}, url = {https://dx.doi.org/10.1086/498238}, volume = {637}, year = {2006} } @article{Arnold2002, author = "Arnold, Douglas and Brezzi, Franco and Cockburn, Bernardo and L. Marini, Donatella", title = "Unified Analysis of Discontinuous {Galerkin} Methods for Elliptic Problems", year = "2002", url = "https://doi.org/10.1137/S0036142901384162", doi = "10.1137/S0036142901384162", journal = "SIAM Journal on Numerical Analysis", number = "5", pages = "1749--1779", volume = "39", } @article{Ayachour2003, author = "Ayachour, E.H.", title = "A fast implementation for {GMRES} method", journal = "Journal of Computational and Applied Mathematics", volume = "159", number = "2", pages = "269 - 283", year = "2003", issn = "0377-0427", doi = "10.1016/S0377-0427(03)00534-X", url = "http://www.sciencedirect.com/science/article/pii/S037704270300534X", } @article{Balsara1999, author = {{Balsara}, D.~S. and {Spicer}, D.~S.}, title = "{A Staggered Mesh Algorithm Using High Order Godunov Fluxes to Ensure Solenoidal Magnetic Fields in Magnetohydrodynamic Simulations}", journal = {Journal of Computational Physics}, year = 1999, month = mar, volume = 149, pages = {270-292}, doi = {10.1006/jcph.1998.6153}, url = {https://doi.org/10.1006/jcph.1998.6153}, adsurl = {http://adsabs.harvard.edu/abs/1999JCoPh.149..270B}, adsnote = {Provided by the SAO/NASA Astrophysics Data System} } @article{Balsara2001, doi = {10.1086/318941}, url = {https://doi.org/10.1086/318941}, year = 2001, month = jan, publisher = {American Astronomical Society}, volume = 132, number = 1, pages = {83--101}, author = {Dinshaw Balsara}, title = {Total Variation Diminishing Scheme for Relativistic Magnetohydrodynamics}, journal = {Astrophysical Journal, Supplement}, } @article{Balsara2016780, title = {An efficient class of WENO schemes with adaptive order}, journal = {Journal of Computational Physics}, volume = 326, pages = {780-804}, year = 2016, issn = {0021-9991}, doi = {10.1016/j.jcp.2016.09.009}, url = {https://www.sciencedirect.com/science/article/pii/S0021999116304211}, author = {Dinshaw S. Balsara and Sudip Garain and Chi-Wang Shu} } @article{Barkett2019uae, author = "Barkett, Kevin and Moxon, Jordan and Scheel, Mark A. and Szilágyi, Béla", title = "{Spectral Cauchy-characteristic extraction of the gravitational wave news function}", year = "2019", eprint = "1910.09677", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = ARXIV:1910.09677;%%" } @article{Barreto2004fn, author = {Barreto, W. and Da Silva, A. and Gomez, R. and Lehner, L. and Rosales, L. and Winicour, J.}, title = {{The 3-dimensional Einstein-Klein-Gordon system in characteristic numerical relativity}}, eprint = {gr-qc/0412066}, archiveprefix = {arXiv}, doi = {10.1103/PhysRevD.71.064028}, journal = {Phys. Rev. D}, volume = {71}, pages = {064028}, year = {2005}, url = {https://doi.org/10.1103/PhysRevD.71.064028} } @article{Baumgarte1996hh, author = "Baumgarte, Thomas W. and Cook, Gregory B. and Scheel, Mark A. and Shapiro, Stuart L. and Teukolsky, Saul A.", title = "Implementing an apparent horizon finder in three-dimensions", journal = "Phys. Rev.", volume = "D54", year = "1996", pages = "4849-4857", doi = "10.1103/PhysRevD.54.4849", url = "https://doi.org/10.1103/PhysRevD.54.4849", eprint = "gr-qc/9606010", archivePrefix = "arXiv", primaryClass = "gr-qc", reportNumber = "CRSR-1115", } @article{Baumgarte2006ug, author = "Baumgarte, Thomas W. and Ó Murchadha, Niall and Pfeiffer, Harald P.", title = "The {Einstein} constraints: Uniqueness and non-uniqueness in the conformal thin sandwich approach", journal = "Phys. Rev.", volume = "D75", year = "2007", pages = "044009", doi = "10.1103/PhysRevD.75.044009", url = "https://doi.org/10.1103/PhysRevD.75.044009", eprint = "gr-qc/0610120", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = GR-QC/0610120;%%" } @article{Baumgarte2007ht, author = "Baumgarte, Thomas W. and Naculich, Stephen G.", title = "{Analytical representation of a black hole puncture solution}", eprint = "gr-qc/0701037", archivePrefix = "arXiv", reportNumber = "BOW-PH-138", doi = "10.1103/PhysRevD.75.067502", url = {https://doi.org/10.1103/PhysRevD.75.067502}, journal = "Phys. Rev. D", volume = "75", pages = "067502", year = "2007" } @book{BaumgarteShapiro, author = {Baumgarte, Thomas W. and Shapiro, Stuart L.}, title = {Numerical Relativity: Solving {Einstein's} Equations on the Computer}, year = {2010}, url = {https://doi.org/10.1017/CBO9781139193344}, doi = {10.1017/CBO9781139193344}, publisher = {Cambridge University Press} } @article{BaylissTurkel, author = {Bayliss, Alvin and Turkel, Eli}, title = {Radiation boundary conditions for wave-like equations}, journal = {Communications on Pure and Applied Mathematics}, volume = 33, number = 6, pages = {707-725}, doi = {10.1002/cpa.3160330603}, url = {https://onlinelibrary.wiley.com/doi/abs/10.1002/cpa.3160330603}, eprint = {https://onlinelibrary.wiley.com/doi/pdf/10.1002/cpa.3160330603}, year = 1980 } @article{Beckwith2011iy, author = "Beckwith, Kris and Stone, James M.", title = "A Second-order {Godunov} Method for Multi-dimensional Relativistic Magnetohydrodynamics", year = "2011", url = "https://doi.org/10.1088/0067-0049/193/1/6", doi = "10.1088/0067-0049/193/1/6", eprint = "1101.3573", archivePrefix = "arXiv", primaryClass = "astro-ph.HE", journal = "Astrophysical Journal, Supplement", number = "1", pages = "6", volume = "193", } @article{Bhagwat2017tkm, author = "Bhagwat, Swetha and Okounkova, Maria and Ballmer, Stefan W. and Brown, Duncan A. and Giesler, Matthew and Scheel, Mark A. and Teukolsky, Saul A.", title = "{On choosing the start time of binary black hole ringdowns}", eprint = "1711.00926", archivePrefix = "arXiv", primaryClass = "gr-qc", journal = "Phys. Rev. D", volume = "97", number = "10", pages = "104065", year = "2018", doi = "10.1103/PhysRevD.97.104065", url = "https://journals.aps.org/prd/abstract/10.1103/ PhysRevD.97.104065", } @article{Bishop1997ik, author = "Bishop, Nigel T. and Gomez, Roberto and Lehner, Luis and Maharaj, Manoj and Winicour, Jeffrey", title = "{High powered gravitational news}", journal = "Phys. Rev.", volume = "D56", year = "1997", pages = "6298-6309", doi = "10.1103/PhysRevD.56.6298", eprint = "gr-qc/9708065", archivePrefix = "arXiv", primaryClass = "gr-qc", url = "https://doi.org/10.1103/PhysRevD.56.6298", } @incollection{Bishop1998uk, author = "Bishop, Nigel T. and Gomez, Roberto and Lehner, Luis and Szilagyi, Bela and Winicour, Jeffrey and Isaacson, Richard A.", title = "{Cauchy characteristic matching}", editor = "Iyer, Bala R. and Bhawal, Biblap", booktitle = "Black Holes, Gravitational Radiation and the Universe: Essays in Honor of C.V. Vishveshwara", journal = "#DONE:In *Iyer, B.R. (ed.) et al.: Black holes, gravitational radiation and the universe* 383-408", pages = "383-408", doi = "10.1007/978-94-017-0934-7_24", year = "1998", eprint = "gr-qc/9801070", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = GR-QC/9801070;%%" } @article{Bjorhus1995, author = {Bjørhus, Morten}, title = {The ODE Formulation of Hyperbolic PDEs Discretized by the Spectral Collocation Method}, journal = {SIAM Journal on Scientific Computing}, volume = {16}, number = {3}, pages = {542-557}, year = {1995}, doi = {10.1137/0916035}, URL = {https://doi.org/10.1137/0916035}, eprint = {https://doi.org/10.1137/0916035} } @article{Blanchet:2013haa, archiveprefix = {arXiv}, author = {Blanchet, Luc}, doi = {10.12942/lrr-2014-2}, eprint = {1310.1528}, journal = {Living Rev. Rel.}, pages = {2}, primaryclass = {gr-qc}, title = {Gravitational Radiation from Post-Newtonian Sources and Inspiralling Compact Binaries}, volume = {17}, year = {2014} } @article{Bohn:2014xxa, author = {Bohn, Andy and Throwe, William and H\'ebert, Fran\c{c}ois and Henriksson, Katherine and Bunandar, Darius and Scheel, Mark A. and Taylor, Nicholas W.}, title = {What does a binary black hole merger look like?}, eprint = {1410.7775}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1088/0264-9381/32/6/065002}, journal = {Class. Quant. Grav.}, volume = {32}, number = {6}, pages = {065002}, year = {2015} } @article{Bohn:2016afc, author = {Bohn, Andy and Kidder, Lawrence E. and Teukolsky, Saul A.}, title = {Parallel adaptive event horizon finder for numerical relativity}, eprint = {1606.00437}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1103/PhysRevD.94.064008}, journal = {Phys. Rev. D}, volume = {94}, number = {6}, pages = {064008}, year = {2016} } @article{Borges20083191, title = {An improved weighted essentially non-oscillatory scheme for hyperbolic conservation laws}, journal = {Journal of Computational Physics}, volume = 227, number = 6, pages = {3191-3211}, year = 2008, issn = {0021-9991}, doi = {10.1016/j.jcp.2007.11.038}, url = {https://www.sciencedirect.com/science/article/pii/S0021999107005232}, author = {Rafael Borges and Monique Carmona and Bruno Costa and Wai Sun Don}, } @article{Borrell2018, title = {Parallel mesh partitioning based on space filling curves}, journal = {Computers & Fluids}, volume = 173, pages = {264-272}, year = 2018, issn = {0045-7930}, doi = {10.1016/j.compfluid.2018.01.040}, url = {https://www.sciencedirect.com/science/article/pii/S0045793018300446}, author = {R.Borrell and J.C.Cajas and D.Mira and A.Taha and S.Koric and M.Vázquez and G.Houzeaux} } @book{Boyd2001, author = {Boyd, John P.}, title = {Chebyshev and Fourier Spectral Methods}, year = 2001, isbn = {0-486-41183-4}, publisher = {Dover Publications} } @article{Boyle:2015nqa, author = "Boyle, Michael", title = "{Transformations of asymptotic gravitational-wave data}", eprint = "1509.00862", archivePrefix ="arXiv", primaryClass = "gr-qc", doi = "10.1103/PhysRevD.93.084031", journal = "Phys.Rev.D", volume = "93", number = "8", pages = "084031", year = "2016" } @article{Boyle2019kee, author = "Boyle, Michael and others", title = "{The SXS Collaboration catalog of binary black hole simulations}", year = "2019", eprint = "1904.04831", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = ARXIV:1904.04831;%%" } @article{BrandtBruegmann1997, title = {A Simple Construction of Initial Data for Multiple Black Holes}, author = {Brandt, Steven and Br\"ugmann, Bernd}, journal = {Phys. Rev. Lett.}, volume = {78}, issue = {19}, pages = {3606--3609}, numpages = {0}, year = {1997}, month = {May}, publisher = {American Physical Society}, doi = {10.1103/PhysRevLett.78.3606}, url = {https://link.aps.org/doi/10.1103/PhysRevLett.78.3606}, eprint = {gr-qc/0404056}, archivePrefix = {arXiv}, primaryClass = {gr-qc} } @article{Brehm2015, author = {Christoph Brehm and Michael F. Barad and Jeffrey A. Housman and Cetin C. Kiris}, doi = {https://doi.org/10.1016/j.compfluid.2015.08.023}, issn = {0045-7930}, journal = {Computers & Fluids}, keywords = {Higher order, Shock capturing, Finite difference, WENO, Localized artificial diffusivity, Artificial dissipation}, pages = {184-208}, title = {A comparison of higher-order finite-difference shock capturing schemes}, url = {https://www.sciencedirect.com/science/article/pii/S0045793015002996}, volume = {122}, year = {2015} } @book{Briggs2000jp, title = "A Multigrid Tutorial, Second Edition", author = "Briggs, William L and Henson, Van Emden and McCormick, Steve F", year = 2000, url = "http://dx.doi.org/10.1137/1.9780898719505", doi = "10.1137/1.9780898719505", publisher = "Society for Industrial and Applied Mathematics" } @article{Brill1963yv, author = "Brill, Dieter R. and Lindquist, Richard W.", title = "{Interaction energy in geometrostatics}", url = "https://dx.doi.org/10.1103/PhysRev.131.471", doi = "10.1103/PhysRev.131.471", journal = "Phys. Rev.", volume = 131, pages = "471--476", year = 1963 } @article{Brune2015, title = "Composing Scalable Nonlinear Algebraic Solvers", volume = "57", issn = "1095-7200", url = "https://doi.org/10.1137/130936725", doi = "10.1137/130936725", number = "4", journal = "SIAM Review", publisher = "Society for Industrial & Applied Mathematics (SIAM)", author = "Brune, Peter R. and Knepley, Matthew G. and Smith, Barry F. and Tu, Xuemin", year = "2015", month = "Jan", pages = "535–565", eprint = "1607.04254", archivePrefix = "arXiv", primaryClass = "math", } @article{Buchman:2012dw, author = "Buchman, Luisa T. and Pfeiffer, Harald P. and Scheel, Mark A. and Szilagyi, Bela", title = "{Simulations of non-equal mass black hole binaries with spectral methods}", eprint = "1206.3015", archivePrefix = "arXiv", primaryClass = "gr-qc", doi = "10.1103/PhysRevD.86.084033", journal = "Phys. Rev. D", volume = "86", pages = "084033", year = "2012" } @article{Casoni2012, author = {Casoni, E. and Peraire, J. and Huerta, A.}, title = {One-dimensional shock-capturing for high-order discontinuous Galerkin methods}, journal = {International Journal for Numerical Methods in Fluids}, volume = 71, number = 6, pages = {737-755}, doi = {10.1002/fld.3682}, url = {https://onlinelibrary.wiley.com/doi/abs/10.1002/fld.3682}, eprint = {https://onlinelibrary.wiley.com/doi/pdf/10.1002/fld.3682}, year = 2013 } @article{CerdaDuran2007, author = {{Cerd{\'a}-Dur{\'a}n}, P. and {Font}, J.~A. and {Dimmelmeier}, H.}, title = "General relativistic simulations of passive-magneto-rotational core collapse with microphysics", journal = {Astronomy and Astrophysics}, year = 2007, month = oct, volume = 474, number = 1, pages = {169-191}, doi = {10.1051/0004-6361:20077432}, url = {https://doi.org/10.1051/0004-6361:20077432}, archivePrefix ={arXiv}, eprint = {astro-ph/0703597} } @article{CerdaDuran2008, author = {{Cerd{\'a}-Dur{\'a}n}, P. and {Font}, J.~A. and {Ant{\'o}n}, L. and {M{\"u}ller}, E.}, title = "A new general relativistic magnetohydrodynamics code for dynamical spacetimes", journal = {Astronomy and Astrophysics}, year = 2008, month = dec, volume = 492, number = 3, pages = {937-953}, doi = {10.1051/0004-6361:200810086}, url = {https://doi.org/10.1051/0004-6361:200810086}, archivePrefix ={arXiv}, eprint = {0804.4572} } @book{Chandrasekhar1939, author = "Chandrasekhar, Subrahmanyan", title = "An introduction to the study of stellar structure", year = "1939" } @article{CHEN2016604, title = {A fifth-order finite difference scheme for hyperbolic equations on block-adaptive curvilinear grids}, journal = {Journal of Computational Physics}, volume = 305, pages = {604-621}, year = 2016, issn = {0021-9991}, doi = {10.1016/j.jcp.2015.11.003}, url = {https://www.sciencedirect.com/science/article/pii/S0021999115007378}, author = {Yuxi Chen and Gábor Tóth and Tamas I. Gombosi}, } @article{Cipolletta2019, author = {{Cipolletta}, F. and {Kalinani}, J.~V. and {Giacomazzo}, B. and {Ciolfi}, R.}, title = "{Spritz: a new fully general-relativistic magnetohydrodynamic code}", journal = {Classical and Quantum Gravity}, year = 2020, month = jul, volume = 37, number = 13, eid = 135010, pages = 135010, doi = {10.1088/1361-6382/ab8be8}, url = {https://doi.org/10.1088/1361-6382/ab8be8}, archivePrefix ={arXiv}, eprint = {1912.04794} } @article{CLAIN20114028, title = {A high-order finite volume method for systems of conservation laws—Multi-dimensional Optimal Order Detection (MOOD)}, author = "S. Clain and S. Diot and R. Loubère", journal = "Journal of Computational Physics", volume = 230, number = 10, pages = "4028 - 4050", year = 2011, issn = "0021-9991", doi = "10.1016/j.jcp.2011.02.026", url = "http://www.sciencedirect.com/science/article/pii/S002199911100115X" } @book{Cockburn1999, author = "Cockburn, Bernardo", editor = "Barth, Timothy J. and Deconinck, Herman", title = "Discontinuous Galerkin Methods for Convection-Dominated Problems", bookTitle = "High-Order Methods for Computational Physics", year = "1999", publisher = "Springer Berlin Heidelberg", address = "Berlin, Heidelberg", pages = "69-224", isbn = "978-3-662-03882-6", doi = "10.1007/978-3-662-03882-6_2", url = "https://doi.org/10.1007/978-3-662-03882-6_2" } @ARTICLE{Cook1992, author = {{Cook}, Gregory B. and {Shapiro}, Stuart L. and {Teukolsky}, Saul A.}, title = "{Spin-up of a Rapidly Rotating Star by Angular Momentum Loss: Effects of General Relativity}", journal = {The Astrophysical Journal}, year = 1992, month = oct, volume = {398}, pages = {203}, doi = {10.1086/171849}, url = {https://doi.org/10.1086/171849} } @ARTICLE{Cook1994, author = {{Cook}, Gregory B. and {Shapiro}, Stuart L. and {Teukolsky}, Saul A.}, title = "{Rapidly Rotating Neutron Stars in General Relativity: Realistic Equations of State}", journal = {The Astrophysical Journal}, year = 1994, month = apr, volume = {424}, pages = {823}, doi = {10.1086/173934}, url = {https://doi.org/10.1086/173934} } @article{Cook1997qc, author = "Cook, Gregory B. and Scheel, Mark A.", title = "{Well behaved harmonic time slices of a charged, rotating, boosted black hole}", reportNumber = "CRSR-1121", doi = "10.1103/PhysRevD.56.4775", journal = "Phys. Rev. D", volume = "56", pages = "4775--4781", year = "1997", url = "https://journals.aps.org/prd/abstract/10.1103/PhysRevD.56.4775" } @article{Davis1988, author = "Davis, S. F.", title = "Simplified Second-Order Godunov-Type Methods", journal = "SIAM J. Sci. Stat. Comput.", volume = "9", year = "1988", number = "3", pages = "445-473", doi = "10.1137/0909030", url = "https://doi.org/10.1137/0909030" } @article{Deaton2013, author = {M. Brett Deaton and Matthew D. Duez and Francois Foucart and Evan O'Connor and Christian D. Ott and Lawrence E. Kidder and Curran D. Muhlberger and Mark A. Scheel and Bela Szilagyi}, doi = {10.1088/0004-637X/776/1/47}, journal = {The Astrophysical Journal}, month = {sep}, pages = {47}, publisher = {The American Astronomical Society}, title = {BLACK HOLE–NEUTRON STAR MERGERS WITH A HOT NUCLEAR EQUATION OF STATE: OUTFLOW AND NEUTRINO-COOLED DISK FOR A LOW-MASS, HIGH-SPIN CASE}, url = {https://dx.doi.org/10.1088/0004-637X/776/1/47}, volume = {776}, year = {2013} } @article{Dedner2002, author = "Dedner, A. and Kemm, F. and Kröner, D. and Munz, C.-D. and Schnitzer, T. and Wesenberg, M.", title = "Hyperbolic Divergence Cleaning for the {MHD} Equations", year = "2002", url = "https://doi.org/10.1006/jcph.2001.6961", doi = "10.1006/jcph.2001.6961", journal = "Journal of Computational Physics", volume = "175", number = "2", pages = "645-673", } @article{DelZanna2002rv, author = "Del Zanna, L. and Bucciantini, N. and Londrillo, P.", title = "{An efficient shock-capturing central-type scheme for multidimensional relativistic flows. II. Magnetohydrodynamics}", journal = "Astron. Astrophys.", volume = "400", year = "2003", pages = "397-414", doi = "10.1051/0004-6361:20021641", url = "https://doi.org/10.1051/0004-6361:20021641", eprint = "astro-ph/0210618", archivePrefix = "arXiv", primaryClass = "astro-ph", SLACcitation = "%%CITATION = ASTRO-PH/0210618;%%" } @article{DelZanna2007pk, author = "Del Zanna, L. and Zanotti, O. and Bucciantini, N. and Londrillo, P.", title = "{ECHO}: An {Eulerian Conservative High Order} scheme for general relativistic magnetohydrodynamics and magnetodynamics", journal = "Astron. Astrophys.", volume = "473", year = "2007", pages = "11-30", doi = "10.1051/0004-6361:20077093", url = "https://doi.org/10.1051/0004-6361:20077093", eprint = "0704.3206", archivePrefix = "arXiv", primaryClass = "astro-ph", SLACcitation = "%%CITATION = ARXIV:0704.3206;%%" } @article{Dennison:2012vf, author = "Dennison, Kenneth A. and Baumgarte, Thomas W.", title = "{Invariants for Tendex and Vortex Fields}", eprint = "1208.1218", archivePrefix = "arXiv", primaryClass = "gr-qc", doi = "10.1103/PhysRevD.86.107503", journal = "Phys. Rev. D", volume = "86", pages = "107503", year = "2012" } @book{DennisSchnabel, author = "Dennis, Jr., J. E. and Schnabel, Robert B.", title = "Numerical Methods for Unconstrained Optimization and Nonlinear Equations", doi = "10.1137/1.9781611971200", url = "https://doi.org/10.1137/1.9781611971200", year = "1996", publisher = "Society for Industrial and Applied Mathematics" } @article{Deppe2018uye, author = "Deppe, Nils and Kidder, Lawrence E. and Scheel, Mark A. and Teukolsky, Saul A.", title = "{Critical behavior in 3D gravitational collapse of massless scalar fields}", journal = "Phys. Rev.", volume = "D99", year = "2019", number = "2", pages = "024018", doi = "10.1103/PhysRevD.99.024018", url = "https://doi.org/10.1103/PhysRevD.99.024018", eprint = "1802.08682", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = ARXIV:1802.08682;%%" } @article{Deppe2021ada, author = {Deppe, Nils and H\'ebert, Fran\c{c}ois and Kidder, Lawrence E. and Teukolsky, Saul A.}, title = {{A high-order shock capturing discontinuous Galerkin\textendash{}finite difference hybrid method for GRMHD}}, eprint = {2109.11645}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1088/1361-6382/ac8864}, journal = {Class. Quant. Grav.}, volume = {39}, number = {19}, pages = {195001}, year = {2022} } @article{Deppe2021bhi, author = {Deppe, Nils and others}, title = {{Simulating magnetized neutron stars with discontinuous Galerkin methods}}, eprint = {2109.12033}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1103/PhysRevD.105.123031}, journal = {Phys. Rev. D}, volume = {105}, number = {12}, pages = {123031}, year = {2022} } @article{Deppe2024ckt, author = {Deppe, Nils and others}, title = {{Binary neutron star mergers using a discontinuous Galerkin-finite difference hybrid method}}, eprint = {2406.19038}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, month = {6}, year = {2024} } @article{Derry1970fk, author = "Derry, L. and Isaacson, R. and Winicour, J.", title = "{Shear-free gravitational radiation}", doi = "10.1103/PhysRev.185.1647", journal = "Phys.Rev.", volume = "185", pages = "1647--1655", year = "1969" } @article{Detweiler2003, title = {Self-force via a Green's function decomposition}, author = {Detweiler, Steven and Whiting, Bernard F.}, journal = {Phys. Rev. D}, volume = {67}, issue = {2}, pages = {024025}, numpages = {5}, year = {2003}, month = {Jan}, publisher = {American Physical Society}, doi = {10.1103/PhysRevD.67.024025}, url = {https://link.aps.org/doi/10.1103/PhysRevD.67.024025} } @article{Diener2005tn, author = "Diener, Peter and Dorband, Ernst Nils and Schnetter, Erik and Tiglio, Manuel", title = "{New, efficient, and accurate high order derivative and dissipation operators satisfying summation by parts, and applications in three-dimensional multi-block evolutions}", eprint = "gr-qc/0512001", archivePrefix ="arXiv", doi = "10.1007/s10915-006-9123-7", journal = "J. Sci. Comput.", volume = "32", pages = "109--145", year = "2007" } @article{Dimmelmeier2001, doi = {10.1086/324406}, url = {https://doi.org/10.1086%2F324406}, year = 2001, month = {oct}, publisher = {American Astronomical Society}, volume = {560}, number = {2}, pages = {L163--L166}, author = {Harald Dimmelmeier and Jose A. Font and Ewald Muller}, title = {Gravitational Waves from Relativistic Rotational Core Collapse}, journal = {The Astrophysical Journal} } @article{DIOT201243, title = {Improved detection criteria for the Multi-dimensional Optimal Order Detection (MOOD) on unstructured meshes with very high-order polynomials}, author = "S. Diot and S. Clain and R. Loubère", journal = "Computers & Fluids", volume = 64, pages = "43 - 63", year = 2012, issn = "0045-7930", doi = "10.1016/j.compfluid.2012.05.004", url = {http://www.sciencedirect.com/science/article/pii/S0045793012001909}, } @article{Diot2013, author = {Diot, S. and Loubère, R. and Clain, S.}, title = {The Multidimensional Optimal Order Detection method in the three-dimensional case: very high-order finite volume method for hyperbolic systems}, journal = {International Journal for Numerical Methods in Fluids}, volume = 73, number = 4, pages = {362-392}, doi = {10.1002/fld.3804}, url = {https://onlinelibrary.wiley.com/doi/abs/10.1002/fld.3804}, eprint = {https://onlinelibrary.wiley.com/doi/pdf/10.1002/fld.3804}, year = 2013 } @article{Dumbser2007, author = "Dumbser, M. and K{\"a}ser, M.", title = "Arbitrary high order non-oscillatory finite volume schemes on unstructured meshes for linear hyperbolic systems", journal = "Journal of Computational Physics", volume = "221", year = "2007", pages = "693-723", doi = "10.1016/j.jcp.2006.06.043", url = "https://doi.org/10.1016/j.jcp.2006.06.043", } @article{Dumbser2013, author = {Michael Dumbser and Arturo Hidalgo and Olindo Zanotti}, title = {High order space–time adaptive {ADER-WENO} finite volume schemes for non-conservative hyperbolic systems}, journal = {Computer Methods in Applied Mechanics and Engineering}, volume = {268}, pages = {359-387}, year = {2014}, issn = {0045-7825}, doi = {https://doi.org/10.1016/j.cma.2013.09.022}, url = {https://www.sciencedirect.com/science/article/pii/S0045782513002491} } @article{Dumbser2014a, title = "A posteriori subcell limiting of the discontinuous Galerkin finite element method for hyperbolic conservation laws", journal = "Journal of Computational Physics", volume = "278", pages = "47 - 75", year = 2014, issn = "0021-9991", doi = "10.1016/j.jcp.2014.08.009", url = "https://doi.org/10.1016/j.jcp.2014.08.009", author = "Michael Dumbser and Olindo Zanotti and Raphaël Loubère and Steven Diot", } @article{Dumbser2017okk, author = "{Dumbser, Michael and Guercilena, Federico and K\"oppel, Sven and Rezzolla, Luciano and Zanotti, Olindo}", title = "{Conformal and covariant Z4 formulation of the Einstein equations: strongly hyperbolic first-order reduction and solution with discontinuous Galerkin schemes}", eprint = "1707.09910", archivePrefix = "arXiv", primaryClass = "gr-qc", doi = "10.1103/PhysRevD.97.084053", url = "https://doi.org/10.1103/PhysRevD.97.084053", journal = "Phys. Rev. D", volume = "97", number = "8", pages = "084053", year = "2018" } @article{Estabrook1973ue, author = "{Estabrook, Frank and Wahlquist, Hugo and Christensen, Steven and DeWitt, Bryce and Smarr, Larry and Tsiang, Elaine}", title = "{Maximally slicing a black hole}", doi = "10.1103/PhysRevD.7.2814", url = "https://doi.org/10.1103/PhysRevD.7.2814", journal = "Phys. Rev. D", volume = "7", pages = "2814--2817", year = "1973" } @article{Etienne2008re, author = {Etienne, Zachariah B. and Liu, Yuk Tung and Shapiro, Stuart L. and Baumgarte, Thomas W.}, title = {General relativistic simulations of black-hole-neutron-star mergers: Effects of black-hole spin}, eprint = {0812.2245}, archiveprefix = {arXiv}, primaryclass = {astro-ph}, doi = {10.1103/PhysRevD.79.044024}, journal = {Phys. Rev. D}, volume = {79}, pages = {044024}, year = {2009} } @article{Etienne2010ui, author = "Etienne, Zachariah B. and Liu, Yuk Tung and Shapiro, Stuart L.", title = "{Relativistic magnetohydrodynamics in dynamical spacetimes: A new AMR implementation}", journal = "Phys. Rev.", volume = "D82", year = "2010", pages = "084031", doi = "10.1103/PhysRevD.82.084031", eprint = "1007.2848", archivePrefix = "arXiv", primaryClass = "astro-ph.HE", SLACcitation = "%%CITATION = ARXIV:1007.2848;%%" } @article{Etienne2017, author = {Zachariah B Etienne and Mew-Bing Wan and Maria C Babiuc and Sean T McWilliams and Ashok Choudhary}, doi = {10.1088/1361-6382/aa8ab3}, journal = {Classical and Quantum Gravity}, month = {sep}, number = {21}, pages = {215001}, publisher = {{IOP} Publishing}, title = {{GiRaFFE}: an open-source general relativistic force-free electrodynamics code}, url = {https://doi.org/10.1088%2F1361-6382%2Faa8ab3}, volume = {34}, year = 2017 } @article{Fischer2021voj, author = {Fischer, Nils L. and Pfeiffer, Harald P.}, title = {Unified discontinuous {Galerkin} scheme for a large class of elliptic equations}, year = {2022}, month = {Jan}, eprint = {2108.05826}, archiveprefix = {arXiv}, primaryclass = {math.NA}, journal = {Phys. Rev. D}, volume = {105}, issue = {2}, pages = {024034}, numpages = {22}, doi = {10.1103/PhysRevD.105.024034} } @article{Fishbone1976apj, author = "Fishbone, L. G. and Moncrief, V.", title = "Relativistic Fluid Disks in Orbit Around {Kerr} Black Holes", year = "1976", url = "https://doi.org/10.1086/154565", doi = "10.1086/154565", journal = "The Astrophysical Journal", number = "1", pages = "962--976", volume = "207", } @ARTICLE{Font1998, author = {{Font}, Jos{\'e} A. and {Ib{\'a}{\~n}ez}, J.~M.}, title = "{A Numerical Study of Relativistic Bondi-Hoyle Accretion onto a Moving Black Hole: Axisymmetric Computations in a Schwarzschild Background}", journal = {The Astrophysical Journal}, year = 1998, month = "Feb", volume = 494, number = 1, pages = {297-316}, doi = {10.1086/305205}, adsurl = {https://ui.adsabs.harvard.edu/abs/1998ApJ...494..297F}, } @book{Fornberg1996, author = {Fornberg, Bengt}, title = {A Practical Guide to Pseudospectral Methods}, year = 1996, isbn = {0-521-49582-2}, url = {https://doi.org/10.1017/CBO9780511626357}, doi = {10.1017/CBO9780511626357}, publisher = {Cambridge University Press} } @article{Fornberg1998, author = {Fornberg, Bengt}, title = {Classroom Note: Calculation of Weights in Finite Difference Formulas}, journal = {SIAM Review}, volume = 40, number = 3, pages = {685-691}, year = 1998, doi = {10.1137/S0036144596322507}, url = "https://doi.org/10.1137/S0036144596322507" } @article{Fortunato2019jl, title = "Efficient Operator-Coarsening Multigrid Schemes for Local Discontinuous {Galerkin} Methods", author = "Fortunato, Daniel and Rycroft, Chris H and Saye, Robert", journal = "SIAM J. Sci. Comput.", publisher = "Society for Industrial and Applied Mathematics", volume = 41, number = 6, pages = "A3913--A3937", month = jan, year = 2019, url = "https://doi.org/10.1137/18M1206357", issn = "1064-8275", doi = "10.1137/18M1206357" } @article{Foucart2008qt, author = {Foucart, Francois and Kidder, Lawrence E. and Pfeiffer, Harald P. and Teukolsky, Saul A.}, title = {Initial data for black hole-neutron star binaries: A Flexible, high-accuracy spectral method}, eprint = {0804.3787}, archivePrefix = {arXiv}, primaryClass = {gr-qc}, doi = {10.1103/PhysRevD.77.124051}, journal = {Phys. Rev. D}, volume = {77}, pages = {124051}, year = {2008} } @article{Foucart2015vpa, author = "Foucart, Francois and O'Connor, Evan and Roberts, Luke and Duez, Matthew D. and Haas, Roland and Kidder, Lawrence E. and Ott, Christian D. and Pfeiffer, Harald P. and Scheel, Mark A. and Szilagyi, Bela", title = "{Post-merger evolution of a neutron star-black hole binary with neutrino transport}", journal = "Phys. Rev.", volume = "D91", year = "2015", number = "12", pages = "124021", doi = "10.1103/PhysRevD.91.124021", eprint = "1502.04146", archivePrefix = "arXiv", primaryClass = "astro-ph.HE", SLACcitation = "%%CITATION = ARXIV:1502.04146;%%" } @article{Foucart2017mbt, author = "Foucart, Francois", title = "{Monte Carlo closure for moment-based transport schemes in general relativistic radiation hydrodynamic simulations}", eprint = "1708.08452", archivePrefix = "arXiv", primaryClass = "astro-ph.HE", doi = "10.1093/mnras/sty108", journal = "Mon. Not. Roy. Astron. Soc.", volume = "475", number = "3", pages = "4186--4207", year = "2018" } @article{Foucart2021mcb, author = "Foucart, Francois and Duez, Matthew D. and Hebert, Francois and Kidder, Lawrence E. and Kovarik, Phillip and Pfeiffer, Harald P. and Scheel, Mark A.", title = "{Implementation of Monte Carlo Transport in the General Relativistic SpEC Code}", eprint = "2103.16588", archivePrefix = "arXiv", primaryClass = "astro-ph.HE", doi = "10.3847/1538-4357/ac1737", journal = "Astrophys. J.", volume = "920", number = "2", pages = "82", year = "2021" } @article{Galeazzi2013mia, author = "Galeazzi, Filippo and Kastaun, Wolfgang and Rezzolla, Luciano and Font, Jos\'e A.", title = "{Implementation of a simplified approach to radiative transfer in general relativity}", eprint = "1306.4953", archivePrefix = "arXiv", primaryClass = "gr-qc", doi = "10.1103/PhysRevD.88.064009", journal = "Phys. Rev. D", volume = "88", pages = "064009", year = "2013" } @article{Gammie2003, author = "Gammie, Charles F. and McKinney, Jonathan C. and Tóth, Gábor", title = "{HARM}: A Numerical Scheme for General Relativistic Magnetohydrodynamics", journal = "The Astrophysical Journal", volume = "589", number = "1", pages = "444", year = "2003", doi = "10.1086/374594", url = "https://doi.org/10.1086/374594", } @article{Gardiner2005hy, author = "Gardiner, Thomas A. and Stone, James M.", title = "{An Unsplit Godunov method for ideal MHD via constrained transport}", journal = "J. Comput. Phys.", volume = "205", year = "2005", pages = "509-539", doi = "10.1016/j.jcp.2004.11.016", url = "https://10.1016/j.jcp.2004.11.016", eprint = "astro-ph/0501557", archivePrefix = "arXiv", primaryClass = "astro-ph", SLACcitation = "%%CITATION = ASTRO-PH/0501557;%%" } @article{Gassner20114232, title = {Explicit one-step time discretizations for discontinuous Galerkin and finite volume schemes based on local predictors}, journal = {Journal of Computational Physics}, volume = {230}, number = {11}, pages = {4232-4247}, year = {2011}, note = {Special issue High Order Methods for CFD Problems}, issn = {0021-9991}, doi = {https://doi.org/10.1016/j.jcp.2010.10.024}, url = {https://www.sciencedirect.com/science/article/pii/S0021999110005802}, author = {Gregor Gassner and Michael Dumbser and Florian Hindenlang and Claus-Dieter Munz} } @article{Giacomazzo2006, author = {{Giacomazzo}, Bruno and {Rezzolla}, Luciano}, title = "{The exact solution of the Riemann problem in relativistic magnetohydrodynamics}", journal = {Journal of Fluid Mechanics}, keywords = {General Relativity and Quantum Cosmology, Astrophysics}, year = 2006, month = sep, volume = 562, pages = {223-259}, doi = {10.1017/S0022112006001145}, url = {https://doi.org/10.1017/S0022112006001145}, archivePrefix ={arXiv}, eprint = {gr-qc/0507102}, primaryClass = {gr-qc} } @article{Goldberg1966uu, author = "Goldberg, J. N. and MacFarlane, A. J. and Newman, E. T. and Rohrlich, F. and Sudarshan, E. C. G.", title = "{Spin s spherical harmonics and edth}", journal = "J. Math. Phys.", volume = "8", year = "1967", pages = "2155", doi = "10.1063/1.1705135", url = "https://doi.org/10.1063/1.1705135" } @article{Gundlach1997us, author = "Gundlach, Carsten", title = "Pseudospectral apparent horizon finders: An Efficient new algorithm", journal = "Phys. Rev.", volume = "D57", year = "1998", pages = "863-875", doi = "10.1103/PhysRevD.57.863", url = "https://doi.org/10.1103/PhysRevD.57.863", eprint = "gr-qc/9707050", archivePrefix = "arXiv", primaryClass = "gr-qc", } @book{Hairer1993, address = {Berlin}, author = {Hairer, E. and N{\o}rsett, S.P. and Wanner, G.}, keywords = {imported}, publisher = {Springer}, title = {Solving Ordinary Differential Equations {I} Nonstiff problems}, year = 1993 } @Inbook{Hairer1996, author="Hairer, Ernst and Wanner, Gerhard", title="Solving Ordinary Differential Equations II: Stiff and Differential-Algebraic Problems", year="1996", publisher="Springer Berlin Heidelberg", address="Berlin, Heidelberg", isbn="978-3-642-05221-7", doi="10.1007/978-3-642-05221-7_1", url="https://doi.org/10.1007/978-3-642-05221-7_1" } @article{Handmer2014qha, author = "Handmer, Casey J. and Szilagyi, B.", title = "{Spectral Characteristic Evolution: A New Algorithm for Gravitational Wave Propagation}", journal = "Class. Quant. Grav.", volume = "32", year = "2015", number = "2", pages = "025008", doi = "10.1088/0264-9381/32/2/025008", eprint = "1406.7029", archivePrefix = "arXiv", primaryClass = "gr-qc", url = "https://doi.org/10.1088/0264-9381/32/2/025008" } @article{Hannam2008, title = {Wormholes and trumpets: Schwarzschild spacetime for the moving-puncture generation}, author = {Hannam, Mark and Husa, Sascha and Ohme, Frank and Br\"ugmann, Bernd and \'O Murchadha, Niall}, journal = {Phys. Rev. D}, volume = 78, issue = 6, pages = 064020, numpages = 19, year = 2008, month = {Sep}, publisher = {American Physical Society}, doi = {10.1103/PhysRevD.78.064020}, url = {https://link.aps.org/doi/10.1103/PhysRevD.78.064020} } @article{Harten1983, author = "Harten, A., and Lax, P. D., and B. van Leer", title = "{On Upstream Differencing and Godunov-Type Schemes for Hyperbolic Conservation Laws}", journal = "SIAM Review", volume = "25", year = "1983", number = "1", pages = "35-61", doi = "10.1137/1025002", url = "https://doi.org/10.1137/1025002" } @article{Harten19973, title = {Uniformly High Order Accurate Essentially Non-oscillatory Schemes, III}, author = "Ami Harten and Bjorn Engquist and Stanley Osher and Sukumar R. Chakravarthy", journal = "Journal of Computational Physics", volume = 131, number = 1, pages = "3 - 47", year = 1997, issn = "0021-9991", doi = "10.1006/jcph.1996.5632", url = {http://www.sciencedirect.com/science/article/pii/S0021999196956326} } @book{Hartle2003gravity, author = "Hartle, J.B.", title = "Gravity: An Introduction to {Einstein's} General Relativity", isbn = "9780805386622", lccn = "2002151118", year = "2003", publisher = "Addison-Wesley", url = "https://www.pearson.com/us/higher-education/program/Hartle-Gravity-An-Introduction-to-Einstein-s-General-Relativity/PGM298455.html", } @ARTICLE{Heger2005, author = {{Heger}, A. and {Woosley}, S.~E. and {Spruit}, H.~C.}, title = "{Presupernova Evolution of Differentially Rotating Massive Stars Including Magnetic Fields}", journal = {The Astrophysical Journal}, keywords = {Stars: Pulsars: General, Stars: Evolution, Stars: Magnetic Fields, Stars: Rotation, Astrophysics}, year = 2005, month = jun, volume = {626}, number = {1}, pages = {350-363}, doi = {10.1086/429868}, archivePrefix = {arXiv}, eprint = {astro-ph/0409422}, primaryClass = {astro-ph}, adsurl = {https://ui.adsabs.harvard.edu/abs/2005ApJ...626..350H}, adsnote = {Provided by the SAO/NASA Astrophysics Data System} } @article{Hemberger2012jz, author = "Hemberger, Daniel A. and Scheel, Mark A. and Kidder, Lawrence E. and Szilágyi, Béla and Lovelace, Geoffrey and Taylor, Nicholas W. and Teukolsky, Saul A.", title = "Dynamical Excision Boundaries in Spectral Evolutions of Binary Black Hole Spacetimes", journal = "Class. Quant. Grav.", volume = "30", year = "2013", pages = "115001", doi = "10.1088/0264-9381/30/11/115001", url = "https://doi.org/10.1088/0264-9381/30/11/115001", eprint = "1211.6079", archivePrefix = "arXiv", primaryClass = "gr-qc", } @book{HesthavenWarburton, author = "Hesthaven, Jan S. and Warburton, Tim", title = "Nodal Discontinuous {Galerkin} Methods", year = "2008", url = "https://doi.org/10.1007/978-0-387-72067-8", doi = "10.1007/978-0-387-72067-8", publisher = "Springer", } @article{Hilditch:2012fp, author = "Hilditch, David and Bernuzzi, Sebastiano and Thierfelder, Marcus and Cao, Zhoujian and Tichy, Wolfgang and Bruegmann, Bernd", title = "{Compact binary evolutions with the Z4c formulation}", eprint = "1212.2901", archivePrefix = "arXiv", primaryClass = "gr-qc", doi = "10.1103/PhysRevD.88.084057", url = "https://doi.org/10.1103/PhysRevD.88.084057", journal = "Phys. Rev. D", volume = "88", pages = "084057", year = "2013" } @article{Holst2004wt, author = "Holst, Michael and Lindblom, Lee and Owen, Robert and Pfeiffer, Harald P. and Scheel, Mark A. and Kidder, Lawrence E.", title = "Optimal constraint projection for hyperbolic evolution systems", journal = "Phys. Rev.", volume = "D70", year = "2004", pages = "084017", doi = "10.1103/PhysRevD.70.084017", url = "https://doi.org/10.1103/PhysRevD.70.084017", eprint = "gr-qc/0407011", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = GR-QC/0407011;%%" } @Article{Hou2007, author = "Hou, Songming and Liu, Xu-Dong", title = "Solutions of Multi-dimensional Hyperbolic Systems of Conservation Laws by Square Entropy Condition Satisfying Discontinuous Galerkin Method", journal = "Journal of Scientific Computing", year = 2007, month = "May", day = 01, volume = 31, number = 1, pages = "127--151", issn = "1573-7691", doi = "10.1007/s10915-006-9105-9", url = "https://doi.org/10.1007/s10915-006-9105-9" } @article{Jiang1996, author = {Guang-Shan Jiang and Chi-Wang Shu}, doi = {https://doi.org/10.1006/jcph.1996.0130}, issn = {0021-9991}, journal = {Journal of Computational Physics}, number = {1}, pages = {202-228}, title = {Efficient Implementation of Weighted ENO Schemes}, url = {https://www.sciencedirect.com/science/article/pii/S0021999196901308}, volume = {126}, year = {1996} } @article{Kastaun2020uxr, author = "Kastaun, Wolfgang and Kalinani, Jay Vijay and Ciolfi, Riccardo", title = "{Robust Recovery of Primitive Variables in Relativistic Ideal Magnetohydrodynamics}", eprint = "2005.01821", archivePrefix ="arXiv", primaryClass = "gr-qc", doi = "10.1103/PhysRevD.103.023018", url = "https://doi.org/10.1103/PhysRevD.103.023018", journal = "Phys. Rev. D", volume = 103, number = 2, pages = 023018, year = 2021 } @article{Kennedy2003, author = "Kennedy, Christopher A. and Carpenter, Mark H.", title = "Additive {Runge-Kutta} schemes for convection-diffusion-reaction equations", journal = "Applied Numerical Mathematics", volume = "44", number = "1", pages = "139--181", year = "2003", doi = "10.1016/S0168-9274(02)00138-1", issn = "0168-9274", url = "https://www.sciencedirect.com/science/article/pii/S0168927402001381", } @techreport{Kennedy2016, author = "Kennedy, Christopher A. and Carpenter, Mark H.", title = "Diagonally Implicit {Runge-Kutta} Methods for Ordinary Differential Equations. {A} Review", number = "20160005923", institution = "NASA STI Repository", year = "2016", month = "March", url = "https://ntrs.nasa.gov/citations/20160005923" } @article{Kidder2001tz, author = "Kidder, Lawrence E. and Scheel, Mark A. and Teukolsky, Saul A.", title = "Extending the lifetime of 3-D black hole computations with a new hyperbolic system of evolution equations", eprint = {gr-qc/0105031}, archiveprefix = {arXiv}, doi = {10.1103/PhysRevD.64.064017}, journal = {Phys. Rev. D}, volume = {64}, pages = {064017}, year = {2001} } @article{Kidder2004rw, author = "Kidder, Lawrence E. and Lindblom, Lee and Scheel, Mark A. and Buchman, Luisa T. and Pfeiffer, Harald P.", title = "{Boundary conditions for the Einstein evolution system}", eprint = "gr-qc/0412116", archivePrefix = "arXiv", doi = "10.1103/PhysRevD.71.064020", journal = "Phys. Rev. D", volume = "71", pages = "064020", year = "2005" } @article{Kidder2016hev, author = "Kidder, Lawrence E. and Field, Scott E. and Foucart, Francois and Schnetter, Erik and Teukolsky, Saul A. and Bohn, Andy and Deppe, Nils and Diener, Peter and Hébert, François and Lippuner, Jonas and Miller, Jonah and Ott, Christian D. and Scheel, Mark A. and Vincent, Trevor", title = "{SpECTRE}: A task-based discontinuous {Galerkin} code for relativistic astrophysics", year = "2017", url = "https://doi.org/10.1016/j.jcp.2016.12.059", doi = "10.1016/j.jcp.2016.12.059", eprint = "1609.00098", archivePrefix = "arXiv", primaryClass = "astro-ph.HE", issn = "0021-9991", journal = "Journal of Computational Physics", pages = "84--114", volume = "335", } @article{Komissarov1999, author = "Komissarov, S. S.", title = "A {Godunov}-type scheme for relativistic magnetohydrodynamics", year = "1999", url = "https://doi.org/10.1046/j.1365-8711.1999.02244.x", journal = "Monthly Notices of the Royal Astronomical Society", volume = "303", number = "2", pages = "343--366", } @article{Komissarov2002, author = {Komissarov, S. S.}, doi = {10.1046/j.1365-8711.2002.05313.x}, issn = {0035-8711}, journal = {Monthly Notices of the Royal Astronomical Society}, number = {3}, pages = {759-766}, title = {{Time-dependent, force-free, degenerate electrodynamics}}, url = {https://doi.org/10.1046/j.1365-8711.2002.05313.x}, volume = {336}, year = {2002} } @article{Komissarov2004, author = {Komissarov, S. S.}, doi = {10.1111/j.1365-2966.2004.07598.x}, issn = {0035-8711}, journal = {Monthly Notices of the Royal Astronomical Society}, month = may, number = {2}, pages = {427--448}, title = {Electrodynamics of black hole magnetospheres}, url = {https://doi.org/10.1111/j.1365-2966.2004.07598.x}, urldate = {2022-09-28}, volume = {350}, year = {2004} } @article{Komissarov2006, author = {Komissarov, S. S.}, doi = {https://doi.org/10.1111/j.1365-2966.2005.09932.x}, eprint = {https://onlinelibrary.wiley.com/doi/pdf/10.1111/j.1365-2966.2005.09932.x}, journal = {Monthly Notices of the Royal Astronomical Society}, keywords = {MHD, relativity, pulsars: general, stars: winds and outflows}, number = {1}, pages = {19-31}, title = {Simulations of the axisymmetric magnetospheres of neutron stars}, url = {https://onlinelibrary.wiley.com/doi/abs/10.1111/j.1365-2966.2005.09932.x}, volume = {367}, year = {2006} } @article{Komissarov2011, author = {Komissarov, S. S.}, doi = {https://doi.org/10.1111/j.1745-3933.2011.01150.x}, eprint = {https://onlinelibrary.wiley.com/doi/pdf/10.1111/j.1745-3933.2011.01150.x}, journal = {Monthly Notices of the Royal Astronomical Society: Letters}, keywords = {black hole physics, magnetic fields, relativistic processes}, number = {1}, pages = {L94-L98}, title = {3+1 magnetodynamics}, url = {https://onlinelibrary.wiley.com/doi/abs/10.1111/j.1745-3933.2011.01150.x}, volume = {418}, year = {2011} } @book{Kopriva, author = "Kopriva, David A.", title = "Implementing Spectral Methods for Partial Differential Equations", year = "2009", url = "https://doi.org/10.1007/978-90-481-2261-5", doi = "10.1007/978-90-481-2261-5", publisher = "Springer", } @article{Kozlowski1978aa, author = "Kozlowski, M. and Jaroszynski, M. and Abramowicz, M. A.", title = "The analytic theory of fluid disks orbiting the {Kerr} black hole", year = "1978", url = "http://cdsads.u-strasbg.fr/abs/1978A%26A....63..209K", journal = "Astronomy and Astrophysics", volume = "63", number = "1-2", pages = "209--220", } @inproceedings{Kreiss1973, title = {Methods for the approximate solution of time dependent problems}, author = {Heinz-Otto Kreiss}, year = {1973}, volume = {10}, series = {Global Atmospheric Research Programme}, publisher = {International Council of Scientific Unions, World Meteorological Organization} } @article{Krivodonova2004, author = "L. Krivodonova and J. Xin and J.-F. Remacle and N. Chevaugeon and J.E. Flaherty", title = "Shock detection and limiting with discontinuous {Galerkin} methods for hyperbolic conservation laws", journal = "Applied Numerical Mathematics", volume = "48", number = "3", pages = "323 - 338", year = "2004", note = "Workshop on Innovative Time Integrators for PDEs", issn = "0168-9274", doi = "https://doi.org/10.1016/j.apnum.2003.11.002", url = "http://www.sciencedirect.com/science/article/pii/S0168927403001831", } @article{Krivodonova2007, title = "Limiters for high-order discontinuous {Galerkin} methods", journal = "Journal of Computational Physics", volume = "226", number = "1", pages = "879 - 896", year = "2007", issn = "0021-9991", url = "https://doi.org/10.1016/j.jcp.2007.05.011", doi = "10.1016/j.jcp.2007.05.011", author = "Krivodonova, Lilia" } @book{Kulikovskii2000, title = "Mathematical Aspects of Numerical Solution of Hyperbolic Systems", author = "Kulikovskii, A. G. and Pogorelov, N. V. and Semenov, A. Y.", isbn = "9780367397739", series = "Monographs and Surveys in Pure and Applied Mathematics", url = "https://www.crcpress.com/Mathematical-Aspects-of-Numerical-Solution-of-Hyperbolic-Systems/Kulikovskii-Pogorelov-Semenov/p/book/9780367397739", year = "2000", publisher = "CRC Press" } @article{Kuzmin2014, title = "Hierarchical slope limiting in explicit and implicit discontinuous Galerkin methods", author = "Kuzmin, Dmitri", journal = "Journal of Computational Physics", volume = "257", pages = "1140-1162", year = "2014", issn = "0021-9991", doi = "https://doi.org/10.1016/j.jcp.2013.04.032", url = "https://www.sciencedirect.com/science/article/pii/S0021999113003161", } @article{Lara2024rwa, author = {Lara, Guillermo and Pfeiffer, Harald P. and Wittek, Nikolas A. and Vu, Nils L. and Nelli, Kyle C. and Carpenter, Alexander and Lovelace, Geoffrey and Scheel, Mark A. and Throwe, William}, title = {{Scalarization of isolated black holes in scalar Gauss-Bonnet theory in the fixing-the-equations approach}}, eprint = {2403.08705}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1103/PhysRevD.110.024033}, journal = {Phys. Rev. D}, volume = {110}, number = {2}, pages = {024033}, year = {2024} } @article{Lehner2010pn, author = "Lehner, Luis and Pretorius, Frans", title = "{Black Strings, Low Viscosity Fluids, and Violation of Cosmic Censorship}", eprint = "1006.5960", archivePrefix ="arXiv", primaryClass = "hep-th", doi = "10.1103/PhysRevLett.105.101102", url = "https://doi.org/10.1103/PhysRevLett.105.101102", journal = "Phys. Rev. Lett.", volume = "105", pages = "101102", year = "2010" } @article{Liebendorfer2005, doi = {10.1086/466517}, url = {https://dx.doi.org/10.1086/466517}, year = {2005}, month = {nov}, publisher = {}, volume = {633}, number = {2}, pages = {1042}, author = {Matthias Liebendörfer}, title = {A Simple Parameterization of the Consequences of Deleptonization for Simulations of Stellar Core Collapse}, journal = {The Astrophysical Journal} } @article{Lindblom1998dp, author = "Lindblom, Lee", title = "Phase transitions and the mass radius curves of relativistic stars", journal = "Phys. Rev.", volume = "D58", year = "1998", pages = "024008", doi = "10.1103/PhysRevD.58.024008", url = "https://doi.org/10.1103/PhysRevD.58.024008", eprint = "gr-qc/9802072", archivePrefix = "arXiv", primaryClass = "gr-qc", reportNumber = "GRP-494", SLACcitation = "%%CITATION = GR-QC/9802072;%%" } @article{Lindblom2005qh, author = "Lindblom, Lee and Scheel, Mark A. and Kidder, Lawrence E. and Owen, Robert and Rinne, Oliver", title = "A New generalized harmonic evolution system", year = "2006", url = "https://doi.org/10.1088/0264-9381/23/16/S09", doi = "10.1088/0264-9381/23/16/S09", journal = "Class. Quant. Grav.", volume = "23", pages = "S447-S462", eprint = "gr-qc/0512093", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = GR-QC/0512093;%%" } @article{Loehner1987, title = {An adaptive finite element scheme for transient problems in CFD}, journal = {Computer Methods in Applied Mechanics and Engineering}, volume = {61}, number = {3}, pages = {323-338}, year = {1987}, issn = {0045-7825}, doi = {https://doi.org/10.1016/0045-7825(87)90098-3}, url = {https://www.sciencedirect.com/science/article/pii/0045782587900983}, author = {Rainald Löhner} } @article{Loubere2014, title = {A New Family of High Order Unstructured MOOD and ADER Finite Volume Schemes for Multidimensional Systems of Hyperbolic Conservation Laws}, volume = 16, DOI = {10.4208/cicp.181113.140314a}, number = 3, journal = {Communications in Computational Physics}, publisher = {Cambridge University Press}, author = {Loubère, Raphaël and Dumbser, Michael and Diot, Steven}, year = 2014, pages = {718–763} } @article{Lovelace2007tn, author = "Lovelace, Geoffrey", title = "The dependence of test-mass thermal noises on beam shape in gravitational-wave interferometers", journal = "Class. Quant. Grav.", volume = "24", year = "2007", number = "17", pages = "4491-4512", doi = "10.1088/0264-9381/24/17/014", url = "https://doi.org/10.1088/0264-9381/24/17/014", eprint = "gr-qc/0610041", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = GR-QC/0610041;%%" } @article{Lovelace2008tw, author = "Lovelace, Geoffrey and Owen, Robert and Pfeiffer, Harald P. and Chu, Tony", title = "Binary-black-hole initial data with nearly-extremal spins", journal = "Phys. Rev.", volume = "D78", year = "2008", pages = "084017", doi = "10.1103/PhysRevD.78.084017", url = "https://doi.org/10.1103/PhysRevD.78.084017", eprint = "0805.4192", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = ARXIV:0805.4192;%%" } @article{Lovelace2016uwp, author = "Lovelace, Geoffrey and Lousto, Carlos O. and Healy, James and Scheel, Mark A. and Garcia, Alyssa and O'Shaughnessy, Richard and Boyle, Michael and Campanelli, Manuela and Hemberger, Daniel A. and Kidder, Lawrence E. and Pfeiffer, Harald P. and Szil\'{a}gyi, B\'{e}la and Teukolsky, Saul A. and Zlochower, Yosef", title = "{Modeling the source of GW150914 with targeted numerical-relativity simulations}", journal = "Class. Quant. Grav.", volume = "33", year = "2016", number = "24", pages = "244002", doi = "10.1088/0264-9381/33/24/244002", eprint = "1607.05377", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = ARXIV:1607.05377;%%", url = "https://doi.org/10.1088/0264-9381/33/24/244002" } @article{Lovelace2017xyf, author = "Lovelace, Geoffrey and Demos, Nicholas and Khan, Haroon", title = "Numerically modeling {Brownian} thermal noise in amorphous and crystalline thin coatings", eprint = "1707.07774", archivePrefix = "arXiv", primaryClass = "gr-qc", reportNumber = "LIGO-P1700183", doi = "10.1088/1361-6382/aa9ccc", journal = "Class. Quant. Grav.", volume = "35", number = "2", pages = "025017", year = "2018", url = "https://doi.org/10.1088/1361-6382/aa9ccc" } @article{Lovelace2024wra, author = {Geoffrey Lovelace and Kyle C. Nelli and Nils Deppe and Nils L. Vu and William Throwe and Marceline S. Bonilla and Alexander Carpenter and Lawrence E. Kidder and Alexandra Macedo and Mark A. Scheel and Azer Afram and Michael Boyle and Andrea Ceja and Matthew Giesler and Sarah Habib and Ken Z. Jones and Prayush Kumar and Guillermo Lara and Denyz Melchor and Iago B. Mendes and Keefe Mitman and Marlo Morales and Jordan Moxon and Eamonn O'Shea and Kyle Pannone and Harald P. Pfeiffer and Teresita Ramirez-Aguilar and Jennifer Sanchez and Daniel Tellez and Saul A. Teukolsky and Nikolas A. Wittek}, title = {Simulating binary black hole mergers using discontinuous {Galerkin} methods}, eprint = {2410.00265}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, month = {9}, year = {2024} } @article{Ma2023sok, author = {Ma, Sizheng and Varma, Vijay and Stein, Leo C. and Foucart, Francois and Duez, Matthew D. and Kidder, Lawrence E. and Pfeiffer, Harald P. and Scheel, Mark A.}, title = {{Numerical simulations of black hole-neutron star mergers in scalar-tensor gravity}}, eprint = {2304.11836}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1103/PhysRevD.107.124051}, journal = {Phys. Rev. D}, volume = {107}, number = {12}, pages = {124051}, year = {2023}, url = {https://doi.org/10.1103/PhysRevD.107.124051} } @article{Mathar2009, author = {Mathar, Richard J.}, title = {Zernike basis to cartesian transformations}, journal = {Serbian Astronomical Journal}, year = 2009, url = {http://dx.doi.org/10.2298/SAJ0979107M}, doi = {10.2298/saj0979107m}, number = 179, pages = {107–120} } @article{Matsushima1995, author = {T. Matsushima and P.S. Marcus}, title = {A Spectral Method for Polar Coordinates}, journal = {Journal of Computational Physics}, volume = 120, number = 2, pages = {365-374}, year = 1995, issn = {0021-9991}, doi = {10.1006/jcph.1995.1171}, url = {https://doi.org/10.1006/jcph.1995.1171} } @Article{Michel1972, author = "Michel, F. Curtis", title = "Accretion of matter by condensed objects", journal = "Astrophysics and Space Science", year = "1972", month = "Jan", day = "01", volume = "15", number = "1", pages = "153--160", doi = "10.1007/BF00649949", url = "https://doi.org/10.1007/BF00649949" } @article{Mignone2010br, author = "Mignone, A. and Tzeferacos, P. and Bodo, G.", title = "{High-order conservative finite difference GLM-MHD schemes for cell-centered MHD}", journal = "J. Comput. Phys.", volume = "229", year = "2010", pages = "5896-5920", doi = "10.1016/j.jcp.2010.04.013", url = "https://doi.org/10.1016/j.jcp.2010.04.013", eprint = "1001.2832", archivePrefix = "arXiv", primaryClass = "astro-ph.HE", SLACcitation = "%%CITATION = ARXIV:1001.2832;%%" } @article{Minerbo1978, author = "Minerbo, Gerald N.", title = "Maximum entropy {Eddington} factors", journal = "Journal of Quantitative Spectroscopy and Radiative Transfer", volume = "20", number = "6", pages = "541 - 545", year = "1978", issn = "0022-4073", doi = "10.1016/0022-4073(78)90024-9", url = "https://doi.org/10.1016/0022-4073(78)90024-9" } @book{Misner1973, author = {Misner, Charles W. and Thorne, Kip S. and Wheeler, John Archibald}, publisher = {W. H. Freeman}, title = {Gravitation}, year = {1973} } @article{Mitman2024review, author = {Keefe Mitman and Michael Boyle and Leo C. Stein and Nils Deppe and Lawrence E. Kidder and Jordan Moxon and Harald P. Pfeiffer and Mark A. Scheel and Saul A. Teukolsky and William Throwe and Nils L. Vu}, title = {A Review of Gravitational Memory and BMS Frame Fixing in Numerical Relativity}, eprint = {2405.08868}, archivePrefix = {arXiv}, primaryClass = {gr-qc}, url = {https://doi.org/10.48550/arXiv.2405.08868}, year = {2024} } @article{Moesta2013dna, author = {M\"osta, Philipp and Mundim, Bruno C. and Faber, Joshua A. and Haas, Roland and Noble, Scott C. and Bode, Tanja and L\"offler, Frank and Ott, Christian D. and Reisswig, Christian and Schnetter, Erik}, title = "{GRHydro: A new open source general-relativistic magnetohydrodynamics code for the Einstein Toolkit}", eprint = "1304.5544", archivePrefix ="arXiv", primaryClass = "gr-qc", doi = "10.1088/0264-9381/31/1/015005", journal = "Class.Quant.Grav.", volume = "31", pages = "015005", year = "2014" } @article{Moesta2014, author = {Philipp Mösta and Bruno C Mundim and Joshua A Faber and Roland Haas and Scott C Noble and Tanja Bode and Frank Löffler and Christian D Ott and Christian Reisswig and Erik Schnetter}, doi = {10.1088/0264-9381/31/1/015005}, journal = {Classical and Quantum Gravity}, month = {nov}, pages = {015005}, publisher = {IOP Publishing}, title = {GRHydro: a new open-source general-relativistic magnetohydrodynamics code for the Einstein toolkit}, url = {https://dx.doi.org/10.1088/0264-9381/31/1/015005}, volume = {31}, year = {2013} } @article{Moldenhauer2014yaa, author = {Moldenhauer, Niclas and Markakis, Charalampos M. and Johnson-McDaniel, Nathan K. and Tichy, Wolfgang and Br\"ugmann, Bernd}, title = {Initial data for binary neutron stars with adjustable eccentricity}, eprint = {1408.4136}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1103/PhysRevD.90.084043}, journal = {Phys. Rev. D}, volume = {90}, number = {8}, pages = {084043}, year = {2014} } @article{Most2022, author = {Most, Elias R and Philippov, Alexander A}, doi = {10.1093/mnras/stac1909}, issn = {0035-8711}, journal = {Monthly Notices of the Royal Astronomical Society}, month = {07}, number = {2}, pages = {2710-2724}, title = {{Electromagnetic precursor flares from the late inspiral of neutron star binaries}}, url = {https://doi.org/10.1093/mnras/stac1909}, volume = {515}, year = {2022} } @article{Moxon2020gha, author = "Moxon, Jordan and Scheel, Mark A. and Teukolsky, Saul A.", title = "{Improved Cauchy-characteristic evolution system for high-precision numerical relativity waveforms}", journal = "Phys. Rev. D", volume = "102", number = "4", pages = "044052", year = "2020", doi = "10.1103/PhysRevD.102.044052", url ="http://dx.doi.org/10.1103/PhysRevD.102.044052", eprint = "2007.01339", archivePrefix = "arXiv", primaryClass = "gr-qc" } @article{Moxon2021gbv, author = {Moxon, Jordan and Scheel, Mark A. and Teukolsky, Saul A. and Deppe, Nils and Fischer, Nils and H\'ebert, Francois and Kidder, Lawrence E. and Throwe, William}, title = {{SpECTRE Cauchy-characteristic evolution system for rapid, precise waveform extraction}}, eprint = {2110.08635}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1103/PhysRevD.107.064013}, journal = {Phys. Rev. D}, volume = {107}, number = {6}, pages = {064013}, year = {2023} } @article{Muhlberger2014pja, author = "Muhlberger, Curran D. and Nouri, Fatemeh Hossein and Duez, Matthew D. and Foucart, Francois and Kidder, Lawrence E. and Ott, Christian D. and Scheel, Mark A. and Szil\'agyi, B\'ela and Teukolsky, Saul A.", title = "{Magnetic effects on the low-T/|W| instability in differentially rotating neutron stars}", eprint = "1405.2144", archivePrefix ="arXiv", primaryClass = "astro-ph.HE", doi = "10.1103/PhysRevD.90.104014", url = {https://journals.aps.org/prd/abstract/10.1103/PhysRevD.90.104014}, journal = "Phys. Rev. D", volume = 90, number = 10, pages = 104014, year = 2014 } @article{Nee2024bur, author = {Nee, Peter James and Lara, Guillermo and Pfeiffer, Harald P. and Vu, Nils L.}, title = {{Quasistationary hair for binary black hole initial data in scalar Gauss-Bonnet gravity}}, eprint = {2406.08410}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, month = {6}, year = {2024} } @article{Nonomura2013, author = {Taku Nonomura and Kozo Fujii}, doi = {https://doi.org/10.1016/j.compfluid.2012.09.001}, issn = {0045-7930}, journal = {Computers & Fluids}, keywords = {Weighted compact nonlinear scheme, Robustness}, note = {International Workshop on Future of CFD and Aerospace Sciences}, pages = {8-18}, title = {Robust explicit formulation of weighted compact nonlinear scheme}, url = {https://www.sciencedirect.com/science/article/pii/S0045793012003441}, volume = {85}, year = {2013} } @book{NumericalRecipes, author = "Press, William~H. and Teukolsky, Saul~A. and Vetterling, William~T. and Flannery, Brian~P.", title = "Numerical Recipes 3rd Edition: The Art of Scientific Computing", publisher = "Cambridge University Press", year = "2007", month = "sep", url = "{http://numerical.recipes}", } @article{OBoyle2020, doi = {10.1103/physrevd.102.083027}, url = {https://doi.org/10.1103%2Fphysrevd.102.083027}, year = 2020, month = {oct}, publisher = {American Physical Society ({APS})}, volume = {102}, number = {8}, author = {Michael F. O'Boyle and Charalampos Markakis and Nikolaos Stergioulas and Jocelyn S. Read}, title = {Parametrized equation of state for neutron star matter with continuous sound speed}, journal = {Physical Review D} } @ARTICLE{Oconnor2015, author = {{O'Connor}, Evan}, title = "{An Open-source Neutrino Radiation Hydrodynamics Code for Core-collapse Supernovae}", journal = {Astrophysical Journal, Supplement}, keywords = {black hole physics, hydrodynamics, neutrinos, radiative transfer, stars: neutron, supernovae: general, Astrophysics - High Energy Astrophysical Phenomena, Nuclear Theory}, year = 2015, month = aug, volume = {219}, number = {2}, eid = {24}, pages = {24}, doi = {10.1088/0067-0049/219/2/24}, archivePrefix = {arXiv}, eprint = {1411.7058}, primaryClass = {astro-ph.HE}, adsurl = {https://ui.adsabs.harvard.edu/abs/2015ApJS..219...24O} } @article{Okounkova:2019zjf, author = "Okounkova, Maria and Stein, Leo C. and Moxon, Jordan and Scheel, Mark A. and Teukolsky, Saul A.", title = "{Numerical relativity simulation of GW150914 beyond general relativity}", eprint = "1911.02588", archivePrefix = "arXiv", primaryClass = "gr-qc", doi = "10.1103/PhysRevD.101.104016", journal = "Phys. Rev. D", volume = "101", number = "10", pages = "104016", year = "2020" } @article{Osburn:2022bby, author = {Osburn, Thomas and Nishimura, Nami}, title = {New self-force method via elliptic partial differential equations for {Kerr} inspiral models}, eprint = {2206.07031}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1103/PhysRevD.106.044056}, journal = {Phys. Rev. D}, volume = {106}, number = {4}, pages = {044056}, year = {2022} } @article{Ossokine2013zga, author = {Ossokine, Serguei and Kidder, Lawrence E. and Pfeiffer, Harald P.}, title = {Precession-tracking coordinates for simulations of compact- object-binaries}, eprint = {1304.3067}, archivePrefix = {arXiv}, primaryClass = {gr-qc}, doi = {10.1103/PhysRevD.88.084031}, journal = {Phys. Rev. D}, volume = {88}, pages = {084031}, year = {2013} } @article{Ossokine2015yla, author = {Ossokine, Serguei and Foucart, Francois and Pfeiffer, Harald P. and Boyle, Michael and Szil\'agyi, B\'ela}, title = {Improvements to the construction of binary black hole initial data}, eprint = {1506.01689}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1088/0264-9381/32/24/245010}, journal = {Class. Quant. Grav.}, volume = {32}, pages = {245010}, year = {2015} } @article{Owen2009sb, author = "Owen, Robert", title = "The Final Remnant of Binary Black Hole Mergers: Multipolar Analysis", journal = "Phys. Rev.", volume = "D80", year = "2009", pages = "084012", doi = "10.1103/PhysRevD.80.084012", url = "https://doi.org/10.1103/PhysRevD.80.084012", eprint = "0907.0280", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = ARXIV:0907.0280;%%" } @article{Owen2017yaj, author = "Owen, Robert and Fox, Alex S. and Freiberg, John A. and Jacques, Terrence Pierre", title = "Black Hole Spin Axis in Numerical Relativity", year = "2017", eprint = "1708.07325", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = ARXIV:1708.07325;%%" } @article{Owren1992, author = {Owren, Brynjulf and Zennaro, Marino}, title = {Derivation of Efficient, Continuous, Explicit Runge–Kutta Methods}, journal = {SIAM Journal on Scientific and Statistical Computing}, volume = {13}, number = {6}, pages = {1488-1501}, year = {1992}, doi = {10.1137/0913084}, URL = {https://epubs.siam.org/doi/10.1137/0913084} } @article{Pajkos2019, doi = {10.3847/1538-4357/ab1de2}, url = {https://doi.org/10.3847%2F1538-4357%2Fab1de2}, year = 2019, month = {jun}, publisher = {American Astronomical Society}, volume = {878}, number = {1}, pages = {13}, author = {Michael A. Pajkos and Sean M. Couch and Kuo-Chuan Pan and Evan P. O'Connor}, title = {Features of Accretion-phase Gravitational-wave Emission from Two-dimensional Rotating Core-collapse Supernovae}, journal = {The Astrophysical Journal} } @article{Palenzuela2010, author = {Palenzuela, Carlos and Garrett, Travis and Lehner, Luis and Liebling, Steven L.}, doi = {10.1103/PhysRevD.82.044045}, issue = {4}, journal = {Phys. Rev. D}, month = {Aug}, numpages = {14}, pages = {044045}, publisher = {American Physical Society}, title = {Magnetospheres of black hole systems in force-free plasma}, url = {https://link.aps.org/doi/10.1103/PhysRevD.82.044045}, volume = {82}, year = {2010} } @article{Palenzuela2018, title = "A Simflowny-based finite-difference code for high-performance computing in numerical relativity", volume = "35", ISSN = "1361-6382", url = "http://dx.doi.org/10.1088/1361-6382/aad7f6", DOI = "10.1088/1361-6382/aad7f6", number = "18", journal = "Classical and Quantum Gravity", publisher = "IOP Publishing", author = "Palenzuela, Carlos and Miñano, Borja and Viganò, Daniele and Arbona, Antoni and Bona-Casas, Carles and Rigo, Andreu and Bezares, Miguel and Bona, Carles and Massó, Joan", year = "2018", month = "aug", pages="185007" } @article{Pareschi2005, author = {Pareschi, Lorenzo and Russo, Giovanni}, title = {Implicit-Explicit {Runge-Kutta} Schemes and Applications to Hyperbolic Systems with Relaxation}, journal = {J Sci Comput}, volume = {25}, year = {2005}, pages = {129--155}, doi = {10.1007/s10915-004-4636-4}, url = {https://doi.org/10.1007/s10915-004-4636-4}, archivePrefix = {arXiv}, eprint = {1009.2757}, primaryClass = {math.NA}, } @article{Paschalidis2013, author = {Paschalidis, Vasileios and Shapiro, Stuart L.}, doi = {10.1103/PhysRevD.88.104031}, journal = {Physical Review D}, month = nov, note = {Publisher: American Physical Society}, number = {10}, pages = {104031}, title = {A new scheme for matching general relativistic ideal magnetohydrodynamics to its force-free limit}, url = {https://link.aps.org/doi/10.1103/PhysRevD.88.104031}, urldate = {2022-09-11}, volume = {88}, year = {2013} } @article{Penner2011, author = {{Penner}, A.~J.}, title = "{General relativistic magnetohydrodynamic Bondi-Hoyle accretion}", journal = {Monthly Notices of the Royal Astronomical Society}, year = 2011, month = "Jun", volume = 414, number = 2, pages = {1467-1482}, doi = {10.1111/j.1365-2966.2011.18480.x}, archivePrefix ={arXiv}, eprint = {1011.2976}, primaryClass = {astro-ph.HE}, adsurl = {https://ui.adsabs.harvard.edu/abs/2011MNRAS.414.1467P}, } @inproceedings{Persson2006sub, title = {Sub-cell shock capturing for discontinuous Galerkin methods}, author = {Persson, Per-Olof and Peraire, Jaime}, booktitle = {44th AIAA Aerospace Sciences Meeting and Exhibit}, pages = 112, year = 2006, doi = {10.2514/6.2006-112} } @phdthesis{Pfeiffer2005zm, author = "Pfeiffer, Harald Paul", title = "Initial data for black hole evolutions", eprint = "gr-qc/0510016", archivePrefix = "arXiv", reportnumber = "UMI-31-04429", school = "Cornell U.", year = "2005" } @article{Porth2016rfi, author = "Porth, Oliver and Olivares, Hector and Mizuno, Yosuke and Younsi, Ziri and Rezzolla, Luciano and Moscibrodzka, Monika and Falcke, Heino and Kramer, Michael", title = "The Black Hole Accretion Code", url = "https://doi.org/10.1186/s40668-017-0020-2", year = "2016", eprint = "1611.09720", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = ARXIV:1611.09720;%%" } @ARTICLE{radice2022, author = {{Radice}, David and {Bernuzzi}, Sebastiano and {Perego}, Albino and {Haas}, Roland}, title = "{A new moment-based general-relativistic neutrino-radiation transport code: Methods and first applications to neutron star mergers}", journal = {Monthly Notices of the Royal Astronomical Society}, keywords = {neutrinos, methods: numerical, neutron star mergers, Astrophysics - High Energy Astrophysical Phenomena, General Relativity and Quantum Cosmology}, year = 2022, month = may, volume = {512}, number = {1}, pages = {1499-1521}, doi = {10.1093/mnras/stac589}, archivePrefix = {arXiv}, eprint = {2111.14858}, primaryClass = {astro-ph.HE}, adsurl = {https://ui.adsabs.harvard.edu/abs/2022MNRAS.512.1499R}, adsnote = {Provided by the SAO/NASA Astrophysics Data System} } @article{Renkhoff2023, author = {Renkhoff, Sarah and Cors, Daniela and Hilditch, David and Br\"ugmann, Bernd}, title = {Adaptive {hp} refinement for spectral elements in numerical relativity}, eprint = {2302.00575}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1103/PhysRevD.107.104043}, journal = {Phys. Rev. D}, volume = {107}, number = {10}, pages = {104043}, year = {2023} } @book{RezzollaBook, author = "{{Rezzolla}, L. and {Zanotti}, O.}", title = "{Relativistic Hydrodynamics}", publisher = "Oxford University Press", year = "2013", month = "sep", url = "{http://adsabs.harvard.edu/abs/2013rehy.book.....R}", } @ARTICLE{Richers2017, author = {{Richers}, Sherwood and {Ott}, Christian D. and {Abdikamalov}, Ernazar and {O'Connor}, Evan and {Sullivan}, Chris}, title = "{Equation of state effects on gravitational waves from rotating core collapse}", journal = {Phys. Rev. D}, keywords = {Astrophysics - High Energy Astrophysical Phenomena}, year = 2017, month = mar, volume = {95}, number = {6}, eid = {063019}, pages = {063019}, doi = {10.1103/PhysRevD.95.063019}, archivePrefix = {arXiv}, eprint = {1701.02752}, primaryClass = {astro-ph.HE}, adsurl = {https://ui.adsabs.harvard.edu/abs/2017PhRvD..95f3019R}, adsnote = {Provided by the SAO/NASA Astrophysics Data System} } @article{Rinne2007ui, author = "Rinne, Oliver and Lindblom, Lee and Scheel, Mark A.", title = "{Testing outer boundary treatments for the Einstein equations}", eprint = "0704.0782", archivePrefix = "arXiv", primaryClass = "gr-qc", doi = "10.1088/0264-9381/24/16/006", journal = "Class. Quant. Grav.", volume = "24", pages = "4053--4078", year = "2007" } @book{Saad2003, title = "Iterative Methods for Sparse Linear Systems: Second Edition", author = "Saad, Yousef", isbn = "978-0898715347", publisher = "Society for Industrial and Applied Mathematics", year = "2003", } @article{Schaal2015, author = "Schaal, K. and Bauer, A. and Chandrashekar, P. and Pakmor, R. and Klingenberg, C. and Springel, V.", title = "Astrophysical hydrodynamics with a high-order discontinuous Galerkin scheme and adaptive mesh refinement", year = "2015", url = "https://academic.oup.com/mnras/article/453/4/4278/2593686", doi = "10.1093/mnras/stv1859", journal = "MNRAS", pages = "4278--4300", volume = "453", } @article{Scheel2003vs, author = "Scheel, Mark A. and Erickcek, Adrienne L. and Burko, Lior M. and Kidder, Lawrence E. and Pfeiffer, Harald P. and Teukolsky, Saul A.", title = "{3-D simulations of linearized scalar fields in Kerr space-time}", eprint = "gr-qc/0305027", archivePrefix = "arXiv", doi = "10.1103/PhysRevD.69.104006", journal = "Phys. Rev. D", volume = "69", pages = "104006", year = "2004", url = {https://journals.aps.org/prd/abstract/10.1103/PhysRevD.69.104006} } @book{Shapiro1983, author = "Shapiro, Stuart L. and Teukolsky, Saul A.", title = "Black holes, white dwarfs, and neutron stars: the physics of compact objects", year = "1983", url = {https://ui.adsabs.harvard.edu/abs/1983bhwd.book.....S}, } @article{Shibata2003, title = "Gravitational waves from axisymmetrically oscillating neutron stars in general relativistic simulations", author = "Shibata, Masaru and Sekiguchi, Yu-ichirou", journal = "Phys. Rev. D", volume = "68", issue = "10", pages = "104020", numpages = "14", year = "2003", month = "Nov", publisher = "American Physical Society", doi = "10.1103/PhysRevD.68.104020", url = "https://link.aps.org/doi/10.1103/PhysRevD.68.104020" } @article{Shiokawa2011ih, author = "Shiokawa, Hotaka and Dolence, Joshua C. and Gammie, Charles F. and Noble, Scott C.", title = "{Global GRMHD Simulations of Black Hole Accretion Flows: a Convergence Study}", eprint = "1111.0396", archivePrefix = "arXiv", primaryClass = "astro-ph.HE", doi = "10.1088/0004-637X/744/2/187", journal = "Astrophys. J.", volume = "744", pages = "187", year = "2012" } @article{Shu1988439, title = "Efficient implementation of essentially non-oscillatory shock-capturing schemes", journal = "Journal of Computational Physics", volume = 77, number = 2, pages = "439 - 471", year = 1988, issn = "0021-9991", doi = "10.1016/0021-9991(88)90177-5", author = "Chi-Wang Shu and Stanley Osher", } @article{Sod19781, title = {A survey of several finite difference methods for systems of nonlinear hyperbolic conservation laws}, journal = {Journal of Computational Physics}, volume = 27, number = 1, pages = {1-31}, year = 1978, issn = {0021-9991}, doi = {https://doi.org/10.1016/0021-9991(78)90023-2}, url = {https://www.sciencedirect.com/science/article/pii/0021999178900232}, author = {Gary A Sod}, } @book{Sommerfeld1949, author = {Sommerfeld, Arnold}, title = {Partial Differential Equations in Physics}, publisher = {Academic Press}, year = 1949, isbn = {978-0-12-654658-3}, doi = {10.1016/B978-0-12-654658-3.50001-X}, url = {https://www.sciencedirect.com/science/article/pii/B978012654658350001X} } @InProceedings{Sonntag2014, author = "Sonntag, Matthias and Munz, Claus-Dieter", editor = "Fuhrmann, J{\"u}rgen and Ohlberger, Mario and Rohde, Christian", title = "Shock Capturing for Discontinuous Galerkin Methods using Finite Volume Subcells", booktitle = "Finite Volumes for Complex Applications VII-Elliptic, Parabolic and Hyperbolic Problems", year = 2014, publisher = "Springer International Publishing", pages = "945--953", isbn = "978-3-319-05591-6", doi = {10.1007/978-3-319-05591-6_96}, url = {https://link.springer.com/chapter/10.1007%2F978-3-319-05591-6_96} } @article{Spitkovsky2006, author = {Anatoly Spitkovsky}, bdsk-url-1 = {https://doi.org/10.1086/507518}, doi = {10.1086/507518}, journal = {The Astrophysical Journal}, month = {aug}, number = {1}, pages = {L51--L54}, publisher = {American Astronomical Society}, title = {Time-dependent Force-free Pulsar Magnetospheres: Axisymmetric and Oblique Rotators}, url = {https://doi.org/10.1086/507518}, volume = {648}, year = 2006 } @article{Stamm2010, author = "Stamm, Benjamin and Wihler, Thomas P.", title = "{hp-Optimal} discontinuous {Galerkin} methods for linear elliptic problems", year = "2010", url = "https://doi.org/10.1090/S0025-5718-10-02335-5", doi = "10.1090/S0025-5718-10-02335-5", journal = "Mathematics of Computation", pages = "2117--2133", volume = "79", } @article{Stiller2016a, author = "Stiller, Jörg", title = "Robust multigrid for high-order discontinuous {Galerkin} methods: A fast {Poisson} solver suitable for high-aspect ratio {Cartesian} grids", volume = "327", issn = "0021-9991", url = "https://doi.org/10.1016/j.jcp.2016.09.041", doi = "10.1016/j.jcp.2016.09.041", journal = "Journal of Computational Physics", publisher = "Elsevier BV", year = "2016", eprint = "1603.02524", archivePrefix = "arXiv", primaryClass = "cs.CE" } @article{Stiller2016b, author = "Stiller, Jörg", title = "Robust Multigrid for {Cartesian} Interior Penalty {DG} Formulations of the {Poisson} Equation in 3D", year = "2016", eprint = "1612.04796", archivePrefix = "arXiv", primaryClass = "cs.NA" } @article{Suresh1997, author = {A. Suresh and H.T. Huynh}, doi = {https://doi.org/10.1006/jcph.1997.5745}, issn = {0021-9991}, journal = {Journal of Computational Physics}, number = {1}, pages = {83-99}, title = {Accurate Monotonicity-Preserving Schemes with Runge–Kutta Time Stepping}, volume = {136}, year = {1997} } @article{Szilagyi2009qz, author = "Szilagyi, Bela and Lindblom, Lee and Scheel, Mark A.", title = "{Simulations of Binary Black Hole Mergers Using Spectral Methods}", journal = "Phys. Rev.", volume = "D80", year = "2009", pages = "124010", doi = "10.1103/PhysRevD.80.124010", url = "https://doi.org/10.1103/PhysRevD.80.124010", eprint = "0909.3557", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = ARXIV:0909.3557;%%" } @article{Szilagyi2014fna, author = "Szil\'agyi, B\'ela", title = "{Key Elements of Robustness in Binary Black Hole Evolutions using Spectral Methods}", eprint = "1405.3693", archivePrefix = "arXiv", primaryClass = "gr-qc", doi = "10.1142/S0218271814300146", journal = "Int. J. Mod. Phys. D", volume = "23", number = "7", pages = "1430014", year = "2014" } @article{Tacik2016zal, author = {Tacik, Nick and Foucart, Francois and Pfeiffer, Harald P. and Muhlberger, Curran and Kidder, Lawrence E. and Scheel, Mark A. and Szil\'agyi, B.}, title = {Initial data for black hole-neutron star binaries, with rotating stars}, eprint = {1607.07962}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1088/0264-9381/33/22/225012}, journal = {Class. Quant. Grav.}, volume = {33}, number = {22}, pages = {225012}, year = {2016} } @article{Teukolsky1982nz, author = "Teukolsky, S. A.", title = "{Linearized quadrupole waves in general relativity and the motion of test particles}", doi = "10.1103/PhysRevD.26.745", url = "https://doi.org/10.1103/PhysRevD.26.745", journal = "Phys.~Rev.~D", volume = "26", pages = "745--750", year = "1982" } @article{Teukolsky2015ega, author = "Teukolsky, Saul A.", title = "Formulation of discontinuous {Galerkin} methods for relativistic astrophysics", journal = "J. Comput. Phys.", volume = "312", year = "2016", pages = "333-356", doi = "10.1016/j.jcp.2016.02.031", url = "https://doi.org/10.1016/j.jcp.2016.02.031", eprint = "1510.01190", archivePrefix = "arXiv", primaryClass = "gr-qc", SLACcitation = "%%CITATION = ARXIV:1510.01190;%%" } @article{Thorne1980, title = {Multipole expansions of gravitational radiation}, author = {Thorne, Kip S.}, journal = {Rev. Mod. Phys.}, volume = {52}, issue = {2}, pages = {299--339}, numpages = {0}, year = {1980}, month = {Apr}, publisher = {American Physical Society}, doi = {10.1103/RevModPhys.52.299}, url = {https://link.aps.org/doi/10.1103/RevModPhys.52.299} } @book{ThorneBlandford2017, author = "Thorne, Kip S. and Blandford, Roger D.", title = "Modern Classical Physics", year = "2017", url = "https://press.princeton.edu/titles/10157.html", publisher = "Princeton University Press", } @article{Toro1994, author = "Toro, E. F. and Spruce, M. and Speares, W.", title = "{Restoration of the Contact Surface in the HLL–Riemann Solver}", journal = "Shock Waves", volume = "4", year = "1994", number = "1", pages = "25--34", doi = "10.1007/BF01414629", url = "https://doi.org/10.1007/BF01414629" } @book{Toro2009, author = "Toro, E. F.", title = "Riemann Solvers and Numerical Methods for Fluid Dynamics", year = "2009", url = "https://www.springer.com/us/book/9783540252023", publisher = "Springer-Verlag Berlin Heidelberg", } @article{Tsitouras2011, author = "Tsitouras, Ch.", title = "Runge-Kutta pairs of order 5(4) satisfying only the first column simplifying assumption", doi = "10.1016/j.camwa.2011.06.002", journal = "Computers & Mathematics with Applications", volume = "62", number = "2", pages = "770--775", year = "2011", } @article{Varma2018sqd, author = "Varma, Vijay and Scheel, Mark A. and Pfeiffer, Harald P.", title = "Comparison of binary black hole initial data sets", eprint = "1808.08228", archivePrefix = "arXiv", primaryClass = "gr-qc", doi = "10.1103/PhysRevD.98.104011", journal = "Phys. Rev. D", volume = "98", number = "10", pages = "104011", year = "2019" } @article{Vincent2019qpd, author = "Vincent, Trevor and Pfeiffer, Harald P. and Fischer, Nils L.", title = "{hp-adaptive} discontinuous {Galerkin} solver for elliptic equations in numerical relativity", eprint = "1907.01572", archivePrefix = "arXiv", primaryClass = "physics.comp-ph", doi = "10.1103/PhysRevD.100.084052", url = "https://journals.aps.org/prd/abstract/10.1103/PhysRevD.100.084052", journal = "Phys. Rev. D", volume = "100", number = "8", pages = "084052", year = "2019" } @article{Vu2021coj, author = {Vu, Nils L. and others}, title = {A scalable elliptic solver with task-based parallelism for the {SpECTRE} numerical relativity code}, eprint = {2111.06767}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1103/PhysRevD.105.084027}, journal = {Phys. Rev. D}, volume = {105}, number = {8}, pages = {084027}, year = {2022}, month = {apr} } @article{Vu2023thn, author = {Nils L Vu and Samuel Rodriguez and Tom Włodarczyk and Geoffrey Lovelace and Harald P Pfeiffer and Gabriel S Bonilla and Nils Deppe and François Hébert and Lawrence E Kidder and Jordan Moxon and William Throwe}, title = {High-accuracy numerical models of Brownian thermal noise in thin mirror coatings}, eprint = {2111.06893}, archiveprefix = {arXiv}, primaryclass = {astro-ph.IM}, journal = {Classical and Quantum Gravity}, doi = {10.1088/1361-6382/acad62}, year = {2023}, month = {jan}, volume = {40}, number = {2}, pages = {025015} } @article{Vu2024cgf, author = {Vu, Nils L.}, title = {A discontinuous {Galerkin} scheme for elliptic equations on extremely stretched grids}, eprint = {2405.06120}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, month = {5}, year = {2024} } @article{Wald1974, author = {Wald, Robert M.}, doi = {10.1103/PhysRevD.10.1680}, issue = {6}, journal = {Phys. Rev. D}, month = {Sep}, numpages = {0}, pages = {1680--1685}, publisher = {American Physical Society}, title = {Black hole in a uniform magnetic field}, url = {https://link.aps.org/doi/10.1103/PhysRevD.10.1680}, volume = {10}, year = {1974} } @article{Wardell:2011gb, author = {Wardell, Barry and Vega, Ian and Thornburg, Jonathan and Diener, Peter}, title = {A Generic effective source for scalar self-force calculations}, eprint = {1112.6355}, archiveprefix = {arXiv}, primaryclass = {gr-qc}, doi = {10.1103/PhysRevD.85.104044}, journal = {Phys. Rev. D}, volume = {85}, pages = {104044}, year = {2012} } @article{White2015omx, author = "White, Christopher J. and Stone, James M. and Gammie, Charles F.", title = "{An Extension of the Athena++ Code Framework for GRMHD Based on Advanced Riemann Solvers and Staggered-Mesh Constrained Transport}", journal = "Astrophys. J. Suppl.", volume = "225", year = "2016", number = "2", pages = "22", doi = "10.3847/0067-0049/225/2/22", url = "https://doi.org/10.3847/0067-0049/225/2/22", eprint = "1511.00943", archivePrefix = "arXiv", primaryClass = "astro-ph.HE", SLACcitation = "%%CITATION = ARXIV:1511.00943;%%" } @article{Wittek:2023nyi, author = "Wittek, Nikolas A. and others", title = "{Worldtube excision method for intermediate-mass-ratio inspirals: Scalar-field model in 3+1 dimensions}", eprint = "2304.05329", archivePrefix = "arXiv", primaryClass = "gr-qc", doi = "10.1103/PhysRevD.108.024041", journal = "Phys. Rev. D", volume = "108", number = "2", pages = "024041", year = "2023" } @article{Wittek:2024gxn, author = "Wittek, Nikolas A. and Pound, Adam and Pfeiffer, Harald P. and Barack, Leor", title = "{Worldtube excision method for intermediate-mass-ratio inspirals: self-consistent evolution in a scalar-charge model}", eprint = "2403.08864", archivePrefix = "arXiv", primaryClass = "gr-qc", month = "3", year = "2024" } @article{Wittek:2024pis, author = "Wittek, Nikolas A. and Barack, Leor and Pfeiffer, Harald P. and Pound, Adam and Deppe, Nils and Kidder, Lawrence E. and Macedo, Alexandra and Nelli, Kyle C. and Throwe, William and Vu, Nils L.", title = "{Relieving scale disparity in binary black hole simulations}", eprint = "2410.22290", archivePrefix = "arXiv", primaryClass = "gr-qc", month = "10", year = "2024" } @article{Yee1999, author = "Yee, H. C. and Sandham, N. D. and Djomehri, M. J.", title = "Low-Dissipative High-Order Shock-Capturing Methods Using Characteristic-Based Filters", journal = "J. Comput. Phys.", volume = "150", year = "1999", pages = "199--238", doi = "10.1006/jcph.1998.6177", url = "http://cdsads.u-strasbg.fr/abs/1999JCoPh.150..199Y", } @article{Zanotti2016efficient, title = {Efficient conservative ADER schemes based on WENO reconstruction and space-time predictor in primitive variables}, author = {Zanotti, Olindo and Dumbser, Michael}, journal = {Computational astrophysics and cosmology}, volume = 3, number = 1, pages = {1--32}, year = 2016, publisher = {SpringerOpen}, doi = "10.1186/s40668-015-0014-x", eprint = "1511.04728", archivePrefix = "arXiv", url = "https://arxiv.org/abs/1511.04728" } @article{Zhong2013, author = "Zhong, Xinghui and Shu, Chi-Wang", title = "A simple weighted essentially nonoscillatory limiter for {Runge-Kutta} discontinuous {Galerkin} methods", journal = "Journal of Computational Physics", volume = "232", year = "2013", number = "1", pages = "397-415", doi = "10.1016/j.jcp.2012.08.028", url = "https://doi.org/10.1016/j.jcp.2012.08.028", } @article{Zhu2016, author = "Zhu, Jun and Zhong, Xinghui and Shu, Chi-Wang and Qiu, Jianxian", title = "{Runge-Kutta} Discontinuous {Galerkin} Method with a Simple and Compact {Hermite} {WENO} Limiter", journal = "Communications in Computational Physics", volume = "19", year = "2016", number = "4", pages = "944–969", doi = "10.4208/cicp.070215.200715a", url = "https://doi.org/10.4208/cicp.070215.200715a", } # When editing this file, please follow the guidelines in # https://spectre-code.org/writing_good_dox.html#writing_dox_citations. ================================================ FILE: docs/Tutorials/BeginnersTutorial.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # A Hitchhiker's Guide to Running SpECTRE {#beginners_guide} \tableofcontents SpECTRE can be a bit complicated to get started with, especially if you aren't familiar with our core concepts of task-based parallelism and Template Meta-Programming (TMP). However, Don't Panic. This guide aims to get you introduced to running, visualizing, editing, and then rebuilding SpECTRE to give you a feel for what SpECTRE is all about, all on your own laptop! Hopefully by the end of this guide you'll feel comfortable enough to look at other executables and maybe even venture into the code itself! ## Prerequisites To start off, you'll need to obtain an environment to build and run SpECTRE in. You could try and install all the dependencies yourself, but that is very tedious and very error prone. Instead, we provide a [Docker](https://docs.docker.com/get-docker/) container with all the dependencies pre-installed for you to use. The container also has the SpECTRE repository cloned in it already so you don't have to worry about getting it yourself. To obtain the docker image, run ``` docker pull sxscollaboration/spectre:demo ``` Another program you will need for this tutorial is [Paraview](https://www.paraview.org/download/) for visualizing the output. You specifically will need version 5.10.1 for this tutorial. If you'd like to use VSCode, the tutorial also has instructions for how to start in VSCode as well. ## Into the Container For both a terminal and VSCode, create the container in a terminal and start it. ``` docker create --entrypoint "/bin/bash" --rm --name spectre_demo -p 11111:11111 \ -i -t sxscollaboration/spectre:demo ``` ``` docker start spectre_demo ``` We connect port `11111` on your local machine to port `11111` of the container so we can use Paraview. The `--rm` will delete the container when you stop it. This won't put you into the container, only start it in the background. \note The `--entrypoint "/bin/bash"` is important because the default entrypoint of the container is the SpECTRE CLI. You can try out the default entrypoint by running `docker run sxscollaboration/spectre:demo -h` and it'll print the help string for the CLI. See the [Python documentation](py/cli.html) for more. You can also run a [Jupyter](https://jupyter.org/index.html) server for accessing the Python bindings (see \ref spectre_using_python) or running Jupyter notebooks. To do so, append another `-p` option with your specified port, e.g. `-p 8000:8000`. You can chain as many `-p` options as you want to expose more ports. The SpECTRE repository is located at `/work/spectre` inside the container. ### With a Terminal {#with_terminal} To hop in the container from a terminal, simply type ``` docker attach spectre_demo ``` and now you're in the container! ### With VSCode If you're using VSCode, you'll need the `Remote-Containers` extension to be able to access the container. Once you have it, open the [command palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) and run the following commands. 1. `Remote-Containers: Attach to Running Container` - you should see the container `spectre_demo` that's currently running. Select that. 2. `File: Open Folder` - select `/work/spectre` which is where the repo is. Now you're in the container within VSCode! The terminal in VSCode will look identical to the one if you hadn't used VSCode. \note Any changes you make inside `/work/spectre` will be lost once you stop the container. If you'd like your changes to persist, get rid of the `--rm` flag in the `docker create` command. ## Compiling the code \note From here on out, all paths are assumed to be inside the container unless specified otherwise. The container already has a SpECTRE build pre-configured. Go to the build directory and compile the executables that we will use in this tutorial: ```sh cd /work/spectre/build make -j2 ExportCoordinates3D EvolveScalarAdvection2D all-pybindings ``` This will compile the code on two cores. If you'd like to use more cores, use the `-j N` option where `N` is the number of cores. Once the executables are compiled they will be available in the `/work/spectre/build/bin` directory. The container already has this directory added to the `PATH` environment variable, so you can run executables from the command line right away: ```sh spectre --help ``` If you are not in the container but instead on a desktop or cluster you can add the bin directory to your path by `cd`ing to the build directory and running ``` export PATH=$PATH:`pwd`/bin ``` If you log out and log back in you will need to set this again, unless you add it to your shell's init file. ## Running ExportCoordinates3D First we will run the `ExportCoordinates3D` executable to visualize the coordinates of a binary black hole domain. Make a directory where you will run everything: ``` mkdir /work/runs cd /work/runs ``` Copy over the input file `/work/spectre/tests/InputFiles/ExportCoordinates/InputTimeDependent3D.yaml` into your `/work/runs` directory. To run the executable, do ``` spectre run --no-schedule -j 4 InputTimeDependent3D.yaml ``` This will run it on 4 cores (the `--no-schedule` means it will run on the login/head node if you are using an HPC system). After this finishes you should see two `H5` files in your run directory: 1. ExportCoordinates3DVolume0 2. ExportCoordinates3DReductions The `Volume` file is where we store data from every element in our domain, like the coordinates or the metric. The `Reductions` file is for more global quantities like the minimum grid spacing over all the elements in our domain. \note Next time you run the executable, you will have to either move or delete the existing `H5` files as SpECTRE will error if it detects that an output file already exists. This is to prevent you from accidentally overwriting data. You can also use the `--force / -f` and `--clean-output / -C` flags to have `spectre run` delete the existing files before running the executable. ## Visualizing our BBH Coordinates Now it's time to use Paraview to visualize the coordinates we use for our BBH evolutions! SpECTRE will actually export the physical frame coordinates for every executable we have because they are a really useful diagnostic to have. We are just using the ExportCoordinates executable here so that you don't have to run a BBH evolution on your laptop which probably wouldn't work because of memory requirements. Before we get to Paraview, we have to tell paraview how to actually use the coordinates in the `Volume` `H5` file. To do this we have a tool called `generate-xdmf` in our Python command-line interface. Inside the `runs` directory where you have the `H5` files, run ``` spectre generate-xdmf \ --subfile-name element_data --output BBH_Coords \ ExportCoordinates3DVolume*h5 ``` We output volume data per node so we append the node number to each volume file we have. Since you're most likely running on a laptop, you'll only be running on one node so you should only get one output file for the volume. The `--subfile-name` argument is the group name inside the `H5` file where the data is stored (groups can be checked by `h5ls -r FILE_NAME`). `generate-xdmf` will generate a file called `BBH_Coords.xmf`. Make sure to keep this `.xmf` file next to the volume file it was generated from. It uses relative paths to find the volume file which means if you move it, you won't be able to visualize anything. ### Attaching Paraview This is where we actually need Paraview. We have a headless (no GUI) vesion of paraview inside the container which we will refer to as the "server". To start the Paraview server, run ``` pvserver & ``` \note For cluster users, check cluster-specific instructions for ParaView. You may require MPI and specify which port to use. You can run `mpirun -np 1 pvserver -p PARAVIEW_REMOTE_PORT` on the remote cluster. Here, `PARAVIEW_REMOTE_PORT` is the port that the ParaView server will use on the cluster. You may choose it to be, for example, 11112. With 'pvserver' running on the remote machine, open a new local terminal. Locally, run `ssh -L11111:YOUR_CLUSTER:PARAVIEW_REMOTE_PORT USERNAME@YOUR_CLUSTER`. The `&` is so that the server runs in the background. If you hit `Enter` a couple times you'll get back to being able to type commands. You should see some output similar to ``` Waiting for client... Connection URL: cs://92bbb69f2af2:11111 Accepting connection(s): 92bbb69f2af2:11111 ``` This means it's waiting for you to connect some external Paraview session (the "client") to the server. Now, ***outside*** the container, start a session of Paraview 5.10.1. (Again, you must use this version otherwise it won't work properly.) \note For cluster users, run `mpirun -n 1 pvserver --version` to check ParaView version. On your computer, download ***exactly the same*** version of Paraview. Go to `File > Connect`. Click `Add Server`. Name it whatever you want, but keep the Host as `localhost`, the Server Type as `Client/Server`, the Port as `11111` (remember the `-p 11111:11111` flag from the docker command?). Here's a snapshot of what it should look like before you configure. \image html paraview_server.png "Paraview server settings" Hit `Configure`, then hit `Save` (we don't care about the launch configuration). Now you should see a list of your configured servers. Select the one you just created and hit `Connect`. It may take a minute or two to connect to the server, but once you do on the left you'll see something like \image html paraview_connect.png "Successfully connected Paraview to a server" \note If you close your client, the server will stop and you won't be able to reconnect. You'll have to restart the server in the container. ### Open the XMF File in Paraview Client {#open_xmf} Now that you have Paraview connected to the container, open the `BBH_Coords.xmf` file you just generated inside Paraview (the paths you'll see are the ones in the container, not your filesystem). You may be prompted to choose which XDMF reader to use. Choose the `XDMF Reader` option. The `Xdmf3` options won't work. Once you choose a reader, on the left, you'll see \image html beginners_paraview_left.png "Paraview side-bar" You can uncheck all the boxes in the `Point Arrays` section as they aren't necessary for visualizing the coordinates. Then hit `Apply`. Now you should see a solid sphere. This isn't super helpful. In the top bar you should see a dropdown to change the style that the points are plotted in. Select `Surface With Edges` like so. (Note: Your top bar may look slightly different from this depending on what version of `Paraview` you have.) \image html beginners_paraview_top.png "Paraview top-bar" Now you'll have a solid sphere with highlighted lines. To view the interior of the domain, you'll need to add a filter. To access the filters, navigate to `Filters` on the top menu bar, hover over `Alphabetical`, and search for your filter of choice. Probably the two most helpful filters for viewing the domain are the `Slice` and `Clip` filters. (Note that you'll have to choose the `Surface With Edges` option for each filter separately.) `Slice` is fairly self explanatory in that it will show you a single plane through the domain. Experiment with different planes to see our whole domain structure! The `Clip` filter will remove all points "above" a certain plane, where "above" is in the direction of the normal of that plane. If you combine two orthogonal `Clip`s, you can actually view a 3D wedge of our domain. Try moving the centers of the planes to view the domain around our excision surfaces! They have a lot of cool structure. If you'd like to read more about our BBH domain, you can look at the documentation for `domain::creators::BinaryCompactObject`. ## Evolution of BBH Coordinates Now that you are able to export and visualize our BBH domain coordinates at a single time, let's make a small movie of the coordinates as they evolve! To do this, we'll need to edit the input file `InputTimeDependent3D.yaml`. If you aren't familiar with YAML, it's a file type that uses key-value pairs to create actual objects in our C++ code. Feel free to experiment with keys and values in our input files. If you're unsure about what a key or value should be, we offer an easy way to check the options in the input file without running a whole simulation. In your `/work/runs` directory, if you run ``` spectre validate InputTimeDependent3D.yaml ``` the executable will parse and check the input file. If you made a typo, or added an incorrect key/value, a list of the available keys and their associated values will be printed. To change the number of times we output the coordinates, we'll need to go to the `%EventsAndTriggers:` block of the input file. This block is mainly where we specify which quantities we want to observe in a simulation or where we "Trigger" a specific "Event" to happen. (For more info on `%EventsAndTriggers`, see the \ref tutorial_events_and_triggers tutorial.) Currently in this input file we only have one Trigger/Event pair. The %Trigger is `TimeCompares:` and the %Event is `Completion`. To have the simulation run longer, change the `Value:` under `TimeCompares:` to something larger. If you look at the `Evolution:` block above the `%EventsAndTriggers:` block, you'll see that the initial time step is `0.5`. The way this executable is set up, the coordinates will be exported every time step. So set the final time `Value:` under `TimeCompares:` to some larger multiple of `0.5` so that you'll have the coordinates at a bunch of different times (a final time of `20` is reasonable. Depending on how many cores you run on this should take a couple minutes). Then, run the executable just like you did above (remember to move or delete the existing `H5` files), run `generate-xdmf`, and open it in Paraview and apply some filters of your choice. We recommend using a `Slice` filter with the normal pointing in the `-z` direction. This is because our BBH domain rotates about the `z` axis. Now, in the top bar of Paraview, you should see a "Play" button that looks like a sideways triangle (see the second image in the \ref open_xmf section). If you click this, Paraview will step through all the timesteps in the output files and you'll be able to see the domain rotate a bit! Next, we encourage you to play with the other inputs that control how the domain evolves over time. These options are housed in the ```yaml DomainCreator: BinaryCompactObject: ... TimeDependentMaps: ExpansionMap: ... RotationMap: ... SizeMapA: ... SizeMapB: ... ``` block of the input file. Since this tutorial is more about running the code, we won't go into too much detail about each option. However, in general: 1. `ExpansionMap` is a global map (all parts of the domain) that controls the separation between the excision surfaces 2. `RotationMap` is a global map that controls how the excision spheres rotate about each other 3. `SizeMap` is a local map only around the excision spheres (not in the wave zone) that control the compression of grid points. Play around with these values! You may get an error if you put something that's too unphysical, but this is a fairly consequence-free playground for you to explore so just try a different value. Now you have a movie of how BBH coordinates evolve in a SpECTRE simulation! ## Exploring DG+FD Now that you are able to run, and visualize SpECTRE, let's explore a feature that is fairly unique to SpECTRE and is really powerful for handling discontinuities and shocks in our simulations. We call this feature `DG+FD` (it's also sometimes referred to as just `subcell`). ### Description of DG+FD `FD` is the usual finite difference you are used to. All of the BSSN codes use finite difference for solving Einstein's equations. FD is very good at capturing shocks and discontinuities and is a very robust method, making it well suited for hydro problems and other systems that have shocks and discontinuities. `DG` stands for Discontinuous Galerkin. DG is a spectral method for representing a solution on a grid, meaning that instead of taking the difference between the function value at two points to get the derivative, it uses known basis functions to represent the solution. Then the derivative can be known analytically and you only need to supply the coefficients for the basis. DG works best for representing smooth solutions; ones with very few shocks and discontinuities (like GR in vacuum). This makes DG much faster than FD for smooth solutions. In SpECTRE, we combine these two different methods into one system to take advantage of the strengths of each. When we have a solution that is smooth in some parts of the domain, but has shocks in other parts, using only one of these methods has disadvantages. If we only used DG, we wouldn't be able to resolve the shocks very well driving the errors up a lot. If we only used FD, we'd be able to represent the solution well, but it would be computationally inefficient. So we combine DG+FD so that we only do DG in the parts of the domain where the solution is smooth, and switch to FD in parts where there may be a shock or discontinuity. The algorithm for switching between DG and FD is explained in this image. \image html dg_fd_schematic.png "Scheme for switching between DG and FD (credit: Nils Deppe)" If you'd like to learn more about how SpECTRE implements its DG+FD scheme, you can read [the paper](https://arxiv.org/abs/2109.11645) on the ArXiv. ### Running the Kuzmin Problem To demonstrate DG+FD, we will be evolving the \link ScalarAdvection::Solutions::Kuzmin Kuzmin \endlink problem using the `EvolveScalarAdvection2D` executable. This is a simple test problem that rotates a set of geometric shapes with uniform angular velocity, which can be used to evaluate how well a numerical code can handle discontinuities stably over time. Inside the container make a new directory `/work/runs2` where you will run it. Also copy the default input file in `/work/spectre/tests/InputFiles/ScalarAdvection/Kuzmin2D.yaml` to this new `/work/runs2` directory. ### Changing the Default Input File The default input file has very low resolution so we'll need to crank that up a bit. The way to do this is to change the initial refinement levels and initial number of grid points which are located in ```yaml DomainCreator: Rectangle: ... InitialRefinement: [x, y] InitialGridPoints: [x, y] ``` `InitialRefinement:` represents how many times we split a `Block` in half in order to create `Element`s, which are the fundamental units of our domain. So an initial refinement of `[1, 1]` means we split a single Block into 4 elements (split in half once in each direction). For an initial refinement of `[2, 2]` we first do 1 refinement like before, and then split each of the resulting 4 elements in half again in each direction, resulting in 16 total Elements. To determine the total number of Elements for a given refinement (same in all directions), just do $2^{\mathrm{Dim * Refinement}}$. If you're confused by the terminology we use to describe the domain, we have a \ref domain_concepts guide that explains all terms related to our domain. `InitialGridPoints` represents the number of grid points per dimension in each Element after the final refinement has been applied. So if we had an initial refinement of `[2, 2]` like above and then initial grid points `[3, 3]` in each Element, we'd have a total of 9x16=144 grid points. As for actual numbers to use, you can experiment to see what gives good, well-resolved results. You'll definitely need more refinement than the default input file, but since refinement scales exponentially, this can become very expensive very quickly. On a laptop, you probably shouldn't go higher than refinement `[6, 6]`. As for grid points, this will depend on how much refinement you have. If you have a ton of small elements, you won't need too many grid points to resolve the solution; something like `[4, 4]` would work. If you don't have a lot of refinement, you may want more grid points if you still want to resolve your solution. For a DG scheme, increasing the number of grid points (p refinement) reduces the numerical error exponentially where the solution is smooth, so computational resources are used more effectively. However, to resolve shocks and discontinuities we have to refine the domain into more and smaller elements instead (h refinement). Striking the most effective balance between h and p refinement in different parts of the domain is the job of an adaptive mesh refinement (AMR) algorithm. The default input file only runs for a few time steps so we'll want to make this run longer so we can actually see some evolution. From the documentation of the \link ScalarAdvection::Solutions::Kuzmin Kuzmin \endlink system, the solution will rotate with an angular velocity of `1.0` (in code units). Thus, to do a full orbit, it will take `6.28` code units of time. In the `%EventsAndTriggers:` block of the input file, we see that the `Completion` event is triggered by the `Slabs` trigger. We could, in theory, calculate out how many slabs `6.28` code units is using the time step, but that's super tedious. Instead let's trigger completion using the `TimeCompares` trigger instead. We used this before when exporting the BBH coordinates, so just copy over the yaml block and change the `Value:`. Your final `%EventsAndTriggers:` block should look something like this: ```yaml EventsAndTriggers: - Trigger: TimeCompares: Comparison: GreaterThanOrEqualTo Value: 6.28 Events: - Completion ... ``` Now you should be ready to run the executable and get some output. Here, you will almost definitely benefit by running this on many cores by adding the `-j N` flag to the command you use to run the executable. Since we use lots of smaller elements, we distribute these over the available resources via a \link domain::BlockZCurveProcDistribution space filling curve \endlink to speed things up. ``` spectre run --no-schedule -j 4 Kuzmin2D.yaml ``` ### Visualizing the Kuzmin Problem Once your run finishes, extract the volume data with `generate-xdmf` using ``` spectre generate-xdmf \ --subfile-name VolumeData --output kuzmin_problem \ ScalarAdvectionKuzmin2DVolume*h5 ``` (Note that the `subfile-name` is different than before because it was different in the input file) and load it into Paraview once again. We are only interested in the quantity `U` which is the scalar field we were evolving. You can uncheck any other boxes. So now, instead of coordinates on your screen, you should see a large square colored by the solution profile described in the \link ScalarAdvection::Solutions::Kuzmin Kuzmin \endlink system. You should also notice that there are smaller squares that don't touch each other in the middle of the domain and on the edges there are large sections that are continuous. These are the FD and DG grids, respectively. If you go to the top bar in Paraview and change how you view the grid to `Surface With Edges`, this will become even more apparent. You will notice that the FD grid is mostly around where the interesting features are in the solution profile; the cylinder with a wedge cut out, the cone, and the hump. And then the DG grid is mostly where the solution should be zero towards the boundary of the domain (i.e. the very smooth part). So right from the start, you can see that we are saving computational effort by only doing the expensive, yet robust, method (FD) where it is necessary and the efficient method (DG) everywhere else where the solution is smooth. Now hit the "Play" button in the top bar of Paraview and watch the solution evolve. You'll notice that the elements in the domain switch back and forth between FD and DG. They do so in such a way that the elements will switch to FD when an interesting feature enters the element and then switch back to DG once the feature leaves. In this way, we are able to actually track shocks and discontinuities in real time in our solution by where the code switches to using FD instead of DG. This is extremely useful for expensive GRMHD simulations where we only want to do FD at a shock boundary, yet that shock boundary is moving through the domain. We are able to dynamically track this shock and resolve it well with FD, then switch back to DG after the shock passes through and the solution has settled down again. A pretty cool filter you can add is `Warp By Scalar`. In the left panel, choose the solution variable `U` as the scalar to use and hit `Apply`. In the viewing panel there should be a `2D` or `3D` button that you can toggle to make the view 3D. Once you do that you should be able to see that the height of the feature is your solution `U`. If you change the grid to `Surface With Edges` you can see the FD or DG grids warp with the solution. And if you hit "Play" it'll rotate around and you'll see the features moving in 3D! (Don't worry if you can't find this filter. Not all versions of Paraview may have it.) We encourage you to play around with the refinement and grid points before the next section to get a feel for how each changes the runtime and accuracy of solution. ## Editing the Kuzmin System Hopefully now you feel comfortable enough running SpECTRE that you can get the default input file for the pre-built executables, edit it, and run it. Now we are going to try our hand at actually editing some code in SpECTRE and then building SpECTRE. We're going to stick with the \link ScalarAdvection::Solutions::Kuzmin Kuzmin \endlink system and add a new feature to the solution profile! You can find the files for the Kuzmin system at `/work/spectre/src/PointwiseFunctions/AnalyticSolutions/ScalarAdvection/ Kuzmin.?pp`. In the `hpp` file, you'll see a lot of Doxygen documentation and then the actual Kuzmin class. The only function that you will need to care about is ```cpp template tuples::TaggedTuple variables( const tnsr::I& x, double t, tmpl::list /*meta*/) const; ``` All of our analytic solutions have a function similar to this that will set the value corresponding to the tag in the return type. If you're unfamiliar with tags in SpECTRE, you can look at these sections for an explanation, \ref databox_a_taggedtuple_databox and \ref databox_a_proper_databox. However, it's basically just a fancy way of doing a compile-time key/value pair. The tag is the key, and the value is whatever you want it to be. In our case, the value is a tensor, representing the solution. The definition of this function in the `cpp` file is where you will be editing the actual Kuzmin solution. Towards the bottom of this function, there is a `for` loop that sets the solution at every grid point. This is where you will add in a new feature to the solution. You can pick any feature you want to add, so long as it's inside the domain bounds of `[0,1]x[0,1]` and centered around `(0.75, 0.5)`. This is because of how the kuzmin solution is set up with existing features at `(0.25, 0.5); (0.5, 0.25); (0.5, 0.75)`. If you're having trouble thinking of a feature to add try one of the following features: - Square centered at `(0.75, 0.5)` with solution value `1.0` - Side length `0.1` (any larger and it might interfere with the other features) - Circle of radius `0.045` centered on the square with value `0.0` - Triangle centered at `(0.75, 0.5)` with one corner facing in the `+x` direction with solution value `1.0` - Square centered at `(0.75, 0.5)` - Side length `0.1` (any larger and it might interfere with the other features) - Left half of the square has value `1.0` and right half of the square has value `0.5` \note The more detailed you make your feature, the more resolution you will need to resolve it. ### Re-building SpECTRE Once you have your feature coded up, go ahead and save your changes. Now we will build SpECTRE! Go to the `/work/spectre/build` directory. This is where you have to be in order to build SpECTRE. We use [CMake](https://cmake.org/) to configure our build directory. However, since the executables are already pre-built, this means the build directory is already configured! So you don't have to worry about `CMake` for now. If you wanted to reconfigure, for example using a different compiler, then you'd have to run `CMake`. If you want to learn more about how we use `CMake`, take a look at the \ref common_cmake_flags developers guide. To build the Kuzmin executable, run ``` make EvolveScalarAdvection2D ``` This should be very fast because you only edited a `cpp` file. Congrats! You've just built SpECTRE! Now re-run the executable in your `/work/runs2` directory. Hopefully everything works and you get some output. When you plot it in Paraview, it should look almost the same as before except your feature will be there too rotating with the others! How cool! You can also see if your feature needs FD or DG more by how much it switches back and forth. Experiment some more with either different features or different resolution! ## Conclusions Congrats! You've made it through the tutorial! If you only want to run our pre-built executables, you have all the tools necessary to run, visualize, and re-build them. If you want a full list of our executables, do `make list` in the build directory. This will also include our `Test_` executables which you can just ignore. In an already configured build directory, all you have to do to build a new executable is ``` make ExecutableName ``` and then you can copy the default input file from `/work/spectre/tests/InputFiles` and run it. Running an executable with the `--help` flag will give a description of what system is being evolved and the input options necessary. ================================================ FILE: docs/Tutorials/CCE.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # %Running CCE {#tutorial_cce} \tableofcontents ## Acquiring the CCE module {#acquiring_the_cce_module} There are a couple different ways to acquire the CCE module/executable. ### From a release {#cce_from_release} Starting from late May 2024, in every [Release of SpECTRE](https://github.com/sxs-collaboration/spectre/releases) we offer a tarball that contains everything needed to run CCE on a large number of different systems. This will be under the `Assets` section towards the bottom of the release (there may be a lot of text detailing what's been updated in this release). Inside this tarball is - the CCE executable `CharacteristicExtract` - an example YAML input file - an example set of Bondi-Sachs worldtube data in the `Tests/` directory (see [Input worldtube data formats](#input_worldtube_data_format) section) - example output from CCE in the `Tests/` directory - a `PreprocessCceWorldtube` executable and YAML files for converting between [worldtube data formats](#input_worldtube_data_format) in the `PreprocessCceWorldtube/` directory - a `WriteCceWorldtubeCoordsToFile` executable that writes [grid points on a sphere](#spherical_nodes) to a text file in the `PreprocessCceWorldtube/` directory - a python script `CheckCceOutput.py` (meant to be run from the root of the tarball and after you run the example YAML input file also in the root of the tarball) that will check if the example output is correct \note The tarball is `.xz` so use `tar -xf TarName.tar.xz` to extract. The `-z` flag to use gzip will cause an error. See [Running the CCE executable](#running_the_cce_executable) for how to run CCE. We have tested that this executable works natively on the following machines: - Expanse - Anvil - Stampede3 - Delta (if you add `LD_LIBRARY_PATH=/sw/spack/deltas11-2023-03/apps/linux-rhel8-x86_64/gcc-8.5.0/gcc-11.4.0-yycklku/lib64/:$LD_LIBRARY_PATH` before running CCE) - Perlmutter - Ubuntu 18.04 LTS or later (LTS version only) We have also tested that this executable works inside our [`dev` Docker container](https://hub.docker.com/r/sxscollaboration/spectre/tags) on the following machines (in addition to the ones above): - Frontera - Delta ### From Docker You can download a docker image `sxscollaboration/spectre:deploy` which has a few pre-built executables within, including the ones listed above in the [release](#cce_from_release) section. See the containerized releases section of our \ref installation instructions for how start the container. The input files can be found within the container at `/work/spectre/tests/InputFiles/`. ### From source You can clone the [spectre repo](https://github.com/sxs-collaboration/spectre) and follow the instructions on the \ref installation page to obtain an environment to configure and build SpECTRE. Once you have a configured `build` directory, build the CCE executable with ``` make CharacteristicExtract ``` \note You may want to add the `-j4` flag to speed up compilation. However, be warned that this executable will need several GB of memory to build. ## Input worldtube data format {#input_worldtube_data_format} In order to run the CCE executable, the worldtube data must be represented as Bondi-Sachs variables decomposed as a subset of spin-weighted spherical harmonic modes on a sphere of constant coordinate radius. We have chosen this format because it is far more space-efficient to store on disk than other formats. This section will detail the [required data format](#required_h5_worldtube_data_format), provide options for [converting worldtube data](#converting_worldtube_data) from other NR codes into our format, and give insights into [what the worldtube data should look like](#worldtube_data_looks). ### Required H5 worldtube data format {#required_h5_worldtube_data_format} Within the H5 file that holds the worldtube data, there must be the following datasets with these exact names (including the `.dat` suffix): - `Beta.dat` - `DrJ.dat` - `DuR.dat` - `H.dat` - `J.dat` - `Q.dat` - `R.dat` - `U.dat` - `W.dat` Each dataset in the file must also have an attribute named `Legend` which is an ASCII-encoded null-terminated variable-length string. That is, the HDF5 type is: ``` DATATYPE H5T_STRING { STRSIZE H5T_VARIABLE; STRPAD H5T_STR_NULLTERM; CSET H5T_CSET_ASCII; CTYPE H5T_C_S1; } ``` This can be checked for a dataset by running ``` h5dump -a Beta.dat/Legend WorldtubeFile.h5 ``` For the ordering of the data, we use spherical harmonic conventions documented by the ylm::Spherepack class. Each row must start with the time stamp, and the remaining values are the complex modes in m-varies-fastest format. For spin-weight zero Bondi variables (`Beta`, `R`, `DuR`, `W`), we omit the redundant negative-m modes and imaginary parts of the m=0 modes to save space on disk. Here is an example of a legend for the spin-weight zero variables: ``` "time", "Re(0,0)", "Re(1,0)", "Re(1,1)", "Im(1,1)", "Re(2,0)", "Re(2,1)", "Im(2,1)", "Re(2,2)", "Im(2,2)", "Re(3,0)", "Re(3,1)", "Im(3,1)", "Re(3,2)", "Im(3,2)", "Re(3,3)", "Im(3,3)", ... ``` For non-zero spin-weight Bondi variables (`J`, `DrJ`, `H`, `Q`, `U`) we must store all complex m-modes. Here is an example of a legend for variables where all complex m-modes must be specified: ``` "time", "Re(0,0)", "Im(0,0)", "Re(1,-1)", "Im(1,-1)", "Re(1,0)", "Im(1,0)", "Re(1,1)", "Im(1,1)", "Re(2,-2)", "Im(2,-2)", "Re(2,-1)", "Im(2,-1)", "Re(2,0)", "Im(2,0)", "Re(2,1)", "Im(2,1)", "Re(2,2)", "Im(2,2)", ... ``` We don't have strict requirement on the name of the H5 file that holds the worldtube data. However, it is recommended to name the H5 file `...CceRXXXX.h5`, where the `XXXX` is to be replaced by the zero-padded integer for which the extraction radius is equal to `XXXX`M. For instance, a 100M extraction should have filename `...CceR0100.h5`. If you do not adhere to this naming convention, you will need to specify the extraction radius in your YAML input file. \note This scheme of labeling files with the extraction radius is constructed for compatibility with worldtube data from the SXS Collaboration's SpEC code. ### Converting to the required H5 format {#converting_worldtube_data} Unless you are using worldtube data that was generated from SpECTRE (or SpEC), it's possible that your worldtube data is not in the correct format. We allow conversion into our data format from a few other data formats using the [`PreprocessCceWorldtube` executable provided](#acquiring_the_cce_module). These are - Nodal cartesian metric data (which we refer to as "metric nodal") - Modal cartesian metric data (which we refer to as "metric modal") - Nodal Bondi-Sachs data (which we refer to as "bondi nodal") Requirements for these data formats are listed below. #### Spherical harmonic modes {#spherical_modes} When we refer to a "modal" data format, we mean that the worldtube data are stored as spherical harmonic coefficients (a.k.a. modes). We use spherical harmonic conventions documented by the ylm::Spherepack class. For each dataset, each row must start with the time stamp, and the remaining values are the complex modes in m-varies-fastest format. That is, ``` "time", "Re(0,0)", "Im(0,0)", "Re(1,-1)", "Im(1,-1)", "Re(1,0)", "Im(1,0)", "Re(1,1)", "Im(1,1)", "Re(2,-2)", "Im(2,-2)", "Re(2,-1)", "Im(2,-1)", "Re(2,0)", "Im(2,0)", "Re(2,1)", "Im(2,1)", "Re(2,2)", "Im(2,2)", ... ``` Each dataset in the H5 file must also have an attribute named `Legend` which is an ASCII-encoded null-terminated variable-length string. #### Spherical harmonic nodes {#spherical_nodes} When we refer to a "nodal" data format, we mean that the worldtube data are stored as values at specially chosen collocation points (a.k.a. grid points or nodes). This allows SpECTRE to perform integrals, derivatives, and interpolation exactly on the input data. These grid points are Gauss-Legendre in $cos(\theta)$ and equally spaced in $\phi$. Below is a routine for computing the spherical harmonic $\theta$ and $\phi$ values. These can be used to compute the Cartesian locations for a given radius using the standard transformation. The routine supports \f$\ell\in[4, 32]\f$.
C Code for computing SpECTRE CCE gridpoint locations \snippet Test_Spherepack.cpp spectre_cce_grid_point_locations
Alternatively, if your code can read in grid points from a text file, you can run the `WriteCceWorldtubeCoordsToFile` executable like so to get a text file with three columns for the x,y,z coordinates of each point. ``` ./WriteCceWorldtubeCoordsToFile -r 200 -L 16 -o GridPointsR200.txt ``` Each dataset holds `1 + (l_max + 1) * (2 * l_max + 1)` columns, with the first one being the `time`. The columns must be in \f$\theta\f$-varies-fastest ordering. That is, ``` "time", "Phi_0_Theta_0", "Phi_0_Theta_1", "Phi_0_Theta_2", "Phi_0_Theta_3", "Phi_0_Theta_4", "Phi_1_Theta_0", "Phi_1_Theta_1", "Phi_1_Theta_2", "Phi_1_Theta_3", "Phi_1_Theta_4", ``` Each dataset in the H5 file must also have an attribute named `Legend` which is an ASCII-encoded null-terminated variable-length string. \note Nodal data is likely the easiest to write out since no conversion to spherical harmonic coefficients is necessary. #### ADM Cartesian metric and derivatives {#adm_cartesian_metric_and_derivatives} For worldtube data stored in an H5 file in the "ADM metric nodal" format, there must be the following datasets with these exact names (including the `.dat` suffix): - `gxx.dat`, `gxy.dat`, `gxz.dat`, `gyy.dat`, `gyz.dat`, `gzz.dat` - `Dxgxx.dat`, `Dxgxy.dat`, `Dxgxz.dat`, `Dxgyy.dat`, `Dxgyz.dat`, `Dxgzz.dat` - `Dygxx.dat`, `Dygxy.dat`, `Dygxz.dat`, `Dygyy.dat`, `Dygyz.dat`, `Dygzz.dat` - `Dzgxx.dat`, `Dzgxy.dat`, `Dzgxz.dat`, `Dzgyy.dat`, `Dzgyz.dat`, `Dzgzz.dat` - `Shiftx.dat`, `Shifty.dat`, `Shiftz.dat` - `DxShiftx.dat`, `DxShifty.dat`, `DxShiftz.dat` - `DyShiftx.dat`, `DyShifty.dat`, `DyShiftz.dat` - `DzShiftx.dat`, `DzShifty.dat`, `DzShiftz.dat` - `Lapse.dat`, `DxLapse.dat`, `DyLapse.dat`, `DzLapse.dat` - `Kxx.dat`, `Kxy.dat`, `Kxz.dat`, `Kyy.dat`, `Kyz.dat`, `Kzz.dat` - Either: `AuxiliaryShiftx.dat`, `AuxiliaryShifty.dat`, `AuxiliaryShiftz.dat` - Or: `ConformalChristoffelx.dat`, `ConformalChristoffely.dat`, `ConformalChristoffelz.dat` Here `g` represents the spacetime metric, but we only require the spatial components (e.g. `gxx.dat`, `gxy.dat`, etc...) so in practice, those are the tensor components of the spatial metric. The temporal components of the spacetime metric are stored separately in the lapse and shift. Each of the spatial metric, lapse, and shift must also have their cartesian derivatives. `K` is the extrinsic curvature, `AuxiliaryShift` is the auxiliary shift vector used in the first-order form of the Gamma-driver condition, and `ConformalChristoffel` is the trace of the conformal second_order symbols. We will compute the time derivative of the spatial metric using Eq. (2.134) of \cite BaumgarteShapiro, \begin{equation} \partial_t \gamma_{ij} = -2\alpha K_{ij} + D_i\beta_j + D_j\beta_i. \end{equation} The time derivative of the lapse is computed using the `1+log` slicing condition from Eq. (4.87) of \cite BaumgarteShapiro \begin{equation} \partial_t \alpha = -2\alpha K + \beta^j\partial_j\alpha, \end{equation} and the time derivative of the shift is computed using either the first order reduction form of the Gamma-driver condition from Eq. (4.89) of \cite BaumgarteShapiro \begin{equation} \partial_t \beta^i = \eta B^i + \beta^j\partial_j\beta^i, \end{equation} where you can choose $\eta$ (typically $\eta=0.75$) or using the integrated Gamma-driver condition from Eq. (12) of \cite Hilditch:2012fp \begin{equation} \partial_t \beta^i = \tilde{\Gamma}^i - \eta\beta^i + \beta^j\partial_j\beta^i, \end{equation} again, where you can choose $\eta$ (typically $\eta=2/M_{\textrm{ADM}}$). \warning If your worldtube data is in the ADM metric nodal format but you have not used `1+log` slicing and the Gamma-driver conditions specified above, your time derivatives will be **wrong**. If you'd like us to support other commonly used gauge conditions (or variants of `1+log` or Gamma-driver), please open an issue on our [GitHub](https://github.com/sxs-collaboration/spectre). The layout of each of these datasets must be [spherical harmonic nodes](#spherical_nodes). #### Cartesian metric and derivatives {#cartesian_metric_and_derivatives} For worldtube data stored in an H5 file in either the "metric nodal" or "metric modal" formats, there must be the following datasets with these exact names (including the `.dat` suffix): - `gxx.dat`, `gxy.dat`, `gxz.dat`, `gyy.dat`, `gyz.dat`, `gzz.dat` - `Drgxx.dat`, `Drgxy.dat`, `Drgxz.dat`, `Drgyy.dat`, `Drgyz.dat`, `Drgzz.dat` - `Dtgxx.dat`, `Dtgxy.dat`, `Dtgxz.dat`, `Dtgyy.dat`, `Dtgyz.dat`, `Dtgzz.dat` - `Shiftx.dat`, `Shifty.dat`, `Shiftz.dat` - `DrShiftx.dat`, `DrShifty.dat`, `DrShiftz.dat` - `DtShiftx.dat`, `DtShifty.dat`, `DtShiftz.dat` - `Lapse.dat` - `DrLapse.dat` - `DtLapse.dat` Here `g` represents the spacetime metric, but we only require the spatial components (e.g. `gxx.dat`, `gxy.dat`, etc...) so in practice, those are the tensor components of the spatial metric. The temporal components of the spacetime metric are stored separately in the lapse and shift. The layout of each of these datasets must be in either [spherical harmonic modes](#spherical_modes) or [spherical harmonic nodes](#spherical_nodes). #### Bondi-Sachs {#bondi_sachs} In the "bondi nodal" format, you must have the same Bondi variables as the [required format](#required_h5_worldtube_data_format), but each variable layout must be the [spherical harmonic nodal layout](#spherical_nodes) with complex values interleaved as `Re`, `Im`, `Re`, `Im`, ... If you already have data in the [required "bondi modal" format](#required_h5_worldtube_data_format), then nothing needs to be done. #### Running the PreprocessCceWorldtube executable The `PreprocessCceWorldtube` executable should be run on any of the [allowed input formats](#converting_worldtube_data), and will produce a corresponding Bondi-Sachs worldtube file that can be read in by CCE. This executable works similarly to our other executables by accepting a YAML input file: ``` PreprocessCceWorldtube --input-file PreprocessCceWorldtube.yaml ``` with a YAML file \snippet PreprocessCceWorldtube.yaml preprocess_cce_worldtube_yaml_doxygen_example In addition to converting worldtube data formats, `PreprocessCceWorldtube` also accepts multiple input worldtube H5 files that have sequential times (e.g. from different checkpoints) and will combine the times from all H5 files alongside converting the worldtube data format. If there are duplicate or overlapping times, the last/latest of the times are chosen. If you pass multiple input worldtube H5 files, it is assumed that they are ordered increasing in time. Here are some notes about the different options in the YAML input file: - If the extraction radius is in the `InputH5File` names, then the `ExtractionRadius` option can be `Auto`. Otherwise, it must be specified. - The option `LMaxFactor` determines the factor by which the resolution of the boundary computation that is run will exceed the resolution of the input and output files. Empirically, we have found that `LMaxFactor` of 3 is sufficient to achieve roundoff precision in all boundary data we have attempted, and an `LMaxFactor` of 2 is usually sufficient to vastly exceed the precision of the simulation that provided the boundary dataset. - `FixSpecNormalization` should always be `False` unless you are using a particualy old version of SpEC - `DescendingM` should always be `False`. This option is to support metric modal data from SpEC. Our [data format](#input_worldtube_data_format) is always in *ascending* m. - `BufferDepth` is an advanced option that lets you load more data into RAM at once so there are fewer filesystem accesses. - If using the ADM metric nodal input data format with a first-order form gamma driver, specify the `InputDataFormat:` like so: \snippet AdmFirstOrderDriverPreprocessCceWorldtube.yaml first_order_input_data_format_example - If using the ADM metric nodal input data format with an integrated gamma driver, specify the `InputDataFormat:` like so: \snippet AdmSecondOrderDriverPreprocessCceWorldtube.yaml second_order_input_data_format_example ### What Worldtube data "should" look like {#worldtube_data_looks} While no two simulations will look exactly the same, there are some general trends in the worldtube data to look for. Here is a plot of some modes of the Bondi variable `J` from the [Bondi-Sachs](#bondi_sachs) worldtube format. \image html worldtube_J.png "Bondi variable J on the Worldtube" The 2,2 modes are oscillatory and capture the orbits of the two objects. The real part of the 2,0 mode contains the gravitational memory of the system. Then for this system, all the other modes are subdominant. If you are using the [cartesian metric](#cartesian_metric_and_derivatives) or [adm cartesian metric](#adm_cartesian_metric_and_derivatives) worldtube format, here is a plot of the imaginary part of the 2,2 mode of the lapse and its radial and time derivative during inspiral. \image html lapse.png "2,2 component of lapse and its radial and time derivative" One thing to keep in mind with this plot is that it was produced using the Generalized Harmonic formulation of Einstein's equations using the damped harmonic gauge. Therefore, if you are using a different formulation and gauge (like BSSN + moving punctures), the lapse may look different than this. One way to sanity check your data (regardless of what type it is or where you got it from) is to look and how the mode amplitude for a given quantity decays as you increase (l,m). Here is a plot of the amplitude of the modes for the lapse in the above plot. \image html amp_lapse.png "Amplitude of modes of Lapse" You'll notice that most modes are around machine precision and only the first few have any real impact. This is expected. ## Input file for CCE Input files for CCE are commonly named `CharacteristicExtract.yaml`. An example input file with comments explaining some of the options can be found in `$SPECTRE_HOME/tests/InputFiles/Cce/CharacteristicExtract.yaml`. Here we expand a bit on why we chose some of those parameters. ### General options - For resolution, the example input file has lmax (`Cce.LMax`) of 20, and filter lmax (`Filtering.FilterLMax`) of 18; that may run a bit slow for basic tests, but this value yields the best precision-to-run-time ratio for a typical BBH system. Note that precision doesn't improve above lmax 24, filter 22 (be sure to update the filter as you update lmax -- the filter should generally be around 2 lower than the maximum l to reduce possible aliasing). - If you want to just run over all times in the worldtube H5 file, you can set both the `StartTime` and `EndTime` to `Auto` and it will automatically figure it out based on the data in the worldtube file. - The `ScriOutputDensity` adds extra interpolation points to the output, which is useful for finite-difference derivatives on the output data, but otherwise it'll just unnecessarily inflate the output files, so if you don't need the extra points, best just set it to 1. - For production level runs, it's recommended to have the `Cce.Evolution.StepChoosers.Constant` option set to 0.1 for an accurate time evolution. However, if you're just testing, this can be increased to 0.5 to speed things up. - We generally do not recommend extracting at less than 100M due to the CCE junk radiation being much worse at these smaller worldtube radii. That being said, we also recommend running CCE over several worldtube radii and checking which is the best based on the Bianchi identity violations. There isn't necessarily a "best radius" to extract waveforms at. - Most users will not need it, but if you want to dump data from the volume (instead of only on future null infinity), this is possible with the `ObserveFields` option to `Events` within `EventsAndTriggersAtSlabs` in the input file. See the input file referenced above for a (commented-out) example, and the documentation of the class `Cce::Events::ObserveFields` for details. ### Initial data on the null hypersurface Choosing initial data on the initial null hypersurface is a non-trivial task and is an active area of research. We want initial data that will reduce the amount of CCE junk radiation as much as possible, while also having the initial data work for as many cases as possible. SpECTRE currently has four different methods to choose the initial data on the null hypersurface. In order from most recommended to least recommended, these are: - `ConformalFactor`: Try to make initial time coordinate as inertial as possible at \f$\mathscr{I}^+\f$ with a smart choice of the conformal factor. This will work for many cases, but not all. But will produce the best initial data when it does work. - `InverseCubic`: Ansatz where \f$J = A/r + B/r^3\f$. This is very robust and almost never fails, but contains a lot of CCE junk radiation compared to `ConformalFactor`. - `ZeroNonSmooth`: Make `J` vanish. Like the name says, it's not smooth. - `NoIncomingRadiation`: Make \f$\Psi_0 = 0\f$; this does not actually lead to no incoming radiation, since \f$\Psi_0\f$ and \f$\Psi_4\f$ both include incoming and outgoing radiation. ### Rechunking worldtube data \note This section is less important than the others and really only matters if you will be doing a large number of CCE runs like for a catalog. For only a couple runs or just for testing, this part is unnecessary and can be skipped. CCE will run faster if the input worldtube hdf5 file is chunked in small numbers of complete rows. This is relevant because by default, SpEC and SpECTRE write their worldtube files chunked along full time-series columns, which is efficient for writing and compression, but not for reading in to CCE. In that case, you can rechunk the input file before running CCE for maximum performance. This can be done, for instance, using h5py (you will need to fill in filenames appropriate to your case in place of "BondiCceR0050.h5" and "RechunkBondiCceR0050.h5"): ```py import h5py input_file = "BondiCceR0050.h5" output_file = "RechunkBondiCceR0050.h5" with h5py.File(input_file,'r') as input_h5,\ h5py.File(output_file, 'w') as output_h5: for dset in input_h5: if("Version" in dset): output_h5[dset] = input_h5[dset][()] continue number_of_columns = input_h5[dset][()].shape[1] output_h5.create_dataset(dset, data=input_h5[dset], maxshape=(None, number_of_columns), chunks=(4, number_of_columns), dtype='d') for attribute in input_h5[dset].attrs.keys(): output_h5[dset].attrs[attribute] = input_h5[dset].attrs[attribute] ``` The rechunked data will still be in the same [format](#input_worldtube_data_format) as before, but will just have a different underlying structure in the H5 file that makes it faster to read in. ## Running the CCE executable {#running_the_cce_executable} Once you have [acquired an executable](#acquiring_the_cce_module), running CCE in a supported environment is a simple command: ``` ./CharacteristicExtract --input-file CharacteristicExtract.yaml ``` You may notice at the beginning you get some warnings that look like ``` Warning: iterative angular solve did not reach target tolerance 1.000000e-13. Exited after 300 iterations, achieving final maximum over collocation points for deviation from target of 2.073455e-08 Proceeding with evolution using the partial result from partial angular solve. ``` This is normal and expected. All it means is that initially an angular solve didn't hit a tolerance. We've found that it never really reaches the tolerance of 1e-13, but we still keep this tolerance so it gets as low as possible. After this, you'll likely see some output like ``` Simulation time: 10.000000 Wall time: 00:00:44 Simulation time: 20.000000 Wall time: 00:01:14 ``` which tells you that the simulation is proceeding as expected. When the run finished, you'll see something like ``` Done! Wall time: 06:01:41 Date and time at completion: Thu May 23 22:31:27 2024 [Partition 0][Node 0] End of program ``` In terms of runtime, we've found that for a ~5000M long cauchy simulation, CCE takes about 6 hours to run. This will vary based on a number of factors like how long the cauchy evolution actually is, the desired error tolerance of your characteristic timestepper, and also how much data you output at future null infinity. Therefore, take these numbers with a grain of salt and only use them as a rough estimate for how long a job will take. \note CCE can technically run on two (2) cores by adding the option `++ppn 2` to the above command, however, we have found in practice that this makes little-to-no difference in the runtime of the executable. ## Output from CCE Once you have the reduction data output file from a successful CCE run, you can confirm the integrity of the h5 file and its contents by running ``` h5ls -r CharacteristicExtractReduction.h5 ``` For the reduction file produced by a successful run, the output of the `h5ls` should resemble ``` /SpectreR0100.cce Group /SpectreR0100.cce/EthInertialRetardedTime Dataset {26451/Inf, 163} /SpectreR0100.cce/News Dataset {26451/Inf, 163} /SpectreR0100.cce/Psi0 Dataset {26451/Inf, 163} /SpectreR0100.cce/Psi1 Dataset {26451/Inf, 163} /SpectreR0100.cce/Psi2 Dataset {26451/Inf, 163} /SpectreR0100.cce/Psi3 Dataset {26451/Inf, 163} /SpectreR0100.cce/Psi4 Dataset {26451/Inf, 163} /SpectreR0100.cce/Strain Dataset {26451/Inf, 163} /src.tar.gz Dataset {7757329} ``` Notice that the worldtube radius will be encoded into the subfile name. \note Prior to [this Pull Request](https://github.com/sxs-collaboration/spectre/pull/5985), merged May 15, 2024, the output of `h5ls` looked like this ``` / Group /Cce Group /Cce/EthInertialRetardedTime.dat Dataset {3995/Inf, 163} /Cce/News.dat Dataset {3995/Inf, 163} /Cce/Psi0.dat Dataset {3995/Inf, 163} /Cce/Psi1.dat Dataset {3995/Inf, 163} /Cce/Psi2.dat Dataset {3995/Inf, 163} /Cce/Psi3.dat Dataset {3995/Inf, 163} /Cce/Psi4.dat Dataset {3995/Inf, 163} /Cce/Strain.dat Dataset {3995/Inf, 163} /src.tar.gz Dataset {3750199} ``` No matter the spin weight of the quantity, the $\ell = 0,1$ modes will always be output by CCE. Also, the `/SpectreR0100.cce` group will have a legend attribute that specifies the columns. ### Raw CCE output The `Strain` represents the asymptotic transverse-traceless contribution to the metric scaled by the Bondi radius (to give the asymptotically leading part), the `News` represents the first time derivative of the strain, and each of the `Psi...` datasets represent the Weyl scalars, each scaled by the appropriate factor of the Bondi-Sachs radius to retrieve the asymptotically leading contribution. The `EthInertialRetardedTime` is a diagnostic dataset that represents the angular derivative of the inertial retarded time, which determines the coordinate transformation that is performed at future null infinity. If you'd like to visualize the output of a CCE run, we offer a [CLI](py/cli.html) that will produce a plot of all of quantities except `EthInertialRetardedTime`. To see how to use this CLI, run ``` spectre plot cce -h ``` If you'd like to do something more complicated than just make a quick plot, you'll have to load in the output data yourself using `h5py` or our `spectre.IO.H5` bindings. \note The CLI can also plot the "old" version of CCE output, described above. Pass `--cce-group %Cce` to the CLI. This option is only for backwards compatibility with the old CCE output and is not supported for the current version of output. This options is deprecated and will be removed in the future. ### Frame fixing You may notice some odd features in some of the output quantities if you try and plot them. This is not a bug in CCE (not that we know of at least). This occurs because the data at future null infinity is in the wrong Bondi-Metzner-Sachs (BMS) frame. In order to put this data into the correct BMS frame, the [SXS Collaboration](https://github.com/sxs-collaboration) offers a python/numba code called [scri](https://github.com/moble/scri) to do these transformations. See their documentation for how to install/run/plot a waveform at future null infinity in the correct BMS frame. Below is a plot of the imaginary part of the 2,2 component for the strain when plotted using the raw output from SpECTRE CCE and BMS frame-fixing with scri. You'll notice that there is a non-zero offset, and this component of the strain doesn't decay back down to zero during the ringdown. This is because of the improper BMS frame that the SpECTRE CCE waveform is in. A supertranslation must be applied to transform the waveform into the correct BMS frame. See \cite Mitman2024review for a review of BMS transformations and gravitational memory. To perform the frame fixing, see [this tutorial](https://scri.readthedocs.io/en/latest/tutorial_abd.html#loading-cce-data-and-adjusting-the-bms-frame) in scri. \image html im_h22.png "Imaginary part of 2,2 component of the strain" The discrepancy is even more apparent if you plot the amplitude of the two waveforms. It's pretty clear which waveform is the more "physical" one. \image html amp_im_h22.png "Amplitude of imaginary part of 2,2 component of the strain" Notice that there are still some oscillations in the strain output by scri towards the beginning of the waveform (up to ~1500M). This is caused by CCE junk radiation from imperfect initial data on the null hypersurface. In order to use this waveform in analysis, the CCE junk must be cut off from the beginning. You are also able to see gravitational memory effects with SpECTRE CCE! This shows up in the real part of the 2,0 mode of the strain. Though you can see the memory effects in the SpECTRE CCE waveform, in order to do any analysis, you must also transform the waveform to a more physically motivated BMS frame. \image html re_h20.png "Real part of 2,0 component of the strain ## Citing CCE If you use the SpECTRE CCE module to extract your waveforms at future null infinity, please cite the following: - [SpECTRE DOI](https://zenodo.org/doi/10.5281/zenodo.4290404) (This link defaults to the latest release of SpECTRE. From there, you can find links to past releases of SpECTRE as well) - [SpECTRE CCE paper](https://doi.org/10.1103/PhysRevD.107.064013) - [CCE paper](https://doi.org/10.1103/PhysRevD.102.044052) If you used scri to perform any frame-fixing, please also consult the [scri GitHub](https://github.com/moble/scri) for how you should cite it. You can also consult our \ref publication_policies page for further questions or contact [spectre-devel@black-holes.org](mailto:spectre-devel@black-holes.org). ================================================ FILE: docs/Tutorials/CheckpointRestart.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # %Setting up checkpoints and restarts {#tutorial_checkpoint_restart} \tableofcontents SpECTRE executables can write checkpoints that save their instantaneous state to disc; the execution can be restarted later from a saved checkpoint. This feature is useful for expensive simulations that would run longer than the wallclock limits on a supercomputer system. Executables can checkpoint when: 1. The `default_phase_order` member variable in the `Metavariables` includes a `WriteCheckpoint` phase. 2. The `WriteCheckpoint` phase is run by a `PhaseControl` specified in the `Metavariables` and the input file. The two supported ways of running the checkpoint phase are: - with `CheckpointAndExitAfterWallclock`. This is the recommended phase control for checkpointing, because it writes only one checkpoint before cleanly terminating the code. This reduces the disc space taken up by checkpoint files and stops using up the allocation's CPU-hours on work that would be redone anyway after the run is restarted. The executable will return exit code 2 when it terminates from `CheckpointAndExitAfterWallclock`, meaning it is incomplete and should continue from the checkpoint. See `Parallel::ExitCode` for a definition of all exit code. - using `VisitAndReturn(WriteCheckpoint)`. This is useful for writing more frequent checkpoint files, which could help when debugging a run by restarting it from just before the failure. To restart an executable from a checkpoint file, run a command like this: ``` ./MySpectreExecutable +restart Checkpoints/Checkpoint_0123 ``` where the `0123` should be the number of the checkpoint to restart from. You can also use the \ref tutorial_cli "command-line interface (CLI)" for restarting: ``` ./spectre run INPUT_FILE --from-last-checkpoint Checkpoints/ ``` There are a number of caveats in the current implementation of checkpointing and restarting: 1. The same binary must be used when writing the checkpoint and when restarting from the checkpoint. If a different binary is used to restart the code, there are no guarantees that the code will restart or that the continued execution will be correct. 2. The code must be restarted on the same hardware configuration used when writing the checkpoint --- this means the same number of nodes with the same number of processors per node. 3. When using `CheckpointAndExitAfterWallclock` to trigger checkpoints, note that the elapsed wallclock time is checked only when the `PhaseControl` is run, i.e., at global synchronization points defined in the input file. This means that to write a checkpoint in the 30 minutes before the end of a job's queue time, the triggers in the input file must trigger global synchronizations at least once every 30 minutes (and probably 2-3 times so there is a margin for the time to write files to disc, etc). It is currently up to the user to find the balance between too-frequent synchronizations (that slow the code) and too-infrequent synchronizations (that won't allow checkpoints to be written). Certain simulation parameters can be modified when restarting from a checkpoint file. This is done by parsing a new input file containing just those options to modify; all other options will preserve their value from the original run. Note, however, that not all tags are permitted to be modified: in the current implementation, only tags from the `const_global_cache_tags` that also have a member variable `static constexpr bool is_overlayable = true;` can be modified. The reason for this "opt-in" design is that in general, most tags interact with past or current simulation data in a way that would invalidate the simulation state if the tag were modified on restart (example: changing the domain invalidates all spatial data, changing the timestepper invalidates the history). Only tags that do not interact with the state should be permitted to be updated. For example: activation thresholds on various algorithms, or frequency of data observation, are safe parameters to modify. The executable will update the global cache with new input file values during the phase `UpdateOptionsAtRestartFromCheckpoint`. The `CheckpointAndExitAfterWallclock` phase control automatically directs code flow to this phase after a restart. In this option-updating phase, the code tries to read an "overlay" input file whose name is computed from the original input file and the number of the checkpoint used to restart. Say the original input file is `path/to/Input.yaml` and the code is restarted using a checkpoint `+restart Checkpoints/Checkpoint_0123`, then the overlay input file to read has name `path/to/Input.overlay_0123.yaml`. If this file does not exist, the executable continues with previous parameter values. ================================================ FILE: docs/Tutorials/Cli.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Command-line interface (CLI) {#tutorial_cli} \tableofcontents SpECTRE has a command-line interface (CLI) that allows you to run executables, work with output data, and generate plots and visualizations. To get started, compile the `cli` target in your build directory. Then run: ```sh ./bin/spectre --help ``` All available commands are listed in the [Python documentation](py/cli.html). ## Autocompletion The CLI supports autocompletion for Bash, Zsh, and Fish. Depending on your shell, source the corresponding file: ```sh # In the build directory: # - Bash: . ./bin/python/shell-completion.bash # - Fish: cp ./bin/python/shell-completion.fish ~/.config/fish/completions/spectre.fish # - Zsh: . ./bin/python/shell-completion.zsh ``` You may want to source the shell completion script on startup, e.g., in your `.bashrc` or `.zshrc` file. ================================================ FILE: docs/Tutorials/DomainCreation.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # %Domain Creation {#tutorial_domain_creation} \tableofcontents ### Domain Decomposition The spatial domain on which the solution is computed is divided into non-overlapping cells. For 2D and 3D domains, we use curvilinear quadrilateral and curvilinear hexahedral elements, respectively. The specification of a particular spatial domain is given by the DomainCreator. DomainCreators specify the properties of the initial elements (before AMR takes place), which are then used by Domain to create Blocks. Each Block holds a CoordinateMap (described below) as well as information about its neighbors. For geometrical domains, (e.g. rectilinear, spherical) there are a few shortcuts that can be used such that a user does not need to specify by hand the map and neighbor information for each %Block; these methods are explained below. ## CoordinateMaps Each Block in the Domain must hold a CoordinateMap which describes how to map the logical cube (a reference cell that covers the interval \f$[-1, 1]\f$ in each dimension) to the curvilinear hexahedral element the %Block describes. The %CoordinateMap also provides the jacobian of the mapping. ### Shortcuts for CoordinateMaps For spherical domains, `Wedge<3>` implements the cubed-sphere map, and there exists the method `sph_wedge_coordinate_maps` in Domain/DomainHelpers.hpp to quickly construct six of these maps at once. For rectilinear multicube domains, Affine and Equiangular map the logical cubes to cartesian cubes. The method `maps_for_rectilinear_domains` in DomainHelpers allows the user to obtain the CoordinateMaps for all of the Blocks in such a domain at once. These can both be used to provide the map arguments to the Domain constructor. ## Boundary Information Each Block must know which of the other Blocks in the Domain are its neighbors and which of its logical directions points to an external boundary. ### Shortcuts for Boundary Information A quick way to encode the neighbor and boundary information for the blocks in a domain is through our convention of numbering and ordering the corners of the blocks in a well-defined way. The corner numbering scheme is described in the \ref tutorial_orientations tutorial. For spherical domains, DomainHelpers has the methods `corners_for_radially_layered_domains` and `corners_for_biradially_layered_domains`, which provides the proper corner numberings for the maps obtained from the method `sph_wedge_coordinate_maps`. These methods are used in the \ref domain::creators::Sphere "Sphere" DomainCreator. For rectilinear multicube domains, DomainHelpers has the methods `corners_for_rectilinear_domains`, which provides the proper corner numberings for the maps obtained from the method `maps_for_rectilinear_domains`. ## Creating Rectilinear Domains with Shortcuts: The construction of a rectilinear domain begins with the specification of the total extents of the domain in each cartesian direction, in terms of the number of blocks. These extents are held in an Index object. For an illustrative example, we will explain how to construct a cubical domain which has an extent of two blocks in each dimension: \image html eightcubes.png "A 2x2x2 domain." The first step is to generate the corner numbering for this Domain. For the purposes of this example, we will construct all blocks with their logical directions aligned with one another. As each block must also have an associated block id, we must be aware of the order in which the corners for each block are constructed. The algorithm `corners_for_rectilinear_domains` always begins with the block located in the lowest cartesian corner of the domain. The second block is its immediate neighbor in the \f$+x\f$ direction, and so on until the block in this row with the highest \f$x\f$ coordinate is reached. The next block is the the immediate neighbor of the lowest corner block in the \f$+y\f$ direction, and then continues through the neighboring blocks in the \f$+x\f$ as before. This is the same order in which the global corners numbers are assigned to the vertices of the blocks. \image html eightcubes_numbered.png "With global corners." The block corners generated by `corners_for_rectilinear_domains` are then: ``` {0,1,3,4,9,10,12,13}, {1,2,4,5,10,11,13,14}, {3,4,6,7,12,13,15,16}, {4,5,7,8,13,14,16,17}, {9,10,12,13,18,19,21,22}, {10,11,13,14,19,20,22,23}, {12,13,15,16,21,22,24,25}, {13,14,16,17,22,23,25,26} ``` What remains is to specify the CoordinateMaps that each Block will hold. This is handled by `maps_for_rectilinear_domains` and currently supports both Affine and Equiangular mappings. The coordinate extents of each map is set by the argument to `block_demarcations`. For a 2x2x1 domain, the call to `maps_for_rectilinear_domains` could be: \snippet Test_DomainHelpers.cpp show_maps_for_rectilinear_domains For this choice of arguments we obtain the maps for a domain that extends from 0.0 to 2.0 in the \f$x\f$-direction, from 0.0 to 2.0 in the \f$y\f$ -direction, and from -0.4 to 0.3 in the \f$z\f$ direction. With the corners and maps in hand, we can pass these as arguments to the Domain constructor. ### Non-trivial Domain Example The aforementioned functions can also take an additional argument to exclude blocks from a domain. For this one needs to know the Index for each block they wish to exclude from the domain. For the 2x2x2 domain example, the block indices are: ``` {0,0,0}, {1,0,0}, {0,1,0}, {1,1,0}, {0,0,1}, {1,0,1}, {0,1,1}, {1,1,1} ``` In this example, we construct a domain with topology \f$S^3\f$, which begins with the net for a tesseract. We begin by specifying that the domain extents are three blocks along the \f$x\f$ and \f$y\f$ directions, and four blocks along the \f$z\f$ direction. In addition, we exclude the following block indices: ``` {0,0,0}, //first block {1,0,0}, //second block {2,0,0}, //third block {0,1,0}, //fourth block {2,1,0}, //sixth block {0,2,0}, //seventh block {1,2,0}, //eight block {2,2,0}, //ninth block {0,0,1}, //10th block {1,0,1}, //11th block {2,0,1}, //12th block {0,1,1}, //13th block {2,1,1}, //15th block {0,2,1}, //16th block {1,2,1}, //17th block {2,2,1}, //18th block {0,0,2}, //19th block {2,0,2}, //21st block {0,2,2}, //25th block {2,2,2}, //27th block {0,0,2}, //28rd block {1,0,2}, //29th block {2,0,2}, //30th block {0,1,2}, //31th block {2,1,2}, //33th block {0,2,2}, //34th block {1,2,2}, //35th block {2,2,2}, //36th block ``` Alternatively, we can exclude none of the blocks in this way and instead selectively copy the block corners from the returned vector into a new vector that only contains the corners for the desired blocks, if one prefers to work with single-number array indices as opposed to tuples. Either way, we end up with a vector of block corners corresponding to the following diagram: \image html tesseract_numbered.png "A numbered tesseract net." The maps are obtained similarly. In this case we suggest using the Equiangular maps for this Domain since they adapt the logical coordinates to the angular coordinates on a sphere. We also need to identify corresponding faces with each other to obtain a domain of topology \f$S^3\f$, so we also need to supply the constructor of Domain with PairsOfFaces. For the \f$S^3\f$ domain, these faces are: ``` //Folding highest cube downward: {{53,54,69,70},{53,54,49,50}}, {{53,57,69,73},{53,57,52,56}}, {{57,58,61,62},{57,58,73,74}}, {{54,58,70,74},{54,58,55,59}}, //Folding cross cubes together: {{54,55,38,39},{54,50,38,34}}, {{58,59,42,43},{58,62,42,46}}, {{53,52,37,36},{53,49,37,33}}, {{57,56,41,40},{57,61,41,45}}, //Folding second lowest cube upward: {{38,42,39,43},{38,42,22,26}}, {{33,34,37,38},{21,22,37,38}}, {{36,37,40,41},{21,37,25,41}}, {{41,42,45,46},{41,42,25,26}}, //Folding bottom cube around domain: {{33,34,49,50},{21,22,5,6}}, {{39,43,55,59},{22,26,6,10}}, {{45,46,61,62},{25,26,9,10}}, {{36,40,52,56},{21,25,5,9}}, {{5,6,9,10},{69,70,73,74}} ``` ================================================ FILE: docs/Tutorials/EventsAndTriggers.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Events and triggers {#tutorial_events_and_triggers} \tableofcontents The "events and triggers" infrastructure (and the related "events and dense triggers") provide some control of SpECTRE executable execution from the input file contents by running user-specified code on the elements. It does not generally have major effects on the flow of the \ref dev_guide_parallelization_core_algorithm "algorithm", but is primarily used for observations, such as writing volume data to H5 files, and minor simulation adjustments. ### Events An \ref Event "event" is an input-file-creatable object that performs some task that (with the exception of the \ref Events::Completion "Completion" event) does not directly affect the execution of the algorithm on the element. The effects of events are limited to sending messages. The most commonly used events (such as the \ref ::Events::ObserveNorms "ObserveNorms" event) send data to be written to disk, but have no long-term effects on the simulation state. Others (such as \ref Events::ChangeSlabSize "ChangeSlabSize") can have indirect effects when \ref dev_guide_parallelization_actions "actions" react to the messages they send. ### Triggers A \ref Trigger "trigger" is an input-file-creatable object that controls when events are run. They are checked periodically, once per Slab in an evolution executable, and once per iteration in an elliptic solve. At each check a trigger may fire, causing its associated events to run or not. Triggers must give a consistent result over the entire domain at each check, so their result must always be independent of element-specific state, such as the local values of the system variables. ### Dense triggers A \ref DenseTrigger "dense trigger" is similar to a trigger, but uses time-stepper dense output (i.e., interpolation or extrapolation) to provide more precise control of the time that it fires. As a time-related feature, dense triggers are only applicable to evolution executables. Dense triggers fire at a precise set of times, independent of the time-step or slab state, by interpolating the evolved variables to the requested time before running the associated events. As with normal triggers, dense triggers are required to fire consistently over the entire domain. ### Input file syntax The `%EventsAndTriggers` (and `%EventsAndDenseTriggers`) sections of the \ref dev_guide_option_parsing "input file" are parsed as a list of Trigger/Events pairs: \snippet PlaneWave1DEventsAndTriggersExample.yaml multiple_events In this example, we are using the \ref Triggers::Slabs "Slabs" trigger to run two events every 10 slabs: ObserveFields and \ref ::Events::ObserveNorms "ObserveNorms". We also run the \ref ::Events::Completion "Completion" event at the \ref ::Triggers::Always "Always" trigger, so the run will terminate immediately. ================================================ FILE: docs/Tutorials/Imex.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # IMEX {#tutorial_imex} \tableofcontents ### Introduction to IMEX IMEX (implicit-explicit) integration is a method for stabilizing the numerical evolution of stiff differential equations. While "stiff" is not a precisely defined term, it generally refers to equations where the time step required to achieve numerical stability is much shorter than the timescale of the evolution of the solution, often by orders of magnitude. An example of a stiff equation is \f{equation} \label{eq:example-equation} \frac{dy}{dt} = -k (y - f(t)) \f} with $k$ very large. After a brief initial transient, the solution is very well-approximated as $y = f(t) + O(k^{-1})$, but will be unstable if evolved using an explicit time stepper with a step size larger than approximately $k^{-1}$, even if $f$ is slowly varying. To see the source of the stability problem, consider evolving $\eqref{eq:example-equation}$ using Euler's method. For a step from $t_0$ to $t_1 = t_0 + \Delta t$, we find \f{equation} \label{eq:example-Euler} y_1 = y_0 + \Delta t \frac{dy}{dt}(y_0, t_0) = y_0 - k \Delta t (y_0 - f(t_0)), \f} giving the divergence from the known infinite-$k$ solution of \f{equation} y_1 - f(t_1) = y_0 - f(t_1) - k \Delta t (y_0 - f(t_0)). \f} If $k \Delta t$, is large, the last term will dominate and the deviation from the approximate solution will increase by roughly that factor every step. To improve this, we can evolve using an implicit time stepper. Taking the same step as above with the backwards Euler method gives \f{equation} \label{eq:example-backwards-Euler} y_1 = y_0 + \Delta t \frac{dy}{dt}(y_1, t_1) = y_0 - k \Delta t (y_1 - f(t_1)), \f} for a deviation of \f{equation} y_1 - f(t_1) = \frac{y_0 - f(t_1)}{1 + k \Delta t}. \f} This goes to zero as $k \Delta t$ becomes large, showing convergence to the infinite-$k$ solution. The unconditional (linear) stability achievable by implicit integrators allows them to solve problems not feasible with explicit methods, but it comes at a significant price. While the explicit update $\eqref{eq:example-Euler}$ directly gave $y_1$, the implicit update $\eqref{eq:example-backwards-Euler}$ required the equation to be solved for the updated quantity. In this example that was fairly easy, but, in a real application, finding an analytic solution is likely to be difficult, if not impossible. Implicit integrators are therefore usually used with a numerical solve of the update equation. Even for simple systems, this root-finding procedure adds significantly to the computational cost of the method, and for a system like a large PDE evolution it is intractable. To mitigate this problem, we turn to the hybrid IMEX methods. The idea behind IMEX is to split the derivative into two terms, one without stability problems that will be treated explicitly, and another that will be treated implicitly. Notationally, we will write \f{equation} \frac{dy}{dt}(y, t) = E(y, t) + I(y, t). \f} The simplest IMEX integrator combines the two forms of Euler's method from above: \f{equation} y_1 = y_0 + \Delta t (E(y_0, t_0) + I(y_1, t_1)). \f} (This integrator is not implemented in SpECTRE.) In our example above, we can, as an example, split $\eqref{eq:example-equation}$ as \f{align} E(y, t) &= k f(t) & I(y, t) &= -k y, \f} which gives \f{equation} y_1 = y_0 + k \Delta t (f(t_0) - y_1) = \frac{y_0 + k \Delta t\, f(t_0)}{1 + k \Delta t}. \f} In the limit where $k \Delta t$ goes to infinity, this gives $y_1 = f(t_0)$, which is as small a deviation from the infinite-$k$ solution as possible when $f$ is treated explicitly. Again, in this simple case there is no downside to using an IMEX integrator over an explicit one, or an implicit method over IMEX. The gain appears in real cases where the implicit-step equation cannot be solved exactly. #### Properties of IMEX time steppers Any IMEX time stepper can be used as either an implicit or an explicit time stepper by choosing $E$ or $I$ to be zero. As such, many significant properties of an IMEX time stepper are actually properties of one or the other part. We won't discuss the standard properties of explicit time steppers here, but most of them, such as error estimation, are used in SpECTRE ignoring the implicit part. As the entire point of using implicit methods is to increase stability, the most important properties of the implicit part of a time stepper are stability properties. There are many stability classifications, but we will only discuss the most important here, and those only qualitatively. More information can be found in \cite Hairer1996 and \cite Kennedy2016. The basic desire for an implicit method is that as the equation being evolved becomes increasingly stiff the evolution remains stable. (Linear) stability for an infinitely large step size (or, equivalently, an infinitely stiff equation) is known as *A-stability*. Adams methods above second order cannot be A-stable, so IMEX work generally focuses on Runge-Kutta schemes. All IMEX time steppers implemented in SpECTRE are A-stable. A stronger stability condition is known as *L-stability*. L-stability is similar to A-stability, but instead of merely requiring that an analytically decaying equation does not numerically diverge in the large-step-size limit, we require that the solution reaches zero in a single step. Since IMEX applications can take steps orders of magnitude larger than the decay timescale of stiff terms, this property is often desirable. In addition to the stability properties, there is one interesting property of the IMEX stepper as a whole. A wide class of time steppers, including all explicit (global time-stepping) methods implementable in the current SpECTRE interface, preserve (linear) conserved quantities. A linear conserved quantity is a linear combination of the evolved variables that is analytically constant under evolution, independent of the initial conditions. In physics, a common example is the integral of the density, i.e., the total mass. Such quantities will be numerically preserved during evolution to the level of roundoff error, even if that is much smaller than the truncation error in the solution. Both the explicit and implicit portions of all IMEX time steppers that we will consider are conservative in this manner. However, the combination of the two parts into an IMEX scheme does not necessarily preserve this property. In general, both the explicit and implicit parts of the split derivative must individually conserve something for the full IMEX method to conserve it as well. Some IMEX schemes, however, do preserve conserved quantities, independent of how the derivative is split between the explicit and implicit parts. Such methods are termed *stiffly accurate*. (This property is also useful in deriving and analyzing implicit schemes, but that is not of great importance to users of the methods.) ### IMEX in SpECTRE SpECTRE supports IMEX integration, with restrictions to reduce the cost of the solve of the implicit equation as much as possible. Additionally, not all integration schemes extend to IMEX integration, so the list of available time steppers is limited for IMEX evolutions. #### Mathematical restrictions For problems of interest to us, the evolved variables consist of several fields coupled by the system derivative. The implicit solve is more expensive when performed on more variables, so there is a method to restrict the solve to a subset of the system if only some variables are affected by stiff terms. The system can define one or more *implicit sectors*, which are subsets of the evolved variables with implicit terms that can be solved independently from one another. (If sectors depend on variables from other sectors, the evolution system defines the order in which the implicit updates are applied.) As an example, for a fluid coupled to neutrinos, the neutrinos obey stiff equations under some conditions. If we consider neutrino flavors to be non-interacting, they can each be placed in their own implicit sector and solved independently. The fluid equations will usually be non-stiff, so the fluid variables will not be in any sector, even though they will still be used as arguments for computing the stiff sources. Within each sector, restrictions are placed on the form of the implicit derivative (the $I$ above). When evolving a hyperbolic PDE, in general, the equation for an implicit step becomes an elliptic PDE. This is far too complex and expensive to solve for every integration substep. We therefore restrict the implicit derivative to only contain source terms, i.e., terms that depend on the sector variables only in a pointwise manner, rather than through derivatives or similar. (The terms may still depend on the derivatives of non-sector variables.) This results in each point in the domain having an independent set of algebraic equations to solve. There is a small complexity in handling non-autonomous (time-dependent) systems of equations, such as those for evolutions with control systems. Some methods are defined in a way such that the values of time for the explicit and implicit parts of a substep appear to be inconsistent. SpECTRE always uses the time derived from the explicit portion of the method, which is equivalent to treating time as an additional evolved variable with a constant explicit derivative of 1 and implicit derivative of 0. SpECTRE supports using an analytic solution of the implicit-step equation as well as two modes for numerical root-finding: implicit and semi-implicit. The analytic mode can be chosen in the definition of the implicit sector if the form of the implicit source allows an analytic solution. The numerical methods can be toggled at runtime. The fully implicit method does a numerical root-find, while the semi-implicit one linearizes the equation and solves that. Semi-implicit solves are faster, and, experimentally, they still stabilize the evolution fairly well. Using a semi-implicit solve instead of a fully implicit one does not affect conservation properties of the method. Both numerical solvers require the jacobian of the implicit source to be coded, but an analytic solution does not. #### Creation of SpECTRE IMEX executables The SpECTRE IMEX interface is defined by two protocols: \link imex::protocols::ImexSystem \endlink and \link imex::protocols::ImplicitSector \endlink. The normal evolution-system interface now only contains the explicit portion of the derivative, and the implicit portion is defined by the contents of the `implicit_sectors` typelist. See those protocols for details. In order to use an IMEX system, various classes must be explicitly instantiated. This is done in a separate source file in the system directory. As an example, the instantiation file for the sectors in one of the tests is \include tests/Unit/Helpers/Evolution/Imex/DoImplicitStepInstantiate.cpp In the executable itself, four sets of changes are necessary. First, the time-stepper type, usually defined as a type alias near the start of the metavariables, must be changed from `TimeStepper` to `ImexTimeStepper` (IMEX-LTS is not currently supported), and an entry must be added to the `factory_creation` list: ``` tmpl::pair ``` (The `TimeStepper` line can be removed, although doing so is not necessary.) Second, the IMEX actions must be added after the corresponding explicit actions: * In the initialization phase, the `imex::Initialize` mutator must be applied by adding it to the arguments of `Initialization::Actions::InitializeItems`. It uses objects initialized by `Initialization::TimeStepperHistory`, so must appear after that. * In the step actions, ``` imex::Actions::RecordTimeStepperData ``` must be added after each occurrence of `RecordTimeStepperData`, ``` imex::Actions::DoImplicitStep ``` must be added after each occurrence of `UpdateU`, and ``` Actions::MutateApply> ``` must be added after each occurrence of `CleanHistory`. Third, the `imex::ImplicitDenseOutput` dense output postprocessor must be added to the argument of the `evolution::Actions::RunEventsAndDenseTriggers` action. It must appear before any other preprocessors that use the evolved variables. Finally, header includes must be added for all these things. The required headers are ``` #include "Evolution/Imex/Actions/DoImplicitStep.hpp" #include "Evolution/Imex/Actions/RecordTimeStepperData.hpp" #include "Evolution/Imex/CleanHistory.hpp" #include "Evolution/Imex/ImplicitDenseOutput.hpp" #include "Evolution/Imex/Initialize.hpp" #include "ParallelAlgorithms/Actions/MutateApply.hpp" #include "Time/TimeSteppers/ImexTimeStepper.hpp" ``` ================================================ FILE: docs/Tutorials/Orientation.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # OrientationMap {#tutorial_orientations} \tableofcontents ### Introduction This tutorial only applies to a Domain (or a region of the Domain) that is constructed from Blocks that are logical hypercubes where each Block has at most a single neighboring Block in each direction. Each element in a domain has a set of internal directions which it uses for computations in its own local coordinate system. These are referred to as the logical directions \f$\xi\f$, \f$\eta\f$, and \f$\zeta\f$, where \f$\xi\f$ is the first dimension, \f$\eta\f$ is the second dimension, and \f$\zeta\f$ is the third dimension. In a domain with multiple Blocks, the logical directions are not necessarily aligned on the interfaces between two Blocks, as shown in the figure below. As certain operations (e.g. fluxes, limiting) communicate information across the boundaries of adjacent elements, there needs to be a class that takes into account the relative orientations of elements which neighbor each other. This class is OrientationMap. ### %OrientationMaps between %Blocks Each Block in a Domain has a set of BlockNeighbors, which each hold an OrientationMap. In this scenario, the Block is referred to as the host, and the OrientationMap held by each BlockNeighbors is referred to as "the orientation the BlockNeighbors has with respect to the host Block." This is a convention, so we give an example of constructing and assigning the correct OrientationMaps: \image html twocubes.png "Two neighboring blocks." In the image above, we see a domain decomposition into two Blocks, which have their logical axes rotated relative to one another. With the left block as the host Block, we see that it has a neighbor in the \f$+\xi\f$ direction. The host Block holds a `std::unordered_map` from Directions to BlockNeighbors; the BlockNeighbors itself holds an OrientationMap that determines the mapping from each logical direction in the host Block to that in the neighboring Block. That is, the OrientationMap takes as input local information (i.e. logical directions in the host's coordinate system) and returns neighbor information (i.e. logical directions in the neighbor's coordinate system). An OrientationMap is constructed by passing in the block neighbor directions that correspond to the \f$+\xi\f$, \f$+\eta\f$, \f$+\zeta\f$ directions in the host. In this case, these directions in the host map to the \f$+\zeta\f$, \f$+\xi\f$, \f$+\eta\f$ directions in the neighbor, respectively. This BlockNeighbors thus holds the OrientationMap constructed with the list (\f$+\zeta\f$, \f$+\xi\f$, \f$+\eta\f$). With the right block as the host block, we see that it has a BlockNeighbors in the \f$-\zeta\f$ direction, and the OrientationMap held by this BlockNeighbors is the one constructed with the array (\f$+\eta\f$, \f$+\zeta\f$, \f$+\xi\f$). For convenience, OrientationMap has a method `inverse_map` which returns the OrientationMap that takes as input neighbor information and returns local information. OrientationMaps need to be provided for each BlockNeighbors in each direction for each Block. This quickly becomes too large of a number to determine by hand as the number of Blocks and the number of dimensions increases. A remedy to this problem is the corner numbering scheme. ### Encoding BlockNeighbors information using Corner Orderings and Numberings The orientation of the \f${dim}\f$ logical directions within each element determines an ordering of the \f$2^{dim}\f$ vertices of that element. This is called the local corner numbering scheme (Local CNS) with respect to that element. We give the ordering of the local corners below for the case of a three-dimensional element: \image html onecube_numbered.png "The local corner numbering." ``` Corner 0 is the location of the lower xi, lower eta, lower zeta corner. Corner 1 is the location of the upper xi, lower eta, lower zeta corner. Corner 2 is the location of the lower xi, upper eta, lower zeta corner. Corner 3 is the location of the upper xi, upper eta, lower zeta corner. Corner 4 is the location of the lower xi, lower eta, upper zeta corner. Corner 5 is the location of the upper xi, lower eta, upper zeta corner. Corner 6 is the location of the lower xi, upper eta, upper zeta corner. Corner 7 is the location of the upper xi, upper eta, upper zeta corner. ``` What remains is to endow the domain decomposition with a global corner numbering (Global CNS). We give an example below: \image html twocubes_numbered.png "A global corner numbering." In the image above, we see that each vertex of the two-block domain has been assigned a number. Although each block has eight corners, four are shared among them, so there are only twelve unique corners in this domain. Any numbering may be used in the global corner numbering, so long as the each distinct corner is given a single distinct corner number. \note This Global CNS assumes that there is no additional identifying of faces with one another for periodic boundary conditions. That is, each element must have \f$2^{dim}\f$ distinct corner numbers. If you wish to additionally identify faces of the same block with each other, that must be done in an additional step. This step is explained in the "Setting Periodic Boundary Conditions" section. ### The Ordered Subset of the Global CNS (Subset CNS): With the Global CNS in hand, each Block inherits an ordered subset of Global CNS. The ordering in this set is determined by the ordering of the Local CNS, and the elements of the set determined by how one assigned the Global CNS to the Domain. For the image above, the Subset CNS corresponding to the left block is {0, 1, 3, 4, 6, 7, 9, 10}, while the Subset CNS corresponding to the right block is {1, 4, 7, 10, 2, 5, 8, 11}. This ordering of the Subset CNS encodes the relative orientations between each Block. Subset CNSs need to be provided for each Block in a Domain. It turns out that for very regular domains, (i.e. spherical or rectilinear) we can generate the appropriate Subset CNSs. As this is a conceptual tutorial, how to construct these domains in SpECTRE is described in the \ref tutorial_domain_creation tutorial. ### Explanation of the Algorithms in DomainHelpers: For illustrative purposes, we will use the following Domain composed of two Blocks as described above as an example. Because there are 12 corners in this Domain, we will arbitrarily assign a unique id to each corner. Knowing the orientation of the logical axes within a block, we construct a Subset CNS for each Block.
Here is one possible result, given some relative orientation between the blocks: ``` Block1: {0, 1, 3, 4, 6, 7, 9, 10} Block2: {1, 4, 7, 10, 2, 5, 8, 11} ``` The values of the ids only serve to identify which corners are unique and which are shared. This is determined by the Global CNS. The order of the ids in the list is determined by the Local CNS. We take advantage of the fact that the array index of the global corner id is the number of the corner in the local CNS. The algorithm begins by determining the shared corners between the Blocks: ``` result: {1, 4, 7, 10} ``` The next step is to determine the local ids of these shared global ids: ``` Block1 result: {1,3,5,7} Block2 result: {0,1,2,3} ``` The next step is to convert these ids into their binary representation. For reference, we give the binary representation for each number 0-7: ``` Corner 0: 000 Corner 1: 001 Corner 2: 010 Corner 3: 011 Corner 4: 100 Corner 5: 101 Corner 6: 110 Corner 7: 111 ``` Here 0 and 1 indicate lower and upper in the corresponding axis (zeta, eta, xi), respectively, and the ordering has been reversed so that the rightmost column corresponds to the xi position and the leftmost column to the zeta position. Returning to the example at hand, we have: ``` Block1 result: {001,011,101,111} Block2 result: {000,001,010,011} ``` Note that we can now read off the shared face relative to each Block easily: ``` Block1 result: Upper xi (All binary Block1 ids have a 1 in the third position) Block2 result: Lower zeta (All binary Block2 ids have a 0 in the first position) ``` Now we know that `Direction<3>::%upper_xi()` in Block1 corresponds to `Direction<3>::%lower_zeta().%opposite()` in Block2. The use of `.%opposite()` is a result of the Directions to a Block face being anti-parallel because each Block lies on the opposite side of the shared face.
The remaining two correspondences are given by the alignment of the shared face. It is useful to know the following information:
In the Local CNS, if an edge lies along the xi direction, if one takes the two corners making up that edge and takes the difference of their ids, one always gets the result \f$ \pm 1\f$. Similarly, if the edge lies in the eta direction, the result will be \f$ \pm 2\f$. Finally, if the edge lies in the zeta direction, the result will be \f$ \pm 4\f$. We use this information to determine the alignment of the shared face: ``` Block1: 3-1=2 => This edge is in the +eta direction. Block2: 1-0=1 => This edge is in the +xi direction. Then, +eta in Block1 corresponds to +xi in Block2. Block1: 5-1=4 => This edge is in the +zeta direction. Block2: 2-0=2 => This edge is in the +eta direction. Then, +zeta in Block1 corresponds to +eta in Block2. ``` The corresponding directions in each Block have now been deduced. To confirm, we can use the other ids as well and arrive at the same result:
``` Block1: 7-5=2 => +eta Block2: 3-2=1 => +xi Block1: 7-3=4 => +zeta Block2: 3-1=2 => +eta ``` ### Setting Periodic Boundary Conditions It is also possible to identify faces of a Block using the subset CNS. For example, to identify the lower zeta face with the upper zeta face of a Block where the corners are labeled `{3,0,4,1,9,6,10,7}`, one may supply the lists `{3,0,4,1}` and `{9,6,10,7}` to the `set_identified_boundaries` function. \note The `set_identified_boundaries` function is sensitive to the order of the corners in the lists supplied as arguments. This is because the function identifies corners and edges with each other as opposed to simply faces. This allows the user to specify more peculiar boundary conditions. For example, using `{3,0,4,1}` and `{6,7,9,10}` to set the periodic boundaries will identify the lower zeta face with the upper zeta face, but after a rotation of a quarter-turn. For reference, here are the corners to use for each face for a Block with corners labelled as `{0,1,2,3,4,5,6,7}` to set up periodic boundary conditions in each dimension, i.e. a \f$\mathrm{T}^3\f$ topology: Face | Corners ------|-------- upper xi| `{1,3,5,7}` lower xi| `{0,2,4,6}` upper eta| `{2,3,6,7}` lower eta| `{0,1,4,5}` upper zeta| `{4,5,6,7}` lower zeta| `{0,1,2,3}` ================================================ FILE: docs/Tutorials/ParallelExecutable/Tutorials.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Writing SpECTRE executables {#tutorials_parallel} \tableofcontents This set of tutorials will develop a parallel executable in stages, beginning with the simplest possible executable, and then introducing SpECTRE's parallel features one step at a time. At each stage, the tutorials will illustrate what code a user needs to add in order to use a particular feature, and then, for those interested, an explanation of the metaprogramming that turns the user-provided code into an actual SpECTRE parallel executable. Prior to going through these tutorials, you should have \ref installation "installed SpECTRE" and built it successfully. | Tutorial name | Concepts introduced | |---------------|---------------------| | \subpage tutorial_parallel_concepts "Parallelism in SpECTRE " | SpECTRE and Charm++ | | \subpage tutorial_minimal_parallel_executable "Minimal executable " | Metavariables, Main component | See also: \subpage ParallelInfoExecutablePage See also: \subpage RandomAmrExecutablePage ================================================ FILE: docs/Tutorials/Python.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Using SpECTRE's Python modules {#spectre_using_python} \tableofcontents Some classes and functions from SpECTRE have Python bindings to make it easier to visualize data, write test code, and provide an introduction to numerical relativity without needing to delve into C++. ## Building the SpECTRE Python modules > tl;dr: Compile the `all-pybindings` or `cli` target. First, build SpECTRE with Python bindings enabled by appending the `-D BUILD_PYTHON_BINDINGS=ON` flag to the `cmake` command (enabled by default). You can specify the Python version, interpreter and libraries used for compiling and testing the bindings by setting the `-D Python_EXECUTABLE` to an absolute path such as `/usr/bin/python3`. Compile the `all-pybindings` (or `cli`) target. You will find that a `BUILD_DIR/bin/python` directory is created that contains the Python modules. ## Importing the SpECTRE Python modules > tl;dr: Spin up a Jupyter notebook with `./bin/python-spectre -m jupyterlab`, > then `import spectre`. You have many options for making the Python modules accessible to import in your scripts: - Use the `BUILD_DIR/bin/python-spectre` shortcut to run your scripts. It just points the `PYTHONPATH` to the modules in `BUILD_DIR/bin/python` and invokes the Python interpreter that you configured your build with. You can also use this shortcut to spin up a Jupyter server: ```sh BUILD_DIR/bin/python-spectre -m jupyterlab ``` If Jupyter is not yet installed in your Python environment, you can install it like this: ```sh BUILD_DIR/bin/python-spectre -m pip install jupyterlab ``` > Note for VSCode users: You can also select this Jupyter server as kernel for > notebooks running in VSCode (see [docs](https://code.visualstudio.com/docs/datascience/jupyter-notebooks#_connect-to-a-remote-jupyter-server)). - Install the modules into your Python environment: ```sh pip install [-e] BUILD_DIR/bin/python ``` The optional `-e` flag installs the modules in _development mode_, which means they are symlinked so that changes to the modules will be reflected in your Python environment. You can install the Python modules like this in any Python environment that supports `pip`, for instance in a [`virtualenv`/`venv`](https://docs.python.org/3/tutorial/venv.html) or in an [Anaconda](https://www.anaconda.com/distribution/) environment. - You can also get access to the SpECTRE Python modules by manually adding `BUILD_DIR/bin/python` to your `PYTHONPATH`. This is done automatically by the `LoadPython.sh` script: ```sh . BUILD_DIR/bin/LoadPython.sh ``` Using any of the above options you should be able to import the `spectre` Python modules in your scripts or notebooks. You can try it like this: ```py import spectre ``` For an overview of all available Python modules see the [Python modules documentation](py/_autosummary/spectre.html). For an example what you can do with them see the tutorial on \ref tutorial_vis_python. ## Running Jupyter within the Docker container You can run [Jupyter lab](https://jupyterlab.readthedocs.io/) in the Docker container and access it through a browser on the host for a convenient way to work with the SpECTRE Python bindings. To do so, make sure you have exposed a port when running the Docker container, e.g. by appending the option `-p 8000:8000` to the `docker run` command (see \ref installation). Inside the docker container, it can be convenient to use `disown` or to `apt-get install screen` and use `screen` to obtain a shell that runs the Jupyter server permanently in the background. Within the shell you want to run your Jupyter server, navigate to a directory that will serve as the root for the file system that Jupyter has access to. Make sure it is shared with the host (e.g. `SPECTRE_HOME`) so your Jupyter notebooks are not lost when the container is deleted. Then, run the following command: ```sh BUILD_DIR/bin/python-spectre -m jupyterlab --ip 0.0.0.0 --port 8000 --allow-root ``` Copy the token that is being displayed. Now you can open a browser on the host machine, point it to `http://localhost:8000` and paste in the token. You will have access to the Python environment within the Docker container. ## Developing Python code > tl;dr: Set `PY_DEV_MODE=ON` in your CMake configuration so Python files are > symlinked to the build directory. When you edit any of the Python files in the repository, the changes are not immediately reflected in the Python modules that you import from the build directory. You have to run `cmake .` in the build directory to update the Python files. This can be avoided by setting `cmake -D PY_DEV_MODE=ON .` in the build directory, which configures CMake to symlink the Python files rather than copy them. Some features that rely on CMake variables break with this mode, e.g. the SpECTRE version number is not inserted into the Python modules so `spectre.__version__` will return nonsense. Nonetheless, enabling this mode avoids a lot of the hassle that comes from re-configuring CMake every time you change a file. Furthermore, enabling `autoreload` in Jupyter notebooks can be very helpful when you are editing Python code. Add the following code before any import statements in your notebook: ``` %load_ext autoreload %autoreload 2 ``` For details on writing Python bindings for our C++ functions, rather than writing Python code, see the developer guide on \ref spectre_writing_python_bindings. ================================================ FILE: docs/Tutorials/Tutorials.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # User Tutorials {#tutorials} - \subpage beginners_guide - A brief intro to getting started with SpECTRE, building and rebuilding an executable with new features, and visualizing the output - \subpage tutorial_visualization - How to run an existing executable and visualize its output - \subpage tutorial_orientations - How to determine orientations - \subpage tutorial_domain_creation - How to set up the initial domain - \subpage spectre_using_python - How to install and work with the Python bindings and other Python modules provided by SpECTRE. - \subpage tutorial_vis_python - How to visualize volume data with Python - \subpage tutorial_cli - How to use the command-line interface - \subpage tutorial_cce - How to get started running stand-alone CCE with externally produced data - \subpage tutorial_checkpoint_restart - How to set up a SpECTRE executable for checkpointing and restarting - \subpage tutorial_events_and_triggers - How to specify code to run in an input file - \subpage tutorial_imex - How to add IMEX support to an evolution system ================================================ FILE: docs/Tutorials/Visualization.md ================================================ \cond NEVER Distributed under the MIT License. See LICENSE.txt for details. \endcond # Running and Visualizing {#tutorial_visualization} \tableofcontents ### Building an Executable from an Existing Source File SpECTRE source files for evolution executables are located in `src/Evolution/Executables`. Executables can be compiled by running the command `make EXECUTABLE_NAME` where `EXECUTABLE_NAME` is the name of the executable as defined in the `CMakeLists.txt` file located in the same directory as the source file. For example, to compile the executable that evolves a scalar wave using a three-dimensional domain, navigate to `$SPECTRE_HOME/build/`, then one runs the command: `make EvolveScalarWave3D`, which then results in an executable of the same name in the `bin` directory of the user's build directory. ### Running an Evolution Executable Each SpECTRE executable reads a user-provided YAML file that specifies the runtime settings of the evolution. This is where options such as the Domain, AnalyticSolution, TimeStepper, etc are supplied. Example input files are kept in `tests/InputFiles`, and are written to provide a functional base input file which the user can then modify as desired. Copy the executable and YAML file to a directory of your choice. The YAML file is then passed as an argument to the executable using the flag `--input-file`. For example, for a scalar wave evolution, run the command: ``` ./EvolveScalarWave3D --input-file PlaneWave3D.yaml ``` You can also use the \ref tutorial_cli "command-line interface (CLI)" to run executables: ``` ./spectre run PlaneWave3D.yaml ``` By default, the example input files do not produce any output. This can be changed by modifying the options passed to `EventsAndTriggers` or `EventsAndDenseTriggers`: \snippet PlaneWave1DObserveExample.yaml observe_event_trigger This will observe the norms of the errors in the system at times \f$0.0\f$ and \f$1.0\f$ and the field data at the start of every 50th slab. A successful observation will result in the creation of H5 files whose names can be specified in the YAML file under the options `VolumeFileName` and `ReductionFileName`. One volume data file will be produced from each Charm++ node that is used to run the executable. Each volume data file will have its corresponding node number appended to its file name. Visualization of the volume data will be described in the next sections. ### Plotting data with Python See the tutorial on \ref tutorial_vis_python to learn how to load and visualize volume data in Python. ### 3D Volume Data In ParaView A SpECTRE executable with observers produces volume and/or reduced data h5 files. An XDMF file must be created from the volume data in order to do visualization using ParaView. To this end we provide the tool `generate-xdmf` in the Python command-line interface. Run it in your build directory as `spectre generate-xdmf`. It takes two required arguments which are passed to `--subfile-name`, and `--output`. The argument passed to `--subfile-name` is the name of the subfile inside the H5 volume data file where data is stored. In the above example, `--subfile-name` would be `VolumePsiPiPhiEvery50Slabs`. The argument passed to `--output` is the desired .xmf file name, also without filename extension. Use `--help` to see a further description of possible arguments. Open the .xmf file in ParaView and select the `Xdmf Reader`, *not* the version 3 readers. On the left hand side of the main ParaView window is a section named `Properties`, here you must click the highlighted `Apply` button. ParaView will now render your volume data. If you only wish to visualize a few datasets out of a large set, we recommended unchecking the boxes for the datasets you wish to ignore under `Point Arrays` before clicking `Apply`. Also, don't forget to check which dataset is being used for the color under `Coloring`. The default won't necessarily be the dataset you want. \note ParaView cannot understand `.xmf` files when subfile names have colons in them. Please avoid subfile names like `My::Subfile:Name`. ### Helpful ParaView Filters Here we describe the usage of filters we've found to better visualize our data. Feel free to contribute to this section! #### Removing Mesh Imprinting You may notice what appears to be mesh imprinting on the data. The imprinting effect can be removed by applying the `Tetrahedralize` filter. To apply the filter select the `Filters` menu item, then `Alphabetical` and finally `Tetrahedralize`. #### Creating Derived Volume Data New volume data can be created from the existing volume data using the `Calculator` filter. In the `Calculator`'s text box, input a numerical expression in terms of existing datasets evaluating to the desired quantity. For example, a vector-valued velocity dataset can be created from three scalar velocity component datasets using the expression `velocity_x * iHat + velocity_y * jHat + velocity_z * kHat` and hitting the `Apply` button. By default, this will create a new dataset `Result`. The name of the new dataset can be changed by changing the name provided to `Result Array Name` above the `Calculator` text box. #### Visualizing Vector Fields Derived From Scalar Fields Use the `Calculator` filter described above in "Creating Derived Volume Data" to create a new vector-valued dataset. Once this is created, use the `Glyph` filter and set the `Active Attributes` to the vector you wish to visualize. Make sure that `Scale Mode` is set to `vector`. ### Visualizing and Extracting Dat Files Global quantities such as error norms are stored in `h5::Dat` subfiles in the reduction/global HDF5 file. The command-line endpoint `spectre plot dat` can be used to plot quantities, and `spectre extract-dat` can be used to extract them into space-separated text files. These text files can then be read with other plotting programs or viewed in an editor. ### Reproducibility of Results Being able to reproduce the results of simulations is important for scientific integrity and accuracy. To this end, SpECTRE encodes the source tree, environment variables, and a record of build information (e.g., the third-party library versions) into the executables. From most executables these can be retrieved using the flags `--dump-source-as filename_without_extension`, `--dump-paths`, `--dump-build-info`, and `--dump-environment`. The flag `--dump-only` will cause the program to exit after the information has been dumped. You can use the `--help` flag to get more details on what flags are available. The flag `--dump-paths` will print to screen the environment variables `PATH`, `CPATH`, `LD_LIBRARY_PATH`, `LIBRARY_PATH`, and `CMAKE_PREFIX_PATH` at link time. The flag `--dump-build-info` will print to screen the contents of the `BuildInfo.txt` file generated by CMake. The flag `--dump-environment` will print to screen the output of `printenv` at link time. Finally, the flag `--dump-source-as filename_without_extension` will dump the archive `filename_without_extension.tar.gz`, which contains the entire source tree at link time. The combined above information should be enough to reproduce simulations results to roundoff error as long as the third party libraries used to build the executable have not changed on the system the simulation was run on. Often only data from the simulation is retained, not the entire executable. In order to make simulations reproducible from only the HDF5 output, any HDF5 files written with SpECTRE's HDF5 wrappers contain the info about the run, output of `printenv` at link time, the contents of `BuildInfo.txt`, and an archive of the source tree. These are inside the `header.hdr` group with names `SimulationInfo`, `EnvironmentVariablesAtCompilation`, `BuildInfo`, and `src.tar.gz`. The source archive can be extracted by running the command ``` h5dump -d /src.tar.gz -b LE -o src.tar.gz /path/to/hdf5/file.h5 ``` You will need to make sure the argument to `-b` is the same endianness as your computer. In the above example little endian is used. ================================================ FILE: docs/Tutorials/VisualizationWithPython.ipynb ================================================ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualization with Python {#tutorial_vis_python}\n", "\n", "This tutorial shows you how to load 3D volume data in Python and visualize it\n", "using `matplotlib`.\n", "\n", "First, you need access to the `spectre` Python bindings. A simple way to do this\n", "is to run a Jupyter server from the build directory:\n", "\n", "```sh\n", "./bin/python-spectre -m jupyterlab\n", "```\n", "\n", "You can find detailed instruction in the tutorial on \\ref spectre_using_python.\n", "\n", "> Note for VSCode users: You can also select this Jupyter server as kernel for\n", "> notebooks running in VSCode (see [docs](https://code.visualstudio.com/docs/datascience/jupyter-notebooks#_connect-to-a-remote-jupyter-server)).\n", "\n", "Now we can import modules from the `spectre` Python package." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Distributed under the MIT License.\n", "# See LICENSE.txt for details.\n", "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import os\n", "\n", "plt.style.use(\"../Examples/plots.mplstyle\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Select an observation\n", "\n", "First, we open the H5 volume data files from a simulation and get a list of all\n", "available observations and their times:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from spectre.IO.H5 import list_observations, open_volfiles\n", "import glob\n", "\n", "h5files = glob.glob(\n", " # Point this to your volume data files\n", " \"BbhVolume*.h5\"\n", ")\n", "subfile_name = \"/VolumeData\"\n", "obs_ids, obs_times = list_observations(open_volfiles(h5files, subfile_name))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also list all available variables in the volume data files:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
ConformalFactor                 ExtrinsicCurvature_xx           ExtrinsicCurvature_yx          \n",
       "ExtrinsicCurvature_yy           ExtrinsicCurvature_zx           ExtrinsicCurvature_zy          \n",
       "ExtrinsicCurvature_zz           InertialCoordinates_x           InertialCoordinates_y          \n",
       "InertialCoordinates_z           Lapse                           RadiallyCompressedCoordinates_x\n",
       "RadiallyCompressedCoordinates_y RadiallyCompressedCoordinates_z ShiftExcess_x                  \n",
       "ShiftExcess_y                   ShiftExcess_z                   Shift_x                        \n",
       "Shift_y                         Shift_z                         SpatialMetric_xx               \n",
       "SpatialMetric_yx                SpatialMetric_yy                SpatialMetric_zx               \n",
       "SpatialMetric_zy                SpatialMetric_zz                                               \n",
       "
\n" ], "text/plain": [ "ConformalFactor ExtrinsicCurvature_xx ExtrinsicCurvature_yx \n", "ExtrinsicCurvature_yy ExtrinsicCurvature_zx ExtrinsicCurvature_zy \n", "ExtrinsicCurvature_zz InertialCoordinates_x InertialCoordinates_y \n", "InertialCoordinates_z Lapse RadiallyCompressedCoordinates_x\n", "RadiallyCompressedCoordinates_y RadiallyCompressedCoordinates_z ShiftExcess_x \n", "ShiftExcess_y ShiftExcess_z Shift_x \n", "Shift_y Shift_z SpatialMetric_xx \n", "SpatialMetric_yx SpatialMetric_yy SpatialMetric_zx \n", "SpatialMetric_zy SpatialMetric_zz \n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import rich.columns\n", "\n", "for volfile in open_volfiles(h5files, subfile_name, obs_ids[-1]):\n", " all_vars = volfile.list_tensor_components(obs_ids[-1])\n", " # Only look into the first file. The other should have the same variables.\n", " break\n", "\n", "rich.print(rich.columns.Columns(all_vars))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Interpolate to a slice\n", "\n", "One way of visualizing your 3D volume data in a 2D plot is with a slice. Use\n", "`interpolate_to_points` to interpolate your volume data to any set of\n", "coordinates:" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "from spectre.IO.Exporter import interpolate_to_points\n", "\n", "# Coordinates of a regular grid in the xy plane\n", "x, y = np.meshgrid(np.linspace(-15, 15, 300), np.linspace(-15, 15, 300))\n", "z = np.zeros(x.shape)\n", "\n", "# Interpolation can be slow, so it's useful to cache the result. Remember to\n", "# delete the cache file if you change anything.\n", "cache_file = \"interpolated_data.npy\"\n", "if os.path.isfile(cache_file):\n", " lapse = np.load(cache_file)\n", "else:\n", " lapse = np.array(\n", " interpolate_to_points(\n", " h5files,\n", " subfile_name=subfile_name,\n", " observation_id=obs_ids[-1],\n", " tensor_components=[\"Lapse\"],\n", " target_points=[x.flatten(), y.flatten(), z.flatten()],\n", " )\n", " ).reshape(x.shape)\n", " np.save(cache_file, lapse)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can plot the 2D slice with `matplotlib`:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/var/folders/xp/5t2ny359187c4ljckf8sz3m80000gn/T/ipykernel_19858/3375439396.py:2: RuntimeWarning: invalid value encountered in subtract\n", " plt.contourf(x, y, np.log(1 - lapse))\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAApAAAAJyCAYAAABzOfDZAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAABcSAAAXEgFnn9JSAABJ2ElEQVR4nO3df3RU9Z3/8VdCCJAEiQoIJPJDBKsRlGAQBCu6rdVaW0G726+1FrTdXWplu1pL7THoEbW2a6142u763bqg1P22K3zRr2WLWqkuyg8FRCxFwIj8EjVkEUhCEn7M9w92MD9mkrkz98fn87nPxzmeIxPIfDK5ufeZ970zk5dIJBICAAAAMpQf9QIAAABgFwISAAAAnhCQAAAA8ISABAAAgCcEJAAAADwhIAEAAOAJAQkAAABPCEgAAAB4QkACAADAEwISAAAAnhCQAAAA8ISABAAAgCcEJAAAADwhIAEAAOCJUQG5du1aPfjgg5o6darKy8uVl5envLy8tH//nnvuOfF3Uv33wx/+MMTVAwAAxENB1Atobc6cOXr22Wc9/7uJEyfqzDPP7HD72LFj/VgWAAAAWjEqICdMmKDRo0erqqpKVVVVGjp0qJqbm7v8d9/61rc0bdq04BcIAAAAswJy1qxZUS8BAAAAXTDqGkgAAACYz6gJZLaWLVum9evXq6mpSeXl5bryyiu5/hEAACAgTgTkggUL2vy5urpa1157rebPn6+SkpKMP09FRUXK2zdv3qxevXpp8ODBOa0TAADAbzt27FBxcbE+/PDD0O7T6oA888wz9dBDD+nKK6/UkCFDtG/fPv3Xf/2XfvCDH2jRokU6evSoFi9enPP9JBIJNdY3asfmPT6s2myJQqs3CQBwRl7LkaiXAEs0Hm0M/T7zEolEIvR7zVDPnj3V3Nwsr0vcs2ePRo0apbq6Oq1cuVLjx4/PaR0VFRXasXmPJp36Nzl9HpMdGV4W9RIAAGkU1OyOegkw2Kt1v9PgswZq48aNod2nk0+iGThwoKZPny5JWrp0acSrMduR4WXEIwAYLrmvZn8NUzh7vnLEiBGSjk8j0RE7IQCwU+v9N5NJRMXZgNy3b58kqbi4OOKVmIVwBAB3EJOIipMBmUgkTjx5prKyMuLVmIFwBAC3EZMIk7XXQNbW1uqXv/ylDh482Ob2+vp6zZgxQ6tXr9aAAQM0derUiFZoBq6ZAYD4Yd+PoBk1gVyyZInmzJlz4s8tLS2S1OZZ1NXV1brqqqvU0NCg7373u/rhD3+oqqoqDRw4ULW1tVq3bp3q6upUWlqqhQsXqqioKPSvwwTsOAAATCURFKMCsra2VqtXr+5we+vbamtrJUmnnnqqZs2apVWrVmnLli1asWKFunXrpmHDhmnatGn6x3/8R5WVxS+iCEcAQCrEJPxk9OtAmsKG14EkHAEA2SAm7RfF60AaNYGEd4QjACAXyeMIIQkvCEhLEY4AAD9xihteEJCWIRwBAEFjKomuEJCWIBwBAGFjKol0CEjDEY4AABMwlURrBKShCEcAgImYSkKy+J1oXEY8AgBswDvexBcTSIPwQwgAsBGnt+OHgDQA4QgAcAGnt+ODU9gRIx4BAC7i9LbbmEBGhB8qAEAccHrbTQRkyAhHAEAccXrbLZzCDhHxCAAAp7ddwAQyBPyQAADQEae37cUEMmDEIwAAnWMiaR8mkAHhBwEAAG+YSNqDCWQAiEcAALLHRNJ8TCB9xMYOAIB/mEiaiwmkT4hHAACCwUTSPEwgc8QGDQBAOJhImoMJZA6IRwAAwsdEMnpMILPARgsAQPSYSEaHCaRHxCMAAGZhIhk+AjJDicICNk4AAAxGSIaHgAQAAE4hJINHQAIAACcRksEhIAEAgNMISf8RkAAAIBYISf8QkAAAIFYIydwRkAAAIJaIyOwRkAAAILaYRmaHgAQAALFHSHpDQAIAAPwPQjIzBCQAAEA7RGTnCEgAAIAUmEamR0ACAAB0gpDsiIAEAADIABH5KQISAAAgQ0wjjyMgAQAAPIp7SBKQAAAAWYprRBKQAAAAOYjjNJKABAAA8EGcIpKABAAA8ElcppEEJAAAgM9cD8mCqBcAwJuDw3pFvQRPem87FPUSACAyR4aXqaBmd9TL8B0BCUTMtiD0Kpuvj+gE4JLkJNKlkCQggQC5HodB8fK4EZsAbOHSNJKABHxAKEanq8eewARgElemkQQk4AGhaB8CE4CJbJ9GEpBACoRifHT2vSYuAQTJ5mkkAQmIYERqxCWAMNg4jSQgETvEIvxAXALwk20RSUDCeQQjwpZumyMsAXTGplPaBCScRDTCRIQlgEzYMI0kIOEEghE2IywBtGf6NJKAhLWIRrgu1TZOVALxYuo0koCEVYhGxB3TSiB+TIxIAhJGIxiBzDCtBNxm2iltAhJGIhyB3DGtBNxjyjSSgIQxiEYgHEwrAbuZEJEEJCJFNAJmICoBu0R9SpuAROiIRsAORCVgviPDy6S68O+XgERoCEfAfkQlYJ5EYfg5R0AicIQj4DaiEogfAhKBIBqBeCMqAbcRkPAV4QggHaIScAcBCV8QjgCyQVQCdiIgkRPCEYDf2u9XCErAPAQkPCMaAYSJKSVgHgISGSMcAZiCKSUQLQISXSIcAZiOKSUQLgISaRGOAGzGlBIIDgGJlIhHAK5hSgn4h4BEG4QjgDhhSglkh4CEJMIRACSCEshUftQLaG3t2rV68MEHNXXqVJWXlysvL095eXld/rv58+dr3LhxKikp0SmnnKIvfvGLWrFiRQgrtt/BYb2IRwBII7mPZF8JtGXUBHLOnDl69tlnPf2b733ve5o7d6569eqlyy+/XE1NTXrxxRf1wgsvaOHChbrmmmuCWazl2BECgHdMKIHjjArICRMmaPTo0aqqqlJVVZWGDh2q5ubmtH//j3/8o+bOnatTTz1VK1eu1IgRIyRJK1eu1OTJkzV9+nRNnjxZpaWlIX0FdiAeAcAfBCXiyqiAnDVrlqe///DDD0uS7rrrrhPxKB0P0b//+7/Xo48+qscff1y33367r+u0FeEIAMFqvZ8lJuEyo66B9OLQoUNatmyZJOm6667r8PHkbc8991yo6zIR1+4AQPi4fhIuM2oC6cXmzZvV3Nysfv36qby8vMPHKysrJUkbNmwIe2lGYacFAGbgdDdcYm1A7tixQ5JSxqMkFRcXq7S0VPv27dPBgwfVu3fvLj9nRUVFyttrampUkH9S9ouNAOEIAGbjdDdsZm1A1tfXS5KKiorS/p3i4mJ98sknGQekK4hHALAL00nYxtqADMLGjRtT3l5RUaHt22pDXo13hCMAuIHpJExnbUCWlJRIkhobG9P+nYaGBkmKxfSReAQANxGTMJG1ATl48GBJ0q5du1J+vKGhQZ988olOPvlkpwOScASA+CAmYQprX8bnrLPOUo8ePVRbW6vdu3d3+Pi6deskSaNHjw57aaEhHgEgvniJIETJ2oDs1auXLrvsMknS008/3eHjCxculCRdffXVoa4rDOwwAACtEZMIm7UBKUm33XabJOm+++7T1q1bT9y+cuVKPfbYYyotLdXNN98c1fICwc4BANAZYhJhMOoayCVLlmjOnDkn/tzS0iJJGj9+/InbqqurddVVV0mSPve5z+kf/uEfNHfuXJ1//vn6/Oc/r5aWFr344otKJBKaN2+eM++DzY4AAOAV10wiKEYFZG1trVavXt3h9ta31da2fTmdRx55ROeff75+8Ytf6MUXX1RhYaE+97nPqbq6WhdddFHgaw4D8QgAyBUxCT/lJRKJRNSLMF3ydSAnnD8z9PsmHgEAQSIm7bdy/aMaMqxf2tezDoLV10C6jngEAASN6yWRDaNOYeM4fpABAGHjFDe8YAJpGOIRABA1ppLoChNIg/DDCgAwCVNJpMME0hDEIwDAZEwl0RoTyIjxwwgAsAlTSUhMICNFPAIAbMZUMr4IyIjwAwcAcAUhGT+cwo4AP2QAABdxejs+mECGjHgEAMQBU0m3EZAh4gcJABA3hKSbOIUdAn5wAABxlzwWcmrbDUwgA0Y8AgDwKSaSbiAgA8QPCAAAqRGSdiMgA8IPBQAAXSMk7URABoAfBAAAvCEk7cKTaHzGxo/6MnN+LyvZfSzqJQCAJzzZxg4EpI+IR/eZFIeZyGS9RCYAExGSZiMgfUI8usW2UMxFV18rgQkgSoSkmQhIHxCPdotTLGYj1eNDVAIIGyFpFgIyR8SjXYhFf6R7HAlLAEEjJM1AQOaAeDQfwRguppUAwkJIRouAzBLxaC6i0Sztvx8EJQA/EZLRICCzQDyah2i0B0EJIAgHh/UiIkNEQMJKBKM7CEoAfmEaGR4C0iOmj9EiHN1HUALIFSEZPALSA+IxGkRjvBGUALLFae3gEJAZOlZIxISJaEQ6rbcNYhJAV5hGBoOAhFEIR3jBdBJApghJfxGQMALhCD8wnQTQFU5r+4OARGSIRgSJ6SSAdJhG5o6AROgIR0SB6SSA9phGZo+ARGgIR5iCmASQxDQyOwQkAkc4wmTEJACJkPSKgERgCEfYhusmAXBaOzMc4REI4hEuqC/LP/EfgPjgjUO6xgQSvuJAC1dxqhuIF05pd46AhC8IR8QJMQnEB6e0UyMgkRPCEXHHdZOA+5hGdsTRH1kjHoGOuG4ScBfXRn6KCSQ848AIZIbpJOAeppHHUQLwhHgEssd0EnBH3KeRTCCREQ54gL+YTgL2i/MTbAhIdIl4BIJHUAJ2iuspbQISaRGOQHQISsAucZtGEpBIiXgEzJLqZ5KoBMwSp4ikEtAB8QjYgSflAOaJy5NrmEDiBA5CgL3S/fwypQTCF4frIglISCIeAVdx6huIjsuntAlIEI9AzHT2M09cAv5yNSIJyBgjHAG0x6lwwH8uRiQBGVPEIwAvmFoCuXEtIgnIGCIeAfipq30KgQkc51JEEpAxQzwCCBuBCXzKlWdoE5AxQjwCMBGBiTiyfRpJQMYE8QjAVpnsv4hM2MjmiCQgY4B4BOA6ppiwla0RSUA6jngEAJ5FDrPZGJEEpMOIRwDoGnEJE9gWkQSko4hHAMgdcYkw2RSRBKSDiEcACB7vM44g2BKRBKRjiEcAiA5vBQk/2BCRBKRDiEcAMBPTSnhlekQSkI4gHqPRWJ77AaBoF987II7a77cJSrRnckQSkA4gHoPhRxz6dT9EJuA+ppRIxdSIJCAtRzz6I6xYzFa69RGWgNuYUkIyMyIJSIsRj9kxPRa9aP+1EJSA2wjK+DItIglISxGP3rgUjZ0hKIF4aX0sICbdZ1JEEpAWIh4zE5do7AxBCcQH08l4MCUiCUjLEI+dIxo71/rxISYBtzGddJcJEUlAwnpEY3aISSA+iEn3RB2RBKRFmD62RTj6J/lYEpKA+zjV7Y4oI5KAtATxeBzRGCymkkD8MJ2028FhvaT14d8vAWkB4pFwjAJTSSB+iElkioCE0QjH6DGVBOIpGZOEpPmOFYa/byYgDRfX6SPhaCamkkD8MJVEKtYfBSZPnqy8vLy0/y1dujTqJWaNeISpGsuP8X0CYqi+LP/Ef4g3ZyaQ1157rUpKSjrcXlZWFsFqchfHH06CxD5MJIH44hR3vDkTkA899JCGDh0a9TKQBcLRfoQkEF+c4o4n9vYGitP0kXh0C6e2gXjj9HZ8ODOBdEVcfvCIDLcxkQTijdPb7nMmIB9//HHV1dUpPz9fI0eO1DXXXKPBgwdHvSykQDzGR2P5MSISiDFOb7vLmYC877772vz5+9//vqqrq1VdXZ3x56ioqEh5e01NjfJ7luayvIy4Pn0kHOOJaSQAiamka6zfo3/2s5/VggULVFNTo8bGRm3evFn333+/CgoKNHv2bM2dOzfqJWaEeITruD4SgMR1kq7ISyQSiagXEYQXXnhBX/jCF1RaWqoPPvhAvXr1yvpzVVRUaNvuOo2+6g4fV9iWyz9MRANSYSIJQGIi6YcNS/5Jw8pO1caNG0O7T2f34JdffrkuuOACffLJJ1q9enXUy+mUq/HIxAmdYdsAIDGRtJXT37ERI0ZIkvbs2RPxSuKHOEAm+CUDQBIhaRenv1P79u2TJBUXF0e8kvRc/GEhCOAV2wyAJELSDs5+h2pra7V8+XJJUmVlZcSrSc3FHxBCANliGgmgNULSbFZ/Z1asWKFnnnlGR48ebXP7+++/rylTpqihoUFf/vKXVV5eHtEK44WDP/zAdgSgNSLSTFa/DuSWLVs0ffp0DRgwQJWVlSotLdX27du1du1aNTU1qaKiQv/6r/8a9TJTcu0HgoM+/MRrRwJojdeQNI/VAXnhhRdqxowZWr16td544w3t27dPxcXFOv/88/XVr35VM2bMyOnle5AZ4hFB4Z1sALRGSJrD6oA8++yz9atf/SrqZXjm0vSReETQiEgA7RGS0WOvjKwRjwgLT7ABkIpLAxnb8MiHzJWNnYM5osB2B6A9nq0dDR5xeMZBHFFiGgkgFSIyXDzaIXJh4+bADVOwLQJoj2lkeHiUkTEO2DAN2ySAVIjI4PEIh4SNGQgGp7QBpMI0Mlg8ssgIB2iYjm0UQCpEZDCsfh1IW9i+8cb1wFwwqDGQz3vkg6JAPi94zUgAqdWX5fOakT4jINGpuMRjULGY6X0Rlf4hIgGkwouP+4uARFoux2OYwZiJ9ushKHPDe2kDSIdppD8IyIDZfvraJaZFY2dar5WYzB7TSACpEJG5Y8+KlFyaPhYMarQqHttLrt/mryFKLm3LAPzDgCc3PHoBsnXjdOWA62J0ufg1hcGVbRqAv3ipn+zxqME5cYisOHyNfuP1IgGkQ0R6xyOGNmw+wMYxquL4NefK5m0cQHCISG94tAJi44Zo64GViOIx8MrWbR1AsGw8dkeFRwrWIpo64jHJHBEJIBUiMjM8SpBk38GUSOocj09muC4SQCpEZNd4hALAhhcs4igzTCMzR0QCaI9jeed4dGDNwZMgyg6PWWZs+TkAEB4iMj3eiQZWIIJyUzCokXe0yQDvXIMgfpFgm7Ib71qTGgHpM9t+W7Fh6kI8+iP5OBKSneN9tN0U5b7Oy32z3ZmJiOyIgITRiEf/MY3MDNNIO9nwS3FnOls/22O0iMi2CMgYM31HSzwGh4jMDBFpLtP3X0FI9zWzjYaHiPwUAekj205fm4x4DB4RmRki0gxxDMZMpXps2GaDQ0QeR0DGlMk7Y+IxPERkZrguMlwm759sQVQGi4gkIGEY4jF8RGTmmEYGh2gMXvvHmG05N3GPSAIyhkzdUROP0SEiM0dE+sPU/VCctP4esE1nJ84RSUD6hOsfc0M8Ro+IzByntL0jGM3GdDJ7cY1IAhKRIx7NQUR6wzSyc0SjvZhOoisEZMyYtkMnHs1DRHrDNLIt0/YxyB0x2bU4TiHZEgB0QNh7F+dwaiw/duI/uI3vdXpxu5SNCaQPbNloTPuBJ1LMxiTSu7hMI03blyAacdnevYjTJJKARCSIR7jMxWsjiUakwynutuISkQQkgLSYQmbPhekM0QivXNjukRkCEqGzYfp49oCPcv4cmz48zYeVRI+IzI1tB1SiEX6wbbv3WxymkARkTJhyUDA5Hv2Ixs4+nytBieyYekA1Zd8AN5m63YfB9YgkIBFrfkdjpvdlW0wyhfSPCdeLEY0IW5xD0lUEZI5seQa2CUyaPoYZjp3dv00hSUT6L4yYJBZhkriFpMtTSAIyBjiAfCrqcGzPxpBEMFL9nHo5yPJzDpu4+EoF6bgakQQkQhH19NG0cGzv7AEfWRGRTCHDRRTCZXGbRrqG7xqcZ3o8Jp094CNr1goAfonDO9u4eLmbe18R0IqNQWb6mqOeJgNwExFpF7e+GhgpiuCwfZpn89oBIFtxmEa6goB0XBx/EF2JL5O/DqaQAILk6rHLpSmkO19JBFzaEIISdmiYHF3ZcO3rAYBMuRqRrqCA4AxXY8vUr4spJICguRiRrgyfeBkfwAK2vMwPAG+C+kXMpZfbcvHlflx4bUgCEk4wdUrnJyISsFuYU/tU92V7VMbpxcdtwHcCgQlrZxmHeEwy7WvlNDaQWsGgxg7/Rc2ktWTLpVPatp/KZgIJq5kWVADiy6Ywa71W2yaTTCLNwHfAYS79poZPEc2AOVyY6tn4NbhyfLN5CmnvyhF7cQ4pk752mw46gB9sDK5M2fR1uRKRtiIgEQhbdkAAkCmb4ipXtnytLkSkrVNIroGElaKYwF3W950T/79s72dCv//2eFY2EDwbIipIya/f5OskuSYyGgQkkELrWPTycRPCEkDu4h6O7ZkekrZHpI2vC0lAwjpBTR+7ikYvnyOskDRlClkwqNHYAwvgFfGYnsk/67ZHpG0ISMSeH+GY7nMykQTsYWI45voLcxC/YJo+jbSVbVNIAhJW8XP6GEQ4prsPQhIwl2nh6Od+rv3n8jMoTZxGMoUMD48yYimMeAzr/kx6SR/ANibF49kDPgr859nv+zDp8Uty4ZnZNmACidgJOx5b3y+TSMAMpoRPVL8AJu/Xj4mkiae0bZ1E2nQam4BErEQVj63vn4gEouVKPKban3ndv/j5RDzTTmnbGpG2ICBhjSB2tlEgIoHomBCP2ezLMt1/tf97mexr/J5GmhSRNrJlCklAIhZMicegmPJyPoCpXA/HTP59VzHp137EpIhkChkcAhLOy2UHXP/fLardfkiHm45KeVJhr27qP6xIRSd1z3lNTCGBcNgYj13tt44dS6hu5yEdqG3WkZaEuhXkqahPgfoPK1ZBYepgyuRVIYhIZIqABFppajiilhff1PJXmrXmrTzt29OU8u8NHz5cJ408qOuvaFbe5Mq0O+zOEJFA8GyLx87C8dy6DVr0u0Pa9PYFWrdunQ4cONDh7xQWFmrkZxIafV53fXlqL+056zzl5eV1uI+uIlLK/ZS2SRFpGxtOYxOQDivalR/7lzPIdPp47t4Nmv94gxYvPKSG+kSXf7+mpkaqkd78g3TyKa+o8trT9dkbTlef/j1yXTIAn7gSj5terdM7/2eT/vFPzUokJOnltJ+jpaVFf94g/XnDYf37gkadXfFfuv7GYhVdWalu3T/9RTesaaQpEckU0n88moi1Y0cT+vDfX9dVn6vVb+Y3ZhSP7e3772N66V+362dXv6bmpWuUSGT+OVy/NhOIigvxOL75bT1/x2t67Nvr9cqyZDx6s2njEVXP2q/Hr1+uM3a+ldH9+s2E7wX8R0DCWV3tGOt2H9Jvpi3Xg3MOqrk59/s7cCChWf+4X8/e+prGt/w5908IICtRB4vXF+tOta/quXKdvvhXe/WH36e+jMarv/z5iKZetVcv/Mu2Dr/kdrav9Ot1KqP+nkj2vcB4fZnZiWb26oD/4feL7X5Y06BHv75W69Yc9vXzStLLLzXrhq/WaWz92xn9faaQQHyl+vlv/P0afedb+/Tfdf4Gz5HD0n/OfU+/q35Hx47GMyLhHwISTupsZ7h3R6N+NW2d9n/kw9gxjXe3HNE3/1edxjdnFpEA/BF1pOQ6eWx5fo1+dMd+HQtwWLZq0Qd6+t53PF1u48pbpto2hTQZAZkD058hhY4ONx/V/57xlg7sbQn8vt5796hm/v0nOnYsiwuXAHhmezyWv7ted96+388lpbXyPz7Qfy3Y2eWaWvMjIqP+Hkl2RaTJp7HNXRmsZsKz7lLZ8tgb+vi98HZgr69q0Sf/d01o9wfEVdRhkmtcHWk5ph/evl9Hj/q0oAwsfWSXKmo3tLmNJ9UgUwSk41x52QIvLyWRbgdYtnW9Hn+swa8lZeyfHjiovTsPdfp3bL8O0tRfGBAPUQeJHy8SvvV/v653txzxa0kZOXTokO78/n5PZ0m4HhJJbtQFkIGHf3ow0OuK0jl0KKFNv34z/DsGEDg/gupgXYv+7V/D/+VWkta83qLi19vun2z/hTYTnMbOnZmr8ujQoUOaPXu2Ro4cqZ49e2rQoEG66aabtHv37qiXBkN89F6DVr4a/HWP6fz+2UO66HBwL+3D+2AjrmybZKWKs09+v16Ho9s96aknvT2GTCEhORCQTU1NuuyyyzRnzhzV19frK1/5ik4//XTNmzdPY8aM0XvvvRf1EmGA3Ys2dP2XAtTcLC36D3aWgEv8CKljRxP67W+i3Tcsf7lZe3fEb/9k0xTSRNYH5H333adVq1ZpwoQJ2rJli373u99p9erV+tnPfqba2lrddNNNUS8xtky6Lm6pTy/Gm4vf/r+8rv8SgIxFOcHKJh5TTR93vH1Au3eF+MyZFBIJqfmVtmdIwnhGtsQU0mZWB2RLS4t+8YtfSJJ++ctfqqSk5MTHbrvtNo0ePVqvvPKK1q5dG9gabHgpH1eeSJOt/R836+OPo/8+fbSlRUcPR78Ov5n0iwLiw5Xw2LnxQNRLkHT8vbPjyJYppInXQZq3Ig9ee+017d+/X8OHD9eYMWM6fPy6666TJD333HNhLw0GOa1mY9RLkHT8cosPa/y/UJ7rH4Fw+fmi2js3HvTtc+Uim4BkChlvVgfkW28df2P4ysrKlB9P3r5hQ7TXv8WZn9OpbENpy+ZwXxqjM/13bI56CYD1bAyOdKeEG2v2hryS1HbuOKrmxmhPpcMuBVEvIBc7duyQJJWXl6f8ePL27du3Z/T5KioqUt5eU1Oj/J6l3hdokKJd+daM6v321n+fIsmM3/Ib6hMqjXoRPuL0NeLG77f0a6g3Z7/c0nhEPYq6nfjzZX3f0bK9nwnlvgsGNUa2P2ksPxb7S72yYfUjVl9fL0kqKkq90RUXF0uSDh40Ix7iKurIqCz960jvv7UjaX7Bz3YnzelrwG5hvvNMV44e9f62q668Rza8s3oC6beNG1NfK1dRUaFtu+tCXg388lb901Ev4YSePd15JnbUvxggnmw8fd2ZHj3M2Sd079Gt678UoCinkDaoL8s36om7Vk8gk8+6bmxMvUNpaDj+hIXevXsHuw6DvqGdcWFEn83E7ZIz9gWwkuyUlfm3g2b6CIQriGnboPJooy2puCRPvU5ipoTMWV0UgwcPliTt2rUr5ceTtw8ZMiS0NSG1KH+rrBjVPbL7bu+DYedGvQRfMCVAFFybPkpSj7MGRr0ESVLFud2Vn2/ONDRscX2OQC6sDsjzzjtPkrRu3bqUH0/ePnr06NDWhOB1NXlrfz1hzaBRKuwR5IoyM2zYMBWf3DFms7n+kekj4IbB554U9RIkSeeONuMXbRd/SXCV1QE5ceJE9enTRzU1NVq/fn2Hjy9cuFCSdPXVV4e8MnNFeRo7qqlVt+75GltVGMl9t1ZZ9WHUS/AF00fEUVBPFhk6po8KDGi3Cydkv4/kiTTxZHVAFhYW6rvf/a4k6ZZbbjlxzaMkPfzww9qwYYMuueQSjR07NvC12HIdZNT8ig+vE7izrhvpy/3m4ms3RPO1AzBXycmFuuKLPSNdw8kDe6qhquObcQCdsTogJemuu+7ShRdeqBUrVmjEiBH6m7/5G40fP1633367+vXrp3/7t3+LeomIQPvTwqMu66f+/aPb3M8d1V27zjyvw+1eT19HHY9MHxEVl09tXn9jcaT3P+0b3ZXfreP1j2G9BqQpbLgO0qS3NDRnJVnq2bOn/vSnP6m6ulpFRUV65plntH37dk2bNk3r1q3TGWecEfUSjRP1s7GjmEJ2656vG2+Obid9098WKy/P7gvUiUcgGB+dfZ7OGxPNeeyS3nk65cvnR3Lf6bj8y4JLrA9ISerVq5fuvfdevfvuu2pubtaePXs0b968tO9Qg3ho/9vzwP91gc6uCP9lKi65rIfy/qrj223aNn0EEIy8vDzd/9NoroW8c/ZJ6n1q9NeIwz5OBKQpbLoOMq5TyC/dV6n8gvAmgb1752nOg31ynj5GHY9MH4FgvVt+nm79Xkmo9/mZSaeo6KrgnyMANxGQiEwYUdJ+ylf2md66ZtaIwO9XkvLzpQce6qN1vUd1ua7OEI+A/TL5mS+/sUoXXRzONLB0QA99bc7ZaX+5jdv1j/COgIyxqKeQkj9x4vV1IT97w+m64rvDcr7fzuTlSff9pI+Ofrbjb/fEI4BUuhXk6ys/n6DKqmDPZffuW6gZj49R6YBon/1tIhueSGOK6AvCMTadxnaJ19C64pYz9JUfnKkgntfSvbv00NxSFX3pgg4fsykeAVPE6UkVPYoL9G+/OUUXTw7m3Q9OPb2XZv5mrE47I9pnfnclTt9zWxGQMefKFFLqPLhShdul04fot4tP1bAz/Hsv2lHnddezS/uq2+dzmzyagOkj4K9M9wEvHztXU345UXfde5J69fLvt9zrv1GkOxaPU78hnf9s27avQjSirwdELs4Ruees8zVj0cX69neKVVSU/Y66qE+BvnTbcE37zSRtGZTb6z1u+vC0yKePxCMQrfz8PPX9apWee6GvzvnsqTl9rpFnFeiJ356icT+aoJ7F4b8SBdzElhSAkt3HjHqxT1sc+aDIl9MWmz48Le1bayVD7rK+75y4rbBnN1XcOl6zpx9R49I39e8LGvXuliMZ3deo87rr698sUv6lY1TYM/Uk07bT1sQjEJxlez/TZv/TlT/3Ha2/fUw6p3aD/s+CRi36j0Yd2J/o8t8VFEiXX9lTX/9msT4+5zzty/B6HaaPyBQBCUnHp5AmXDwcRkRKqXfiPUsK1PO6Kt1ybUL7P2rWzo0HtfPPB1S7vVGHm49Jecdj87QzinV6RW+dXtFbvfumv07Jxtd5JB4BM/2l32idd5t07sxj+ui9Ru3ceEC7Nh7Ugb0tOtJ8TN2656lX7wKVn9Nb5eecpLLPlKiwVzfVSsr03ArxaIf6snwjnm9BQMI4YUakpA4hmZeXp9IBPVU6oKdG/VW/rO6beASQjtcpZGvdCvI1aGSJBo0s0YVTfF4Y4AEBGRAbT2ObMoWUwotIKX1IZoNwBGCjXKaPJuzHED4CEm3ENSKltjvQTGPS9p0u8QhEI5cppN84dY1sEJABsnEKaRo/I1JSRiEpBbtDNSEcJeIRiJoJEUk8IlvUDTow4WV9WjvyQZGvL/MTVcCZ8PI8kr+PJxAGE7bXoH52oww44hG5MKsUYAzTIlLy9yASZsyZEo6SGQdiAG1FEXJ+3acp+zaEj1PYAbP5NLZJ10Mm+XVKO6n1zi/T09teP68JCEfAbH4+mS+T+wFyRUCiU6ZGpOT/e6W2j75Mg9K0WGyPeAT8kekT8nIRVEgSjvAbARkCm6eQJvN7Gtme6WHYFcIRsJdfIRmHJwQiGgQkumTiFDIpqGmkzQhHIDhhTCFbC/vlxUzBfsx8BGRIbJ9CmhyREiEpscOF24I+42ADk8KQ6SPsLRqEzsRnZrcXx5eoiePXDESJeAIIyFCZ8ObnubIhIiX3oyr59bn8NQIwEwENiYBEFmyJSMmtkCQaAXPENaLi+nWjI3tKwBEuTCEluyJSsje+bF03EATTfg6IqWCY9n02jSkdwZNokDXTn1iTTuudk2kX5bPjBGAqghmtEZARsP0Z2a3ZGpFJ7YMtzKAkFgH7hf2yPlEhHtEeAYmcJU9n2xySSV1FnZfAJBAB/5n4cj6uRyTxiFQIyIi4NIVMsn0amQmiEEAqrkdkWKLex9p2fX+UeKTgK374AMSVi5M6F78m+IOjfYRMeSaV34hIAEGKekrVGZeCy6WvBf7jSB8xlyOSkAQQR7aH16YPT4vkazD5FwN0xBEegSIiAQTB9NiwNSJtXTfCx9HdAK5OIZOYRgKIo6gmedmKcq0m/ELAccobHi1DuB6REj+cAPxlQnRkwvSItC1048ykVuBlfBAql14zEu7y85cdtvVgmfi6kKkkA82kl/oxJRpt+UUAbRGQBnHxtSHTISRhkiCn460/N9s7TAhJU8IRdiMgDROniJQISUQjqsspiMlg2DKFbC2KkDQxHE2ZPnKJlXcEJIxASCJIJh4ciElIHaPO76A0MRrhBgLSQHGbQrZGSMIvJkZjOmz3ubNxCplKquDLNCpti0VTpo/IDgFpqDhHpMQBFdmxKRpTicP7yQfJlYhsz7YwRDBMega2REDCcIQkumJ7NLbHNp8bVyPSNSZNH13bh4SFgDRY3KeQrXG9GJLisrMnJOEqk+IR2YvHnthipo2sTcA728RP8nsex+97HL/mXBEoQPCYQFqASWRqTCXdRjh9immkd5zKNpNpcc9+Jns8cpZgEtm5OE+oXML3sXM8Lt6YFitxx/cjeyY2ABNIOKf9QZapjbkIIu+YRnrDJNIMJsYj+5/c8OhZxMTfQGzAVMssfD/8weOXORPjJU54/N3EBNIyXA+ZG6aT4SN0gsPrRmaOSWQ0iEd3EZAWIiL9Q1D6j2AMF6e0M0dEhsvkeLRpP2Xq2UcC0lJEZDBS7VQ4MKdn007YdUwjM0NEhsPkeIQ/CEiLEZHhSBdJcTtYE4vmIyIzQ0QGy/R4ZF/mDwLSckRkdFwNS3audiMiM0NEBsP0eLSNqaevJQLSCUSkWTIJsKgP8ESi27guMjNEpL9siEf2ff4hIB1BRNqFnRjCwDSya8noISRzY0M8wl8cxRxi8qgbQDT4ZSUzBFD2bHnsbPtZMP2YbtejiS6ZvsEBCJ9tB86oHPmgyJoYMgGPV7yxV3EQEQmgPd79J3NEUddse4zY9v3HI+ooIhJAKhxIM8N0LTUbHxcbt3kbjuH2ParImA0bIIDw2XhAjYqNwRQUHge0xl7EcUQkgFSISG/iHJI2f+1s58HhZXxiIBmRvMwPgNZ4vUjv4vSyP7ZGY5Kt8WjL4MfORxdZsWWjBBAuWw+0UbJ5KtcVl782+Ie9RswQkQBSISKz40psJb8OF74Wie05DJzCjiHetQZAKrxzTfZah5ctp7ddicX2bI5Hm4Y8BGRMEZEAUuG6yNy1DzOTgtLVaET4CMgY48k1ANJhGumfKIMybsHI9DE8BCSYRgJIiYgMRrqoyyUs4xaKqdgcjzYiICGJiASQGhEZHiIwe7bHo23TR4lnYaOVkt3HrNyIAQSL99EG0B57BHRARAJIhYiEidguo8GjjpSYRgJIhYM1TOLC9mjrsdb+Rx6BsnXDBhAcTmnDBGyD0eLRR5eYRgJIhQM4ouLKtmfzsdWN7wBCYfOGDiAYTCMRNrY3M/BdgCdMIwGkwkEdYXBpO7P9WOrOdwKhIiQBtOfSwR3mcWn7cuH46c53A5Fw4YcAgH84pY0gsE2Zx9rvyMsvv6y8vLy0/40fPz7qJcYG00gA7XHAh19c25ZcOV5a/1aGw4cP16RJk1LejnAlfyh4S0QA0qcHft4KEdlyLR5dYn1ATpo0SfPnz496GWiFkATQGu+njWy4GI+uTB8li09hw3yc2gaQxLWR8IJtxXx8hxA4QhJAEmGAzrj8i4Zrx0HrT2Fv3bpVd955p+rq6tS3b19NmjRJV1xxhfLz3dwAbcapbQAS10YiNVfDUXIvHiUHAnLFihVasWJFm9tGjRqlRYsWacSIEZ4+V0VFRcrba2pqlN+zNNsloh1CEoBESOJTLsejq6z9jvXp00d33HGHVq1apbq6OtXV1emll17S+PHj9fbbb+vyyy/X/v37o14mOsGpbQAS8RBnLp+yTnL1OJeXSCQSUdzxlClTtGnTJk//5sknn9S4ceM6/TtHjx7VpZdequXLl+uBBx7QnXfemcsyJR2fTG7bXafRV92R8+dCekwkATCNjA/Xw1EKLx43LPknDSs7VRs3bgzl/qQIT2Fv27ZNmzdv9vRvGhsbu/w73bp106xZs7R8+XI9//zzvgQkwsGpbQCc1o6HOMSj6yILyPXr1wf2uZPXPu7Zsyew+0BwWv/GRkwC8URIuilO4ejqqesk659Ek8q+ffskScXFxRGvBLliKgnEGyHphjiFo+R+PEqOBuSiRYskSZWVlRGvBH5hKgnEGyFpr7jFY1xY+1195JFHtHPnzja3JRIJPfbYY/r5z3+uvLw8zZgxI6LVIUg8exuIrzg8a9cVcf1exeX4ZO0E8pFHHtH3v/99VVZWatiwYWpqatLbb7+tbdu2KT8/X48++qjGjh0b9TIRIKaSQHwxkTRXHKMxKS7xKFkckLfffrteeOEFbdy4UX/5y190+PBhDRw4UDfccINmzpypqqqqqJeIEBGTQDwRkuaIczjGkbUBeeutt+rWW28N7f7yW9g52YKYBOKndbwQk+EiHI+L0/RRsjgggUwQk0D8MJUMB+H4qbjFo0RAetJ72yEdHNYr6mUgS8QkEC9MJYNBOLYVx3iUCEjPiEg3EJNAvDCVzA3RmFpc41EiILNCRLqFmATio30IEZTpEY3oDAGZJSLSTe1/myQoAbdxmrstojFzcZ4+SgRkTohI9zGdBOIjrtNJotG7uMejREDmjIiMD6aTQLy4GpQEY26Ix+MISB8QkfFEUALxkiq8TI9KYtFfxOOnCEifEJEgKIH46SzQwopLIjEcxGNbBKSPiEi0lmpnQ1QC8UHYuYN47IiA9BkRic4QlQBgF+IxNQIyAEQkvCAqAcBMxGN6BGRAiEjkgqgEgGgRj50jIANERMJPne3MiEsA8A/x2DUCMmBEJMKQbmdHWAKAN8RjZgjIEBCRiEpXO0ICEwA+RTxmjoAMCREJE3FaHACOIx69ISBDRETCJpnsTIlMAC4gHr0jIENGRMIlnCIHYDviMTsEZAR6bzskSYQknEdgAjAZ8Zg9AjJCTCMRdwQmgKgQj7khICNGRALp8SQfAEEgHnNHQBqAiAS8Iy4BeEU4+oeANAQRCfiHF1YH0B7x6C8C0iBEJBAswhKIJ+LRfwSkYXiGNhA+whJwF/EYDALSUEwjgei1P/AQlIA9CMdgEZAGIyIBsxCUgB2Ix+ARkIYjIgFzpTpIEZVAtIjHcBCQFuC6SMAeTCmBaBCO4SIgLcI0ErAPQQkEj3gMHwFpGSISsFvrAx0xCeSGcIwOAWkhTmkDbmA6CWSPeIwWAWkxppGAW5hOAl0jHM1AQFqOaSTgJqaTQFuEo1nYIzkiGZIA3FSy+9iJ/4C4Ybs3DxNIh3BKG4gHTnUjLghHcxGQjuGUNhAvnOqGiwhH8xGQjmIaCcQT00nYjHC0BwHpMKaRQLwRk7AF4WgfAjIGmEYCICZhIsLRXgRkTDCNBJDEdZOIGuFoPwIyZghJAO0xnURYCEd3EJAxxWltAKkQkwgC4egeAjLGmEYC6AynupELotFtBCSYRgLICNNJZIJwDF9+S/iPOQEJSUwjAXjDdBKtEY3RieqtjAlItEFIAsgGQRk/RGP0oopHiYBEGpzWBpALgtJNRCOSCEikxTQSgF8ISnsRjWaKcvooEZDIACEJwG8EpdmIRrNFHY8SAQkPCEkAQUkVLERleAhGe5gQjxIBiSwQkgDCQFQGh2C0kynxKBGQyAFPtAEQNqLSO2LRDSbFo0RAIkdMIwFErbNAilNcEoruMi0eJQISPiEkAZioq6iyLTCJxPgxMR4lAhI+IyQB2CSbIPMzOglCdMbUeJQISASEkATgKqIPYTA5HiXJrtk9rNN72yHjfwgAADCJDcdNAhKhICQBAOiaLcdKAhKhIiQBAEjNpuMj10AiElwjCQDAcTaFYxIBiUi1/qEhJgEAcWNjPEqcwoZBOL0NAIgTm495BCSMQ0gCAFxn+3GOgISxCEkAgItcOLZxDSSMx3WSAABXuBCPEhNIWIapJADAVi4dv5hAwkpMJQEAtnApHJOYQMJ6TCUBAKZy9fjEBBLOYCoJADCJq/EoMYGEo5hKAgCi5PoxiAkknMZUEgAQJtfDMYkJJGKDqSQAIEhxOsYwgUTsMJUEAPgtTvEoGTKBbGho0IIFC3TrrbfqwgsvVI8ePZSXl6d77rmny3+7a9cuTZ8+XYMGDVLPnj01cuRI3X333Wpqagp+4bBecioZtx98AIA/4noMMWICuXXrVt14442e/927776rCRMmaO/evTr33HN18cUXa82aNbr33nv10ksv6aWXXlKPHj0CWDFcxGQSAOBFHMMxyYgJZO/evXXzzTfrX/7lX7R27Vrde++9Gf27adOmae/evZo5c6befvtt/e53v9PmzZs1ZcoUvfbaa/rxj38c8MrhKiaTAIDOxP34YERADh8+XL/+9a/1d3/3d6qsrFT37t27/Devv/66XnvtNfXv318//elPT9xeUFCgf/7nf1b37t316KOP6siRI0EuHTFATAIAkjgeHGdEQGZjyZIlkqSrr766w2nq0047TRdffLH27dunV199NYrlwVHEJADEF/v+T1kbkG+99ZYkqbKyMuXHk7dv2LAhtDUhXohJAIgH9vUdGfEkmmzs2LFDklReXp7y48nbt2/fnvHnrKioSHl7TU2NCvJP8rhCxEn7HQtPwgEANxCOqVkbkPX19ZKkoqKilB8vLi6WJB08eDC0NQFJPKMbAOxGOHbOl4CcMmWKNm3a5OnfPPnkkxo3bpwfd++bjRs3pry9oqJC27fVhrwauIKYBAC7EI9d8yUgt23bps2bN3v6N42NjTndZ0lJSaefp6GhQdLxlwgCTMGpbgAwF+GYOV8Ccv369X58Gk8GDx6sN998U7t27Ur58eTtQ4YMCXNZgCcEJQBEj3D0ztpnYZ933nmSpHXr1qX8ePL20aNHh7YmIFc8sxsAwsX+NjvWBuRVV10lSXruuefU3Nzc5mMfffSRli9frpNPPlkTJ06MYnlAzlrHJDs4APAX+9bcWBuQ48aN08SJE/Xxxx9r1qxZJ24/cuSIvvOd7+jw4cOaOXNmRu9qA9iAoASA3LEP9UdeIpFIRL0I6fgzuffs2SNJ+uCDD7Rz506VlZWdeD3HgQMHavHixW3+zdatWzVhwgTV1dVp1KhROuecc/TGG2/ovffe00UXXaRly5Z1eJeabCSfhT3h/Jk5fy4gKFw/CQCdczUcV65/VEOG9Uv7ajJBMOZ1IN98880OL/q9e/du7d69W1LqJ8OMGDFCb775pmbPnq2lS5dq8eLFGjx4sKqrq/WjH/3Il3gEbMETcgAgNVfDMUrGBOT777+f1b87/fTTNW/ePH8XAziAoAQQd4RjcIwJSADBIigBxAXhGDwCEoipVDtYohKAzQjH8BCQAE5gSgnARoRj+AhIAGkxpQRgMsIxOgQkAE+YUgKIGuEYPQISQE6YUgIIC+FoDgISgO+ISgB+IhzNQ0ACCAWnvgF4QTSajYAEEAmmlABSIRztQEACMAZRCcQX4WgXAhKA0YhKwF1Eo70IyAzltRyJegkA/gdRCdiNcLQfAelBQc1uSdKR4WURrwRAe0QlYDai0S0EZBYKanYTkYAF0h2wCEsgHESjuwjILBGRgL2YVgLBIRrjgYDMAae0AXcQlUD2iMb4ISB9wDQScBOnwIH0iMZ4IyB9QkQC8cG0EnFFNCKJgPQRp7SB+GJaCVcRjUiFgAwA00gASYQlbEMwIhMEZECYRgLoDGEJUxCMyAYBGTCmkQC86OxgTlzCDwQj/EBAhoCIBOAHppbwilhEUAjIkHBKG0BQmFpCIhYRLgIyZEwjAYSpq6ggMO1ELCJqBGQEmEYCMAWBaS4iESYjICPENBKA6TKJGCIze0QibEVARoxpJADbeY2gOAQnYQjXEZCGYBoJIC6CiKtco5TgA7whIA3CNBIAskMAAuHKj3oB6CgZkgAAACYiIA1VULObkAQAAEYiIA1HSAIAANMQkJYgIgEAgCkISIswjQQAACYgIC1ERAIAgCgRkJZiGgkAAKJCQFqOkAQAAGEjIB1BRAIAgLAQkA5hGgkAAMJAQDqIkAQAAEEiIB1GSAIAgCAQkDFARAIAAD8RkDHBNBIAAPiFgIwZQhIAAOSKgIwpQhIAAGSLgIw5QhIAAHhFQEISIQkAADJHQKINIhIAAHSFgEQHTCMBALBDQc1u5bUcCf1+CUikRUgCAGCuKI/RBCS6REgCAGCWqI/LBZHeO6yS3FiPDC+LeCUAAMRT1OGYxAQSnjGRBAAgfCYde5lAImtMJAEACJ5J4ZjEBBI5YyIJAEAwTD2+MoGEb5hIAgDgD1PDMYmAhO9ab/TEJAAA3pgejxIBiYAxlQQAIDM2hGMS10AiFFwnCQBAerYdI5lAIlRMJAEA+JRt4ZhEQCIShCQAIM5sDcckTmEjUpzaBgDEjQvHPSaQMALP3AYAuM6FcEwiIGEcTm8DAFziUjgmcQobxuL0NgDAdq4ex5hAwnic3gYA2MbVcEwiIGEVTm8DAEzmejgmEZCwElNJAIBJ4hKOSQQkrMdUEgAQlbiFYxIBCWcwlQQAhCmu8SgRkHAUU0kAQFDiHI5JBCScxlQSAOAXwvFTBCRig5gEAGSDcOyIgEQscYobANAVwjE9I96JpqGhQQsWLNCtt96qCy+8UD169FBeXp7uueeeTv9dXl5ep/81NTWF8wXAWsl3u2EnAQBI4rjQNSMmkFu3btWNN96Y1b8tLi7Wddddl/Jj3bp1y2VZiBlOcQNAvBGNmTMiIHv37q2bb75ZVVVVqqqq0pIlSzR79uyM/m3fvn01f/78YBeI2CEmASA+CEfvjAjI4cOH69e//vWJP7/wwgsRrgZoi+slAcBNhGP2jAhIwAZMJQHAfkSjP6wPyIaGBt1///3asWOHioqKNGbMGE2dOlUlJSVRLw0OIyYBwC6Eo7+sD8i9e/fqrrvuanPbbbfdpieeeEJXXXWVp89VUVGR8vZ33nlHOia9Wve7rNcJh9V9+r+JQut/pADAKXktR6JeQuAaj+7Xjh2HQ71Pq492N954o66//nqNGjVKffr00datW/Xwww9rwYIFmjp1ql599VVVVVXlfD/Hjh1Tfn6+Bp810IdVoys1NTWSjl8bi+DxeIePxzxcPN7h4zEP1zvv7NehQ4dCvU9fAnLKlCnatGmTp3/z5JNPaty4cTnd7xNPPNHmz+eff76efPJJnX766XrggQd011136fnnn8/4823cuDHl7cnJZLqPw1883uHi8Q4fj3m4eLzDx2MernRnUIPkS0Bu27ZNmzdv9vRvGhsb/bjrlH7wgx/oJz/5iV5++WW1tLSosLAwsPsCAACIG18Ccv369X58Gt/06dNH/fv31549e1RXV6eBAzn1DAAA4Bcj3srQb8eOHdOBAwckHX+nGgAAAPjHyYBcunSpGhoaNHz4cJ100klRLwcAAMAp1gbkb3/7W73xxhsdbn/llVf07W9/W5J0yy23hL0sAAAA5+UlEolE1IuQjj+Te8+ePZKkDz74QDt37lRZWZnKy8slSQMHDtTixYtP/P1p06bpiSee0MiRI1VRUaHu3btry5YtJ67H/NrXvqannnpK+fnWNjIAAICRjAnIoUOHavv27Wk/PmTIEL3//vsn/vyHP/xBTz31lNauXasPP/xQ9fX1OuWUUzR27FjddNNNuu6660JYNQAAQPwYE5AAAACwA+d3AQAA4AkBCQAAAE8ISAAAAHhCQAIAAMATAhIAAACeEJAAAADwhIBMo6GhQQsWLNCtt96qCy+8UD169FBeXp7uueeeTv9dXl5ep/81NTWF8wVYJtvHW5J27dql6dOna9CgQerZs6dGjhypu+++m8c6Sy+//HKn2/D48eOjXqK1Dh06pNmzZ2vkyJHq2bOnBg0apJtuukm7d++OemnOmTx5cqfb8dKlS6NeopXWrl2rBx98UFOnTlV5efmJx7Mr8+fP17hx41RSUqJTTjlFX/ziF7VixYoQVmw3r4/3Pffc0+l2/8Mf/tC3tRX49pkcs3XrVt14441Z/dvi4uK0L2TerVu3XJblrGwf73fffVcTJkzQ3r17de655+riiy/WmjVrdO+99+qll17SSy+9pB49egSwYvcNHz5ckyZNSnk7vGtqatJll12mVatWaeDAgfrKV76i999/X/PmzdPvf/97rVq1SmeccUbUy3TOtddeq5KSkg63l5WVRbAa+82ZM0fPPvusp3/zve99T3PnzlWvXr10+eWXq6mpSS+++KJeeOEFLVy4UNdcc00wi3VANo+3JE2cOFFnnnlmh9vHjh3rx7IkEZBp9e7dWzfffLOqqqpUVVWlJUuWaPbs2Rn92759+2r+/PnBLtAx2T7e06ZN0969ezVz5kzNnTtXknTkyBH99V//tRYvXqwf//jHGU0x0dGkSZPYjn103333adWqVZowYYJeeOGFE1Hz8MMP6/bbb9dNN92kl19+OdpFOuihhx7S0KFDo16GMyZMmKDRo0ef2FcPHTpUzc3Naf/+H//4R82dO1ennnqqVq5cqREjRkiSVq5cqcmTJ2v69OmaPHmySktLQ/oK7OL18U761re+pWnTpgW7uAQy8uMf/zghKXH33Xd3+vckJYYMGRLKmlyWyeO9evXqhKRE//79E01NTW0+9uGHHya6d++eOPnkkxOHDx8OeLVu+dOf/pSQlPjmN78Z9VKc0dzcnOjTp09CUmLdunUdPj569OiEpMSaNWsiWJ2bLrnkkoSkxLZt26JeitN69OiR6CwlrrzyyoSkxM9//vMOH5s5c2ZCUuKhhx4KcIVu6erxvvvuuxOSEvPmzQt8LVwDCWstWbJEknT11Vd3OE192mmn6eKLL9a+ffv06quvRrE84ITXXntN+/fv1/DhwzVmzJgOH09e8vLcc8+FvTQgMIcOHdKyZcskKeVlXWz3duMUdgAaGhp0//33a8eOHSoqKtKYMWM0derUlNfhIHtvvfWWJKmysjLlxysrK7Vs2TJt2LBBkydPDnFlbti6davuvPNO1dXVqW/fvpo0aZKuuOIK5efze6dXmWyrkrRhw4bQ1hQXjz/+uOrq6pSfn6+RI0fqmmuu0eDBg6NeVixs3rxZzc3N6tevn8rLyzt8nO0+OMuWLdP69evV1NSk8vJyXXnllb5e/ygRkIHYu3ev7rrrrja33XbbbXriiSd01VVXRbQq9+zYsUOSUu6YWt++ffv20NbkkhUrVnR4luSoUaO0aNGiE9cxITNsq9G577772vz5+9//vqqrq1VdXR3RiuKjq+2+uLhYpaWl2rdvnw4ePKjevXuHuTynLViwoM2fq6urde2112r+/Pm+DbMYJfjsxhtv1NKlS7V7927V19frzTff1De+8Q3V1dVp6tSpeuONN6JeojPq6+slSUVFRSk/XlxcLEk6ePBgaGtyQZ8+fXTHHXdo1apVqqurU11dnV566SWNHz9eb7/9ti6//HLt378/6mVahW01fJ/97Ge1YMEC1dTUqLGxUZs3b9b999+vgoICzZ49+8ST7hCcrrZ7iW3fb2eeeaYeeughbdy4UfX19dq5c6eeeuoplZWVadGiRfrGN77h2305O4GcMmWKNm3a5OnfPPnkkxo3blxO9/vEE0+0+fP555+vJ598UqeffroeeOAB3XXXXXr++edzug8TRfV4o6NcvxdjxozpcJ3eZZddpldffVWXXnqpli9frl/96le68847fVsz4Ld77723zZ9HjhypH/3oR7rgggv0hS98Qffcc4/+9m//Vr169YpohYD/brjhhjZ/Li4u1vXXX69LL71Uo0aN0jPPPKNVq1b58nq+zgbktm3btHnzZk//prGxMaDVSD/4wQ/0k5/8RC+//LJaWlpUWFgY2H1FIYrHOzmGT/d5GhoaJCl2p0WC+l5069ZNs2bN0vLly/X8888TkB6wrZrj8ssv1wUXXKA1a9Zo9erVXB8doK62e4ltPywDBw7U9OnT9dBDD2np0qUEZGfWr18f9RLa6NOnj/r37689e/aorq5OAwcOjHpJvori8R48eLDefPNN7dq1K+XHk7cPGTIkzGVFLsjvRfLaxz179gR2Hy5KPmmDbdUMI0aM0Jo1a9iOA9bVdt/Q0KBPPvlEJ598MgEZAr/331wDGZJjx47pwIEDkj695gO5Oe+88yRJ69atS/nx5O2jR48ObU2u27dvnyS2Ya/YVs3CdhyOs846Sz169FBtbW3Kt+tkuw+X39s9ARmSpUuXqqGhQcOHD9dJJ50U9XKckHxG+3PPPdfhlfk/+ugjLV++XCeffLImTpwYxfKctGjRIknpX44GqU2cOFF9+vRRTU1NygnxwoULJR1/TVMEq7a2VsuXL5fEdhy0Xr166bLLLpMkPf300x0+znYfnkQiocWLF0vyb7snIH3029/+NuWzrF955RV9+9vfliTdcsstYS/LWePGjdPEiRP18ccfa9asWSduP3LkiL7zne/o8OHDmjlzprp37x7hKu3zyCOPaOfOnW1uSyQSeuyxx/Tzn/9ceXl5mjFjRkSrs1NhYaG++93vSjq+D0he9yUdfyvDDRs26JJLLvH9ddriasWKFXrmmWd09OjRNre///77mjJlihoaGvTlL3857cvLwD+33XabpOMvp7R169YTt69cuVKPPfaYSktLdfPNN0e1PKfU1tbql7/8ZYdntNfX12vGjBlavXq1BgwYoKlTp/pyf3mJRCLhy2dy0JQpU05cK/DBBx9o586dKisrO7HTGThw4Imil46/L/MTTzyhkSNHqqKiQt27d9eWLVtOTBy+9rWv6amnnuKFmNPw+nhLx1/sesKECaqrq9OoUaN0zjnn6I033tB7772niy66SMuWLevwLjXo3NChQ7Vr1y5VVlZq2LBhampq0ttvv61t27YpPz9fc+fOPRFDyFxTU5MmT56s1atXa+DAgbr44ou1fft2rV69Wv369dOqVat0xhlnRL1MJ8yfP1/Tp0/XgAEDVFlZqdLSUm3fvl1r165VU1OTKioqtGzZMvXv3z/qpVpnyZIlmjNnzok/v/7660okErrwwgtP3FZdXd3mNY+/973vae7cuSoqKtLnP/95tbS06MUXX1QikdDChQt1zTXXhPklWMXL4/3+++9r2LBhKikpUVVVlQYOHKja2lqtW7dOdXV1Ki0t1e9//3v/zsoF/maJFhsyZEhCUtr/2r/n9X/+538mvv71ryc+85nPJEpLSxMFBQWJ/v37J6688srE008/Hc0XYRGvj3fSjh07EtOmTUsMGDAgUVhYmDjzzDMT1dXViUOHDoX7BTji0UcfTXzpS19KDBs2LFFcXJwoLCxMDBkyJHHDDTckXn/99aiXZ7XGxsZEdXV1Yvjw4YnCwsLEgAEDEtOmTUvs3Lkz6qU55S9/+UtixowZicrKykS/fv0SBQUFiT59+iTGjx+f+NnPfpZobGyMeonWmjdvXqf7aaV5H+Z58+Ylxo4dmygqKkqUlpYmrrjiisRrr70W/hdgGS+P94EDBxKzZs1KXHLJJYmysrJEjx49EkVFRYmKiorE7bffnti1a5eva2MCCQAAAE84lwoAAABPCEgAAAB4QkACAADAEwISAAAAnhCQAAAA8ISABAAAgCcEJAAAADwhIAEAAOAJAQkAAABPCEgAAAB4QkACAADAEwISAAAAnhCQAAAA8ISABAAAgCcEJAAAADwhIAEAAOAJAQkAAABP/j+/sr3Dwge5LAAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Plot lapse\n", "plt.contourf(x, y, np.log(1 - lapse))\n", "\n", "# Plot circles for black holes\n", "ax = plt.gca()\n", "for bh_pos in [-8, 8]:\n", " ax.add_patch(\n", " plt.Circle(xy=(bh_pos, 0), radius=0.89, color=\"black\", fill=True)\n", " )\n", "\n", "# Make plot square\n", "ax.set_aspect(\"equal\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plot individual elements\n", "\n", "You can also iterate over elements in your volume data to plot things like\n", "element boundaries, collocation points, etc. Use `iter_elements`:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkgAAAJICAYAAACaHhuvAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAABcSAAAXEgFnn9JSAABqgElEQVR4nO3deXhM1/8H8PdkXyQRiS22ECQiliwiiT32rZZaQu1atKXVlha1JlpVVFstpahd7bXvWyIJIgmCSEiEIEGCIPsyvz/y6/3O3KDCTO4s79fzeJ5z7r2Z+Wglec89554jk8vlchARERGRwEDqAoiIiIg0DQMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxIRERGRCAMSERERkQgDEhEREZEIAxKpVVhYGAoLC6Uug4iIqFSMpC6AdNd3332H6dOnw8jICI6OjrC2thbCkkwmg6GhIYyNjWFiYgJTU1OYm5vDwsIC5cqVg5WVFWxsbGBjYwNbW1vY2trCzs4O9vb2sLe3h62tLQwMmO+JiEg9ZHK5XC51EaSb7O3tkZ6erpbXNjIyQsWKFVG1alVUrVoVDg4OqFatGqpXr44aNWqgRo0aqFmzJiwtLdXy/kREpNt4B4nUYvfu3WoLRwBQUFCAlJQUpKSkvPY6Ozs7ODo6onbt2qhduzbq1KkDJycn1K1bFzVr1oShoaHaaiQiIu3FO0ikcunp6XBzc0NqaioAwMTEBHl5eUrXGBgYoGXLlujTpw9sbW2Rk5ODrKwsZGVl4cWLF3jx4gUyMjLw9OlTPHnyBI8fP0Z6ejrS0tJUNqfJ2NgYderUQf369eHs7AxnZ2e4uLjAxcUF9vb2KnkPIiLSTgxIpHJDhw7Fhg0bAACmpqaIiopCXFwcZsyYgatXrypda2RkhFGjRmH69OmoUaPGf752UVERnj59iocPH+LBgwfCXaT79+/j3r17uHv3LpKTk3H37l0UFBS89d/B3t4eDRo0gKurKxo2bAg3Nze4ubmhYsWKb/2aRESkPRiQSKX279+PHj16CP0FCxZg0qRJAIDCwkJs3boVs2fPRnx8vNLXmZiYYOzYsZg6dSqqVq36znUUFhYiJSUFd+7cQVJSEhITE3Hr1i3cvHkTCQkJuHfv3lu9bqVKldC4cWOlP66urjA1NX3nmomISHMwIJHKZGRkoGHDhkL4aN68OUJDQ0vM8ykoKMCGDRsQGBiIW7duKZ0zNzfHp59+iq+//lqtd2uys7ORkJCAGzduID4+HnFxcYiLi0NsbCyePHlSqtcyMjKCq6srmjZtCnd3d3h4eKBp06awtrZWU/VERKRuDEikMh9//DH++OMPAMV3hKKiotCwYcNXXp+Xl4e//voLc+fOxd27d5XOlStXDp9//jm++uor2NraqrVuRXK5HA8fPkRsbCyuXbuGq1ev4urVq7hy5UqpJ53XrVsXnp6e8PLygpeXFzw8PBiaiIi0BAMSqcSZM2fQqlUroR8YGIgZM2a80dfm5ORgxYoV+P777/HgwQOlczY2Nvjqq6/w+eefSxou5HI5Hjx4gJiYGMTExODy5cu4dOkSrl27VmIC+qvIZDLUr18fzZo1g7e3N5o3b44mTZpweI6ISAMxINE7y8vLQ9OmTREbGwsAcHNzQ2RkJExMTEr1OpmZmVi6dCnmz59f4m6NnZ0dvvnmG3z66aewsLBQWe3vKj8/H9evX8fFixcRHR0t/MnIyHijrzcxMYG7uzuaN28OHx8f+Pj4wNHRETKZTM2VExHR6zAg0Tv7d8VsoPguSWhoKHx9fd/69Z4/f46ff/4ZixYtKhE0KleujKlTp2Ls2LEwMzN7p7rVpaioCImJiYiKisKFCxcQGRmJyMjINw5NlSpVgp+fH3x9feHn5wcvLy+N/bsSEekqBiR6J4mJiWjYsCFycnIAAJ988gl+//13lbz2kydP8NNPP+Hnn3/GixcvlM5Vq1YN06dPx6hRo0p9p0oKRUVFSEhIQEREBM6fP4+IiAhERUUJ/91ex8TEBJ6enmjRogVatmyJFi1acJ0mIiI1Y0CityaXy9G9e3ccPHgQQPHdnevXr6N8+fIqfZ+0tDTMnz8fv//+O7Kzs5XOOTo6YtasWRgyZAiMjLRrYfj8/HxcvnwZ586dw9mzZ3H27FncuHHjjb7WxcUFLVu2RKtWrdC6dWs4Ojqqt1giIj3DgERv7Z9//kGfPn2E/qZNmzBo0CC1vV9qairmzZuHP/74o8TE6Pr162P27NkYOHCgVm9im5aWhrNnzyIsLAxhYWE4f/58iVD4MjVr1kTr1q3RunVrtGnTBvXq1eM8JiKid8CARG8lKysLrq6uuH37NgCgffv2OHr0aJn8Uk5OTsZ3332HVatWlVgt283NDXPmzEGfPn10IiDk5+fj4sWLCA0NRWhoKM6cOSNs4fI6VapUQdu2bdG2bVu0a9eOgYmIqJQYkOitzJw5E0FBQQCKF0q8fPkyGjRoUKY1JCYmIjAwEOvXr0dRUZHSOQ8PDwQGBqJbt246FQzkcjkSEhJw5swZhISEIDg4GDdv3vzPr3NwcEDbtm3h7+8Pf39/1K5duwyqJSLSXgxIVGpJSUlwcXFBbm4uAGDy5Mn48ccfJasnLi4Os2fPxpYtWyD+5+zj44OgoCC0b99ep4KSopSUFAQHByM4OBinT58usd/dyzg6OsLf3x/t27eHv78/qlSpUgaVEhFpDwYkKrX+/ftj+/btAICqVasiLi4OVlZWElcFxMTEYNasWdi1a1eJc23atEFQUJDSYpa6Ki0tDcHBwTh58iROnTqFK1eu/OfXuLm5oUOHDujQoQNat26tEf8/iYikxIBEpXLq1Cm0a9dO6K9btw5Dhw6VsKKSIiMjMXPmTBw4cKDEuU6dOiEoKAje3t4SVCaNhw8f4vTp0zh58iROnDiBuLi4115vZGQEX19fdOzYEZ06dYKXl1eJ/fSIiHQdAxK9scLCQnh5eeHixYsAAG9vb4SHh2vsU2NhYWGYMWMGTpw4UeJcz549ERgYiKZNm5Z9YRK7f/8+Tp48iWPHjuH48eNITk5+7fW2trZo3749OnXqhE6dOqFWrVplVCkRkXQYkOiNrVmzBiNHjhT64eHh8PHxkbCiN3Py5ElMnz4dYWFhJc71798fs2fPhqurqwSVSU8ul+PmzZs4fvw4jh49ihMnTuDp06ev/RoXFxd07twZXbp0QZs2bWBubl42xRIRlSEGJHojWVlZqFevHu7fvw8ACAgIwObNmyWu6s3J5XIcPnwYM2bMwIULF5TOyWQyDB48GLNmzUK9evUkqlAzFBYWIjIyEkeOHMHRo0cRFhZWYikFRWZmZmjTpg26dOmCrl27on79+jo7GZ6I9AsDEr0Rxf3WTE1Ncf36da1cvVkul2PPnj2YOXMmLl++rHTO0NAQw4cPx8yZMzmM9P+eP3+OU6dO4ejRozh8+DDi4+Nfe33t2rXRrVs3dOvWDW3bttWojYWJiEqDAYn+06NHj+Dk5ITnz58DAL7++mvMnz9f4qreTVFREbZv345Zs2bh+vXrSueMjY3x0Ucf4dtvv4WDg4NEFWqmW7du4fDhwzh48CBOnDhRYo88RWZmZmjXrh26d++Obt26ce0lItIqDEj0nyZOnIhffvkFAFChQgUkJCSofL81qRQWFmLjxo2YM2cOEhMTlc6ZmZnh448/xpQpU1CpUiWJKtRceXl5CAsLw6FDh3Dw4MESd+TEXF1d0aNHD/To0QO+vr5at3ceEekXBiR6rdu3b6NevXrIz88HACxatAhffvmlxFWpXn5+PtauXYvAwMAST3VZWlpiwoQJmDx5MipUqCBRhZrv3r17OHToEA4cOICjR48KdxxfxtbWFl27dkXPnj3RpUsXnQncRKQ7GJDotUaOHIk1a9YAAGrUqIH4+HiYmZlJW5Qa5ebm4s8//8R3331XYs8za2trfPHFF/jiiy9gY2MjUYXaIS8vD2fOnMH+/ftx4MCBEsOYioyMjNCqVSu89957eO+991CnTp0yrJSI6OUYkOiVYmNj4ebmJuxztmrVKowaNUriqspGVlYWli1bhh9++AFpaWlK52xtbfH1119jwoQJsLS0lKhC7ZKQkID9+/dj3759OHXqlHBH8mUaNmwohCVvb2+NXWeLiHQbAxK9UkBAALZs2QIAqF+/Pq5evap380aeP3+OJUuWYMGCBSXWB6pYsSKmTp2KcePGcS2gUnj+/DmOHDmCffv2Yf/+/Xj06NErr61SpQp69uyJ3r17w9/fX6fvXhKRZmFAopeKiYlBkyZNhM1fN2/ejICAAImrks7Tp0+xePFiLF68uMTcGgcHB3z77bcYPXo0TE1NJapQOxUWFuL8+fPYs2cP9uzZg2vXrr3y2nLlyqFr167o3bs3unfvzmFOIlIrBiR6qX79+mHHjh0Aioc8Ll++zKEOAOnp6ViwYAGWLFmCrKwspXO1atXCjBkzMGzYMBgbG0tUoXZLSEjAnj17sHv3bpw5cwaFhYUvvc7Y2Bj+/v7o06cPevXqhSpVqpRxpUSk6xiQqISYmBg0btxY6G/btg39+vWTsCLN8+DBA/zwww9YtmwZcnNzlc7VrVsXs2fPRkBAADd5fQfp6enYv38/du/ejUOHDpUIpP+SyWTw8/ND37590adPH663REQqwYBEJQwcOBBbt24FADRq1AgXL17k3aNXuHfvHr777jusXLmyxMRjV1dXzJ49G++//z7/+72j7OxsHDt2DP/88w/27NlTYuK8Ind3d7z//vt4//334eLiUoZVEpEuYUAiJbGxsWjYsKEw92jLli0YMGCAxFVpvqSkJAQFBWHt2rUlhoWaNGmCwMBA9OzZk/uUqUBhYSFCQ0Oxa9cu7Nq1C7dv337ltQ0bNsT777+Pfv36wc3Njf/9ieiNMSCRkuHDh2PdunUAgAYNGiAmJobDRKVw48YNzJkzB5s2bYL4W6tZs2aYO3cuOnbsyF/UKiKXyxEVFYVdu3Zh586diI2NfeW19evXR79+/dCvXz80bdqU/w+I6LUYkEhw+/Zt1K1bV9i9ff369RgyZIjEVWmnq1evYvbs2di+fXuJcy1btsTcuXPRpk0bCSrTbbGxsdixYwd27NiBixcvvvK6unXrol+/fujfvz/c3d0ZloioBAYkEnz22WdYsmQJAMDR0RE3btzQu3WPVC06OhozZ87Evn37Spxr3749goKC4OvrK0Flui8hIQE7d+7E9u3bcf78+Vde5+TkhAEDBmDAgAFo0qQJwxIRAWBAov+XlpaGmjVrIjs7GwCwdOlSfPzxxxJXpTvOnTuHGTNm4OjRoyXOde/eHUFBQXB3d5egMv1w+/Zt7Ny5E9u2bUN4ePgrr6tXrx4GDhyIgQMHws3NrQwrJCJNw4BEAIDAwEDMmjULQPEK0bdv3+bq0GoQHByM6dOnIyQkpMS5vn37Ys6cOfzFrGbJycnYsWMHtm3bhrCwsFde5+rqioEDByIgIAD169cvwwqJSBMwIBGys7NRq1YtYcuHwMBAzJgxQ+KqdJdcLsexY8cwY8YMnDt3TumcTCZDQEAAZs+ezV/KZeDu3bvYvn07tm7d+to7S+7u7ggICMDAgQNRq1atMqyQiKTCgERYuXIlPvroIwCAubk5kpOTYWdnJ3FVuk8ul2P//v2YMWNGiQnFBgYGGDZsGGbOnMmFD8vInTt3sHXrVmzZsgUXLlx45XV+fn4YNGgQ+vfvj8qVK5dhhURUlhiQ9JxcLoebm5uwB9bHH3+MpUuXSlyVfikqKsKuXbswc+bMEnuRGRkZYfTo0Zg+fTqqV68uUYX6JyEhAVu3bsXff/+Ny5cvv/QaAwMDdOjQAYMGDUKfPn24NxyRjmFA0nNHjhxB586dhf7169fh7OwsYUX6q7CwEFu2bMGsWbNw8+ZNpXOmpqYYN24cpkyZwn3HylhsbCy2bNmCzZs3Iz4+/qXXmJqaokePHhg8eDC6desGMzOzMq6SiFSNAUnP9ezZU3gEvVu3bti/f7/EFVFBQQHWrVuHwMDAEqtEm5ubY8KECZg8eTLs7e0lqlA/yeVyREdH4++//8bff/+N5OTkl15nY2ODfv364YMPPkCbNm24zQyRlmJA0mMJCQmoV6+esOLz4cOH0alTJ4mron/l5eVh9erVCAoKwv3795XOlStXDl988QW+/PJLlC9fXpoC9VhRURFCQ0OxefNmbN26Fenp6S+9rlq1ahg8eDCGDh2KRo0alXGVRPQuGJD02KRJk7Bo0SIAgIuLC65du8ZF8jRQdnY2li9fjnnz5uHhw4dK58qXL49Jkybhs88+g5WVlUQV6rf8/HwcPXoUGzduxD///IOsrKyXXte4cWMMGTIEgwcPRrVq1cq4SiIqLQYkPZWdnY1q1arhyZMnAIAlS5Zg/PjxEldFr5OZmYnffvsNP/74Ix4/fqx0zt7eHt988w0++eQTWFhYSFQhZWZmYvfu3diwYQOOHDlSYuNioHgph/bt22Po0KHo27cvypUrJ0GlRPRfGJD01Jo1azBy5EgAgKWlJe7du8encLTEs2fP8PPPP2PRokV49uyZ0rkqVapg2rRpGDNmDExNTSWqkADg4cOH2Lp1KzZs2FBivat/WVhYoG/fvhg2bBj8/f25MTSRBmFA0lN+fn7CwnhjxozB8uXLJa6ISuvx48dYuHAhfv31V2RmZiqdq1GjBmbMmIERI0bA2NhYogrpX/Hx8diwYQM2bNiAW7duvfQaBwcHDBkyBMOHD4erq2sZV0hEYgxIeigmJgaNGzcW+pGRkfDw8JCwInoXDx8+xPz587F06VLk5OQonatTpw5mzpyJDz74gBsPawC5XI7Q0FCsX78eW7duxdOnT196nZeXF4YPH45BgwZx0VYiiTAg6aHPPvsMS5YsAQB4enq+dtVg0h7379/HvHnzsHz5cuTn5yudc3Z2xpw5c9C/f38+dq4hcnJysG/fPqxbtw4HDx5EQUFBiWuMjY3x3nvvYcSIEejSpQtDLlEZYkDSMzk5OXBwcBAmZ//xxx8YO3asxFWRKt2+fRtz587FX3/9VWKScKNGjTBnzhz07t2bTyxqkIcPH2Lz5s1Yt24doqKiXnpN5cqVMWTIEIwcORINGzYs4wqJ9A8Dkp7ZunUrBg4cCKB40cGUlBROztZRN2/eRGBgIDZs2ADxt7mnpyeCgoLQpUsXBiUNExMTg7Vr12LDhg148ODBS6/x8vLCqFGjMGjQIK6DRaQmDEh6pmvXrjh06BAAYNiwYVi7dq3EFZG6xcbGYtasWdi2bVuJc76+vpg7dy78/f0lqIxep6CgAEeOHMGaNWuwe/du5OXllbjG1NQUffv2xahRo+Dv78/hUyIVYkDSIykpKahevTqKiooAACdPnkTbtm2lLYrKzKVLlzBr1izs3r27xLl27dohKCgILVq0kKAy+i+PHz/G5s2b8ddffyEyMvKl19SqVQsjR47EiBEjUKtWrTKukEj3MCDpkYULF2Ly5MkAin+YJiYm8hOnHoqIiMCMGTNw+PDhEue6dOmCoKAgeHl5SVAZvYmYmBj89ddf2LBhAx49elTivEwmQ4cOHTB69Gj07t2b62ERvSUGJD3SpEkTXL58GQAwffp0BAUFSVwRSenMmTOYMWMGTp06VeJcr169EBgYqLQcBGmWvLw87N+/H6tXr8aBAweEO8OKKlSogGHDhmH06NFwc3OToEoi7cWApCeuXLmitFlmXFwc6tevL2FFpAnkcjlOnDiBGTNmCAuHKhowYABmz56NBg0aSFAdvan79+9j/fr1WLVqFW7cuPHSa3x8fPDhhx9i4MCB3N6E6A0wIOmJadOmYd68eQCKn4CJiIiQuCLSJHK5HAcPHsSMGTNKPGZuYGCADz74ALNmzYKTk5NEFdKbkMvlCAkJwapVq7Bt2zZkZ2eXuMbKygqDBg3CRx99xKFUotdgQNIDcrkcTk5OwhYHP/30E7744guJqyJNJJfLsXv3bsyYMQNXrlxROmdkZISRI0di+vTpqFmzpkQV0pvKyMjA5s2bsXLlyldO7HZ3d8eYMWMwePBgWFtbl3GFRJqNAUkPREREwNvbG0DxBM7k5GRUq1ZN4qpIkxUVFWHr1q2YPXs24uLilM6ZmJjgo48+wrRp0+Dg4CBRhVQa0dHRWLlyJTZs2FBig2OgeNPcQYMGYcyYMWjWrBnXxiICA5JemDx5MhYuXAgAaNWqFYKDgyWuiLRFQUEBNm7ciDlz5pTYZNXMzAyffvopvvnmG1SsWFGiCqk0srKysG3bNqxYsQJhYWEvvaZp06YYO3YsPvjgA1hZWZVxhUSagwFJx8nlctSpUwdJSUkAgN9++w2ffvqptEWR1snPz8dff/2FoKAg3L17V+mcpaUlPv/8c0yaNAm2trYSVUildfXqVaxcuRJr164Vth5SVK5cOQwePBjjxo2Du7u7BBUSSYsBScdFRkYKEzFlMhnu3buHqlWrSlwVaaucnBysWLEC33//fYltMGxsbPDVV1/h888/53wWLZKTk4Pt27djxYoVCAkJeek1zZs3x7hx4zBw4ECYm5uXcYVE0mBA0nHffvstvv/+ewBAixYtcObMGYkrIl2QlZWFpUuX4ocffkB6errSuQoVKuCbb77Bp59+CktLS4kqpLdx7do1rFixAmvXrsXTp09LnLe1tcWIESMwbtw4LhNCOo8BScc1bNgQ165dAwAsWrQIX375pcQVkS55/vw5fvnlFyxcuBAZGRlK5ypVqoRp06Zh7NixMDMzk6hCehv/zlVatmwZzp0799JrOnTogI8//hjvvfcejIyMyrhCIvVjQNJhN27cUPqUl5CQgDp16khYEemqJ0+e4KeffsLPP/+MFy9eKJ2rVq0apk+fjlGjRsHExESiCultRUdHY/ny5diwYQMyMzNLnK9WrRrGjh2LDz/8kMP3pFMYkHTYokWLMGnSJACAm5sbYmJiJK6IdF1aWhrmz5+P33//vcQihY6Ojpg5cyaGDh3KOw5a6NmzZ9iwYQOWLl2Kq1evljhvZGSE999/H59++ilatmzJpQJI63GnUh22b98+od2rVy8JKyF9YW9vjwULFiAxMRGfffaZ0h2jpKQkjBo1Cq6urti0aRMKCwslrJRKy9raGp988gliYmIQHByMgIAAGBsbC+cLCgqwZcsWtG7dGk2bNsWKFSteeseJSFvwDpKOevr0Kezt7YVfQuHh4fDx8ZG4KtI3ycnJmDt3LlavXo2CggKlcw0bNsScOXPQp08fGBjws5o2Sk1NxapVq/DHH3+UWP4BKH6ycdSoURgwYADy8vLQunVrCaokejsMSDpq27ZtGDBgAIDiT/WpqakwNDSUuCrSV4mJiQgMDMT69etL7Drv7u6OwMBAdO/encMyWqqgoAD79u3Db7/9huPHj7/yur1796JHjx5lWBnR2+PHNh118OBBod2lSxeGI5JUnTp1sGbNGly7dg0BAQFKQSg6Oho9e/aEr68vjh49Cn5m0z5GRkbo3bs3jh07hmvXrmHs2LEvnZD/xx9/SFAd0dthQNJBcrkchw4dEvpdu3aVsBqi/3F2dsbmzZtx6dIl9OnTR+ncuXPn0KlTJ7Rt2/aVCxaSZsvLy8OJEyewe/du5OXllThfuXJlCaoiejsMSDro6tWrSElJAVC8enbHjh0lrohIWaNGjbBz505cuHAB3bp1UzoXHByM1q1bo1OnTq9cg4c0S2FhIdatWwdnZ2eMHz8eqampwjnFidwMSKRNGJB00NGjR4W2u7s7NxIljeXp6Yn9+/cjLCwM/v7+SueOHj0KHx8fvPfee7h48aI0BdJryeVy7Nq1C40bN8bw4cOFPR+B4s2Mv/76a3z11VfCsbi4OAmqJHo7DEg6SHGSJO8ekTbw9fXF8ePHcfLkSbRo0ULp3N69e+Hu7o7+/fsLq8KT9E6cOAFfX1/07dtX6f+LkZERxo0bh4SEBMyfP19po1sGJNImDEg6Jj8/H6dPnxb6HTp0kLAaotL5d/7RoUOH0KxZM6Vz27dvh5ubG4YMGYIbN25IVCGdP38eHTp0QPv27ZWGQGUyGQYPHozY2FgsW7YMDg4OAKC0mv/NmzdLPMVIpKkYkHRMZGSksNWDiYkJ/Pz8JK6IqHRkMhk6d+6Mc+fOYffu3WjcuLFwTi6XY+PGjWjQoAFGjx6tNKRD6nX16lX06dMHzZs3L/Eof8+ePXHp0iVs3LgRdevWVTpXr149oZ2bm4vk5OQyqZfoXTEg6RjFu0c+Pj6wsLCQsBqityeTyfDee+8hOjoaW7ZsgYuLi3CusLAQq1evRv369fHJJ5/g3r17Elaq25KSkjB8+HA0atQI//zzj9K5Nm3aICwsDHv27EGjRo1e+vWWlpaoXr260I+Pj1dnuUQqw4CkYxQDUps2bSSshEg1DAwMMGDAAFy5cgXr1q2Dk5OTcC4/Px/Lli2Dk5MTGjdujO3bt+PevXvIysqSsGLd8ODBA0yYMAH169fHunXrlNan8vDwwOHDh3Hy5En4+vr+52sp3kViQCJtwR0jdUhhYSFCQ0OFPpf1J11iaGiIoUOHIiAgAGvXrkVQUBDu3LkDoHjoJiYmBv379xeut7CwgIODA2rUqIE6deqgbt26cHFxgaurK5ycnLh46is8ffoUCxYswM8//1wiaDo7O2Pu3Ll4//33S7Xqef369XHy5EkA4Pwx0hrcakSHXLp0CU2bNgVQ/Mvk6dOnKFeunLRFEalJbm4uVq5cicDAQDx8+LBUX2tubg43Nzd4eHjAy8sL3t7eaNiwoV6HpszMTCxZsgTz58/H06dPlc7VqFEDs2fPxrBhw2BkVPrP1YsWLcKkSZMAFC9ce+DAAVWUTKRWvIOkQ8LCwoR206ZNGY5Ip5mamuKTTz7B1q1bSx2QsrOzERERgYiICCxfvhwAUK5cOXh7e6NFixZo3bo1fH19YWlpqY7SNUpeXh7+/PNPzJ07V2mBRwCoWLEipk2bhnHjxsHMzOyt30NxiI13kEhbMCDpkPDwcKEtXkuGSBetWbMGwcHBQn/q1KmYOXMmnjx5ggcPHuDevXu4ffs2EhIScOPGDVy7dg2JiYkv3e/txYsXOHHiBE6cOAGgeD0fb29v+Pv7o0OHDvD19X3p/mLaqrCwEJs2bcKsWbNw69YtpXPW1taYPHkyPv/8c1hZWb3zeykGpKSkJOTn5yutsE2kiTjEpkPq168vfDrbtGkTBg0aJHFFROrz+PFj1K9fH+np6QCAXr16YdeuXf85NyYrKwtXr15FdHQ0IiMjERERgcuXL6OwsPC1X2dpaYl27dqhS5cu6Nq1K+rUqaOyv0tZksvl2LNnD6ZPn44rV64onTMzM8P48eMxZcoU2NnZqew9c3JyYGFhIQTTmzdvKk22J9JEDEg6Ij09Hfb29kI/MTERtWvXlrAiIvX6/PPP8euvvwIoDi+xsbGoUaPGW71WVlYWLly4gNDQUISEhCA0NBTPnj177dc4OzujR48e6NmzJ1q0aPFWc3PK2okTJzBt2rQSe9wZGRlh9OjRmDlzprDAo6rVqlVLmFR/6NAhdO7cWS3vQ6QqDEg64vDhw+jSpQsAwN7eHg8fPizVUyZE2uTmzZto0KABCgoKAADz5s3DlClTVPb6hYWFiI6OxvHjx3H8+HGEhIQgJyfnlddXqFABPXr0QJ8+fdC5c2eYm5urrBZViIiIwLRp03Ds2DGl4zKZDAEBAQgMDCyxwKOqtW/fXhi+XLJkCcaPH6/W9yN6V1wHSUdcuHBBaDdr1ozhiHTarFmzhHDk6OiIiRMnqvT1DQ0N4eXlhW+++QZHjhzBkydPcOTIEXz11Vdo0KBBiesfP36MdevWoU+fPrC3t8eAAQOwdetWZGZmqrSu0rp27Rr69u0Lb2/vEuGoR48euHjxIjZt2qT2cARAaUgtISFB7e9H9K4YkHSEYkDy8vKSsBIi9bp+/To2b94s9IOCgt7pCas3YWZmho4dO2LhwoW4du0abt26hSVLlqBTp04lJhtnZWVh27ZtGDhwICpWrIgBAwZg586dr70DpWpJSUkYMWIEGjVqhF27dimda9OmDUJDQ7F3716lbVzUjQGJtA0Dko6Ijo4W2h4eHhJWQqRe8+fPFyb7uri4SPIwgqOjI8aPH4/Dhw8jLS0NW7ZsQUBAQIknvrKzs7Ft2za8//77qFy5MkaOHIljx47954Twt/XgwQN89tlnqF+/PtauXau0MayHhwcOHTqEkydPSrJHIwMSaRvOQdIBT548QYUKFYR+UlISatWqJWFFROqRkpKCWrVqIT8/HwCwbt06DB06VOKq/ic3NxdHjx7F9u3b8c8//yAjI+Ol1zk4OGDw4MEYPnw43Nzc3vl91bH6tapFR0cLH97MzMyQlZXFqQCk0RiQdMDp06fRtm1bAICtrS3S09P5g4d00uzZszFnzhwAQPXq1ZGYmKix6+nk5ubiyJEj+Pvvv7F79+5Xzkfy9PTEyJEjMXjwYNja2pbqPdS5+rWqZWRkoHz58kL//v37qFq1qnQFEf0HDrHpgMuXLwvtxo0bMxyRTiooKMDKlSuF/qeffqqx4QgoXum7Z8+e2LhxIx4+fIjNmzejR48eJcJKZGQkxo8fj6pVq2Lw4ME4ceKE0tDYy+Tl5WHZsmWoW7cupk6dqhSO7O3tsXjxYsTHx2PUqFEaEY4AwMbGRmltpcTERAmrIfpvDEg6ICYmRmg3atRIwkqI1Ofo0aO4d+8eAMDY2BijRo2SuKI3Z2FhgYCAAOzduxf379/Hr7/+Ck9PT6VrcnNzsXnzZrRv3x7Ozs5YsGABHj16pHRNYWEhNmzYgAYNGuCTTz5R2hrE2toac+bMQWJiIiZOnKj2ietvQ3FxTQYk0nQMSDrg6tWrQpsBiXTVhg0bhHaPHj1QqVIlCat5exUrVsSECRNw4cIFxMTE4KuvvkLFihWVrrl58ya+/vprVKtWDR988AHOnDmDf/75B02aNMHQoUOVwoWZmRkmTZqEhIQEzJw5UyVbg6iLYkDiRG3SdAxIWk4ul+PatWtC39XVVcJqiNQjJycHe/bsEfpDhgyRsBrVcXNzw8KFC3H37l3s2LEDXbt2VRoiz8/Px6ZNm9CqVSv06dNH6cOQoaEhxowZg5s3b2LBggVKK+lrKsXV/cX7vxFpGgYkLffgwQOl+QcvW8SOSNudOHECL168AFC8rUjXrl0lrki1TExM0LdvXxw4cABJSUmYPn36aycwBwQEIDY2FsuXL0e1atXKsNJ3w4BE2oQBSctdv35daNvb26t0g0kiTbF//36hrYlbeahSzZo1ERQUhNu3b2Pbtm1Ke6NZWFjg4sWL2Lx5M+rVqydhlW+HAYm0iWY83kBvLS4uTmg7OztLWAmR+ihuk6Frd49exdjYGP369UP58uXRsWNHAICVlRWaNGkicWVvTzEg3bt3D3l5eTAxMZGwIqJX4x0kLXfz5k2hXb9+fQkrIVKP1NRUxMfHC/327dtLWE3ZU/y+fvDggTDUqI1q1qwpzLGSy+VITk6WuCKiV2NA0nKKT4KUxYaTRGUtPDxcaFerVg2Ojo7SFSOB6tWrK91l0ebH401MTJTmTCUlJUlXDNF/YEDScooBSXGvIyJdERkZKbR9fHz0biFUAwMDpaEpbQ5IAJQCLuchkSZjQNJicrlc6QeM4g9RIl2huFK8u7u7hJVIR5cmNyvuE3n79m0JKyF6PQYkLfbkyRM8f/5c6DMgkS6KjY0V2g0bNpSwEuko3nXR9lDBgETaggFJi925c0dom5uba8VCcUSlUVhYqDRPRRsfbVcFxVCh+H2vjXQp7JFuY0DSYoo/KBWfDiHSFampqSgoKBD6+jZB+181a9YU2toekHgHibQFA5IWu3v3rtCuXr26hJUQqceDBw+EtrW1NSwtLSWsRjqK39+K3/faSDHs3b17F4WFhRJWQ/RqDEha7P79+0Jbm7YbIHpTjx8/FtoVKlSQsBJpKX5/P3z4EPn5+RJW824UA1JhYaHSzzEiTcKApMUYkEjXKS6KaG1tLWEl0lLcbkQulyvdWdM2FhYWSvMlOcxGmooBSYulpqYK7SpVqkhYCZF65ObmCm1TU1MJK5GWubk5bGxshH5KSoqE1by7GjVqCG2upk2aigFJiyl+iqxcubKElRCph1wuF9r6/hCC4ocgxQ9H2khxmI0BiTQVA5IWe/jwodCuVKmShJUQqYexsbHQ1uZ5N6qg+CHo0aNHElby7ngHibQBA5IWS0tLE9oVK1aUsBIi9VB8ak2bN2lVBcXvcQYkIvVjQNJSWVlZyMnJEfp2dnYSVkOkHra2tkJb8Yk2faT4Pa744UgbKQYkbV+2gHQXA5KWevLkiVJfnx+BJt2lOKyUnp6uNGlb3ygGJG0Pi4rrOvEOEmkqBiQtpRiQzM3N9foJH9JdDg4OSpOz9fmXqeKHIG0PSIp3kB4+fKjXwZc0FwOSlsrIyBDa5cuXl64QIjUyMTFR+mUaHx8vYTXSUvw+f/r0qWR1qILiuk4AuFgkaSQGJC317Nkzoa3PC+iR7nN1dRXaMTExElYiLcV1kBQ/IGkjExMTpeHTe/fuSVgN0csxIGkpxYBkZWUlYSVE6tWkSROhHRkZKWEl0lL8IPT8+XMJK1ENxdX/OVGbNBEDkpbKysoS2vq6gSfpB29vb6EdGhqqtHikPilXrpzQ1oUlDxQDEu8gkSZiQNJSigHJwsJCwkqI1Ktly5ZC+/79+3o7D0nxg1BmZqaElagGAxJpOgYkLZWdnS20zc3NJayESL0qVaqExo0bC/0DBw5IWI10FL/PFb//tRUDEmk6BiQtxU08SZ90795daO/cuVPCSqRjZmYmtAsKClBYWChhNe9O8Uk2BiTSRAxIWooBifRJ3759hfaZM2dw584dCauRhvj7PC8vT6JKVEMxIKWkpEhYCdHLMSBpqYKCAqFtZGQkYSVE6ufp6Yl69eoJ/TVr1khXjEQUN+4FtH/zXnFA0tfJ96S5GJC0FAMS6ROZTIaRI0cK/eXLl2t9QCgt8fe54s8AbaQYkLKzs7V+8UvSPQxIWqqoqEhoGxjwfyPpvlGjRgl3Ue7fv4+///5b4orKlvj7XPFngDays7NTuivGYTbSNPzNqgMU96oi0lWVK1fGBx98IPS///57rZ+orM9kMhmqVKki9FNTUyWshqgkBiQdwLF70hfffPON8IHg+vXrWLduncQVlR3x97kufDCqWrWq0OYdJNI0DEhaSvF2OwMS6QsXFxelu0jffvutTmy78SbEd8sMDQ0lqkR1GJBIkzEgaSnFgMRhBtInc+fOFR55T0lJwcyZMyWuqGyIJ6WLn2rTRhxiI03GgKSlFH84avvTLESlUatWLUyZMkXo//LLLwgLC5OworIhXvfIxMREokpUhwGJNBkDkpZS/OGouGgkkT6YMmUKnJ2dARQPMQ8dOhTPnj2TuCr1UtxexMDAgHeQiNSMAUlLMSCRPjMzM8OaNWuEoebExESMGDFCp9dGUtygWnHjWm1WuXJlof3gwQMJKyEqiQFJS+naxpVEpeXj44NZs2YJ/V27dqFmzZoSVqReipPRy5UrJ2ElqsOARJqMAUlLKQYkxU+WRPrk22+/haenp9BPTU1Fnz59JKxIfTIyMoS2tbW1hJWojmJASktL43xK0igMSFpK8RMkAxLpq507d+L69etKx3bv3q2Tu8M/efJEaNva2kpYieooBiS5XI60tDQJqyFSxoCkpaysrIS2vqwDQ/SvvLw8TJw4EQMGDEBmZqbSOblcjoCAAK3f7V5MMTzY2dlJWInqWFpaKt0Nf/jwoYTVECljQNJSigFJ15/eIVKUnJyMNm3a4JdffhGO2djYYNiwYUL/zJkzGD9+vE4toqoYHipVqiRhJaojk8mU/i4MSKRJGJC0VPny5YW24twEIl129OhReHh44OzZs8KxJk2a4MKFC1izZg1GjBghHP/zzz/x/fffS1Clety/f19oKz4er+0YkEhTMSBpKcWA9Pz5c05uJJ1WVFSEoKAgdO7cWWmoadSoUQgPD0fdunUhk8mwbNky+Pr6CuenT5+O33//XYqSVe7u3btCu3r16hJWoloVK1YU2o8ePZKwEiJlDEhaqkKFCkr9x48fS1QJkXqlpaWhW7dumDlzpjBkZmZmhlWrVmHVqlVKc1jMzMywe/du1KtXTzg2fvx4/Pbbb2Vet6rdvn1baOvScgaKd5AYkEiTMCBpqXLlyimtpJueni5hNUTqcf78eXh4eODw4cPCMScnJ4SHh2PUqFEv/ZqKFSvi6NGjqFGjhnBswoQJCAwM1No5SQUFBUoBqXbt2hJWo1q8g0SaigFJS8lkMv5gIZ0ll8vx+++/o2XLlkhOThaO9+7dGxcuXEDTpk1f+/W1atXCqVOnlO60zJo1C6NGjdLKledv3bolrBIuk8ng5OQkcUWqw59jpKkYkLQYJzeSLnrx4gU++OADjB8/XggFhoaGWLBgAXbu3Kk0/+516tSpg5CQEGHPNgBYs2YNWrdurXQ3RhtcvXpVaNeuXRtmZmYSVqNa9vb2QpvrIJEmYUDSYoqLrHGjR9IFsbGx8Pb2xubNm4VjVatWxcmTJzFp0iTIZLJSvV7NmjURGhqKVq1aCcfOnz+Ppk2bYtu2bSqrW90uXboktBs1aiRhJaqnGJB4B4k0CQOSFqtatarQTklJkbASonf3999/o1mzZoiNjRWOtW3bFlFRUUoBp7Ts7Oxw7NgxjBkzRjj29OlTDBgwAAMHDtSKDxfnz58X2h4eHhJWonq8g0SaigFJizk4OAhtXdxagfRDbm4uJkyYgEGDBimtij1lyhQcPXpUJWv+mJiYYPny5Vi3bp3SNj1bt26Fs7Mzfv75Z41debuoqAjh4eFCv3nz5hJWo3qKAenx48coKiqSsBqi/2FA0mLVqlUT2oprpBBpizt37qB169ZKj+GXL18ee/bswbx582BkZKTS9xs6dCguXryIli1bCseePXuGL774Aq6urli/fr3GrSkWHR0t7MNmaGiotM6TLlDcNqWoqAhPnz6VrhgiBQxIWkzxMeY7d+5IWAlR6R0+fBju7u5Kw0fu7u6IiopCz5491fa+Tk5OOH36NJYuXQobGxvheEJCAoYNGwZnZ2f89ttvGrPH4YEDB4S2t7c3rK2tJaxG9cqXLw8Dg//9KuKSJaQpGJC0mOIjzMnJyVq7xgvpl8LCQsyaNQtdu3ZVWuD0ww8/RFhYWJms8WNgYICPP/4YN27cwLhx42BoaCicS0xMxIQJE+Dg4IAxY8YgJCREkmGf/Px8/PzzzwgKChKO9ejRo8zrUDcDAwPY2toKfS56S5pCJudvVa2VkZGh9MhzSkqKTu3RRLrn0aNH+OCDD3D06FHhmLm5OZYtW4bhw4dLVteNGzcQFBSETZs2obCwsMR5BwcH9OrVC127dkWbNm3UchdHLpcjMTERJ0+exJEjR3DkyJES+yxevnxZ555iAwBnZ2fEx8cDAPbv349u3bpJXBERA5LWq1ChgjA/ITQ0FH5+fhJXRPRy4eHhGDBggNJ8uXr16mH79u1o3LixhJX9T1JSEn799VesXr36lZtAGxgYoEmTJvD29kbTpk3h6uqKevXqoXLlykpDRa/z7Nkz3Lp1C/Hx8bhy5Qqio6Nx/vx5PHjw4LVft3HjRgwePLjUfy9N5+fnJ0xEX7duHYYOHSpxRUSAamdAUplzcnLChQsXABTPoWBAIk0jl8vx66+/YtKkSUoToPv164dVq1Zp1JwaR0dH/PTTT5g7dy527NiBdevW4cSJE0pDbEVFRYiOjkZ0dLTS15qYmKBKlSqws7ODtbU1zM3NYWRkhKKiIuTk5ODFixd4/PgxHjx48Mbzm8zMzGBiYoJnz54B0N35OYp7S/77gY9IagxIWq5u3bpCQLpx44bE1RApe/78OUaPHq20KKORkRF+/PFHTJw4sdQLP5YVCwsLDB06FEOHDsWjR4+wb98+HDhwAMePH3/lL/C8vDzcuXPnnR+YcHFxgb+/Pzp37oz27dtj5syZ+OmnnwAAp0+fxoQJE97p9TWR4hwkBiTSFAxIWk5x1/J/x/CJNMGVK1fQr18/xMXFCcccHBywdetWtGjRQsLKSqdixYoYOXIkRo4ciaKiIly9ehVnz55FZGQkYmJiEBcX91Z3dkxNTeHk5IQGDRqgcePG8PT0hLe3t9LeZEDxYpn/BqTg4GDI5XKNDZZvS/EOEidpk6ZgQNJyLi4uQvv69esSVkL0Pxs2bMDYsWORlZUlHGvfvj02bdqktIegtjEwMECjRo3QqFEjfPTRR8LxjIwM3L17Fw8ePEB6ejqeP3+OnJwcFBQUwMDAAKampihXrhxsbW1RsWJFODg4vPGcpZYtW0Imk0Eul+PRo0eIjY2Fq6urOv+aZU7xYRPeQSJNwYCk5RQDUlxcHAoLC5UeWSYqS7m5uZg4cSL++OMPpePffvst5syZo7P/Nm1sbGBjY4OGDRuq/LVtbW3RuHFjYT+206dP61xA4hAbaSKug6TlXFxchNvtOTk5SEpKkrYg0ltJSUlo0aKFUjiytbXF/v37MXfuXJ0NR2WhTZs2Qjs4OFjCStSDAYk0EQOSlrOwsICjo6PQv3LlinTFkN46cOAAPDw8EBkZKRxr1qwZoqKiuKaNCigGpNOnT+vcorCKAelVyysQlTUGJB2guIZMTEyMhJWQviksLMT06dPRvXt3pU/+H3/8MUJCQpTCO729Vq1aCe2UlBTcvHlTwmpUj3OQSBMxIOkAxYD07zwFInV7+PAhOnXqhO+++044ZmFhgY0bN2Lp0qUwNTWVsDrdUrFiRaX5TadPn5awGtVT3BOPm9WSpmBA0gFNmjQR2uLF64jU4cyZM3B3d8eJEyeEYy4uLoiIiNDJlZ41QevWrYW2rgUkxTtImZmZSguKEkmFAUkHuLu7C+2EhASO4ZPayOVy/PTTT2jbti3u378vHB84cCDOnz+vc09XaRLFgKRrE7UV7yABEFYOJ5ISA5IOqF27ttInMMWJskSqkpGRgX79+uGrr74SNnQ1NjbGr7/+is2bN8PKykriCnWb4kTtO3fu6NQTq+J/OxxmI03AgKQDZDIZPD09hX5ERISE1ZAuunz5Mry8vLBz507hWI0aNRAcHIwJEybo3MrOmqhq1apKK+fr0jCboaGhUkh6073qiNSJAUlHeHt7C+3z589LWAnpmjVr1qB58+ZKT0516tQJUVFR8PHxkbAy/SN+3F+XKG5azCE20gQMSDqiefPmQjs8PFzn1kmhspeTk4OPPvoII0eORE5ODoDiu5WzZs3CgQMHYG9vL3GF+kdfAhLnUZIm4FYjOkLxk3xKSgqSk5NRs2ZNCSsibZaYmIh+/fopPRVpZ2eHjRs3onPnzhJWpt8UA1JiYiLu3r2L6tWrS1iR6nCIjTQN7yDpiMqVK6NOnTpC/8yZMxJWQ9psz5498PDwUApHzZs3R1RUFMORxGrUqIHatWsLfV26i8SARJqGAUmHKK62y4BEpVVQUIApU6agV69eSkMc48ePR3BwMO9IaghdfdxfMSBxDhJpAgYkHdKyZUuhrUufLEn9UlNT0aFDB8yfP184Zmlpic2bN2PJkiUwMTGRsDpS1LZtW6GtS9/nigHpxYsXElZCVIwBSYco/uC8du0aHj58KF0xpDWCg4Ph7u6u9MvW1dUVERERCAgIkLAyehnFO0hxcXF48OCBhNWoDgMSaRoGJB3i5OSEatWqCf2TJ09KWA1pOrlcjgULFsDf3x+pqanC8cGDB+PcuXNo0KCBhNXRq9SuXVtpYrau3EUqV66c0OYcJNIEDEg6RCaTwd/fX+gfP35cwmpIkz19+hR9+vTB119/rbQq9u+//44NGzYo/bIizSKTyZSeZtOVeUiK/+YyMzMlrISoGAOSjunQoYPQPnbsGNdDohIuXrwILy8v7N69WzhWs2ZNhIaG4pNPPuGq2FpAF9dDUgxIHGIjTcCApGMUA9KtW7eUVj8mWr16NXx9fZGQkCAc69q1K6KiotCsWTMJK6PSUAxIV65cQVpamoTVqIalpaXQ5hAbaQIGJB3j4OAANzc3oX/o0CEJqyFNkZ2djVGjRmH06NFKq2IHBQVh3759sLOzk7hCKo169eqhSpUqQj8kJETCalRDMSBlZWVJWAlRMQYkHdSlSxehfeDAAQkrIU1w48YN+Pj44K+//hKO2dvb48iRI5g+fToMDPhjQNvIZDKlp9l0YZhNMSBxDhJpAv5k1EHdunUT2idPnuQPGz22a9cueHl54fLly8IxPz8/REdHKw3HkvbRtXlIFhYWQps/s0gTMCDpoJYtWwobP+bm5uLYsWMSV0RlLT8/H5MmTULfvn2VViX+4osvcOrUKZ3Zv0ufKQakS5cu4enTp9IVowKKd5Cys7MlrISoGAOSDjI2NlYaZlN8Wol03/379+Hv749FixYJx6ysrLBt2zb89NNPMDY2lrA6UhVXV1fY29sDKF7TStu3F1K8g8SARJqAAUlH9e7dW2jv3btXWOuGdNvJkyfh7u6u9MvSzc0NFy5cQL9+/SSsjFRNJpMp7b+o7cNs5ubmQpuTtEkTMCDpqG7dugl3CtLS0nTiKRd6taKiInz//ffo0KGD0hYzw4YNw7lz51C/fn0JqyN10aV5SIoBKS8vjx/qSHIMSDrKxsYG7du3F/rbt2+XsBpSpydPnqBXr1749ttvUVRUBAAwMTHB8uXLsWbNGqWhC9ItigEpKipKq9cPUgxIAITlKIikwoCkwxSHVHbs2MFPZDooMjISHh4e2Ldvn3DM0dERYWFhGDNmDFfF1nGNGjVC+fLlAQCFhYUICwuTtqB3IA5InIdEUmNA0mG9e/eGkZERACA1NZXDbDpELpdjxYoV8PPzQ1JSknC8e/fuiIyMhKenp3TFUZkxNDTUmXlIZmZmSn3eQSKpMSDpMDs7O3Ts2FHob968WcJqSFUyMzMxfPhwjB07Fnl5eQAAAwMDfP/999izZw8qVKggcYVUlnRlHpKRkZHSoqW8g0RSY0DScQEBAUJ727ZtyM3NlbAaeldxcXHw8fHB+vXrhWOVKlXCsWPHMHXqVK6KrYcUV9SOiIjQ2ifAZDIZTE1NhT5/VpHU+NNUx/Xp00cY23/y5Am3HtFi27dvR7NmzXDlyhXhWKtWrRAdHY127dpJWBlJyd3dHVZWVgCKFwg9e/asxBW9PQYk0iQMSDrOysoKvXr1Evrr1q2TsBp6G3l5eZg4cSL69++v9JTS5MmTcfz4cTg4OEhYHUnNyMgILVq0EPraPMzGgESahAFJDwwfPlxo79u3D48ePZKwGiqNu3fvom3btvjll1+EY9bW1ti5cyd+/PFHropNAHRnHpJiQPp3fh2RVBiQ9EDHjh2FuwwFBQXYsGGDxBXRmzh27Bjc3d0RHh4uHGvSpAkiIyPRp08fCSsjTaM4D+ns2bNa+wQY7yCRJmFA0gOGhoZKd5FWrlwJuVwuYUX0OkVFRQgKCkKnTp2QlpYmHB85ciTCw8NRt25dCasjTeTl5SXMNczNzcX58+clrujtmJiYCG3eQSKpMSDpiVGjRgnta9euafWCcrosPT0dPXr0wMyZM4UQa2ZmhlWrVmH16tUlFtMjAoqDhZ+fn9DX1mE2xSHj/Px8CSshYkDSG3Xr1lV60mn58uUSVkMvc/78eXh4eODgwYPCsTp16iAsLEwp4BK9jC7MQ1K8g8SARFJjQNIj48aNE9pbt25VGr4h6cjlcixduhQtW7bEnTt3hOO9e/dGZGQk3N3dJayOtIViQAoPD9fKISreQSJNwoCkR3r37o3KlSsDKJ6nsGrVKokrohcvXmDIkCH49NNPhV8IhoaG+PHHH7Fz505hny2i/+Lt7S1Mcs7KykJkZKTEFZXev1sjAQxIJD0GJD1iYmKCMWPGCP2lS5eioKBAwor0W2xsLJo3b45NmzYJx6pUqYITJ05g8uTJ3GiWSsXMzAw+Pj5CXxuH2XgHiTQJA5KeGTt2rPAp7c6dO9i9e7fEFemnLVu2oFmzZrh27ZpwrG3btoiOjlZ6ZJuoNBT/7WhjQDI0NBTahYWFElZCxICkd6pVq4Z+/foJ/cWLF0tYjf7Jy8vDZ599hoCAAGRmZgrHv/nmGxw9ehRVqlSRsDrSdorzkM6cOaN1d4gVh9i0rXbSPQxIeuiLL74Q2qGhoTh37pyE1eiPO3fuoHXr1liyZIlwrHz58tizZw9++OEHpV8ORG/D19dX+Hf04sULREdHS1xR6fAOEmkSBiQ95O3trbR304IFCySsRj8cPnwYHh4eSmHUw8MDkZGR6Nmzp4SVkS6xsLBAs2bNhH5wcLCE1ZSeYkAqKiqSsBIiBiS9NXnyZKG9c+dOxMfHS1iN7iosLMSsWbPQtWtXpKenC8c/+ugjhIaGok6dOhJWR7pIm9dD4h0k0iQMSHqqZ8+ecHZ2BlC8Ds/8+fMlrkj3pKWloVu3bggMDBRWxTY3N8eaNWuwYsUKmJmZSVwh6SLFgBQSEqJVd2IYkEiTMCDpKQMDA0yZMkXor1u3TmmRQno3Z8+ehbu7O44cOSIcq1u3Ls6ePau0Lx6RqrVo0UIIGk+fPkVMTIzEFb05xaUtuF8kSY0BSY998MEHqFmzJoDiJ0Z4F+ndyeVy/Prrr2jVqhXu3r0rHO/bty8uXLiAxo0bS1gd6QMrKyt4eHgI/VOnTklXTCkZGPzvVxLvIJHUGJD0mLGxMb755huhv3LlSqVf6lQ6z58/R0BAAD7//HPhEWUjIyP89NNP2L59O2xsbCSukPSF4jCbNk3U5uKopEkYkPTcqFGj4ODgAKB4jZ558+ZJXJF2unr1Kpo1a4atW7cKxxwcHHDy5El88cUX/MFPZUockLRxuEobaybdwoCk58zMzDB16lSh/+eff+L27dsSVqR9Nm7cCG9vb8TFxQnH/P39ER0djZYtW0pYGemrFi1aCKE8LS1NacV2TcY5SKRJGJAIH330EWrUqAGgeP+jOXPmSFyRdsjNzcUnn3yCIUOGICsrSzj+7bff4siRI6hUqZKE1ZE+s7W1RZMmTYS+tjzuzzutpEkYkAimpqaYOXOm0F+7dq3WfOKUSlJSElq2bIlly5YJx2xtbbFv3z7MnTtX6XFlIilo6zwkIk3BgEQAgBEjRqB+/foAilewnTZtmsQVaa79+/fDw8MDFy5cEI55eXkhKioK3bt3l7Ayov8RLxipDUNW2lAj6Q8GJAJQ/LTV3Llzhf7u3bsREhIiYUWap7CwENOnT0ePHj3w5MkT4fi4ceNw5swZODo6SlcckUirVq2EdmpqKm7cuCFhNW9GcVFLxUf+iaTAf4Ek6NevH7y9vYX+pEmTtGoVXnV6+PAhOnfujO+++044ZmFhgfXr12PZsmUwNTWVsDqikuzt7dGwYUOhrw3zkBTvIHE+EkmNAYkEMpkMCxcuFPrnz5/H5s2bJaxIM4SFhcHDwwPHjx8XjtWvXx/nzp3DkCFDJKyM6PW0bV823kEiTcJ/gaSkVatW6Nu3r9D/5ptvkJmZKWFF0pHL5Vi8eDHatGmDe/fuCcf79++PCxcuwM3NTcLqiP6btq2HxIBEmoT/AqmEBQsWwMTEBABw7949/PDDDxJXVPaePXuG/v3748svv1RaFfuXX37Bli1bYGVlJXGFRP+tdevWQjs5ORlJSUnSFfMGFLcX4ZOgJDUGJCqhTp06+PLLL4X+ggULkJCQIGFFZSsmJgZeXl7YsWOHcKx69eoIDg7GZ599xrkRpDWqVKkCZ2dnoa/pw2wMSKRJGJDopb799lthC5Lc3Fx8/vnnGn97XhXWrl2L5s2bKz3x07FjR0RFRcHX11fCyojejuJdJAYkojfHgEQvVa5cOSxatEjo79+/H//88490BalZTk4OxowZgxEjRiA7OxtA8aT1WbNm4eDBg6hYsaLEFRK9HW2aqK0YkIyMjCSshIgBiV5j4MCB8Pf3F/qfffYZnj9/LmFF6pGYmAg/Pz/8+eefwjE7OzscPHgQs2fP5idZ0mqKAenWrVtITk6WsJrX+3e+H8CARNJjQKJXkslkWLp0qTBh++7du5g+fbrEVanW3r174enpiejoaOGYt7c3oqKi0LlzZwkrI1KN6tWro3bt2kJfk7cdyc/PF9oMSCQ1BiR6LWdnZ0ydOlXoL1myBGfPnpWwItUoKCjA1KlT8d577+Hp06fC8fHjxyMkJAQ1a9aUrjgiFdOWYTbFgGRsbCxhJUQMSPQGpk6dChcXFwDFawONHj0aubm5Elf19lJTU9GxY0el5QssLS2xadMmLFmyRLhjRqQrGJCISo8Bif6TqakpVq5cKTzefu3aNQQGBkpc1dsJDg6Gu7s7Tp06JRxr0KABIiIiMGjQIOkKI1IjxYAUHx+P1NRUCat5NcWAxA8qJDUGJHojLVq0wPjx44X+/PnzERERIWFFpSOXy7FgwQL4+/sr/XIYNGgQzp8/jwYNGkhYHZF6OTo6okaNGkJfU+ch5eXlCW0GJJIaAxK9sXnz5gmTPQsLCzFs2DDhkXhN9vTpU/Tt2xdff/218BixsbExfvvtN2zcuBHlypWTuEIi9ZLJZFoxzKY4dM+ARFJjQKI3Zmlpib/++ksYart+/Tq+/fZbiat6vYsXL8LLy0tpDaeaNWvizJkz+PTTT7kqNukNbVgwUjEgmZqaSlgJEQMSlVKbNm0wceJEob948WIcO3ZMuoJeY9WqVfDx8VHaJqVLly6IioqCt7e3hJURlT3FO0hXr15FWlqahNW8XE5OjtBmQCKpMSBRqX333XdwdXUV+sOGDUN6erqEFSnLzs7G6NGj8eGHHwqfSGUyGQIDA7F//37Y2dlJXCFR2atXrx6qVKki9DVxHpLiHSQzMzMJKyFiQKK3YG5ujk2bNglzBFJSUjBq1CiN2KstISEBvr6+WL16tXDM3t4eR44cwYwZM2BgwH/ypJ+0YR6S4h0kBiSSGn9b0Ftp0qQJ5s2bJ/T37NmD3377TcKKgH/++Qeenp64dOmScMzX1xfR0dHo0KGDhJURaQbFgKRpd5CKioqUnmJjQCKpMSDRW5s4cSK6dOki9CdNmoTIyMgyr6OgoACTJ09Gnz59kJGRoVTf6dOnUb169TKviUgTKQakS5cu4cmTJxJWo0z8RKyFhYVElRAVY0Cit2ZgYIC1a9cK8xry8vLQv3//Mv2hm5KSAn9/fyxcuFA4Vq5cOWzduhWLFy/marxECho0aAB7e3sAxWuDnTlzRuKK/kcckMzNzSWqhKgYAxK9k0qVKmHz5s3C3J5bt25h+PDhKCoqUvt7nzp1Cu7u7ggJCRGOubm54cKFC+jfv7/a359I28hkMo193D8rK0upzztIJDUGJHpnbdu2RVBQkNDfu3ev0vwkVSsqKsIPP/yA9u3b48GDB8LxoUOH4uzZs3B2dlbbexNpO02dh6QYkExNTWFoaChhNUQMSKQiU6ZMQffu3YX+jBkzcOjQIZW/z5MnT9CrVy9MnTpVuEtlYmKC5cuXY+3atbC0tFT5exLpEsWAFBUVhefPn0tYzf9kZmYKbd49Ik3AgEQqYWBggPXr16NOnToAiuc3BAQE4MaNGyp7j6ioKHh6emLfvn3CMUdHR4SGhmLMmDFcFZvoDTRq1Ajly5cHULxlUGhoqLQF/b8XL14IbW7/Q5qAAYlUxtbWFrt27RI+/WVkZKBXr1549uzZO72uXC7HihUr4Ofnh1u3bgnHu3fvjsjISHh5eb3T6xPpEwMDA7Rq1Uroa8o8JMWAxDvBpAkYkEilGjdujDVr1gj92NhYBAQEoKCg4K1eLysrCyNGjMDYsWOFVXYNDAzw3XffYc+ePahQoYIqyibSK5q4YKRiQLKyspKwEqJiDEikcv3798f06dOF/sGDBzFp0qRSv058fDx8fHywbt064VilSpVw9OhRTJs2jatiE70lxYAUERGhNP9HKopzoTjERpqAv2FILebMmYO+ffsK/V9++QW///77G3/9jh074OXlhZiYGOFYy5YtER0dDX9/f5XWSqRvmjZtKtylKSgoQHh4uMQVKQck3kEiTcCARGphYGCAdevWwcPDQzj22WefYe/eva/9uvz8fHz55Zfo16+f0g/Mr776CidOnICDg4PaaibSF0ZGRmjRooXQ14TH/RW/362trSWshKgYAxKpjaWlJfbu3Sts9VFUVISAgACcP3/+pdffu3cP7dq1w+LFi4Vj1tbW2LFjBxYuXMhVsYlUSNPmISluE8Q7SKQJGJBIrRwcHHDgwAHhE2FWVha6d++O+Ph4peuOHz8Od3d3pUeOGzdujAsXLigN1RGRaigGpHPnziEnJ0fCapQDko2NjYSVEBVjQCK1a9SoEXbs2CHcAUpLS0Pnzp1x//59FBUVYe7cuejYsSMePXokfM2IESMQHh6OevXqSVU2kU7z8vISluTIzc3FuXPnJK1HcTkQBiTSBAxIVCY6dOig9DRaUlIS2rZti5YtW2LGjBmQy+UAircY+PPPP/HXX39xNV0iNTI2Noafn5/Ql3qY7enTp0L734UsiaTEgERlJiAgAD///LPQv3HjhtLTM3Xq1EF4eDg+/PBDCaoj0j+atC8bAxJpGgYkKlOff/45Ro8eXeJ4z549ERkZCXd3dwmqItJPigEpLCwMeXl5ktXy5MkToc2ARJqAAYnK3J9//okqVaooHfv666/5Q5GojHl7e8PU1BQAkJ2djQsXLkhWi2JA4gr5pAkYkKjMyWQyxMfHKz22P3r0aGRnZ0tYFZH+MTU1hY+Pj9CXah6SXC5XGmKztbWVpA4iRQxIJAkrKyucPn0aMpkMQPG2IorbkxBR2dCE9ZAyMjJQWFgo9O3s7CSpg0gRAxJJxtfXF1988YXQX7x4MUJCQiSsiEj/KAak0NDQt95Y+l08fvxYaMtkMj7mTxqBAYkkNXfuXLi4uAAovs0+fPhwpS0HiEi9fHx8hOHuFy9eICoqqsxrSEtLE9oVKlSAoaFhmddAJMaARJIyNzfH2rVrhR+It27dwsSJE6UtikiPWFhYwNvbW+hL8bi/YkDi8BppCgYkkpy3tze+/fZbob969Wrs2rVLwoqI9Evr1q2FthTzkBRX0be3ty/z9yd6GQYk0gjTp09X+hQ7evRoJCcnS1gRkf5QnIcUEhKiNGG6LCgGpIoVK5bpexO9CgMSaQRjY2Ns2LABlpaWAIrXRBkyZEiZ/6Am0kd+fn7CMHdGRgYuX75cpu/PgESaiAGJNEa9evXw22+/Cf3g4GAEBQVJWBGRfrCysoKnp6fQL+t5SA8ePBDalStXLtP3JnoVBiTSKMOHD8egQYOEfmBgIE6cOCFhRUT6Qcp5SA8fPhTalSpVKtP3JnoVBiTSKDKZDH/88QecnJwAFD/6P3jwYKSkpEhcGZFuE29cW1RUVGbvnZqaKrTF2xARSYUBiTSOtbU1tm3bBhMTEwDFt98HDhyI/Px8iSsj0l0tW7YUVrZPT09HbGxsmb23YkDiEBtpCgYk0kju7u74+eefhX5ISAimTp0qXUFEOq58+fJo2rSp0C+rYbbCwkKlOUhVq1Ytk/cl+i8MSKSxxo0bhyFDhgj9RYsWYcuWLRJWRKTbpNiX7dGjR0rDeQxIpCkYkEhjyWQyLF++HI0aNRKOjRo1CpcuXZKwKiLdJQ5Icrlc7e95//59oW1paQkrKyu1vyfRm2BAIo1mYWGBXbt2oXz58gCArKws9O7dW2lrAiJSjZYtWwrtBw8eID4+Xu3vqRiQqlWrpvb3I3pTDEik8ZycnLB582ZhAmlSUhL69euHvLw8iSsj0i329vZwc3MT+mWxHtK9e/eEtoODg9rfj+hNMSCRVujSpQt++OEHoX/69GmMHz++TIYAiPRJWc9DUtxSqEaNGmp/P6I3xYBEWmPy5MkYOnSo0P/zzz/x008/SVgRke4p63lId+/eFdrVq1dX63sRlQYDEmkNmUyGFStWwMfHRzg2efJk/PPPP9IVRaRjFFfUvnv3Lm7duqXW97tz547Qrlmzplrfi6g0GJBIq5iZmWH37t1wdHQE8L+Vts+dOydtYUQ6onLlynB2dhb66h5m4xAbaSoGJNI6lSpVwv79+2FjYwMAyM7ORs+ePZGQkCBxZUS6oazmIRUVFSndQapVq5ba3ouotBiQSCu5urpi586dMDY2BlC82Fznzp2VVuQlordTVgHpwYMHSk+jcoiNNAkDEmktf39/rF69WugnJCSgW7duePbsmYRVEWk/xYCUlJSkdJdHlZKSkoR2hQoVYG1trZb3IXobDEik1YYMGYL58+cL/aioKPTu3Rs5OTkSVkWk3apVqwYnJyehr667SIoTwP+dV0ikKRiQSOtNnjwZX3zxhdA/efIkBg4ciPz8fAmrItJuZTHMlpiYKLTr1KmjlvcgelsMSKT1ZDIZFi5cqLRG0p49ezBixAgUFhZKWBmR9lIMSOpaUVvxwQoGJNI0DEikEwwMDLB69Wr06tVLOLZp0yaMHTtWaadwInoziush3bhxAykpKSp/DwYk0mQMSKQzjIyM8Pfff6N9+/bCsVWrVmHChAnckoSolBwdHZWeKlPHMNvNmzeFdr169VT++kTvggGJdMq/C0m2atVKOLZ06VKGJKK3oM55SC9evFC6K1W3bl2Vvj7Ru2JAIp1jaWmJffv2KW1J8vvvv2PChAkcbiMqBXUGpBs3bghtMzMz7sNGGocBiXSStbU1Dh06BG9vb+HY77//jo8//pghiegNKQak2NhYPHz4UGWvHR8fL7Tr1q0LAwP+OiLNwn+RpLNsbGxw+PBhpZC0YsUKjBw5EgUFBRJWRqQdnJyc4ODgIPRDQkJU9trXr18X2i4uLip7XSJVYUAinVa+fHkcOXIEfn5+wrF169Zh0KBBSlscEFFJMplM6Wk2VQ6zxcbGCm0GJNJEDEik82xsbHDo0CGl4YLt27ejV69eyMzMlLAyIs2nrnlIigGpQYMGKntdIlVhQCK9YGVlhQMHDqBLly7CsUOHDqFjx454/PixhJURaTbFO0gxMTEq+X4pKChQGmJjQCJNxIBEesPCwgK7d+9Gv379hGPh4eFo1aoVkpOTJayMSHM1aNAAFStWBADI5XKcOXPmnV8zMTFRGOI2MDDgEBtpJAYk0ismJib4+++/MXbsWOHYtWvX4OvriytXrkhYGZFmUsc8pJiYGKHt5OQEc3Pzd35NIlVjQCK9Y2hoiGXLlmHGjBnCsXv37qFFixY4fvy4hJURaSZVz0NSDEiNGjV659cjUgcGJNJLMpkMgYGBWLZsmbD+yrNnz9ClSxesWbNG2uKINIxiQIqOjkZGRsY7vd7ly5eFNgMSaSoGJNJr48aNw65du4Rb/AUFBRg5ciSmTp3KBSWJ/p+bmxsqVKgAACgqKkJYWNg7vd7FixeFdtOmTd/ptYjUhQGJ9N57772H06dPo1KlSsKxH374Af369cOLFy8krIxIMxgYGCjtb/guw2wZGRm4deuW0G/SpMk71UakLgxIRACaNWuGc+fOwc3NTTi2a9cutGjRArdv35awMiLNoKp5SIp3j8qXLw9HR8d3qIpIfRiQiP6fo6MjQkND0bVrV+HY5cuX4eXlhZMnT0pYGZH0FJ9ku3DhwlsvshoZGSm03d3dIZPJ3rk2InVgQCJSYG1tjb1792LSpEnCsbS0NHTs2BGLFy+GXC6XsDoi6TRt2hTW1tYAiufqhYeHv9XrXLhwQWh7enqqpDYidWBAIhIxNDTEggULsG7dOpiamgIACgsL8eWXXyIgIADPnz+XuEKismdoaIiWLVsK/bcdZjt//rzQ9vLyeue6iNSFAYnoFYYOHYrQ0FDUqFFDOLZ161Z4e3tzUUnSS++6YGR6ejoSEhKEfvPmzVVSF5E6MCARvYanpyciIyPRvn174dj169fh7e3N9ZJI7yhO1D537hyys7NL9fXnzp0T2hUrVkStWrVUVhuRqjEgEf2HihUr4vDhw5g2bZpwLDs7GyNHjsTQoUM55EZ6w9PTE5aWlgCAvLw8pcDzJs6ePSu0fXx8OEGbNBoDEtEbMDQ0xHfffYcDBw7Azs5OOL5hwwZ4eHggIiJCwuqIyoaxsTH8/PyEfmmH2UJDQ4W2r6+vyuoiUgcGJKJS6Nq1K6Kjo5Umq968eRN+fn6YN28eCgsLJayOSP0U5yEFBwe/8dfl5+cr3XFq0aKFSusiUjUGJKJSqlGjBk6ePImZM2cKQwQFBQWYNm0a2rZti8TERIkrJFIfxXlI4eHhyMvLe6Ovi46OFtZOMjExQbNmzdRSH5GqMCARvQUjIyPMmTMHp06dUnrK7cyZM2jSpAlWrFjBNZNIJ3l7e8PMzAxA8Vy8Nx1eVrzb1KxZM2H/QyJNxYBE9A5at26Ny5cvY9CgQcKxFy9eYOzYsejSpQvu3LkjYXVEqmdqagofHx+h/6bzkE6dOiW0Fe9CEWkqBiSid1S+fHls2rQJf//9N2xtbYXjR44cgZubG/744w8UFRVJWCGRapV2X7b8/HylO0gMSKQNGJCIVGTgwIG4cuUKevToIRx7/vw5Pv74Y7Rr1w5xcXESVkekOooBJywsDAUFBa+9PiIiQlgOw8TEROkhByJNxYBEpEIODg7Ys2cP1q5dq3Q3KTg4GI0bN0ZgYCByc3MlrJDo3fn4+MDY2BhA8ZByVFTUa68/evSo0Pbz84OFhYVa6yNSBQYkIhWTyWQYNmwYrl27hr59+wrH8/LyMGvWLDRu3BjHjx+XsEKid2Nubg5vb2+h/1/DbIcPHxbanTp1UltdRKrEgESkJlWqVMGOHTuwa9cuVKtWTTgeHx+PDh06ICAgAHfv3pWwQqK396bzkB4/fqy0/hEDEmkLBiQiNevduzeuXbuGzz77DAYG//uW27JlC1xcXDBv3jzk5ORIWCFR6SkGpJCQkFcuknr48GHhIYUqVarA3d29TOojelcMSERlwNraGr/88gsiIiKUhiYyMzMxbdo0NGzYEDt37uTaSaQ1/Pz8YGhoCAB49uwZLl269NLr9u7dK7S7du2q9CGBSJPxXypRGfLw8EB4eDj+/PNPpT3dEhMT8f7776NNmzbc1420Qrly5eDl5SX0XzbMlpeXhwMHDgj9nj17lkltRKrAgERUxgwMDPDhhx/ixo0bmDhxIoyMjIRzISEh8Pb2RkBAABISEiSskui//dc8pFOnTiEjIwMAYGZmxvlHpFUYkIgkYmtri8WLFyMmJkZp7STgf/OTPvnkE6SkpEhUIdHriechiRdE3bFjh9Du1KkTLC0ty6w2onfFgEQkMRcXF+zduxfHjh1TmsBaUFCAZcuWwcnJCZMnT8ajR48krJKopBYtWghzih4/foyrV68K5/Lz87Fz506h369fvzKvj+hdMCARaYj27dvjwoULWL9+PRwdHYXj2dnZWLhwIWrXro0pU6YwKJHGsLGxQdOmTYW+4jDb8ePHkZaWBqB49WzOPyJtw4BEpEEMDAwwZMgQXL9+HUuWLEHlypWFc5mZmZg/fz5q166NyZMnIzU1VcJKiYq9ah7Sxo0bhXa3bt1Qvnz5siyL6J0xIBFpIFNTU4wfPx4JCQn48ccflZ54y8zMxMKFC+Ho6IhPP/0UiYmJElZK+k4xIAUHB0Mul+PFixfYtWuXcPyDDz6QojSidyKTc+EVIo33/Plz/P7771i4cCHS09OVzhkYGKB///6YNGmS0mPXRGUhPT0d9vb2Qj82Nhbh4eEYNWoUgOJhuNTUVJiZmUlVItFb4R0kIi1gZWWFKVOmICkpCYsWLUKVKlWEc0VFRdiyZQuaNWuGNm3a4J9//nnlqsZEqmZnZ4dGjRoJ/dOnT2PlypVCf/DgwQxHpJUYkIi0SLly5fDll1/i1q1b+OOPP+Dk5KR0Pjg4GH369EHdunWxcOFCPH78WKJKSZ8oDrPt2bMHYWFhQn/06NFSlET0zjjERqTFCgsLsWvXLixatAhnz54tcd7MzAyDBw/Gxx9/zOE3Upvt27ejf//+AABLS0tkZmYCKF45PjIyUsrSiN4aAxKRjggLC8Mvv/yCHTt2vHSIzcPDAx999BEGDRoEGxsbCSokXfXw4UOlJy7/tWrVKmEuEpG2YUAi0jHJycn4448/8Oeff750zSRzc3O8//77GDlyJNq2bcvNQ0klXF1dERsbK/Tt7Oxw584dWFhYSFgV0dvjT0YiHVOjRg189913SE5OxoYNG9CyZUul89nZ2diwYQPat2+P2rVrY9q0abh27ZpE1ZIuuHHjRoltRMaNG8dwRFqNd5CI9MDVq1excuVKrFu37pUTt5s0aYJBgwZh4MCBSit5E4nJ5XJcvnwZu3btwq5du3D58uUS19y/fx9Vq1aVoDoi1WBAItIjubm52Lt3L/766y8cOnSoxOai/2rWrBn69++Pvn37lnhSjvRTXl4egoODsW/fPuzZswe3bt165bUymQwxMTFo2LBhGVZIpFoMSER6KjU1FZs3b8b69esRHR39yuuaNGmCXr164b333oOHhwdkMlkZVklSunfvHg4dOoSDBw/iyJEjeP78+Suvbdy4MerWrQsHBwd8+eWXqF27dhlWSqR6DEhEhLi4OGzevBl///034uLiXnmdg4MDunfvju7du8Pf3x9WVlZlWCWpW1ZWFoKDg3Hs2DEcOXIEMTExr73ex8cHvXv3Rp8+fVC/fv0yqpKobDAgEZFALpfjypUr2Lp1K3bt2oWrV6++8lojIyO0bNkSHTt2RIcOHeDp6QlDQ8MyrJbeVW5uLs6ePYtTp07h5MmTCA8PR15e3iuvNzMzQ4cOHdCjRw/07NkTDg4OZVgtUdliQCKiV4qLi8OePXuwe/duhIWF4XU/LsqXL4/WrVujXbt2aNOmDRo3bszApGEyMjJw9uxZhISEICQkBOfOnUNubu5rv6Z27dro2rUrunbtCn9/fz6ZRnqDAYmI3sijR49w6NAh7N+/H0eOHMGTJ09ee721tTX8/Pzg5+eHFi1aoFmzZhySK0MFBQW4du0aIiIicO7cOYSHh+Pq1auvDblA8b5/7dq1Q8eOHdGpUyfUq1eP885ILzEgEVGpFRYWIiIiAkeOHMHRo0dx9uxZFBQUvPZrZDIZXF1d0bx5c3h5ecHLywtubm4wNzcvo6p1V15eHmJjYxEdHY2oqChERUUhOjoaWVlZ//m15ubmaNGiBdq1a4d27dqhWbNmMDIyKoOqiTQbAxIRvbPnz5/jzJkzOHnyJE6fPo3IyMiXbnciZmhoCBcXFzRp0gSNGzdGo0aN0LBhQ9SoUYMrfL9EYWEhkpKScPXqVeHP5cuXERsb+58B9V8VKlSAr68vWrdujVatWsHT0xMmJiZqrpxI+zAgEZHKvXjxAmfPnkVYWBhCQ0Nx7tw5ZGRkvPHXW1pawsXFBc7OznB2dka9evVQt25dODk5wdbWVqeHfAoKCnD37l3cunULN2/eREJCAm7cuIG4uDjcuHHjtZOoxQwNDdGoUSM0a9YMvr6+8PPzQ/369XX6vx+RqjAgEZHaFRUVIT4+HmfPnkVkZCQiIiJw6dIl5OTklPq1rKysULt2bdSsWRM1a9ZEjRo14ODggGrVqqFKlSqoXLkyKlSooJF3oDIzM/Hw4UOkpqYiJSUF9+/fx71795CcnIzk5GTcuXMHycnJb3T3TczY2Biurq7w9PSEh4cH3N3d0bRpU06qJnpLDEhEJImCggLExcXh4sWLuHz5MmJiYhATE4O7d+++82sbGRnBzs4O9vb2sLOzg62tLWxtbVG+fHlYWVnB2toa5cqVg4WFBSwsLGBqair8MTIygpGREQwMDCCTySCTySCXy1FYWIjCwkLk5+cjLy8PeXl5yM7OFv68ePECL168wPPnz/H06VNkZGTg6dOnSE9PR3p6OtLS0pCZmamC/3LFT5Y1bNgQDRs2hJubG5o0aQJnZ2cOlRGpEAMSEWmUZ8+eITY2FtevX0d8fDzi4uKQkJCAmzdv4sWLF1KXV2aqVKkCJycnYWhRcbiRd4WI1I8BiYi0glwuR1paGm7duoVbt24Jw1LJyclISUnBvXv3kJqaivz8fKlL/U92dnaoWrUqHBwcULVqVdSoUUP4U7t2bdSqVYtP9xFJjAGJiHSGXC7H06dP8eDBA6SlpQnDW0+ePMGTJ0+QkZGB58+f49mzZ8jKykJWVhYyMzORm5sr/CksLERBQQEKCwshl8shl8thYGAAAwMDGBoawtjYGCYmJjA2Noa5ubnwp1y5crCyskK5cuVQvnx52NjYwMbGRmmor1KlSrC3t4exsbHU/6mI6D8wIBERERGJaN5jHkREREQSY0AiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhJhQCIiIiISYUAiIiIiEmFAIiIiIhL5PxxpDhR+pBK3AAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from spectre.IO.H5.IterElements import iter_elements\n", "\n", "# Create a 3D plot\n", "ax = plt.gcf().add_subplot(111, projection=\"3d\")\n", "ax.axis(\"off\")\n", "\n", "# Iterate over elements\n", "for element in iter_elements(\n", " open_volfiles(h5files, subfile_name),\n", " obs_ids=obs_ids[0],\n", " element_patterns=[\"B3,*\"], # Only plot elements in block 3\n", "):\n", " # Draw outline of the element by mapping the edges of the logical cube to\n", " # inertial coordinates using the element map\n", " for d in range(3):\n", " for edge in range(4):\n", " line = np.zeros((3, 100))\n", " line[d, :] = np.linspace(-1, 1, 100)\n", " line[(d + 1) % 3, :] = 2 * (edge % 2) - 1\n", " line[(d + 2) % 3, :] = 2 * (edge // 2) - 1\n", " x, y, z = element.map(line)\n", " ax.plot(x, y, z, color=\"black\")\n", "\n", "# Make plot square\n", "ax.set_aspect(\"equal\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Transforming volume data\n", "\n", "Often you want to post-process volume data to compute derived quantities from\n", "the ones the simulation has written out. You can sometimes do this within tools\n", "like ParaView (e.g. using ParaView's \"Calculator\" filter) if the computation is\n", "simple enough and pointwise (i.e., needs no derivatives or other mesh\n", "information). If you can't get what you need in ParaView, you can use `spectre\n", "transform-vol`. It takes any Python function (a \"kernel\"), runs it over your\n", "volume data, and writes the result back into the files.\n", "\n", "For example, let's add the number of grid points in each element as a field\n", "that we can visualize:\n", "\n", "```sh\n", "spectre transform-vol BbhVolume*.h5 -d VolumeData \\\n", " -k spectre.Spectral.Mesh3D:extents\n", "```\n", "\n", "You will be prompted to select an output dataset name (hit enter to select the\n", "default \"Extents\"). The result will be written back into the H5 files. If you\n", "now regenerate an XDMF file for the volume data you will be able to see the\n", "output in ParaView.\n", "\n", "The `transform-vol` tool supports arbitrary Python functions as kernels. Many\n", "Python functions from the `spectre` module are useful kernels. For example,\n", "here are some useful kernels:\n", "\n", "- p-refinement (number of grid points per dimension):\n", " `spectre.Spectral.Mesh3D:extents`\n", "- Relative/absolute truncation error (from power monitors):\n", " `spectre.NumericalAlgorithms.LinearOperators:relative_truncation_error`\n", " or `absolute_truncation_error`\n", "- Coordinates in different frames: `Element:grid_coordinates` or\n", " `Element:distorted_coordinates`\n", "\n", "You can find more useful kernels by browsing the `spectre.PointwiseFunctions`\n", "module: https://spectre-code.org/py/_autosummary/spectre.PointwiseFunctions.html\n", "\n", "You can also write your own kernels. Create a Python file, e.g. `kernel.py`, and\n", "write a function like this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%file kernel.py\n", "from spectre.DataStructures.Tensor import Scalar, DataVector\n", "\n", "def lapse_squared(lapse: Scalar[DataVector]) -> Scalar[DataVector]:\n", " return np.array(lapse)**2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now you can run this kernel over your volume data like this:\n", "\n", "```sh\n", "spectre transform-vol BbhVolume*.h5 -d VolumeData \\\n", " -e kernel.py -k lapse_squared\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can find more details by running `spectre transform-vol --help`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.13" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 } ================================================ FILE: docs/_templates/autosummary/module.rst ================================================ {% extends "!autosummary/module.rst" %} .. Distributed under the MIT License. See LICENSE.txt for details. .. Include pybindings documentation. This won't do anything for modules that have no pybindings but print a warning. {% block modules %} .. automodule:: {{ fullname }}._Pybindings .. currentmodule:: {{ fullname }} {{ super() }} {% endblock %} ================================================ FILE: docs/cli.rst ================================================ .. Distributed under the MIT License. See LICENSE.txt for details. .. click:: spectre.__main__:cli :prog: spectre :nested: full ================================================ FILE: docs/conf.py ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # import os import sys # -- Project information ----------------------------------------------------- project = "SpECTRE Python interface" copyright = "2017-2026, SXS Collaboration" author = "SXS Collaboration" # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ "sphinx.ext.autodoc", "sphinx.ext.autosummary", "sphinx.ext.mathjax", # Parse Numpy-style docstrings "sphinx.ext.napoleon", # Support markdown files "myst_parser", # "breathe", "sphinx_click", ] # Autodoc configuration autodoc_default_options = { "members": True, "undoc-members": True, "inherited-members": True, } autodoc_preserve_defaults = True # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = "furo" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] # -- C++ documentation with Breathe + Exhale --------------------------------- # We have also experimented with generating our C++ documentation with Sphinx. # See issue: https://github.com/sxs-collaboration/spectre/issues/2138 # Tell sphinx what the primary language being documented is. # primary_domain = "cpp" # Tell sphinx what the pygments highlight language should be. # highlight_language = "cpp" # Configure Breathe for parsing and including C++ documentation. # breathe_projects = {"SpECTRE": "@CMAKE_BINARY_DIR@/docs/xml"} # breathe_default_project = "SpECTRE" # Setup the Exhale extension for automatically building namespace, # file, and group documentation. We have had issues with Exhale # failing when dealing with function overloads. To enable you must # add `'exhale'` to the extensions. # # exhale_args = { # # These arguments are required # "containmentFolder": "./api", # "rootFileName": "library_root.rst", # "rootFileTitle": "Library API", # "doxygenStripFromPath": "..", # # Suggested optional arguments # "createTreeView": True, # # TIP: if using the sphinx-bootstrap-theme, you need # # "treeViewIsBootstrap": True, # "exhaleExecutesDoxygen": False # # "exhaleDoxygenStdin": "INPUT = ../include" # } # # a simple label style which uses the bibtex keys for labels # class NumberedLabelStyle(BaseLabelStyle): # def format_labels(self, sorted_entries): # for entry in sorted_entries: # # Add one since refs usually start at 1 not 0 # yield str(sorted_entries.index(entry) + 1) # class SpectreBibStyle(UnsrtStyle): # default_label_style = NumberedLabelStyle # register_plugin('pybtex.style.formatting', 'SpectreStyle', SpectreBibStyle) ================================================ FILE: docs/config/DoxygenLayout_1_8_10.xml ================================================ ================================================ FILE: docs/config/DoxygenLayout_1_9_8.xml ================================================ ================================================ FILE: docs/config/MathJax.js ================================================ window.MathJax = { tex: { tags: "ams", packages: ['base', 'ams', 'bbox', 'color', 'physics', 'newcommand', 'boldsymbol'] }, options: { ignoreHtmlClass: 'tex2jax_ignore', processHtmlClass: 'tex2jax_process' }, loader: { load: ['[tex]/bbox', '[tex]/color', '[tex]/physics', '[tex]/newcommand', '[tex]/boldsymbol'] } }; (function () { var script = document.createElement('script'); script.src = 'https://cdn.jsdelivr.net/npm/mathjax@3.1.0/es5/tex-chtml-full.js'; // cryptographic hashes can be found here: // https://www.jsdelivr.com/package/npm/mathjax?path=es5 script.integrity = 'sha256-HJUiQvFxmEVWZ3D0qyz7Bg0JyJ2bkriI/WHQYo1ch5Y='; script.crossOrigin = 'anonymous'; script.async = true; document.head.appendChild(script); })(); ================================================ FILE: docs/config/cppreference-doxygen-web.tag.xml ================================================ algorithm cpp/header/algorithm std any cpp/header/any std array cpp/header/array std atomic cpp/header/atomic std bitset cpp/header/bitset std cassert cpp/header/cassert std ccomplex cpp/header/ccomplex std cctype cpp/header/cctype std cerrno cpp/header/cerrno std cfenv cpp/header/cfenv std cfloat cpp/header/cfloat std chrono cpp/header/chrono std cinttypes cpp/header/cinttypes std ciso646 cpp/header/ciso646 std climits cpp/header/climits std clocale cpp/header/clocale std cmath cpp/header/cmath std codecvt cpp/header/codecvt std complex cpp/header/complex std condition_variable cpp/header/condition_variable std csetjmp cpp/header/csetjmp std csignal cpp/header/csignal std cstdalign cpp/header/cstdalign std cstdarg cpp/header/cstdarg std cstdbool cpp/header/cstdbool std cstddef cpp/header/cstddef std cstdint cpp/header/cstdint std cstdio cpp/header/cstdio std cstdlib cpp/header/cstdlib std cstring cpp/header/cstring std ctgmath cpp/header/ctgmath std ctime cpp/header/ctime std cuchar cpp/header/cuchar std cwchar cpp/header/cwchar std cwctype cpp/header/cwctype std deque cpp/header/deque std exception cpp/header/exception std execution cpp/header/execution std filesystem cpp/header/filesystem std forward_list cpp/header/forward_list std fstream cpp/header/fstream std functional cpp/header/functional std future cpp/header/future std initializer_list cpp/header/initializer_list std iomanip cpp/header/iomanip std ios cpp/header/ios std iosfwd cpp/header/iosfwd std iostream cpp/header/iostream std istream cpp/header/istream std iterator cpp/header/iterator std limits cpp/header/limits std list cpp/header/list std locale cpp/header/locale std map cpp/header/map std memory cpp/header/memory std memory_resource cpp/header/memory_resource std mutex cpp/header/mutex std new cpp/header/new std numeric cpp/header/numeric std optional cpp/header/optional std ostream cpp/header/ostream std queue cpp/header/queue std random cpp/header/random std ratio cpp/header/ratio std regex cpp/header/regex std scoped_allocator cpp/header/scoped_allocator std set cpp/header/set std shared_mutex cpp/header/shared_mutex std sstream cpp/header/sstream std stack cpp/header/stack std stdexcept cpp/header/stdexcept std streambuf cpp/header/streambuf std string cpp/header/string std string_view cpp/header/string_view std strstream cpp/header/strstream std system_error cpp/header/system_error std thread cpp/header/thread std tuple cpp/header/tuple std type_traits cpp/header/type_traits std typeindex cpp/header/typeindex std typeinfo cpp/header/typeinfo std unordered_map cpp/header/unordered_map std unordered_set cpp/header/unordered_set std utility cpp/header/utility std valarray cpp/header/valarray std variant cpp/header/variant std vector cpp/header/vector std std std::FILE T _Exit cpp/utility/program/_Exit (T... args) T abort cpp/utility/program/abort (T... args) T abs(float) cpp/numeric/math/fabs (T... args) T abs(int) cpp/numeric/math/abs (T... args) T accumulate cpp/algorithm/accumulate (T... args) T acos cpp/numeric/math/acos (T... args) T acosh cpp/numeric/math/acosh (T... args) std::add_const std::add_const_t std::add_cv std::add_cv_t std::add_lvalue_reference std::add_lvalue_reference_t std::add_pointer std::add_pointer_t std::add_rvalue_reference std::add_rvalue_reference_t std::add_volatile std::add_volatile_t T addressof cpp/memory/addressof (T... args) T adjacent_difference cpp/algorithm/adjacent_difference (T... args) T adjacent_find cpp/algorithm/adjacent_find (T... args) std::adopt_lock_t T advance cpp/iterator/advance (T... args) T align cpp/memory/align (T... args) std::align_val_t T aligned_alloc cpp/memory/c/aligned_alloc (T... args) std::aligned_storage std::aligned_storage_t std::aligned_union std::aligned_union_t std::alignment_of T alignment_of_v cpp/types/alignment_of T all_of cpp/algorithm/all_any_none_of (T... args) T allocate_shared cpp/memory/shared_ptr/allocate_shared (T... args) std::allocator std::allocator_arg_t std::allocator_traits std::any T any_cast cpp/utility/any/any_cast (T... args) T any_of cpp/algorithm/all_any_none_of (T... args) T apply cpp/utility/apply (T... args) std::array T as_const cpp/utility/as_const (T... args) T asctime cpp/chrono/c/asctime (T... args) T asin cpp/numeric/math/asin (T... args) T asinh cpp/numeric/math/asinh (T... args) T assoc_laguerre cpp/numeric/special_math/assoc_laguerre (T... args) T assoc_laguerref cpp/numeric/special_math/assoc_laguerre (T... args) T assoc_laguerrel cpp/numeric/special_math/assoc_laguerre (T... args) T assoc_legendre cpp/numeric/special_math/assoc_legendre (T... args) T assoc_legendref cpp/numeric/special_math/assoc_legendre (T... args) T assoc_legendrel cpp/numeric/special_math/assoc_legendre (T... args) T async cpp/thread/async (T... args) T at_quick_exit cpp/utility/program/at_quick_exit (T... args) T atan cpp/numeric/math/atan (T... args) T atan2 cpp/numeric/math/atan2 (T... args) T atanh cpp/numeric/math/atanh (T... args) T atexit cpp/utility/program/atexit (T... args) T atof cpp/string/byte/atof (T... args) T atoi cpp/string/byte/atoi (T... args) T atol cpp/string/byte/atoi (T... args) T atoll cpp/string/byte/atoi (T... args) std::atomic std::atomic_bool std::atomic_char16_t std::atomic_char32_t T atomic_compare_exchange_strong cpp/atomic/atomic_compare_exchange (T... args) T atomic_compare_exchange_strong_explicit cpp/atomic/atomic_compare_exchange (T... args) T atomic_compare_exchange_weak cpp/atomic/atomic_compare_exchange (T... args) T atomic_compare_exchange_weak_explicit cpp/atomic/atomic_compare_exchange (T... args) T atomic_exchange cpp/atomic/atomic_exchange (T... args) T atomic_exchange_explicit cpp/atomic/atomic_exchange (T... args) T atomic_fetch_add cpp/atomic/atomic_fetch_add (T... args) T atomic_fetch_add_explicit cpp/atomic/atomic_fetch_add (T... args) T atomic_fetch_and cpp/atomic/atomic_fetch_sub (T... args) T atomic_fetch_and_explicit cpp/atomic/atomic_fetch_sub (T... args) T atomic_fetch_or cpp/atomic/atomic_fetch_or (T... args) T atomic_fetch_or_explicit cpp/atomic/atomic_fetch_or (T... args) T atomic_fetch_sub cpp/atomic/atomic_fetch_sub (T... args) T atomic_fetch_sub_explicit cpp/atomic/atomic_fetch_sub (T... args) T atomic_fetch_xor cpp/atomic/atomic_fetch_xor (T... args) T atomic_fetch_xor_explicit cpp/atomic/atomic_fetch_xor (T... args) std::atomic_flag T atomic_init cpp/atomic/atomic_init (T... args) std::atomic_int std::atomic_int16_t std::atomic_int32_t std::atomic_int64_t std::atomic_int8_t std::atomic_int_fast16_t std::atomic_int_fast32_t std::atomic_int_fast64_t std::atomic_int_fast8_t std::atomic_int_least16_t std::atomic_int_least32_t std::atomic_int_least64_t std::atomic_int_least8_t std::atomic_intmax_t std::atomic_intptr_t T atomic_is_lock_free cpp/atomic/atomic_is_lock_free (T... args) std::atomic_llong T atomic_load cpp/atomic/atomic_load (T... args) T atomic_load_explicit cpp/atomic/atomic_load (T... args) std::atomic_long std::atomic_ptrdiff_t std::atomic_schar std::atomic_short T atomic_signal_fence cpp/atomic/atomic_signal_fence (T... args) std::atomic_size_t T atomic_store cpp/atomic/atomic_store (T... args) T atomic_store_explicit cpp/atomic/atomic_store (T... args) T atomic_thread_fence cpp/atomic/atomic_thread_fence (T... args) std::atomic_uchar std::atomic_uint std::atomic_uint16_t std::atomic_uint32_t std::atomic_uint64_t std::atomic_uint8_t std::atomic_uint_fast16_t std::atomic_uint_fast32_t std::atomic_uint_fast64_t std::atomic_uint_fast8_t std::atomic_uint_least16_t std::atomic_uint_least32_t std::atomic_uint_least64_t std::atomic_uint_least8_t std::atomic_uintmax_t std::atomic_uintptr_t std::atomic_ullong std::atomic_ulong std::atomic_ushort std::atomic_wchar_t std::auto_ptr std::back_insert_iterator T back_inserter cpp/iterator/back_inserter (T... args) std::bad_alloc std::bad_any_cast std::bad_array_length std::bad_array_new_length std::bad_cast std::bad_exception std::bad_function_call std::bad_optional_access std::bad_typeid std::bad_variant_access std::bad_weak_ptr std::basic_filebuf std::basic_fstream std::basic_ifstream std::basic_ios std::basic_iostream std::basic_istream std::basic_istringstream std::basic_ofstream std::basic_ostream std::basic_ostringstream std::basic_regex std::basic_streambuf std::basic_string std::basic_string_view std::basic_stringbuf std::basic_stringstream T begin cpp/iterator/begin (T... args) std::bernoulli_distribution T beta cpp/numeric/special_math/beta (T... args) T betaf cpp/numeric/special_math/beta (T... args) T betal cpp/numeric/special_math/beta (T... args) std::bidirectional_iterator_tag std::binary_function std::binary_negate T binary_search cpp/algorithm/binary_search (T... args) T bind cpp/utility/functional/bind (T... args) std::binomial_distribution std::bit_and std::bit_not std::bit_or std::bitset std::bool_constant T boolalpha cpp/io/manip/boolalpha (T... args) std::boyer_moore_horspool_searcher std::boyer_moore_searcher T bsearch cpp/algorithm/bsearch (T... args) T btowc cpp/string/multibyte/btowc (T... args) T c16rtomb cpp/string/multibyte/c16rtomb (T... args) T c32rtomb cpp/string/multibyte/c32rtomb (T... args) T call_once cpp/thread/call_once (T... args) T calloc cpp/memory/c/calloc (T... args) std::cauchy_distribution T cbegin cpp/iterator/begin (T... args) T cbrt cpp/numeric/math/cbrt (T... args) T ceil cpp/numeric/math/ceil (T... args) T cend cpp/iterator/end (T... args) std::centi std::cerr std::char_traits std::chi_squared_distribution std::chrono std::cin T clamp cpp/algorithm/clamp (T... args) T clearerr cpp/io/c/clearerr (T... args) T clock cpp/chrono/c/clock (T... args) std::clock_t std::clog std::cmatch std::codecvt std::codecvt_base std::codecvt_byname std::codecvt_utf16 std::codecvt_utf8 std::codecvt_utf8_utf16 std::collate std::collate_byname std::common_type std::common_type_t T comp_ellint_1 cpp/numeric/special_math/comp_ellint_1 (T... args) T comp_ellint_1f cpp/numeric/special_math/comp_ellint_1 (T... args) T comp_ellint_1l cpp/numeric/special_math/comp_ellint_1 (T... args) T comp_ellint_2 cpp/numeric/special_math/comp_ellint_2 (T... args) T comp_ellint_2f cpp/numeric/special_math/comp_ellint_2 (T... args) T comp_ellint_2l cpp/numeric/special_math/comp_ellint_2 (T... args) T comp_ellint_3 cpp/numeric/special_math/comp_ellint_3 (T... args) T comp_ellint_3f cpp/numeric/special_math/comp_ellint_3 (T... args) T comp_ellint_3l cpp/numeric/special_math/comp_ellint_3 (T... args) std::complex std::condition_variable std::condition_variable_any std::conditional std::conditional_t std::conjunction T conjunction_v cpp/types/conjunction T const_pointer_cast cpp/memory/shared_ptr/pointer_cast (T... args) T copy cpp/algorithm/copy (T... args) T copy_backward cpp/algorithm/copy_backward (T... args) T copy_if cpp/algorithm/copy (T... args) T copy_n cpp/algorithm/copy_n (T... args) T copysign cpp/numeric/math/copysign (T... args) T cos cpp/numeric/math/cos (T... args) T cosh cpp/numeric/math/cosh (T... args) T count cpp/algorithm/count (T... args) T count_if cpp/algorithm/count (T... args) std::cout T crbegin cpp/iterator/rbegin (T... args) T cref cpp/utility/functional/ref (T... args) std::cregex_iterator std::cregex_token_iterator T crend cpp/iterator/rend (T... args) std::csub_match T ctime cpp/chrono/c/ctime (T... args) std::ctype std::ctype_base std::ctype_byname T current_exception cpp/error/current_exception (T... args) T cyl_bessel_i cpp/numeric/special_math/cyl_bessel_i (T... args) T cyl_bessel_if cpp/numeric/special_math/cyl_bessel_i (T... args) T cyl_bessel_il cpp/numeric/special_math/cyl_bessel_i (T... args) T cyl_bessel_j cpp/numeric/special_math/cyl_bessel_j (T... args) T cyl_bessel_jf cpp/numeric/special_math/cyl_bessel_j (T... args) T cyl_bessel_jl cpp/numeric/special_math/cyl_bessel_j (T... args) T cyl_bessel_k cpp/numeric/special_math/cyl_bessel_k (T... args) T cyl_bessel_kf cpp/numeric/special_math/cyl_bessel_k (T... args) T cyl_bessel_kl cpp/numeric/special_math/cyl_bessel_k (T... args) T cyl_neumann cpp/numeric/special_math/cyl_neumann (T... args) T cyl_neumannf cpp/numeric/special_math/cyl_neumann (T... args) T cyl_neumannl cpp/numeric/special_math/cyl_neumann (T... args) T data cpp/iterator/data (T... args) T dec cpp/io/manip/hex (T... args) std::deca std::decay std::decay_t std::deci T declare_no_pointers cpp/memory/gc/declare_no_pointers (T... args) T declare_reachable cpp/memory/gc/declare_reachable (T... args) T declval cpp/utility/declval (T... args) std::default_delete std::default_random_engine std::default_searcher T defaultfloat cpp/io/manip/fixed (T... args) std::defer_lock_t std::deque T destroy cpp/memory/destroy (T... args) T destroy_at cpp/memory/destroy_at (T... args) T destroy_n cpp/memory/destroy_n (T... args) T difftime cpp/chrono/c/difftime (T... args) std::discard_block_engine std::discrete_distribution std::disjunction T disjunction_v cpp/types/disjunction T distance cpp/iterator/distance (T... args) T div cpp/numeric/math/div (T... args) std::div_t std::divides std::domain_error T dynamic_pointer_cast cpp/memory/shared_ptr/pointer_cast (T... args) T ellint_1 cpp/numeric/special_math/ellint_1 (T... args) T ellint_1f cpp/numeric/special_math/ellint_1 (T... args) T ellint_1l cpp/numeric/special_math/ellint_1 (T... args) T ellint_2 cpp/numeric/special_math/ellint_2 (T... args) T ellint_2f cpp/numeric/special_math/ellint_2 (T... args) T ellint_2l cpp/numeric/special_math/ellint_2 (T... args) T ellint_3 cpp/numeric/special_math/ellint_3 (T... args) T ellint_3f cpp/numeric/special_math/ellint_3 (T... args) T ellint_3l cpp/numeric/special_math/ellint_3 (T... args) T empty cpp/iterator/empty (T... args) std::enable_if std::enable_if_t std::enable_shared_from_this T end cpp/iterator/end (T... args) T endl cpp/io/manip/endl (T... args) T ends cpp/io/manip/ends (T... args) T equal cpp/algorithm/equal (T... args) T equal_range cpp/algorithm/equal_range (T... args) std::equal_to T erf cpp/numeric/math/erf (T... args) T erfc cpp/numeric/math/erfc (T... args) std::errc std::error_category std::error_code std::error_condition std::exa std::exception std::exception_ptr T exchange cpp/utility/exchange (T... args) T exclusive_scan cpp/algorithm/exclusive_scan (T... args) std::execution T exit cpp/utility/program/exit (T... args) T exp cpp/numeric/math/exp (T... args) T exp2 cpp/numeric/math/exp2 (T... args) std::experimental T expint cpp/numeric/special_math/expint (T... args) T expintf cpp/numeric/special_math/expint (T... args) T expintl cpp/numeric/special_math/expint (T... args) T expm1 cpp/numeric/math/expm1 (T... args) std::exponential_distribution std::extent T extent_v cpp/types/extent std::extreme_value_distribution T fabs cpp/numeric/math/fabs (T... args) std::false_type T fclose cpp/io/c/fclose (T... args) T fdim cpp/numeric/math/fdim (T... args) T feclearexcept cpp/numeric/fenv/feclearexcept (T... args) T fegetenv cpp/numeric/fenv/feenv (T... args) T fegetexceptflag cpp/numeric/fenv/feexceptflag (T... args) T fegetround cpp/numeric/fenv/feround (T... args) T feholdexcept cpp/numeric/fenv/feholdexcept (T... args) std::femto T feof cpp/io/c/feof (T... args) T feraiseexcept cpp/numeric/fenv/feraiseexcept (T... args) T ferror cpp/io/c/ferror (T... args) T fesetenv cpp/numeric/fenv/feenv (T... args) T fesetexceptflag cpp/numeric/fenv/feexceptflag (T... args) T fesetround cpp/numeric/fenv/feround (T... args) T fetestexcept cpp/numeric/fenv/fetestexcept (T... args) T feupdateenv cpp/numeric/fenv/feupdateenv (T... args) T fflush cpp/io/c/fflush (T... args) T fgetc cpp/io/c/fgetc (T... args) T fgetpos cpp/io/c/fgetpos (T... args) T fgets cpp/io/c/fgets (T... args) T fgetwc cpp/io/c/fgetwc (T... args) T fgetws cpp/io/c/fgetws (T... args) std::filebuf std::filesystem T fill cpp/algorithm/fill (T... args) T fill_n cpp/algorithm/fill_n (T... args) T find cpp/algorithm/find (T... args) T find_end cpp/algorithm/find_end (T... args) T find_first_of cpp/algorithm/find_first_of (T... args) T find_if cpp/algorithm/find (T... args) T find_if_not cpp/algorithm/find (T... args) std::fisher_f_distribution T fixed cpp/io/manip/fixed (T... args) T floor cpp/numeric/math/floor (T... args) T flush cpp/io/manip/flush (T... args) T fma cpp/numeric/math/fma (T... args) T fmax cpp/numeric/math/fmax (T... args) T fmin cpp/numeric/math/fmin (T... args) T fmod cpp/numeric/math/fmod (T... args) T fopen cpp/io/c/fopen (T... args) T for_each cpp/algorithm/for_each (T... args) T for_each_n cpp/algorithm/for_each_n (T... args) T forward cpp/utility/forward (T... args) T forward_as_tuple cpp/utility/tuple/forward_as_tuple (T... args) std::forward_iterator_tag std::forward_list T fpclassify cpp/numeric/math/fpclassify (T... args) std::fpos std::fpos_t T fprintf cpp/io/c/fprintf (T... args) T fputc cpp/io/c/fputc (T... args) T fputs cpp/io/c/fputs (T... args) T fputwc cpp/io/c/fputwc (T... args) T fputws cpp/io/c/fputws (T... args) T fread cpp/io/c/fread (T... args) T free cpp/memory/c/free (T... args) T freopen cpp/io/c/freopen (T... args) T frexp cpp/numeric/math/frexp (T... args) std::front_insert_iterator T front_inserter cpp/iterator/front_inserter (T... args) T fscanf cpp/io/c/fscanf (T... args) T fseek cpp/io/c/fseek (T... args) T fsetpos cpp/io/c/fsetpos (T... args) std::fstream T ftell cpp/io/c/ftell (T... args) std::function std::future T future_category cpp/thread/future/future_category (T... args) std::future_error T fwprintf cpp/io/c/fwprintf (T... args) T fwrite cpp/io/c/fwrite (T... args) T fwscanf cpp/io/c/fwscanf (T... args) std::gamma_distribution T gcd cpp/numeric/gcd (T... args) T generate cpp/algorithm/generate (T... args) T generate_canonical cpp/numeric/random/generate_canonical (T... args) T generate_n cpp/algorithm/generate_n (T... args) T generic_category cpp/error/generic_category (T... args) std::geometric_distribution T get_if cpp/utility/variant/get_if (T... args) T get_money cpp/io/manip/get_money (T... args) T get_new_handler cpp/memory/new/get_new_handler (T... args) T get_pointer_safety cpp/memory/gc/get_pointer_safety (T... args) T get_temporary_buffer cpp/memory/get_temporary_buffer (T... args) T get_terminate cpp/error/get_terminate (T... args) T get_time cpp/io/manip/get_time (T... args) T get_unexpected cpp/error/get_unexpected (T... args) T getc cpp/io/c/fgetc (T... args) T getchar cpp/io/c/getchar (T... args) T getenv cpp/utility/program/getenv (T... args) T getline cpp/string/basic_string/getline (T... args) T gets cpp/io/c/gets (T... args) T getwchar cpp/io/c/getwchar (T... args) std::giga T gmtime cpp/chrono/c/gmtime (T... args) std::greater std::greater_equal std::gslice std::gslice_array T has_facet cpp/locale/has_facet (T... args) std::has_unique_object_representations T has_unique_object_representations_v cpp/types/has_unique_object_representations std::has_virtual_destructor T has_virtual_destructor_v cpp/types/has_virtual_destructor std::hash std::hecto T hermite cpp/numeric/special_math/hermite (T... args) T hermitef cpp/numeric/special_math/hermite (T... args) T hermitel cpp/numeric/special_math/hermite (T... args) T hex cpp/io/manip/hex (T... args) T hexfloat cpp/io/manip/fixed (T... args) T holds_alternative cpp/utility/variant/holds_alternative (T... args) T hypot cpp/numeric/math/hypot (T... args) std::ifstream T ilogb cpp/numeric/math/ilogb (T... args) T imaxdiv cpp/numeric/math/div (T... args) std::imaxdiv_t T in_place cpp/utility/in_place (T... args) std::in_place_index_t std::in_place_t std::in_place_tag std::in_place_type_t T includes cpp/algorithm/includes (T... args) T inclusive_scan cpp/algorithm/inclusive_scan (T... args) std::independent_bits_engine std::index_sequence std::index_sequence_for std::indirect_array std::initializer_list T inner_product cpp/algorithm/inner_product (T... args) T inplace_merge cpp/algorithm/inplace_merge (T... args) std::input_iterator_tag std::insert_iterator T inserter cpp/iterator/inserter (T... args) std::int16_t std::int32_t std::int64_t std::int8_t std::int_fast16_t std::int_fast32_t std::int_fast64_t std::int_fast8_t std::int_least16_t std::int_least32_t std::int_least64_t std::int_least8_t std::integer_sequence std::integral_constant T internal cpp/io/manip/left (T... args) std::intmax_t std::intptr_t std::invalid_argument T invoke cpp/utility/functional/invoke (T... args) std::ios_base std::iostream T iostream_category cpp/io/iostream_category (T... args) T iota cpp/algorithm/iota (T... args) std::is_abstract T is_abstract_v cpp/types/is_abstract std::is_arithmetic T is_arithmetic_v cpp/types/is_arithmetic std::is_array T is_array_v cpp/types/is_array std::is_assignable T is_assignable_v cpp/types/is_assignable std::is_base_of T is_base_of_v cpp/types/is_base_of std::is_bind_expression T is_bind_expression_v cpp/utility/functional/is_bind_expression std::is_callable T is_callable_v cpp/types/is_callable std::is_class T is_class_v cpp/types/is_class std::is_compound T is_compound_v cpp/types/is_compound std::is_const T is_const_v cpp/types/is_const std::is_constructible T is_constructible_v cpp/types/is_constructible std::is_convertible T is_convertible_v cpp/types/is_convertible std::is_copy_assignable T is_copy_assignable_v cpp/types/is_copy_assignable std::is_copy_constructible T is_copy_constructible_v cpp/types/is_copy_constructible std::is_default_constructible T is_default_constructible_v cpp/types/is_default_constructible std::is_destructible T is_destructible_v cpp/types/is_destructible std::is_empty T is_empty_v cpp/types/is_empty std::is_enum T is_enum_v cpp/types/is_enum std::is_error_code_enum std::is_error_code_enum_v std::is_error_condition_enum T is_error_condition_enum_v cpp/error/error_condition/is_error_condition_enum std::is_execution_policy T is_execution_policy_v cpp/algorithm/is_execution_policy std::is_final T is_final_v cpp/types/is_final std::is_floating_point T is_floating_point_v cpp/types/is_floating_point std::is_function T is_function_v cpp/types/is_function std::is_fundamental T is_fundamental_v cpp/types/is_fundamental T is_heap cpp/algorithm/is_heap (T... args) T is_heap_until cpp/algorithm/is_heap_until (T... args) std::is_integral T is_integral_v cpp/types/is_integral std::is_literal_type T is_literal_type_v cpp/types/is_literal_type std::is_lvalue_reference T is_lvalue_reference_v cpp/types/is_lvalue_reference std::is_member_function_pointer T is_member_function_pointer_v cpp/types/is_member_function_pointer std::is_member_object_pointer T is_member_object_pointer_v cpp/types/is_member_object_pointer std::is_member_pointer T is_member_pointer_v cpp/types/is_member_pointer std::is_move_assignable T is_move_assignable_v cpp/types/is_move_assignable std::is_move_constructible T is_move_constructible_v cpp/types/is_move_constructible std::is_nothrow_assignable T is_nothrow_assignable_v cpp/types/is_assignable std::is_nothrow_callable T is_nothrow_callable_v cpp/types/is_callable std::is_nothrow_constructible T is_nothrow_constructible_v cpp/types/is_constructible std::is_nothrow_copy_assignable T is_nothrow_copy_assignable_v cpp/types/is_copy_assignable std::is_nothrow_copy_constructible T is_nothrow_copy_constructible_v cpp/types/is_copy_constructible std::is_nothrow_default_constructible T is_nothrow_default_constructible_v cpp/types/is_default_constructible std::is_nothrow_destructible T is_nothrow_destructible_v cpp/types/is_destructible std::is_nothrow_move_assignable T is_nothrow_move_assignable_v cpp/types/is_move_assignable std::is_nothrow_move_constructible T is_nothrow_move_constructible_v cpp/types/is_move_constructible std::is_nothrow_swappable T is_nothrow_swappable_v cpp/types/is_swappable std::is_nothrow_swappable_with T is_nothrow_swappable_with_v cpp/types/is_swappable_with std::is_null_pointer T is_null_pointer_v cpp/types/is_null_pointer std::is_object T is_object_v cpp/types/is_object T is_partitioned cpp/algorithm/is_partitioned (T... args) T is_permutation cpp/algorithm/is_permutation (T... args) std::is_placeholder T is_placeholder_v cpp/utility/functional/is_placeholder std::is_pod T is_pod_v cpp/types/is_pod std::is_pointer T is_pointer_v cpp/types/is_pointer std::is_polymorphic T is_polymorphic_v cpp/types/is_polymorphic std::is_reference T is_reference_v cpp/types/is_reference std::is_rvalue_reference T is_rvalue_reference_v cpp/types/is_rvalue_reference std::is_same T is_same_v cpp/types/is_same std::is_scalar T is_scalar_v cpp/types/is_scalar std::is_signed T is_signed_v cpp/types/is_signed T is_sorted cpp/algorithm/is_sorted (T... args) T is_sorted_until cpp/algorithm/is_sorted_until (T... args) std::is_standard_layout T is_standard_layout_v cpp/types/is_standard_layout std::is_swappable T is_swappable_v cpp/types/is_swappable std::is_swappable_with T is_swappable_with_v cpp/types/is_swappable_with std::is_trivial T is_trivial_v cpp/types/is_trivial std::is_trivially_assignable T is_trivially_assignable_v cpp/types/is_assignable std::is_trivially_constructible T is_trivially_constructible_v cpp/types/is_constructible std::is_trivially_copy_assignable T is_trivially_copy_assignable_v cpp/types/is_copy_assignable std::is_trivially_copy_constructible T is_trivially_copy_constructible_v cpp/types/is_copy_constructible std::is_trivially_copyable T is_trivially_copyable_v cpp/types/is_trivially_copyable std::is_trivially_default_constructible T is_trivially_default_constructible_v cpp/types/is_default_constructible std::is_trivially_destructible T is_trivially_destructible_v cpp/types/is_destructible std::is_trivially_move_assignable T is_trivially_move_assignable_v cpp/types/is_move_assignable std::is_trivially_move_constructible T is_trivially_move_constructible_v cpp/types/is_move_constructible std::is_union T is_union_v cpp/types/is_union std::is_unsigned T is_unsigned_v cpp/types/is_unsigned std::is_void T is_void_v cpp/types/is_void std::is_volatile T is_volatile_v cpp/types/is_volatile T isalnum (<cctype>) cpp/string/byte/isalnum (T... args) T isalnum (<clocale>) cpp/locale/isalnum (T... args) T isalpha (<cctype>) cpp/string/byte/isalpha (T... args) T isalpha (<clocale>) cpp/locale/isalpha (T... args) T isblank (<cctype>) cpp/string/byte/isblank (T... args) T isblank (<clocale>) cpp/locale/isblank (T... args) T iscntrl (<cctype>) cpp/string/byte/iscntrl (T... args) T iscntrl (<clocale>) cpp/locale/iscntrl (T... args) T isdigit (<cctype>) cpp/string/byte/isdigit (T... args) T isdigit (<clocale>) cpp/locale/isdigit (T... args) T isfinite cpp/numeric/math/isfinite (T... args) T isgraph (<cctype>) cpp/string/byte/isgraph (T... args) T isgraph (<clocale>) cpp/locale/isgraph (T... args) T isinf cpp/numeric/math/isinf (T... args) T islower (<cctype>) cpp/string/byte/islower (T... args) T islower (<clocale>) cpp/locale/islower (T... args) T isnan cpp/numeric/math/isnan (T... args) T isnormal cpp/numeric/math/isnormal (T... args) T isprint (<cctype>) cpp/string/byte/isprint (T... args) T isprint (<clocale>) cpp/locale/isprint (T... args) T ispunct (<cctype>) cpp/string/byte/ispunct (T... args) T ispunct (<clocale>) cpp/locale/ispunct (T... args) T isspace (<cctype>) cpp/string/byte/isspace (T... args) T isspace (<clocale>) cpp/locale/isspace (T... args) std::istream std::istream_iterator std::istreambuf_iterator std::istringstream std::istrstream T isupper (<cctype>) cpp/string/byte/isupper (T... args) T isupper (<clocale>) cpp/locale/isupper (T... args) T iswalnum cpp/string/wide/iswalnum (T... args) T iswalpha cpp/string/wide/iswalpha (T... args) T iswblank cpp/string/wide/iswblank (T... args) T iswcntrl cpp/string/wide/iswcntrl (T... args) T iswctype cpp/string/wide/iswctype (T... args) T iswdigit cpp/string/wide/iswdigit (T... args) T iswgraph cpp/string/wide/iswgraph (T... args) T iswlower cpp/string/wide/iswlower (T... args) T iswprint cpp/string/wide/iswprint (T... args) T iswpunct cpp/string/wide/iswpunct (T... args) T iswspace cpp/string/wide/iswspace (T... args) T iswupper cpp/string/wide/iswupper (T... args) T iswxdigit cpp/string/wide/iswxdigit (T... args) T isxdigit (<cctype>) cpp/string/byte/isxdigit (T... args) T isxdigit (<clocale>) cpp/locale/isxdigit (T... args) T iter_swap cpp/algorithm/iter_swap (T... args) std::iterator std::iterator_traits std::jmp_buf T kill_dependency cpp/atomic/kill_dependency (T... args) std::kilo std::knuth_b T labs cpp/numeric/math/abs (T... args) T laguerre cpp/numeric/special_math/laguerre (T... args) T laguerref cpp/numeric/special_math/laguerre (T... args) T laguerrel cpp/numeric/special_math/laguerre (T... args) T launder cpp/utility/launder (T... args) T lcm cpp/numeric/lcm (T... args) std::lconv T ldexp cpp/numeric/math/ldexp (T... args) T ldiv cpp/numeric/math/div (T... args) std::ldiv_t T left cpp/io/manip/left (T... args) T legendre cpp/numeric/special_math/legendre (T... args) T legendref cpp/numeric/special_math/legendre (T... args) T legendrel cpp/numeric/special_math/legendre (T... args) std::length_error std::less std::less_equal T lexicographical_compare cpp/algorithm/lexicographical_compare (T... args) T lgamma cpp/numeric/math/lgamma (T... args) std::linear_congruential_engine std::list T llabs cpp/numeric/math/abs (T... args) T lldiv cpp/numeric/math/div (T... args) std::lldiv_t T llrint cpp/numeric/math/rint (T... args) T llround cpp/numeric/math/round (T... args) std::locale T localeconv cpp/locale/localeconv (T... args) T localtime cpp/chrono/c/localtime (T... args) T lock cpp/thread/lock (T... args) std::lock_guard T log cpp/numeric/math/log (T... args) T log10 cpp/numeric/math/log10 (T... args) T log1p cpp/numeric/math/log1p (T... args) T logb cpp/numeric/math/logb (T... args) std::logic_error std::logical_and std::logical_not std::logical_or std::lognormal_distribution T longjmp cpp/utility/program/longjmp (T... args) T lower_bound cpp/algorithm/lower_bound (T... args) T lrint cpp/numeric/math/rint (T... args) T lround cpp/numeric/math/round (T... args) T make_any cpp/utility/any/make_any (T... args) std::make_boyer_moore_horspool_searcher std::make_boyer_moore_searcher std::make_default_searcher T make_exception_ptr cpp/error/make_exception_ptr (T... args) T make_from_tuple cpp/utility/make_from_tuple (T... args) T make_heap cpp/algorithm/make_heap (T... args) std::make_index_sequence std::make_integer_sequence T make_move_iterator cpp/iterator/make_move_iterator (T... args) T make_optional cpp/utility/optional/make_optional (T... args) T make_pair cpp/utility/pair/make_pair (T... args) T make_reverse_iterator cpp/iterator/make_reverse_iterator (T... args) T make_shared cpp/memory/shared_ptr/make_shared (T... args) std::make_signed std::make_signed_t T make_tuple cpp/utility/tuple/make_tuple (T... args) T make_unique cpp/memory/unique_ptr/make_unique (T... args) std::make_unsigned std::make_unsigned_t T malloc cpp/memory/c/malloc (T... args) std::map std::mask_array std::match_results T max cpp/algorithm/max (T... args) std::max_align_t T max_element cpp/algorithm/max_element (T... args) T mblen cpp/string/multibyte/mblen (T... args) T mbrlen cpp/string/multibyte/mbrlen (T... args) T mbrtoc16 cpp/string/multibyte/mbrtoc16 (T... args) T mbrtoc32 cpp/string/multibyte/mbrtoc32 (T... args) T mbrtowc cpp/string/multibyte/mbrtowc (T... args) T mbsinit cpp/string/multibyte/mbsinit (T... args) T mbsrtowcs cpp/string/multibyte/mbsrtowcs (T... args) std::mbstate_t T mbstowcs cpp/string/multibyte/mbstowcs (T... args) T mbtowc cpp/string/multibyte/mbtowc (T... args) std::mega T mem_fn cpp/utility/functional/mem_fn (T... args) T memchr cpp/string/byte/memchr (T... args) T memcmp cpp/string/byte/memcmp (T... args) T memcpy cpp/string/byte/memcpy (T... args) T memmove cpp/string/byte/memmove (T... args) T memset cpp/string/byte/memset (T... args) T merge cpp/algorithm/merge (T... args) std::mersenne_twister_engine std::messages std::messages_base std::messages_byname std::micro std::milli T min cpp/algorithm/min (T... args) T min_element cpp/algorithm/min_element (T... args) T minmax cpp/algorithm/minmax (T... args) T minmax_element cpp/algorithm/minmax_element (T... args) std::minstd_rand std::minstd_rand0 std::minus T mismatch cpp/algorithm/mismatch (T... args) T mktime cpp/chrono/c/mktime (T... args) T modf cpp/numeric/math/modf (T... args) std::modulus std::money_base std::money_get std::money_put std::moneypunct std::moneypunct_byname std::monostate T move (algorithm) cpp/algorithm/move (T... args) T move (utility) cpp/utility/move (T... args) T move_backward cpp/algorithm/move_backward (T... args) T move_if_noexcept cpp/utility/move_if_noexcept (T... args) std::move_iterator std::mt19937 std::mt19937_64 std::multimap std::multiplies std::multiset std::mutex T nan cpp/numeric/math/nan (T... args) T nanf cpp/numeric/math/nan (T... args) T nanl cpp/numeric/math/nan (T... args) std::nano T nearbyint cpp/numeric/math/nearbyint (T... args) std::negate std::negation T negation_v cpp/types/negation std::negative_binomial_distribution std::nested_exception std::new_handler T next cpp/iterator/next (T... args) T next_permutation cpp/algorithm/next_permutation (T... args) T nextafter cpp/numeric/math/nextafter (T... args) T nexttoward cpp/numeric/math/nextafter (T... args) T noboolalpha cpp/io/manip/boolalpha (T... args) T none_of cpp/algorithm/all_any_none_of (T... args) std::normal_distribution T noshowbase cpp/io/manip/showbase (T... args) T noshowpoint cpp/io/manip/showpoint (T... args) T noshowpos cpp/io/manip/showpos (T... args) T noskipws cpp/io/manip/skipws (T... args) T not1 cpp/utility/functional/not1 (T... args) T not2 cpp/utility/functional/not2 (T... args) std::not_equal_to T not_fn cpp/utility/functional/not_fn (T... args) std::nothrow_t T notify_all_at_thread_exit cpp/thread/notify_all_at_thread_exit (T... args) T nounitbuf cpp/io/manip/unitbuf (T... args) T nouppercase cpp/io/manip/uppercase (T... args) T nth_element cpp/algorithm/nth_element (T... args) std::nullopt_t std::nullptr_t std::num_get std::num_put std::numeric_limits std::numpunct std::numpunct_byname T oct cpp/io/manip/hex (T... args) std::ofstream std::once_flag std::optional std::ostream std::ostream_iterator std::ostreambuf_iterator std::ostringstream std::ostrstream std::out_of_range std::output_iterator_tag std::overflow_error std::owner_less std::packaged_task std::pair T partial_sort cpp/algorithm/partial_sort (T... args) T partial_sort_copy cpp/algorithm/partial_sort_copy (T... args) T partial_sum cpp/algorithm/partial_sum (T... args) T partition cpp/algorithm/partition (T... args) T partition_copy cpp/algorithm/partition_copy (T... args) T partition_point cpp/algorithm/partition_point (T... args) T perror cpp/io/c/perror (T... args) std::peta std::pico std::piecewise_constant_distribution std::piecewise_construct_t std::piecewise_linear_distribution std::placeholders std::plus std::pmr std::pointer_safety std::pointer_traits std::poisson_distribution T pop_heap cpp/algorithm/pop_heap (T... args) T pow cpp/numeric/math/pow (T... args) T prev cpp/iterator/prev (T... args) T prev_permutation cpp/algorithm/prev_permutation (T... args) T printf cpp/io/c/fprintf (T... args) std::priority_queue std::promise std::ptrdiff_t T push_heap cpp/algorithm/push_heap (T... args) T put_money cpp/io/manip/put_money (T... args) T put_time cpp/io/manip/put_time (T... args) T putc cpp/io/c/fputc (T... args) T putchar cpp/io/c/putchar (T... args) T puts cpp/io/c/puts (T... args) T putwchar cpp/io/c/putwchar (T... args) T qsort cpp/algorithm/qsort (T... args) std::queue T quick_exit cpp/utility/program/quick_exit (T... args) T quoted cpp/io/manip/quoted (T... args) T raise cpp/utility/program/raise (T... args) T rand cpp/numeric/random/rand (T... args) std::random_access_iterator_tag std::random_device T random_shuffle cpp/algorithm/random_shuffle (T... args) std::range_error std::rank T rank_v cpp/types/rank std::ranlux24 std::ranlux24_base std::ranlux48 std::ranlux48_base std::ratio std::ratio_add std::ratio_divide std::ratio_equal T ratio_equal_v cpp/numeric/ratio/ratio_equal std::ratio_greater std::ratio_greater_equal T ratio_greater_equal_v cpp/numeric/ratio/ratio_greater_equal T ratio_greater_v cpp/numeric/ratio/ratio_greater std::ratio_less std::ratio_less_equal T ratio_less_equal_v cpp/numeric/ratio/ratio_less_equal T ratio_less_v cpp/numeric/ratio/ratio_less std::ratio_multiply std::ratio_not_equal T ratio_not_equal_v cpp/numeric/ratio/ratio_not_equal std::ratio_subtract std::raw_storage_iterator T rbegin cpp/iterator/rbegin (T... args) T realloc cpp/memory/c/realloc (T... args) std::recursive_mutex std::recursive_timed_mutex T reduce cpp/algorithm/reduce (T... args) T ref cpp/utility/functional/ref (T... args) std::reference_wrapper std::regex std::regex_constants std::regex_error std::regex_iterator T regex_match cpp/regex/regex_match (T... args) T regex_replace cpp/regex/regex_replace (T... args) T regex_search cpp/regex/regex_search (T... args) std::regex_token_iterator std::regex_traits std::rel_ops T remainder cpp/numeric/math/remainder (T... args) T remove (<algorithm>) cpp/algorithm/remove (T... args) T remove (<cstdio>) cpp/io/c/remove (T... args) std::remove_all_extents std::remove_all_extents_t std::remove_const std::remove_const_t T remove_copy cpp/algorithm/remove_copy (T... args) T remove_copy_if cpp/algorithm/remove_copy (T... args) std::remove_cv std::remove_cv_t std::remove_extent std::remove_extent_t T remove_if cpp/algorithm/remove (T... args) std::remove_pointer std::remove_pointer_t std::remove_reference std::remove_reference_t std::remove_volatile std::remove_volatile_t T remquo cpp/numeric/math/remquo (T... args) T rename cpp/io/c/rename (T... args) T rend cpp/iterator/rend (T... args) T replace cpp/algorithm/replace (T... args) T replace_copy cpp/algorithm/replace_copy (T... args) T replace_copy_if cpp/algorithm/replace_copy (T... args) T replace_if cpp/algorithm/replace (T... args) T resetiosflags cpp/io/manip/resetiosflags (T... args) std::result_of std::result_of_t T rethrow_exception cpp/error/rethrow_exception (T... args) T rethrow_if_nested cpp/error/rethrow_if_nested (T... args) T return_temporary_buffer cpp/memory/return_temporary_buffer (T... args) T reverse cpp/algorithm/reverse (T... args) T reverse_copy cpp/algorithm/reverse_copy (T... args) std::reverse_iterator T rewind cpp/io/c/rewind (T... args) T riemann_zeta cpp/numeric/special_math/riemann_zeta (T... args) T riemann_zetaf cpp/numeric/special_math/riemann_zeta (T... args) T riemann_zetal cpp/numeric/special_math/riemann_zeta (T... args) T right cpp/io/manip/left (T... args) T rint cpp/numeric/math/rint (T... args) T rotate cpp/algorithm/rotate (T... args) T rotate_copy cpp/algorithm/rotate_copy (T... args) T round cpp/numeric/math/round (T... args) std::runtime_error T sample cpp/algorithm/sample (T... args) T scalbln cpp/numeric/math/scalbn (T... args) T scalbn cpp/numeric/math/scalbn (T... args) T scanf cpp/io/c/fscanf (T... args) T scientific cpp/io/manip/fixed (T... args) std::scoped_allocator_adaptor T search cpp/algorithm/search (T... args) T search_n cpp/algorithm/search_n (T... args) std::seed_seq std::set T set_difference cpp/algorithm/set_difference (T... args) T set_intersection cpp/algorithm/set_intersection (T... args) T set_new_handler cpp/memory/new/set_new_handler (T... args) T set_symmetric_difference cpp/algorithm/set_symmetric_difference (T... args) T set_terminate cpp/error/set_terminate (T... args) T set_unexpected cpp/error/set_unexpected (T... args) T set_union cpp/algorithm/set_union (T... args) T setbase cpp/io/manip/setbase (T... args) T setbuf cpp/io/c/setbuf (T... args) T setfill cpp/io/manip/setfill (T... args) T setiosflags cpp/io/manip/setiosflags (T... args) T setlocale cpp/locale/setlocale (T... args) T setprecision cpp/io/manip/setprecision (T... args) T setvbuf cpp/io/c/setvbuf (T... args) T setw cpp/io/manip/setw (T... args) std::shared_future std::shared_lock std::shared_mutex std::shared_ptr std::shared_timed_mutex T showbase cpp/io/manip/showbase (T... args) T showpoint cpp/io/manip/showpoint (T... args) T showpos cpp/io/manip/showpos (T... args) T shuffle cpp/algorithm/random_shuffle (T... args) std::shuffle_order_engine std::sig_atomic_t T signal cpp/utility/program/signal (T... args) T signbit cpp/numeric/math/signbit (T... args) T sin cpp/numeric/math/sin (T... args) T sinh cpp/numeric/math/sinh (T... args) T size cpp/iterator/size (T... args) std::size_t T skipws cpp/io/manip/skipws (T... args) std::slice std::slice_array std::smatch T snprintf cpp/io/c/fprintf (T... args) T sort cpp/algorithm/sort (T... args) T sort_heap cpp/algorithm/sort_heap (T... args) T sph_bessel cpp/numeric/special_math/sph_bessel (T... args) T sph_besself cpp/numeric/special_math/sph_bessel (T... args) T sph_bessell cpp/numeric/special_math/sph_bessel (T... args) T sph_legendre cpp/numeric/special_math/sph_legendre (T... args) T sph_legendref cpp/numeric/special_math/sph_legendre (T... args) T sph_legendrel cpp/numeric/special_math/sph_legendre (T... args) T sph_neumann cpp/numeric/special_math/sph_neumann (T... args) T sph_neumannf cpp/numeric/special_math/sph_neumann (T... args) T sph_neumannl cpp/numeric/special_math/sph_neumann (T... args) T sprintf cpp/io/c/fprintf (T... args) T sqrt cpp/numeric/math/sqrt (T... args) T srand cpp/numeric/random/srand (T... args) std::sregex_iterator std::sregex_token_iterator T sscanf cpp/io/c/fscanf (T... args) std::ssub_match T stable_partition cpp/algorithm/stable_partition (T... args) T stable_sort cpp/algorithm/stable_sort (T... args) std::stack T static_pointer_cast cpp/memory/shared_ptr/pointer_cast (T... args) T stod cpp/string/basic_string/stof (T... args) T stof cpp/string/basic_string/stof (T... args) T stoi cpp/string/basic_string/stol (T... args) T stol cpp/string/basic_string/stol (T... args) T stold cpp/string/basic_string/stof (T... args) T stoll cpp/string/basic_string/stol (T... args) T stoul cpp/string/basic_string/stoul (T... args) T stoull cpp/string/basic_string/stoul (T... args) T strcat cpp/string/byte/strcat (T... args) T strchr cpp/string/byte/strchr (T... args) T strcmp cpp/string/byte/strcmp (T... args) T strcoll cpp/string/byte/strcoll (T... args) T strcpy cpp/string/byte/strcpy (T... args) T strcspn cpp/string/byte/strcspn (T... args) std::streambuf std::streamoff std::streampos std::streamsize T strerror cpp/string/byte/strerror (T... args) T strftime cpp/chrono/c/strftime (T... args) std::string std::string_view std::stringbuf std::stringstream T strlen cpp/string/byte/strlen (T... args) T strncat cpp/string/byte/strncat (T... args) T strncmp cpp/string/byte/strncmp (T... args) T strncpy cpp/string/byte/strncpy (T... args) T strpbrk cpp/string/byte/strpbrk (T... args) T strrchr cpp/string/byte/strrchr (T... args) T strspn cpp/string/byte/strspn (T... args) T strstr cpp/string/byte/strstr (T... args) std::strstream std::strstreambuf T strtod cpp/string/byte/strtof (T... args) T strtof cpp/string/byte/strtof (T... args) T strtoimax cpp/string/byte/strtoimax (T... args) T strtok cpp/string/byte/strtok (T... args) T strtol cpp/string/byte/strtol (T... args) T strtold cpp/string/byte/strtof (T... args) T strtoll cpp/string/byte/strtol (T... args) T strtoul cpp/string/byte/strtoul (T... args) T strtoull cpp/string/byte/strtoul (T... args) T strtoumax cpp/string/byte/strtoimax (T... args) T strxfrm cpp/string/byte/strxfrm (T... args) std::student_t_distribution std::sub_match std::subtract_with_carry_engine T swap cpp/algorithm/swap (T... args) T swap_ranges cpp/algorithm/swap_ranges (T... args) T swprintf cpp/io/c/fwprintf (T... args) T swscanf cpp/io/c/fwscanf (T... args) T system cpp/utility/program/system (T... args) T system_category cpp/error/system_category (T... args) std::system_error T tan cpp/numeric/math/tan (T... args) T tanh cpp/numeric/math/tanh (T... args) std::tera T terminate cpp/error/terminate (T... args) std::terminate_handler T tgamma cpp/numeric/math/tgamma (T... args) std::this_thread std::thread T throw_with_nested cpp/error/throw_with_nested (T... args) T tie cpp/utility/tuple/tie (T... args) T time cpp/chrono/c/time (T... args) std::time_base std::time_get std::time_get_byname std::time_put std::time_put_byname std::time_t std::timed_mutex T timespec cpp/chrono/c/timespec (T... args) T timespec_get cpp/chrono/c/timespec_get (T... args) std::tm T tmpfile cpp/io/c/tmpfile (T... args) T tmpnam cpp/io/c/tmpnam (T... args) T to_string cpp/string/basic_string/to_string (T... args) T to_wstring cpp/string/basic_string/to_wstring (T... args) T tolower (<cctype>) cpp/string/byte/tolower (T... args) T tolower (<clocale>) cpp/locale/tolower (T... args) T toupper (<cctype>) cpp/string/byte/toupper (T... args) T toupper (<clocale>) cpp/locale/toupper (T... args) T towctrans cpp/string/wide/towctrans (T... args) T towlower cpp/string/wide/towlower (T... args) T towupper cpp/string/wide/towupper (T... args) T transform cpp/algorithm/transform (T... args) T transform_exclusive_scan cpp/algorithm/transform_exclusive_scan (T... args) T transform_inclusive_scan cpp/algorithm/transform_inclusive_scan (T... args) T transform_reduce cpp/algorithm/transform_reduce (T... args) std::true_type T trunc cpp/numeric/math/trunc (T... args) T try_lock cpp/thread/try_lock (T... args) std::try_to_lock_t std::tuple T tuple_cat cpp/utility/tuple/tuple_cat (T... args) T tuple_size_v cpp/utility/tuple/tuple_size std::type_index std::type_info std::u16streampos std::u16string std::u16string_view std::u32streampos std::u32string std::u32string_view std::uint16_t std::uint32_t std::uint64_t std::uint8_t std::uint_fast16_t std::uint_fast32_t std::uint_fast64_t std::uint_fast8_t std::uint_least16_t std::uint_least32_t std::uint_least64_t std::uint_least8_t std::uintmax_t std::uintptr_t std::unary_function std::unary_negate T uncaught_exception cpp/error/uncaught_exception (T... args) T undeclare_no_pointers cpp/memory/gc/undeclare_no_pointers (T... args) T undeclare_reachable cpp/memory/gc/undeclare_reachable (T... args) std::underflow_error std::underlying_type std::underlying_type_t T unexpected cpp/error/unexpected (T... args) std::unexpected_handler T ungetc cpp/io/c/ungetc (T... args) T ungetwc cpp/io/c/ungetwc (T... args) std::uniform_int_distribution std::uniform_real_distribution T uninitialized_copy cpp/memory/uninitialized_copy (T... args) T uninitialized_copy_n cpp/memory/uninitialized_copy_n (T... args) T uninitialized_default_construct cpp/memory/uninitialized_default_construct (T... args) T uninitialized_default_construct_n cpp/memory/uninitialized_default_construct_n (T... args) T uninitialized_fill cpp/memory/uninitialized_fill (T... args) T uninitialized_fill_n cpp/memory/uninitialized_fill_n (T... args) T uninitialized_move cpp/memory/uninitialized_move (T... args) T uninitialized_move_n cpp/memory/uninitialized_move_n (T... args) T uninitialized_value_construct cpp/memory/uninitialized_value_construct (T... args) T uninitialized_value_construct_n cpp/memory/uninitialized_value_construct_n (T... args) T unique cpp/algorithm/unique (T... args) T unique_copy cpp/algorithm/unique_copy (T... args) std::unique_lock std::unique_ptr T unitbuf cpp/io/manip/unitbuf (T... args) std::unordered_map std::unordered_multimap std::unordered_multiset std::unordered_set T upper_bound cpp/algorithm/upper_bound (T... args) T uppercase cpp/io/manip/uppercase (T... args) T use_facet cpp/locale/use_facet (T... args) std::uses_allocator T uses_allocator_v cpp/memory/uses_allocator std::valarray std::variant std::variant_alternative std::variant_alternative_t std::variant_size T variant_size_v cpp/utility/variant/variant_size std::vector T vfprintf cpp/io/c/vfprintf (T... args) T vfscanf cpp/io/c/vfscanf (T... args) T vfwprintf cpp/io/c/vfwprintf (T... args) T vfwscanf cpp/io/c/vfwscanf (T... args) T visit cpp/utility/variant/visit (T... args) std::void_t T vprintf cpp/io/c/vfprintf (T... args) T vscanf cpp/io/c/vfscanf (T... args) T vsnprintf cpp/io/c/vfprintf (T... args) T vsprintf cpp/io/c/vfprintf (T... args) T vsscanf cpp/io/c/vfscanf (T... args) T vswprintf cpp/io/c/vfwprintf (T... args) T vswscanf cpp/io/c/vfwscanf (T... args) T vwprintf cpp/io/c/vfwprintf (T... args) T vwscanf cpp/io/c/vfwscanf (T... args) std::wbuffer_convert std::wcerr std::wcin std::wclog std::wcmatch std::wcout std::wcregex_iterator std::wcregex_token_iterator T wcrtomb cpp/string/multibyte/wcrtomb (T... args) T wcscat cpp/string/wide/wcscat (T... args) T wcschr cpp/string/wide/wcschr (T... args) T wcscmp cpp/string/wide/wcscmp (T... args) T wcscoll cpp/string/wide/wcscoll (T... args) T wcscpy cpp/string/wide/wcscpy (T... args) T wcscspn cpp/string/wide/wcscspn (T... args) T wcsftime cpp/chrono/c/wcsftime (T... args) T wcslen cpp/string/wide/wcslen (T... args) T wcsncat cpp/string/wide/wcsncat (T... args) T wcsncmp cpp/string/wide/wcsncmp (T... args) T wcsncpy cpp/string/wide/wcsncpy (T... args) T wcspbrk cpp/string/wide/wcspbrk (T... args) T wcsrchr cpp/string/wide/wcsrchr (T... args) T wcsrtombs cpp/string/multibyte/wcsrtombs (T... args) T wcsspn cpp/string/wide/wcsspn (T... args) T wcsstr cpp/string/wide/wcsstr (T... args) T wcstod cpp/string/wide/wcstof (T... args) T wcstof cpp/string/wide/wcstof (T... args) T wcstoimax cpp/string/wide/wcstoimax (T... args) T wcstok cpp/string/wide/wcstok (T... args) T wcstol cpp/string/wide/wcstol (T... args) T wcstold cpp/string/wide/wcstof (T... args) T wcstoll cpp/string/wide/wcstol (T... args) T wcstombs cpp/string/multibyte/wcstombs (T... args) T wcstoul cpp/string/wide/wcstoul (T... args) T wcstoull cpp/string/wide/wcstoul (T... args) T wcstoumax cpp/string/wide/wcstoimax (T... args) std::wcsub_match T wcsxfrm cpp/string/wide/wcsxfrm (T... args) T wctob cpp/string/multibyte/wctob (T... args) T wctomb cpp/string/multibyte/wctomb (T... args) T wctrans cpp/string/wide/wctrans (T... args) T wctype cpp/string/wide/wctype (T... args) std::weak_ptr std::weibull_distribution std::wfilebuf std::wfstream std::wifstream std::wiostream std::wistream std::wistringstream T wmemchr cpp/string/wide/wmemchr (T... args) T wmemcmp cpp/string/wide/wmemcmp (T... args) T wmemcpy cpp/string/wide/wmemcpy (T... args) T wmemmove cpp/string/wide/wmemmove (T... args) T wmemset cpp/string/wide/wmemset (T... args) std::wofstream std::wostream std::wostringstream T wprintf cpp/io/c/fwprintf (T... args) std::wregex T ws cpp/io/manip/ws (T... args) T wscanf cpp/io/c/fwscanf (T... args) std::wsmatch std::wsregex_iterator std::wsregex_token_iterator std::wssub_match std::wstreambuf std::wstreampos std::wstring std::wstring_convert std::wstring_view std::wstringbuf std::wstringstream std::yocto std::yotta std::zetta std::FILE cpp/io/c std::add_const cpp/types/add_cv std::add_const_t cpp/types/add_cv std::add_cv cpp/types/add_cv std::add_cv_t cpp/types/add_cv std::add_lvalue_reference cpp/types/add_reference std::add_lvalue_reference_t cpp/types/add_reference std::add_pointer cpp/types/add_pointer std::add_pointer_t cpp/types/add_pointer std::add_rvalue_reference cpp/types/add_reference std::add_rvalue_reference_t cpp/types/add_reference std::add_volatile cpp/types/add_cv std::add_volatile_t cpp/types/add_cv std::adopt_lock_t cpp/thread/lock_tag_t std::align_val_t cpp/memory/new/align_val_t std::aligned_storage cpp/types/aligned_storage std::aligned_storage_t cpp/types/aligned_storage std::aligned_union cpp/types/aligned_union std::aligned_union_t cpp/types/aligned_union std::alignment_of cpp/types/alignment_of std::allocator cpp/memory/allocator T address cpp/memory/allocator/address (T... args) T allocate cpp/memory/allocator/allocate (T... args) T allocator cpp/memory/allocator/allocator (T... args) T construct cpp/memory/allocator/construct (T... args) T deallocate cpp/memory/allocator/deallocate (T... args) T destroy cpp/memory/allocator/destroy (T... args) T max_size cpp/memory/allocator/max_size (T... args) T ~allocator cpp/memory/allocator/~allocator (T... args) std::allocator_arg_t cpp/memory/allocator_arg_t std::allocator_traits cpp/memory/allocator_traits T allocate cpp/memory/allocator_traits/allocate (T... args) T construct cpp/memory/allocator_traits/construct (T... args) T deallocate cpp/memory/allocator_traits/deallocate (T... args) T destroy cpp/memory/allocator_traits/destroy (T... args) T max_size cpp/memory/allocator_traits/max_size (T... args) T select_on_container_copy_construction cpp/memory/allocator_traits/select_on_container_copy_construction (T... args) std::any cpp/utility/any T any cpp/utility/any/any (T... args) T emplace cpp/utility/any/emplace (T... args) T has_value cpp/utility/any/has_value (T... args) T operator= cpp/utility/any/operator= (T... args) T reset cpp/utility/any/reset (T... args) T swap cpp/utility/any/swap (T... args) T type cpp/utility/any/type (T... args) T ~any cpp/utility/any/~any (T... args) std::array cpp/container/array T at cpp/container/array/at (T... args) T back cpp/container/array/back (T... args) T begin cpp/container/array/begin (T... args) T cbegin cpp/container/array/begin (T... args) T cend cpp/container/array/end (T... args) T crbegin cpp/container/array/rbegin (T... args) T crend cpp/container/array/rend (T... args) T data cpp/container/array/data (T... args) T empty cpp/container/array/empty (T... args) T end cpp/container/array/end (T... args) T fill cpp/container/array/fill (T... args) T front cpp/container/array/front (T... args) T max_size cpp/container/array/max_size (T... args) T operator[] cpp/container/array/operator_at (T... args) T rbegin cpp/container/array/rbegin (T... args) T rend cpp/container/array/rend (T... args) T size cpp/container/array/size (T... args) T swap cpp/container/array/swap (T... args) std::atomic cpp/atomic/atomic T atomic cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_bool cpp/atomic/atomic T atomic_bool cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_char16_t cpp/atomic/atomic T atomic_char16_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_char32_t cpp/atomic/atomic T atomic_char32_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_flag cpp/atomic/atomic_flag T atomic_flag cpp/atomic/atomic_flag/atomic_flag (T... args) T clear cpp/atomic/atomic_flag/clear (T... args) T operator= cpp/atomic/atomic_flag/operator= (T... args) T test_and_set cpp/atomic/atomic_flag/test_and_set (T... args) std::atomic_int cpp/atomic/atomic T atomic_int cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_int16_t cpp/atomic/atomic T atomic_int16_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_int32_t cpp/atomic/atomic T atomic_int32_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_int64_t cpp/atomic/atomic T atomic_int64_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_int8_t cpp/atomic/atomic T atomic_int8_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_int_fast16_t cpp/atomic/atomic T atomic_int_fast16_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_int_fast32_t cpp/atomic/atomic T atomic_int_fast32_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_int_fast64_t cpp/atomic/atomic T atomic_int_fast64_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_int_fast8_t cpp/atomic/atomic T atomic_int_fast8_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_int_least16_t cpp/atomic/atomic T atomic_int_least16_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_int_least32_t cpp/atomic/atomic T atomic_int_least32_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_int_least64_t cpp/atomic/atomic T atomic_int_least64_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_int_least8_t cpp/atomic/atomic T atomic_int_least8_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_intmax_t cpp/atomic/atomic T atomic_intmax_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_intptr_t cpp/atomic/atomic T atomic_intptr_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_llong cpp/atomic/atomic T atomic_llong cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_long cpp/atomic/atomic T atomic_long cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_ptrdiff_t cpp/atomic/atomic T atomic_ptrdiff_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_schar cpp/atomic/atomic T atomic_schar cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_short cpp/atomic/atomic T atomic_short cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_size_t cpp/atomic/atomic T atomic_size_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uchar cpp/atomic/atomic T atomic_uchar cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint cpp/atomic/atomic T atomic_uint cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint16_t cpp/atomic/atomic T atomic_uint16_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint32_t cpp/atomic/atomic T atomic_uint32_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint64_t cpp/atomic/atomic T atomic_uint64_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint8_t cpp/atomic/atomic T atomic_uint8_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint_fast16_t cpp/atomic/atomic T atomic_uint_fast16_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint_fast32_t cpp/atomic/atomic T atomic_uint_fast32_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint_fast64_t cpp/atomic/atomic T atomic_uint_fast64_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint_fast8_t cpp/atomic/atomic T atomic_uint_fast8_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint_least16_t cpp/atomic/atomic T atomic_uint_least16_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint_least32_t cpp/atomic/atomic T atomic_uint_least32_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint_least64_t cpp/atomic/atomic T atomic_uint_least64_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uint_least8_t cpp/atomic/atomic T atomic_uint_least8_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uintmax_t cpp/atomic/atomic T atomic_uintmax_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_uintptr_t cpp/atomic/atomic T atomic_uintptr_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_ullong cpp/atomic/atomic T atomic_ullong cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_ulong cpp/atomic/atomic T atomic_ulong cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_ushort cpp/atomic/atomic T atomic_ushort cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::atomic_wchar_t cpp/atomic/atomic T atomic_wchar_t cpp/atomic/atomic/atomic (T... args) T compare_exchange_strong cpp/atomic/atomic/compare_exchange (T... args) T compare_exchange_weak cpp/atomic/atomic/compare_exchange (T... args) T exchange cpp/atomic/atomic/exchange (T... args) T fetch_add cpp/atomic/atomic/fetch_add (T... args) T fetch_and cpp/atomic/atomic/fetch_and (T... args) T fetch_or cpp/atomic/atomic/fetch_or (T... args) T fetch_sub cpp/atomic/atomic/fetch_sub (T... args) T fetch_xor cpp/atomic/atomic/fetch_xor (T... args) T is_lock_free cpp/atomic/atomic/is_lock_free (T... args) T load cpp/atomic/atomic/load (T... args) T operator T cpp/atomic/atomic/operator_T (T... args) T operator&= cpp/atomic/atomic/operator_arith2 (T... args) T operator++ cpp/atomic/atomic/operator_arith (T... args) T operator++(int) cpp/atomic/atomic/operator_arith (T... args) T operator+= cpp/atomic/atomic/operator_arith2 (T... args) T operator-- cpp/atomic/atomic/operator_arith (T... args) T operator--(int) cpp/atomic/atomic/operator_arith (T... args) T operator-= cpp/atomic/atomic/operator_arith2 (T... args) T operator= cpp/atomic/atomic/operator= (T... args) T operator^= cpp/atomic/atomic/operator_arith2 (T... args) T operator|= cpp/atomic/atomic/operator_arith2 (T... args) T store cpp/atomic/atomic/store (T... args) std::auto_ptr cpp/memory/auto_ptr T auto_ptr cpp/memory/auto_ptr/auto_ptr (T... args) T get cpp/memory/auto_ptr/get (T... args) T operator auto_ptr<Y> cpp/memory/auto_ptr/operator_auto_ptr (T... args) T operator* cpp/memory/auto_ptr/operator* (T... args) T operator-> cpp/memory/auto_ptr/operator* (T... args) T operator= cpp/memory/auto_ptr/operator= (T... args) T release cpp/memory/auto_ptr/release (T... args) T reset cpp/memory/auto_ptr/reset (T... args) T ~auto_ptr cpp/memory/auto_ptr/~auto_ptr (T... args) std::back_insert_iterator cpp/iterator/back_insert_iterator std::bad_alloc cpp/memory/new/bad_alloc T bad_alloc cpp/memory/new/bad_alloc (T... args) T operator= cpp/memory/new/bad_alloc (T... args) T what cpp/error/exception/what (T... args) std::bad_any_cast cpp/utility/any/bad_any_cast std::bad_array_length cpp/memory/new/bad_array_length T bad_array_length cpp/memory/new/bad_array_length (T... args) T what cpp/memory/new/bad_alloc (T... args) std::bad_array_new_length cpp/memory/new/bad_array_new_length T bad_array_new_length cpp/memory/new/bad_array_new_length/bad_array_new_length (T... args) T what cpp/memory/new/bad_alloc (T... args) std::bad_cast cpp/types/bad_cast T bad_cast cpp/types/bad_cast/bad_cast (T... args) T what cpp/error/exception/what (T... args) std::bad_exception cpp/error/bad_exception std::bad_function_call cpp/utility/functional/bad_function_call T bad_function_call cpp/utility/functional/bad_function_call (T... args) T what cpp/error/exception/what (T... args) std::bad_optional_access cpp/utility/optional/bad_optional_access std::bad_typeid cpp/types/bad_typeid T bad_typeid cpp/types/bad_typeid/bad_typeid (T... args) T what cpp/error/exception/what (T... args) std::bad_variant_access cpp/utility/variant/bad_variant_access std::bad_weak_ptr cpp/memory/bad_weak_ptr T bad_weak_ptr cpp/memory/bad_weak_ptr/bad_weak_ptr (T... args) T what cpp/error/exception/what (T... args) std::basic_filebuf cpp/io/basic_filebuf T basic_filebuf cpp/io/basic_filebuf/basic_filebuf (T... args) T close cpp/io/basic_filebuf/close (T... args) T eback cpp/io/basic_streambuf/gptr (T... args) T egptr cpp/io/basic_streambuf/gptr (T... args) T epptr cpp/io/basic_streambuf/pptr (T... args) T gbump cpp/io/basic_streambuf/gbump (T... args) T getloc cpp/io/basic_streambuf/getloc (T... args) T gptr cpp/io/basic_streambuf/gptr (T... args) T imbue cpp/io/basic_streambuf/pubimbue (T... args) T in_avail cpp/io/basic_streambuf/in_avail (T... args) T is_open cpp/io/basic_filebuf/is_open (T... args) T open cpp/io/basic_filebuf/open (T... args) T operator= cpp/io/basic_filebuf/operator= (T... args) T overflow cpp/io/basic_streambuf/overflow (T... args) T pbackfail cpp/io/basic_streambuf/pbackfail (T... args) T pbase cpp/io/basic_streambuf/pptr (T... args) T pbump cpp/io/basic_streambuf/pbump (T... args) T pptr cpp/io/basic_streambuf/pptr (T... args) T pubimbue cpp/io/basic_streambuf/pubimbue (T... args) T pubseekoff cpp/io/basic_streambuf/pubseekoff (T... args) T pubseekpos cpp/io/basic_streambuf/pubseekpos (T... args) T pubsetbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T pubsync cpp/io/basic_streambuf/pubsync (T... args) T sbumpc cpp/io/basic_streambuf/sbumpc (T... args) T seekoff cpp/io/basic_streambuf/pubseekoff (T... args) T seekpos cpp/io/basic_streambuf/pubseekpos (T... args) T setbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T setg cpp/io/basic_streambuf/setg (T... args) T setp cpp/io/basic_streambuf/setp (T... args) T sgetc cpp/io/basic_streambuf/sgetc (T... args) T sgetn cpp/io/basic_streambuf/sgetn (T... args) T showmanyc cpp/io/basic_streambuf/showmanyc (T... args) T snextc cpp/io/basic_streambuf/snextc (T... args) T sputbackc cpp/io/basic_streambuf/sputbackc (T... args) T sputc cpp/io/basic_streambuf/sputc (T... args) T sputn cpp/io/basic_streambuf/sputn (T... args) T sungetc cpp/io/basic_streambuf/sungetc (T... args) T swap cpp/io/basic_streambuf/swap (T... args) T sync cpp/io/basic_streambuf/pubsync (T... args) T uflow cpp/io/basic_streambuf/uflow (T... args) T underflow cpp/io/basic_streambuf/underflow (T... args) T xsgetn cpp/io/basic_streambuf/sgetn (T... args) T xsputn cpp/io/basic_streambuf/sputn (T... args) T ~basic_filebuf cpp/io/basic_filebuf/~basic_filebuf (T... args) std::basic_fstream cpp/io/basic_fstream std::basic_fstream::Init T bad cpp/io/basic_ios/bad (T... args) T basic_fstream cpp/io/basic_fstream/basic_fstream (T... args) T clear cpp/io/basic_ios/clear (T... args) T close cpp/io/basic_fstream/close (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::basic_fstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::basic_fstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T is_open cpp/io/basic_fstream/is_open (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T open cpp/io/basic_fstream/open (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator= cpp/io/basic_fstream/operator= (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::basic_fstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::basic_fstream::Init cpp/io/ios_base/Init std::basic_fstream::event_callback cpp/io/ios_base/event_callback std::basic_fstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::basic_fstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::basic_ifstream cpp/io/basic_ifstream std::basic_ifstream::Init T bad cpp/io/basic_ios/bad (T... args) T basic_ifstream cpp/io/basic_ifstream/basic_ifstream (T... args) T clear cpp/io/basic_ios/clear (T... args) T close cpp/io/basic_ifstream/close (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::basic_ifstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::basic_ifstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T is_open cpp/io/basic_ifstream/is_open (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T open cpp/io/basic_ifstream/open (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator= cpp/io/basic_ifstream/operator= (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) std::basic_ifstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::basic_ifstream::Init cpp/io/ios_base/Init std::basic_ifstream::event_callback cpp/io/ios_base/event_callback std::basic_ifstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::basic_ifstream::sentry cpp/io/basic_istream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::basic_ios cpp/io/basic_ios std::basic_ios::Init T bad cpp/io/basic_ios/bad (T... args) T basic_ios cpp/io/basic_ios/basic_ios (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::basic_ios::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::basic_ios::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T imbue cpp/io/ios_base/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T precision cpp/io/ios_base/precision (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tie cpp/io/basic_ios/tie (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~basic_ios cpp/io/basic_ios/~basic_ios (T... args) std::basic_ios::Init cpp/io/ios_base/Init std::basic_ios::event_callback cpp/io/ios_base/event_callback std::basic_ios::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::basic_iostream cpp/io/basic_iostream std::basic_iostream::Init T bad cpp/io/basic_ios/bad (T... args) T basic_iostream cpp/io/basic_iostream/basic_iostream (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::basic_iostream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::basic_iostream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::basic_iostream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~basic_iostream cpp/io/basic_iostream/~basic_iostream (T... args) std::basic_iostream::Init cpp/io/ios_base/Init std::basic_iostream::event_callback cpp/io/ios_base/event_callback std::basic_iostream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::basic_iostream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::basic_istream cpp/io/basic_istream std::basic_istream::Init T bad cpp/io/basic_ios/bad (T... args) T basic_istream cpp/io/basic_istream/basic_istream (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::basic_istream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::basic_istream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) std::basic_istream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~basic_istream cpp/io/basic_istream/~basic_istream (T... args) std::basic_istream::Init cpp/io/ios_base/Init std::basic_istream::event_callback cpp/io/ios_base/event_callback std::basic_istream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::basic_istream::sentry cpp/io/basic_istream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::basic_istringstream cpp/io/basic_istringstream std::basic_istringstream::Init T bad cpp/io/basic_ios/bad (T... args) T basic_istringstream cpp/io/basic_istringstream/basic_istringstream (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::basic_istringstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::basic_istringstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator= cpp/io/basic_istringstream/operator= (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) std::basic_istringstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T str cpp/io/basic_istringstream/str (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::basic_istringstream::Init cpp/io/ios_base/Init std::basic_istringstream::event_callback cpp/io/ios_base/event_callback std::basic_istringstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::basic_istringstream::sentry cpp/io/basic_istream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::basic_ofstream cpp/io/basic_ofstream std::basic_ofstream::Init T bad cpp/io/basic_ios/bad (T... args) T basic_ofstream cpp/io/basic_ofstream/basic_ofstream (T... args) T clear cpp/io/basic_ios/clear (T... args) T close cpp/io/basic_ofstream/close (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::basic_ofstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::basic_ofstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T is_open cpp/io/basic_ofstream/is_open (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T open cpp/io/basic_ofstream/open (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator= cpp/io/basic_ofstream/operator= (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::basic_ofstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::basic_ofstream::Init cpp/io/ios_base/Init std::basic_ofstream::event_callback cpp/io/ios_base/event_callback std::basic_ofstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::basic_ofstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_ostream/sentry (T... args) T sentry cpp/io/basic_ostream/sentry (T... args) T ~sentry cpp/io/basic_ostream/sentry (T... args) std::basic_ostream cpp/io/basic_ostream std::basic_ostream::Init T bad cpp/io/basic_ios/bad (T... args) T basic_ostream cpp/io/basic_ostream/basic_ostream (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::basic_ostream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::basic_ostream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::basic_ostream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~basic_ostream cpp/io/basic_ostream/~basic_ostream (T... args) std::basic_ostream::Init cpp/io/ios_base/Init std::basic_ostream::event_callback cpp/io/ios_base/event_callback std::basic_ostream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::basic_ostream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_ostream/sentry (T... args) T sentry cpp/io/basic_ostream/sentry (T... args) T ~sentry cpp/io/basic_ostream/sentry (T... args) std::basic_ostringstream cpp/io/basic_ostringstream std::basic_ostringstream::Init T bad cpp/io/basic_ios/bad (T... args) T basic_ostringstream cpp/io/basic_ostringstream/basic_ostringstream (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::basic_ostringstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::basic_ostringstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator= cpp/io/basic_ostringstream/operator= (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::basic_ostringstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T str cpp/io/basic_ostringstream/str (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::basic_ostringstream::Init cpp/io/ios_base/Init std::basic_ostringstream::event_callback cpp/io/ios_base/event_callback std::basic_ostringstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::basic_ostringstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_ostream/sentry (T... args) T sentry cpp/io/basic_ostream/sentry (T... args) T ~sentry cpp/io/basic_ostream/sentry (T... args) std::basic_regex cpp/regex/basic_regex T assign cpp/regex/basic_regex/assign (T... args) T basic_regex cpp/regex/basic_regex/basic_regex (T... args) T flags cpp/regex/basic_regex/flags (T... args) T getloc cpp/regex/basic_regex/getloc (T... args) T imbue cpp/regex/basic_regex/imbue (T... args) T mark_count cpp/regex/basic_regex/mark_count (T... args) T operator= cpp/regex/basic_regex/operator= (T... args) T swap cpp/regex/basic_regex/swap (T... args) T ~basic_regex cpp/regex/basic_regex/~basic_regex (T... args) std::basic_streambuf cpp/io/basic_streambuf T basic_streambuf cpp/io/basic_streambuf/basic_streambuf (T... args) T eback cpp/io/basic_streambuf/gptr (T... args) T egptr cpp/io/basic_streambuf/gptr (T... args) T epptr cpp/io/basic_streambuf/pptr (T... args) T gbump cpp/io/basic_streambuf/gbump (T... args) T getloc cpp/io/basic_streambuf/getloc (T... args) T gptr cpp/io/basic_streambuf/gptr (T... args) T imbue cpp/io/basic_streambuf/pubimbue (T... args) T in_avail cpp/io/basic_streambuf/in_avail (T... args) T operator= cpp/io/basic_streambuf/operator= (T... args) T overflow cpp/io/basic_streambuf/overflow (T... args) T pbackfail cpp/io/basic_streambuf/pbackfail (T... args) T pbase cpp/io/basic_streambuf/pptr (T... args) T pbump cpp/io/basic_streambuf/pbump (T... args) T pptr cpp/io/basic_streambuf/pptr (T... args) T pubimbue cpp/io/basic_streambuf/pubimbue (T... args) T pubseekoff cpp/io/basic_streambuf/pubseekoff (T... args) T pubseekpos cpp/io/basic_streambuf/pubseekpos (T... args) T pubsetbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T pubsync cpp/io/basic_streambuf/pubsync (T... args) T sbumpc cpp/io/basic_streambuf/sbumpc (T... args) T seekoff cpp/io/basic_streambuf/pubseekoff (T... args) T seekpos cpp/io/basic_streambuf/pubseekpos (T... args) T setbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T setg cpp/io/basic_streambuf/setg (T... args) T setp cpp/io/basic_streambuf/setp (T... args) T sgetc cpp/io/basic_streambuf/sgetc (T... args) T sgetn cpp/io/basic_streambuf/sgetn (T... args) T showmanyc cpp/io/basic_streambuf/showmanyc (T... args) T snextc cpp/io/basic_streambuf/snextc (T... args) T sputbackc cpp/io/basic_streambuf/sputbackc (T... args) T sputc cpp/io/basic_streambuf/sputc (T... args) T sputn cpp/io/basic_streambuf/sputn (T... args) T sungetc cpp/io/basic_streambuf/sungetc (T... args) T swap cpp/io/basic_streambuf/swap (T... args) T sync cpp/io/basic_streambuf/pubsync (T... args) T uflow cpp/io/basic_streambuf/uflow (T... args) T underflow cpp/io/basic_streambuf/underflow (T... args) T xsgetn cpp/io/basic_streambuf/sgetn (T... args) T xsputn cpp/io/basic_streambuf/sputn (T... args) T ~basic_streambuf cpp/io/basic_streambuf/~basic_streambuf (T... args) std::basic_string cpp/string/basic_string T append cpp/string/basic_string/append (T... args) T assign cpp/string/basic_string/assign (T... args) T at cpp/string/basic_string/at (T... args) T back cpp/string/basic_string/back (T... args) T basic_string cpp/string/basic_string/basic_string (T... args) T begin cpp/string/basic_string/begin (T... args) T c_str cpp/string/basic_string/c_str (T... args) T capacity cpp/string/basic_string/capacity (T... args) T cbegin cpp/string/basic_string/begin (T... args) T cend cpp/string/basic_string/end (T... args) T clear cpp/string/basic_string/clear (T... args) T compare cpp/string/basic_string/compare (T... args) T copy cpp/string/basic_string/copy (T... args) T crbegin cpp/string/basic_string/rbegin (T... args) T crend cpp/string/basic_string/rend (T... args) T data cpp/string/basic_string/data (T... args) T empty cpp/string/basic_string/empty (T... args) T end cpp/string/basic_string/end (T... args) T erase cpp/string/basic_string/erase (T... args) T find cpp/string/basic_string/find (T... args) T find_first_not_of cpp/string/basic_string/find_first_not_of (T... args) T find_first_of cpp/string/basic_string/find_first_of (T... args) T find_last_not_of cpp/string/basic_string/find_last_not_of (T... args) T find_last_of cpp/string/basic_string/find_last_of (T... args) T front cpp/string/basic_string/front (T... args) T get_allocator cpp/string/basic_string/get_allocator (T... args) T insert cpp/string/basic_string/insert (T... args) T length cpp/string/basic_string/size (T... args) T max_size cpp/string/basic_string/max_size (T... args) T operator= cpp/string/basic_string/operator= (T... args) T operator[] cpp/string/basic_string/operator_at (T... args) T pop_back cpp/string/basic_string/pop_back (T... args) T push_back cpp/string/basic_string/push_back (T... args) T rbegin cpp/string/basic_string/rbegin (T... args) T rend cpp/string/basic_string/rend (T... args) T replace cpp/string/basic_string/replace (T... args) T reserve cpp/string/basic_string/reserve (T... args) T resize cpp/string/basic_string/resize (T... args) T rfind cpp/string/basic_string/rfind (T... args) T shrink_to_fit cpp/string/basic_string/shrink_to_fit (T... args) T size cpp/string/basic_string/size (T... args) T substr cpp/string/basic_string/substr (T... args) T swap cpp/string/basic_string/swap (T... args) std::basic_string_view cpp/string/basic_string_view T at cpp/string/basic_string_view/at (T... args) T back cpp/string/basic_string_view/back (T... args) T basic_string_view cpp/string/basic_string_view/basic_string_view (T... args) T begin cpp/string/basic_string_view/begin (T... args) T cbegin cpp/string/basic_string_view/begin (T... args) T cend cpp/string/basic_string_view/end (T... args) T compare cpp/string/basic_string_view/compare (T... args) T copy cpp/string/basic_string_view/copy (T... args) T crbegin cpp/string/basic_string_view/rbegin (T... args) T crend cpp/string/basic_string_view/rend (T... args) T data cpp/string/basic_string_view/data (T... args) T empty cpp/string/basic_string_view/empty (T... args) T end cpp/string/basic_string_view/end (T... args) T find cpp/string/basic_string_view/find (T... args) T find_first_not_of cpp/string/basic_string_view/find_first_not_of (T... args) T find_first_of cpp/string/basic_string_view/find_first_of (T... args) T find_last_not_of cpp/string/basic_string_view/find_last_not_of (T... args) T find_last_of cpp/string/basic_string_view/find_last_of (T... args) T front cpp/string/basic_string_view/front (T... args) T length cpp/string/basic_string_view/size (T... args) T max_size cpp/string/basic_string_view/max_size (T... args) T operator= cpp/string/basic_string_view/operator= (T... args) T operator[] cpp/string/basic_string_view/operator_at (T... args) T rbegin cpp/string/basic_string_view/rbegin (T... args) T remove_prefix cpp/string/basic_string_view/remove_prefix (T... args) T remove_suffix cpp/string/basic_string_view/remove_suffix (T... args) T rend cpp/string/basic_string_view/rend (T... args) T rfind cpp/string/basic_string_view/rfind (T... args) T size cpp/string/basic_string_view/size (T... args) T substr cpp/string/basic_string_view/substr (T... args) T swap cpp/string/basic_string_view/swap (T... args) std::basic_stringbuf cpp/io/basic_stringbuf T basic_stringbuf cpp/io/basic_stringbuf/basic_stringbuf (T... args) T eback cpp/io/basic_streambuf/gptr (T... args) T egptr cpp/io/basic_streambuf/gptr (T... args) T epptr cpp/io/basic_streambuf/pptr (T... args) T gbump cpp/io/basic_streambuf/gbump (T... args) T getloc cpp/io/basic_streambuf/getloc (T... args) T gptr cpp/io/basic_streambuf/gptr (T... args) T imbue cpp/io/basic_streambuf/pubimbue (T... args) T in_avail cpp/io/basic_streambuf/in_avail (T... args) T operator= cpp/io/basic_stringbuf/operator= (T... args) T overflow cpp/io/basic_streambuf/overflow (T... args) T pbackfail cpp/io/basic_streambuf/pbackfail (T... args) T pbase cpp/io/basic_streambuf/pptr (T... args) T pbump cpp/io/basic_streambuf/pbump (T... args) T pptr cpp/io/basic_streambuf/pptr (T... args) T pubimbue cpp/io/basic_streambuf/pubimbue (T... args) T pubseekoff cpp/io/basic_streambuf/pubseekoff (T... args) T pubseekpos cpp/io/basic_streambuf/pubseekpos (T... args) T pubsetbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T pubsync cpp/io/basic_streambuf/pubsync (T... args) T sbumpc cpp/io/basic_streambuf/sbumpc (T... args) T seekoff cpp/io/basic_streambuf/pubseekoff (T... args) T seekpos cpp/io/basic_streambuf/pubseekpos (T... args) T setbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T setg cpp/io/basic_streambuf/setg (T... args) T setp cpp/io/basic_streambuf/setp (T... args) T sgetc cpp/io/basic_streambuf/sgetc (T... args) T sgetn cpp/io/basic_streambuf/sgetn (T... args) T showmanyc cpp/io/basic_streambuf/showmanyc (T... args) T snextc cpp/io/basic_streambuf/snextc (T... args) T sputbackc cpp/io/basic_streambuf/sputbackc (T... args) T sputc cpp/io/basic_streambuf/sputc (T... args) T sputn cpp/io/basic_streambuf/sputn (T... args) T str cpp/io/basic_stringbuf/str (T... args) T sungetc cpp/io/basic_streambuf/sungetc (T... args) T swap cpp/io/basic_streambuf/swap (T... args) T sync cpp/io/basic_streambuf/pubsync (T... args) T uflow cpp/io/basic_streambuf/uflow (T... args) T underflow cpp/io/basic_streambuf/underflow (T... args) T xsgetn cpp/io/basic_streambuf/sgetn (T... args) T xsputn cpp/io/basic_streambuf/sputn (T... args) std::basic_stringstream cpp/io/basic_stringstream std::basic_stringstream::Init T bad cpp/io/basic_ios/bad (T... args) T basic_stringstream cpp/io/basic_stringstream/basic_stringstream (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::basic_stringstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::basic_stringstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator= cpp/io/basic_stringstream/operator= (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::basic_stringstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T str cpp/io/basic_stringstream/str (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::basic_stringstream::Init cpp/io/ios_base/Init std::basic_stringstream::event_callback cpp/io/ios_base/event_callback std::basic_stringstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::basic_stringstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::bernoulli_distribution cpp/numeric/random/bernoulli_distribution T bernoulli_distribution cpp/numeric/random/bernoulli_distribution/bernoulli_distribution (T... args) T max cpp/numeric/random/bernoulli_distribution/max (T... args) T min cpp/numeric/random/bernoulli_distribution/min (T... args) T p cpp/numeric/random/bernoulli_distribution/p (T... args) T param cpp/numeric/random/bernoulli_distribution/param (T... args) T reset cpp/numeric/random/bernoulli_distribution/reset (T... args) std::bidirectional_iterator_tag cpp/iterator/iterator_tags std::binary_function cpp/utility/functional/binary_function std::binary_negate cpp/utility/functional/binary_negate T binary_negate cpp/utility/functional/binary_negate (T... args) T operator() cpp/utility/functional/binary_negate (T... args) std::binomial_distribution cpp/numeric/random/binomial_distribution T binomial_distribution cpp/numeric/random/binomial_distribution/binomial_distribution (T... args) T max cpp/numeric/random/binomial_distribution/max (T... args) T min cpp/numeric/random/binomial_distribution/min (T... args) T p cpp/numeric/random/binomial_distribution/params (T... args) T param cpp/numeric/random/binomial_distribution/param (T... args) T reset cpp/numeric/random/binomial_distribution/reset (T... args) T t cpp/numeric/random/binomial_distribution/params (T... args) std::bit_and cpp/utility/functional/bit_and T operator() cpp/utility/functional/bit_and (T... args) std::bit_not cpp/utility/functional/bit_not T operator() cpp/utility/functional/bit_not (T... args) std::bit_or cpp/utility/functional/bit_or T operator() cpp/utility/functional/bit_or (T... args) std::bitset cpp/utility/bitset T all cpp/utility/bitset/all_any_none (T... args) T any cpp/utility/bitset/all_any_none (T... args) T bitset cpp/utility/bitset/bitset (T... args) T count cpp/utility/bitset/count (T... args) T flip cpp/utility/bitset/flip (T... args) T none cpp/utility/bitset/all_any_none (T... args) T operator!= cpp/utility/bitset/operator_cmp (T... args) T operator&= cpp/utility/bitset/operator_logic (T... args) T operator<< cpp/utility/bitset/operator_ltltgtgt (T... args) T operator<<= cpp/utility/bitset/operator_ltltgtgt (T... args) T operator== cpp/utility/bitset/operator_cmp (T... args) T operator>> cpp/utility/bitset/operator_ltltgtgt (T... args) T operator>>= cpp/utility/bitset/operator_ltltgtgt (T... args) T operator[] cpp/utility/bitset/operator_at (T... args) T operator^= cpp/utility/bitset/operator_logic (T... args) T operator|= cpp/utility/bitset/operator_logic (T... args) T operator~ cpp/utility/bitset/operator_logic (T... args) std::bitset::reference T reset cpp/utility/bitset/reset (T... args) T set cpp/utility/bitset/set (T... args) T size cpp/utility/bitset/size (T... args) T test cpp/utility/bitset/test (T... args) T to_string cpp/utility/bitset/to_string (T... args) T to_ullong cpp/utility/bitset/to_ullong (T... args) T to_ulong cpp/utility/bitset/to_ulong (T... args) std::bitset::reference cpp/utility/bitset/reference std::bool_constant cpp/types/integral_constant std::boyer_moore_horspool_searcher cpp/utility/functional/boyer_moore_horspool_searcher T boyer_moore_horspool_searcher cpp/utility/functional/boyer_moore_horspool_searcher (T... args) std::boyer_moore_searcher cpp/utility/functional/boyer_moore_searcher T boyer_moore_searcher cpp/utility/functional/boyer_moore_searcher (T... args) std::cauchy_distribution cpp/numeric/random/cauchy_distribution T a cpp/numeric/random/cauchy_distribution/params (T... args) T b cpp/numeric/random/cauchy_distribution/params (T... args) T cauchy_distribution cpp/numeric/random/cauchy_distribution/cauchy_distribution (T... args) T max cpp/numeric/random/cauchy_distribution/max (T... args) T min cpp/numeric/random/cauchy_distribution/min (T... args) T operator() cpp/numeric/random/cauchy_distribution/operator() (T... args) T param cpp/numeric/random/cauchy_distribution/param (T... args) T reset cpp/numeric/random/cauchy_distribution/reset (T... args) std::centi cpp/numeric/ratio/ratio std::cerr cpp/io/cerr std::char_traits cpp/string/char_traits T assign cpp/string/char_traits/assign (T... args) T compare cpp/string/char_traits/compare (T... args) T copy cpp/string/char_traits/copy (T... args) T eof cpp/string/char_traits/eof (T... args) T eq cpp/string/char_traits/cmp (T... args) T eq_int_type cpp/string/char_traits/eq_int_type (T... args) T find cpp/string/char_traits/find (T... args) T length cpp/string/char_traits/length (T... args) T lt cpp/string/char_traits/cmp (T... args) T move cpp/string/char_traits/move (T... args) T not_eof cpp/string/char_traits/not_eof (T... args) T to_char_type cpp/string/char_traits/to_char_type (T... args) T to_int_type cpp/string/char_traits/to_int_type (T... args) std::chi_squared_distribution cpp/numeric/random/chi_squared_distribution T chi_squared_distribution cpp/numeric/random/chi_squared_distribution/chi_squared_distribution (T... args) T max cpp/numeric/random/chi_squared_distribution/max (T... args) T min cpp/numeric/random/chi_squared_distribution/min (T... args) T n cpp/numeric/random/chi_squared_distribution/n (T... args) T operator() cpp/numeric/random/chi_squared_distribution/operator() (T... args) T param cpp/numeric/random/chi_squared_distribution/param (T... args) T reset cpp/numeric/random/chi_squared_distribution/reset (T... args) std::chrono std::chrono::duration T duration_cast cpp/chrono/duration/duration_cast (T... args) std::chrono::duration_values std::chrono::high_resolution_clock std::chrono::hours std::chrono::microseconds std::chrono::milliseconds std::chrono::minutes std::chrono::nanoseconds std::chrono::seconds std::chrono::steady_clock std::chrono::system_clock std::chrono::time_point T time_point_cast cpp/chrono/time_point/time_point_cast (T... args) std::chrono::treat_as_floating_point std::chrono::duration cpp/chrono/duration T count cpp/chrono/duration/count (T... args) T duration cpp/chrono/duration/duration (T... args) T max cpp/chrono/duration/max (T... args) T min cpp/chrono/duration/min (T... args) T operator%= cpp/chrono/duration/operator_arith3 (T... args) T operator*= cpp/chrono/duration/operator_arith3 (T... args) T operator+ cpp/chrono/duration/operator_arith (T... args) T operator++ cpp/chrono/duration/operator_arith2 (T... args) T operator++(int) cpp/chrono/duration/operator_arith2 (T... args) T operator+= cpp/chrono/duration/operator_arith3 (T... args) T operator- cpp/chrono/duration/operator_arith (T... args) T operator-- cpp/chrono/duration/operator_arith2 (T... args) T operator--(int) cpp/chrono/duration/operator_arith2 (T... args) T operator-= cpp/chrono/duration/operator_arith3 (T... args) T operator/= cpp/chrono/duration/operator_arith3 (T... args) T operator= cpp/chrono/duration/operator= (T... args) T zero cpp/chrono/duration/zero (T... args) std::chrono::duration_values cpp/chrono/duration_values T max cpp/chrono/duration_values/max (T... args) T min cpp/chrono/duration_values/min (T... args) T zero cpp/chrono/duration_values/zero (T... args) std::chrono::high_resolution_clock cpp/chrono/high_resolution_clock T now cpp/chrono/high_resolution_clock/now (T... args) std::chrono::hours cpp/chrono/duration T count cpp/chrono/duration/count (T... args) T hours cpp/chrono/duration/duration (T... args) T max cpp/chrono/duration/max (T... args) T min cpp/chrono/duration/min (T... args) T operator%= cpp/chrono/duration/operator_arith3 (T... args) T operator*= cpp/chrono/duration/operator_arith3 (T... args) T operator+ cpp/chrono/duration/operator_arith (T... args) T operator++ cpp/chrono/duration/operator_arith2 (T... args) T operator++(int) cpp/chrono/duration/operator_arith2 (T... args) T operator+= cpp/chrono/duration/operator_arith3 (T... args) T operator- cpp/chrono/duration/operator_arith (T... args) T operator-- cpp/chrono/duration/operator_arith2 (T... args) T operator--(int) cpp/chrono/duration/operator_arith2 (T... args) T operator-= cpp/chrono/duration/operator_arith3 (T... args) T operator/= cpp/chrono/duration/operator_arith3 (T... args) T operator= cpp/chrono/duration/operator= (T... args) T zero cpp/chrono/duration/zero (T... args) std::chrono::microseconds cpp/chrono/duration T count cpp/chrono/duration/count (T... args) T max cpp/chrono/duration/max (T... args) T microseconds cpp/chrono/duration/duration (T... args) T min cpp/chrono/duration/min (T... args) T operator%= cpp/chrono/duration/operator_arith3 (T... args) T operator*= cpp/chrono/duration/operator_arith3 (T... args) T operator+ cpp/chrono/duration/operator_arith (T... args) T operator++ cpp/chrono/duration/operator_arith2 (T... args) T operator++(int) cpp/chrono/duration/operator_arith2 (T... args) T operator+= cpp/chrono/duration/operator_arith3 (T... args) T operator- cpp/chrono/duration/operator_arith (T... args) T operator-- cpp/chrono/duration/operator_arith2 (T... args) T operator--(int) cpp/chrono/duration/operator_arith2 (T... args) T operator-= cpp/chrono/duration/operator_arith3 (T... args) T operator/= cpp/chrono/duration/operator_arith3 (T... args) T operator= cpp/chrono/duration/operator= (T... args) T zero cpp/chrono/duration/zero (T... args) std::chrono::milliseconds cpp/chrono/duration T count cpp/chrono/duration/count (T... args) T max cpp/chrono/duration/max (T... args) T milliseconds cpp/chrono/duration/duration (T... args) T min cpp/chrono/duration/min (T... args) T operator%= cpp/chrono/duration/operator_arith3 (T... args) T operator*= cpp/chrono/duration/operator_arith3 (T... args) T operator+ cpp/chrono/duration/operator_arith (T... args) T operator++ cpp/chrono/duration/operator_arith2 (T... args) T operator++(int) cpp/chrono/duration/operator_arith2 (T... args) T operator+= cpp/chrono/duration/operator_arith3 (T... args) T operator- cpp/chrono/duration/operator_arith (T... args) T operator-- cpp/chrono/duration/operator_arith2 (T... args) T operator--(int) cpp/chrono/duration/operator_arith2 (T... args) T operator-= cpp/chrono/duration/operator_arith3 (T... args) T operator/= cpp/chrono/duration/operator_arith3 (T... args) T operator= cpp/chrono/duration/operator= (T... args) T zero cpp/chrono/duration/zero (T... args) std::chrono::minutes cpp/chrono/duration T count cpp/chrono/duration/count (T... args) T max cpp/chrono/duration/max (T... args) T min cpp/chrono/duration/min (T... args) T minutes cpp/chrono/duration/duration (T... args) T operator%= cpp/chrono/duration/operator_arith3 (T... args) T operator*= cpp/chrono/duration/operator_arith3 (T... args) T operator+ cpp/chrono/duration/operator_arith (T... args) T operator++ cpp/chrono/duration/operator_arith2 (T... args) T operator++(int) cpp/chrono/duration/operator_arith2 (T... args) T operator+= cpp/chrono/duration/operator_arith3 (T... args) T operator- cpp/chrono/duration/operator_arith (T... args) T operator-- cpp/chrono/duration/operator_arith2 (T... args) T operator--(int) cpp/chrono/duration/operator_arith2 (T... args) T operator-= cpp/chrono/duration/operator_arith3 (T... args) T operator/= cpp/chrono/duration/operator_arith3 (T... args) T operator= cpp/chrono/duration/operator= (T... args) T zero cpp/chrono/duration/zero (T... args) std::chrono::nanoseconds cpp/chrono/duration T count cpp/chrono/duration/count (T... args) T max cpp/chrono/duration/max (T... args) T min cpp/chrono/duration/min (T... args) T nanoseconds cpp/chrono/duration/duration (T... args) T operator%= cpp/chrono/duration/operator_arith3 (T... args) T operator*= cpp/chrono/duration/operator_arith3 (T... args) T operator+ cpp/chrono/duration/operator_arith (T... args) T operator++ cpp/chrono/duration/operator_arith2 (T... args) T operator++(int) cpp/chrono/duration/operator_arith2 (T... args) T operator+= cpp/chrono/duration/operator_arith3 (T... args) T operator- cpp/chrono/duration/operator_arith (T... args) T operator-- cpp/chrono/duration/operator_arith2 (T... args) T operator--(int) cpp/chrono/duration/operator_arith2 (T... args) T operator-= cpp/chrono/duration/operator_arith3 (T... args) T operator/= cpp/chrono/duration/operator_arith3 (T... args) T operator= cpp/chrono/duration/operator= (T... args) T zero cpp/chrono/duration/zero (T... args) std::chrono::seconds cpp/chrono/duration T count cpp/chrono/duration/count (T... args) T max cpp/chrono/duration/max (T... args) T min cpp/chrono/duration/min (T... args) T operator%= cpp/chrono/duration/operator_arith3 (T... args) T operator*= cpp/chrono/duration/operator_arith3 (T... args) T operator+ cpp/chrono/duration/operator_arith (T... args) T operator++ cpp/chrono/duration/operator_arith2 (T... args) T operator++(int) cpp/chrono/duration/operator_arith2 (T... args) T operator+= cpp/chrono/duration/operator_arith3 (T... args) T operator- cpp/chrono/duration/operator_arith (T... args) T operator-- cpp/chrono/duration/operator_arith2 (T... args) T operator--(int) cpp/chrono/duration/operator_arith2 (T... args) T operator-= cpp/chrono/duration/operator_arith3 (T... args) T operator/= cpp/chrono/duration/operator_arith3 (T... args) T operator= cpp/chrono/duration/operator= (T... args) T seconds cpp/chrono/duration/duration (T... args) T zero cpp/chrono/duration/zero (T... args) std::chrono::steady_clock cpp/chrono/steady_clock T now cpp/chrono/steady_clock/now (T... args) std::chrono::system_clock cpp/chrono/system_clock T from_time_t cpp/chrono/system_clock/from_time_t (T... args) T now cpp/chrono/system_clock/now (T... args) T to_time_t cpp/chrono/system_clock/to_time_t (T... args) std::chrono::time_point cpp/chrono/time_point T max cpp/chrono/time_point/max (T... args) T min cpp/chrono/time_point/min (T... args) T operator+ cpp/chrono/time_point/operator_arith (T... args) T operator- cpp/chrono/time_point/operator_arith (T... args) T time_point cpp/chrono/time_point/time_point (T... args) T time_since_epoch cpp/chrono/time_point/time_since_epoch (T... args) std::chrono::treat_as_floating_point cpp/chrono/treat_as_floating_point std::cin cpp/io/cin std::clock_t cpp/chrono/c/clock_t std::clog cpp/io/clog std::cmatch cpp/regex/match_results T begin cpp/regex/match_results/begin (T... args) T cbegin cpp/regex/match_results/begin (T... args) T cend cpp/regex/match_results/end (T... args) T cmatch cpp/regex/match_results/match_results (T... args) T empty cpp/regex/match_results/empty (T... args) T end cpp/regex/match_results/end (T... args) T format cpp/regex/match_results/format (T... args) T get_allocator cpp/regex/match_results/get_allocator (T... args) T length cpp/regex/match_results/length (T... args) T max_size cpp/regex/match_results/max_size (T... args) T operator[] cpp/regex/match_results/operator_at (T... args) T position cpp/regex/match_results/position (T... args) T prefix cpp/regex/match_results/prefix (T... args) T ready cpp/regex/match_results/ready (T... args) T size cpp/regex/match_results/size (T... args) T str cpp/regex/match_results/str (T... args) T suffix cpp/regex/match_results/suffix (T... args) T swap cpp/regex/match_results/swap (T... args) T ~cmatch cpp/regex/match_results/~match_results (T... args) std::codecvt cpp/locale/codecvt T always_noconv cpp/locale/codecvt/always_noconv (T... args) T codecvt cpp/locale/codecvt/codecvt (T... args) T do_always_noconv cpp/locale/codecvt/always_noconv (T... args) T do_encoding cpp/locale/codecvt/encoding (T... args) T do_in cpp/locale/codecvt/in (T... args) T do_length cpp/locale/codecvt/length (T... args) T do_max_length cpp/locale/codecvt/max_length (T... args) T do_out cpp/locale/codecvt/out (T... args) T do_unshift cpp/locale/codecvt/unshift (T... args) T encoding cpp/locale/codecvt/encoding (T... args) std::codecvt::extern_type T in cpp/locale/codecvt/in (T... args) std::codecvt::intern_type T length cpp/locale/codecvt/length (T... args) T max_length cpp/locale/codecvt/max_length (T... args) T out cpp/locale/codecvt/out (T... args) std::codecvt::state_type T unshift cpp/locale/codecvt/unshift (T... args) T ~codecvt cpp/locale/codecvt/~codecvt (T... args) std::codecvt::extern_type cpp/locale/codecvt std::codecvt::intern_type cpp/locale/codecvt std::codecvt::state_type cpp/locale/codecvt std::codecvt_base cpp/locale/codecvt_base std::codecvt_byname cpp/locale/codecvt_byname T always_noconv cpp/locale/codecvt/always_noconv (T... args) T codecvt_byname cpp/locale/codecvt_byname (T... args) T do_always_noconv cpp/locale/codecvt/always_noconv (T... args) T do_encoding cpp/locale/codecvt/encoding (T... args) T do_in cpp/locale/codecvt/in (T... args) T do_length cpp/locale/codecvt/length (T... args) T do_max_length cpp/locale/codecvt/max_length (T... args) T do_out cpp/locale/codecvt/out (T... args) T do_unshift cpp/locale/codecvt/unshift (T... args) T encoding cpp/locale/codecvt/encoding (T... args) std::codecvt_byname::extern_type T in cpp/locale/codecvt/in (T... args) std::codecvt_byname::intern_type T length cpp/locale/codecvt/length (T... args) T max_length cpp/locale/codecvt/max_length (T... args) T out cpp/locale/codecvt/out (T... args) std::codecvt_byname::state_type T unshift cpp/locale/codecvt/unshift (T... args) T ~codecvt_byname cpp/locale/codecvt_byname (T... args) std::codecvt_byname::extern_type cpp/locale/codecvt std::codecvt_byname::intern_type cpp/locale/codecvt std::codecvt_byname::state_type cpp/locale/codecvt std::codecvt_utf16 cpp/locale/codecvt_utf16 T always_noconv cpp/locale/codecvt/always_noconv (T... args) T do_always_noconv cpp/locale/codecvt/always_noconv (T... args) T do_encoding cpp/locale/codecvt/encoding (T... args) T do_in cpp/locale/codecvt/in (T... args) T do_length cpp/locale/codecvt/length (T... args) T do_max_length cpp/locale/codecvt/max_length (T... args) T do_out cpp/locale/codecvt/out (T... args) T do_unshift cpp/locale/codecvt/unshift (T... args) T encoding cpp/locale/codecvt/encoding (T... args) std::codecvt_utf16::extern_type T in cpp/locale/codecvt/in (T... args) std::codecvt_utf16::intern_type T length cpp/locale/codecvt/length (T... args) T max_length cpp/locale/codecvt/max_length (T... args) T out cpp/locale/codecvt/out (T... args) std::codecvt_utf16::state_type T unshift cpp/locale/codecvt/unshift (T... args) std::codecvt_utf16::extern_type cpp/locale/codecvt std::codecvt_utf16::intern_type cpp/locale/codecvt std::codecvt_utf16::state_type cpp/locale/codecvt std::codecvt_utf8 cpp/locale/codecvt_utf8 T always_noconv cpp/locale/codecvt/always_noconv (T... args) T do_always_noconv cpp/locale/codecvt/always_noconv (T... args) T do_encoding cpp/locale/codecvt/encoding (T... args) T do_in cpp/locale/codecvt/in (T... args) T do_length cpp/locale/codecvt/length (T... args) T do_max_length cpp/locale/codecvt/max_length (T... args) T do_out cpp/locale/codecvt/out (T... args) T do_unshift cpp/locale/codecvt/unshift (T... args) T encoding cpp/locale/codecvt/encoding (T... args) std::codecvt_utf8::extern_type T in cpp/locale/codecvt/in (T... args) std::codecvt_utf8::intern_type T length cpp/locale/codecvt/length (T... args) T max_length cpp/locale/codecvt/max_length (T... args) T out cpp/locale/codecvt/out (T... args) std::codecvt_utf8::state_type T unshift cpp/locale/codecvt/unshift (T... args) std::codecvt_utf8::extern_type cpp/locale/codecvt std::codecvt_utf8::intern_type cpp/locale/codecvt std::codecvt_utf8::state_type cpp/locale/codecvt std::codecvt_utf8_utf16 cpp/locale/codecvt_utf8_utf16 T always_noconv cpp/locale/codecvt/always_noconv (T... args) T do_always_noconv cpp/locale/codecvt/always_noconv (T... args) T do_encoding cpp/locale/codecvt/encoding (T... args) T do_in cpp/locale/codecvt/in (T... args) T do_length cpp/locale/codecvt/length (T... args) T do_max_length cpp/locale/codecvt/max_length (T... args) T do_out cpp/locale/codecvt/out (T... args) T do_unshift cpp/locale/codecvt/unshift (T... args) T encoding cpp/locale/codecvt/encoding (T... args) std::codecvt_utf8_utf16::extern_type T in cpp/locale/codecvt/in (T... args) std::codecvt_utf8_utf16::intern_type T length cpp/locale/codecvt/length (T... args) T max_length cpp/locale/codecvt/max_length (T... args) T out cpp/locale/codecvt/out (T... args) std::codecvt_utf8_utf16::state_type T unshift cpp/locale/codecvt/unshift (T... args) std::codecvt_utf8_utf16::extern_type cpp/locale/codecvt std::codecvt_utf8_utf16::intern_type cpp/locale/codecvt std::codecvt_utf8_utf16::state_type cpp/locale/codecvt std::collate cpp/locale/collate std::collate::char_type T collate cpp/locale/collate/collate (T... args) T compare cpp/locale/collate/compare (T... args) T do_compare cpp/locale/collate/compare (T... args) T do_hash cpp/locale/collate/hash (T... args) T do_transform cpp/locale/collate/transform (T... args) T hash cpp/locale/collate/hash (T... args) std::collate::string_type T transform cpp/locale/collate/transform (T... args) T ~collate cpp/locale/collate/~collate (T... args) std::collate::char_type cpp/locale/collate std::collate::string_type cpp/locale/collate std::collate_byname cpp/locale/collate_byname std::collate_byname::char_type T collate_byname cpp/locale/collate_byname (T... args) T compare cpp/locale/collate/compare (T... args) T do_compare cpp/locale/collate/compare (T... args) T do_hash cpp/locale/collate/hash (T... args) T do_transform cpp/locale/collate/transform (T... args) T hash cpp/locale/collate/hash (T... args) std::collate_byname::string_type T transform cpp/locale/collate/transform (T... args) T ~collate_byname cpp/locale/collate_byname (T... args) std::collate_byname::char_type cpp/locale/collate std::collate_byname::string_type cpp/locale/collate std::common_type cpp/types/common_type std::common_type_t cpp/types/common_type std::complex cpp/numeric/complex T complex cpp/numeric/complex/complex (T... args) T imag cpp/numeric/complex/imag (T... args) T operator*= cpp/numeric/complex/operator_arith (T... args) T operator+= cpp/numeric/complex/operator_arith (T... args) T operator-= cpp/numeric/complex/operator_arith (T... args) T operator/= cpp/numeric/complex/operator_arith (T... args) T operator= cpp/numeric/complex/operator= (T... args) T real cpp/numeric/complex/real (T... args) std::condition_variable cpp/thread/condition_variable T condition_variable cpp/thread/condition_variable/condition_variable (T... args) T native_handle cpp/thread/condition_variable/native_handle (T... args) T notify_all cpp/thread/condition_variable/notify_all (T... args) T notify_one cpp/thread/condition_variable/notify_one (T... args) T wait cpp/thread/condition_variable/wait (T... args) T wait_for cpp/thread/condition_variable/wait_for (T... args) T wait_until cpp/thread/condition_variable/wait_until (T... args) T ~condition_variable cpp/thread/condition_variable/~condition_variable (T... args) std::condition_variable_any cpp/thread/condition_variable_any T condition_variable_any cpp/thread/condition_variable_any/condition_variable_any (T... args) T native_handle cpp/thread/condition_variable_any/native_handle (T... args) T notify_all cpp/thread/condition_variable_any/notify_all (T... args) T notify_one cpp/thread/condition_variable_any/notify_one (T... args) T wait cpp/thread/condition_variable_any/wait (T... args) T wait_for cpp/thread/condition_variable_any/wait_for (T... args) T wait_until cpp/thread/condition_variable_any/wait_until (T... args) T ~condition_variable_any cpp/thread/condition_variable_any/~condition_variable_any (T... args) std::conditional cpp/types/conditional std::conditional_t cpp/types/conditional std::conjunction cpp/types/conjunction std::cout cpp/io/cout std::cregex_iterator cpp/regex/regex_iterator T cregex_iterator cpp/regex/regex_iterator/regex_iterator (T... args) T operator!= cpp/regex/regex_iterator/operator_cmp (T... args) T operator* cpp/regex/regex_iterator/operator* (T... args) T operator++ cpp/regex/regex_iterator/operator_arith (T... args) T operator++(int) cpp/regex/regex_iterator/operator_arith (T... args) T operator-> cpp/regex/regex_iterator/operator* (T... args) T operator= cpp/regex/regex_iterator/operator= (T... args) T operator== cpp/regex/regex_iterator/operator_cmp (T... args) std::cregex_token_iterator cpp/regex/regex_token_iterator T cregex_token_iterator cpp/regex/regex_token_iterator/regex_token_iterator (T... args) T operator!= cpp/regex/regex_token_iterator/operator_cmp (T... args) T operator* cpp/regex/regex_token_iterator/operator* (T... args) T operator++ cpp/regex/regex_token_iterator/operator_arith (T... args) T operator++(int) cpp/regex/regex_token_iterator/operator_arith (T... args) T operator-> cpp/regex/regex_token_iterator/operator* (T... args) T operator= cpp/regex/regex_token_iterator/operator= (T... args) T operator== cpp/regex/regex_token_iterator/operator_cmp (T... args) std::csub_match cpp/regex/sub_match T compare cpp/regex/sub_match/compare (T... args) T csub_match cpp/regex/sub_match/sub_match (T... args) T length cpp/regex/sub_match/length (T... args) T operator string_type cpp/regex/sub_match/str (T... args) T str cpp/regex/sub_match/str (T... args) std::ctype cpp/locale/ctype T ctype cpp/locale/ctype/ctype (T... args) T do_is cpp/locale/ctype/is (T... args) T do_narrow cpp/locale/ctype/narrow (T... args) T do_scan_is cpp/locale/ctype/scan_is (T... args) T do_tolower cpp/locale/ctype/tolower (T... args) T do_toupper cpp/locale/ctype/toupper (T... args) T do_widen cpp/locale/ctype/widen (T... args) T is cpp/locale/ctype/is (T... args) std::ctype::mask T narrow cpp/locale/ctype/narrow (T... args) T scan_is cpp/locale/ctype/scan_is (T... args) T tolower cpp/locale/ctype/tolower (T... args) T toupper cpp/locale/ctype/toupper (T... args) T widen cpp/locale/ctype/widen (T... args) T ~ctype cpp/locale/ctype/~ctype (T... args) std::ctype::mask cpp/locale/ctype_base std::ctype_base cpp/locale/ctype_base std::ctype_base::mask std::ctype_base::mask cpp/locale/ctype_base std::ctype_byname cpp/locale/ctype_byname T ctype_byname cpp/locale/ctype_byname (T... args) T do_is cpp/locale/ctype/is (T... args) T do_narrow cpp/locale/ctype/narrow (T... args) T do_scan_is cpp/locale/ctype/scan_is (T... args) T do_tolower cpp/locale/ctype/tolower (T... args) T do_toupper cpp/locale/ctype/toupper (T... args) T do_widen cpp/locale/ctype/widen (T... args) T is cpp/locale/ctype/is (T... args) std::ctype_byname::mask T narrow cpp/locale/ctype/narrow (T... args) T scan_is cpp/locale/ctype/scan_is (T... args) T tolower cpp/locale/ctype/tolower (T... args) T toupper cpp/locale/ctype/toupper (T... args) T widen cpp/locale/ctype/widen (T... args) T ~ctype_byname cpp/locale/ctype_byname (T... args) std::ctype_byname::mask cpp/locale/ctype_base std::deca cpp/numeric/ratio/ratio std::decay cpp/types/decay std::decay_t cpp/types/decay std::deci cpp/numeric/ratio/ratio std::default_delete cpp/memory/default_delete T default_delete cpp/memory/default_delete (T... args) T operator() cpp/memory/default_delete (T... args) std::default_random_engine cpp/numeric/random std::default_searcher cpp/utility/functional/default_searcher T default_searcher cpp/utility/functional/default_searcher (T... args) std::defer_lock_t cpp/thread/lock_tag_t std::deque cpp/container/deque T assign cpp/container/deque/assign (T... args) T at cpp/container/deque/at (T... args) T back cpp/container/deque/back (T... args) T begin cpp/container/deque/begin (T... args) T cbegin cpp/container/deque/begin (T... args) T cend cpp/container/deque/end (T... args) T clear cpp/container/deque/clear (T... args) T crbegin cpp/container/deque/rbegin (T... args) T crend cpp/container/deque/rend (T... args) T deque cpp/container/deque/deque (T... args) T emplace cpp/container/deque/emplace (T... args) T emplace_back cpp/container/deque/emplace_back (T... args) T emplace_front cpp/container/deque/emplace_front (T... args) T empty cpp/container/deque/empty (T... args) T end cpp/container/deque/end (T... args) T erase cpp/container/deque/erase (T... args) T front cpp/container/deque/front (T... args) T get_allocator cpp/container/deque/get_allocator (T... args) T insert cpp/container/deque/insert (T... args) T max_size cpp/container/deque/max_size (T... args) T operator= cpp/container/deque/operator= (T... args) T operator[] cpp/container/deque/operator_at (T... args) T pop_back cpp/container/deque/pop_back (T... args) T pop_front cpp/container/deque/pop_front (T... args) T push_back cpp/container/deque/push_back (T... args) T push_front cpp/container/deque/push_front (T... args) T rbegin cpp/container/deque/rbegin (T... args) T rend cpp/container/deque/rend (T... args) T resize cpp/container/deque/resize (T... args) T shrink_to_fit cpp/container/deque/shrink_to_fit (T... args) T size cpp/container/deque/size (T... args) T swap cpp/container/deque/swap (T... args) T ~deque cpp/container/deque/~deque (T... args) std::discard_block_engine cpp/numeric/random/discard_block_engine T base cpp/numeric/random/discard_block_engine/base (T... args) T discard cpp/numeric/random/discard_block_engine/discard (T... args) T discard_block_engine cpp/numeric/random/discard_block_engine/discard_block_engine (T... args) T max cpp/numeric/random/discard_block_engine/max (T... args) T min cpp/numeric/random/discard_block_engine/min (T... args) T operator() cpp/numeric/random/discard_block_engine/operator() (T... args) T seed cpp/numeric/random/discard_block_engine/seed (T... args) std::discrete_distribution cpp/numeric/random/discrete_distribution T discrete_distribution cpp/numeric/random/discrete_distribution/discrete_distribution (T... args) T max cpp/numeric/random/discrete_distribution/max (T... args) T min cpp/numeric/random/discrete_distribution/min (T... args) T operator() cpp/numeric/random/discrete_distribution/operator() (T... args) T param cpp/numeric/random/discrete_distribution/param (T... args) T probabilities cpp/numeric/random/discrete_distribution/probabilities (T... args) T reset cpp/numeric/random/discrete_distribution/reset (T... args) std::disjunction cpp/types/disjunction std::div_t cpp/numeric/math/div T quot cpp/numeric/math/div T rem cpp/numeric/math/div std::divides cpp/utility/functional/divides T operator() cpp/utility/functional/divides (T... args) std::domain_error cpp/error/domain_error T domain_error cpp/error/domain_error (T... args) T what cpp/error/exception/what (T... args) std::enable_if cpp/types/enable_if std::enable_if_t cpp/types/enable_if std::enable_shared_from_this cpp/memory/enable_shared_from_this T enable_shared_from_this cpp/memory/enable_shared_from_this/enable_shared_from_this (T... args) T operator= cpp/memory/enable_shared_from_this/operator= (T... args) T shared_from_this cpp/memory/enable_shared_from_this/shared_from_this (T... args) T weak_from_this cpp/memory/enable_shared_from_this/weak_from_this (T... args) T ~enable_shared_from_this cpp/memory/enable_shared_from_this/~enable_shared_from_this (T... args) std::equal_to cpp/utility/functional/equal_to T operator() cpp/utility/functional/equal_to (T... args) std::errc cpp/error/errc std::error_category cpp/error/error_category T default_error_condition cpp/error/error_category/default_error_condition (T... args) T equivalent cpp/error/error_category/equivalent (T... args) T error_category cpp/error/error_category/error_category (T... args) T message cpp/error/error_category/message (T... args) T name cpp/error/error_category/name (T... args) T operator!= cpp/error/error_category/operator_cmp (T... args) T operator< cpp/error/error_category/operator_cmp (T... args) T operator== cpp/error/error_category/operator_cmp (T... args) T ~error_category cpp/error/error_category/~error_category (T... args) std::error_code cpp/error/error_code T assign cpp/error/error_code/assign (T... args) T category cpp/error/error_code/category (T... args) T clear cpp/error/error_code/clear (T... args) T default_error_condition cpp/error/error_code/default_error_condition (T... args) T error_code cpp/error/error_code/error_code (T... args) T message cpp/error/error_code/message (T... args) T operator bool cpp/error/error_code/operator_bool (T... args) T operator= cpp/error/error_code/operator= (T... args) T value cpp/error/error_code/value (T... args) std::error_condition cpp/error/error_condition T assign cpp/error/error_condition/assign (T... args) T category cpp/error/error_condition/category (T... args) T clear cpp/error/error_condition/clear (T... args) T error_condition cpp/error/error_condition/error_condition (T... args) T message cpp/error/error_condition/message (T... args) T operator bool cpp/error/error_condition/operator_bool (T... args) T operator= cpp/error/error_condition/operator= (T... args) T value cpp/error/error_condition/value (T... args) std::exa cpp/numeric/ratio/ratio std::exception cpp/error/exception T exception cpp/error/exception/exception (T... args) T operator= cpp/error/exception/operator= (T... args) T what cpp/error/exception/what (T... args) T ~exception cpp/error/exception/~exception (T... args) std::exception_ptr cpp/error/exception_ptr std::execution std::execution::parallel_policy std::execution::parallel_unsequenced_policy std::execution::sequenced_policy std::execution::parallel_policy cpp/algorithm/execution_policy_tag_t std::execution::parallel_unsequenced_policy cpp/algorithm/execution_policy_tag_t std::execution::sequenced_policy cpp/algorithm/execution_policy_tag_t std::experimental T alignment_of_v cpp/experimental/type_trait_variable_templates std::experimental::any T any_cast cpp/experimental/any/any_cast (T... args) T apply cpp/experimental/apply (T... args) std::experimental::bad_optional_access std::experimental::basic_string_view std::experimental::boyer_moore_horspool_searcher std::experimental::boyer_moore_searcher std::experimental::default_searcher std::experimental::detected_or std::experimental::detected_or_t std::experimental::erased_type T extent_v cpp/experimental/type_trait_variable_templates std::experimental::filesystem T gcd cpp/experimental/gcd (T... args) T has_virtual_destructor_v cpp/experimental/type_trait_variable_templates std::experimental::invocation_type T is_abstract_v cpp/experimental/type_trait_variable_templates T is_arithmetic_v cpp/experimental/type_trait_variable_templates T is_array_v cpp/experimental/type_trait_variable_templates T is_assignable_v cpp/experimental/type_trait_variable_templates T is_base_of_v cpp/experimental/type_trait_variable_templates T is_bind_expression_v cpp/experimental/type_trait_variable_templates T is_class_v cpp/experimental/type_trait_variable_templates T is_compound_v cpp/experimental/type_trait_variable_templates T is_const_v cpp/experimental/type_trait_variable_templates T is_constructible_v cpp/experimental/type_trait_variable_templates T is_convertible_v cpp/experimental/type_trait_variable_templates T is_copy_assignable_v cpp/experimental/type_trait_variable_templates T is_copy_constructible_v cpp/experimental/type_trait_variable_templates T is_default_constructible_v cpp/experimental/type_trait_variable_templates T is_destructible_v cpp/experimental/type_trait_variable_templates std::experimental::is_detected std::experimental::is_detected_convertible T is_detected_convertible_v cpp/experimental/is_detected std::experimental::is_detected_exact T is_detected_exact_v cpp/experimental/is_detected T is_detected_v cpp/experimental/is_detected T is_empty_v cpp/experimental/type_trait_variable_templates T is_enum_v cpp/experimental/type_trait_variable_templates T is_error_code_enum_v cpp/experimental/type_trait_variable_templates T is_error_condition_enum_v cpp/experimental/type_trait_variable_templates T is_final_v cpp/experimental/type_trait_variable_templates T is_floating_point_v cpp/experimental/type_trait_variable_templates T is_function_v cpp/experimental/type_trait_variable_templates T is_fundamental_v cpp/experimental/type_trait_variable_templates T is_integral_v cpp/experimental/type_trait_variable_templates T is_literal_type_v cpp/experimental/type_trait_variable_templates T is_lvalue_reference_v cpp/experimental/type_trait_variable_templates T is_member_function_pointer_v cpp/experimental/type_trait_variable_templates T is_member_object_pointer_v cpp/experimental/type_trait_variable_templates T is_member_pointer_v cpp/experimental/type_trait_variable_templates T is_move_assignable_v cpp/experimental/type_trait_variable_templates T is_move_constructible_v cpp/experimental/type_trait_variable_templates T is_nothrow_assignable_v cpp/experimental/type_trait_variable_templates T is_nothrow_constructible_v cpp/experimental/type_trait_variable_templates T is_nothrow_copy_assignable_v cpp/experimental/type_trait_variable_templates T is_nothrow_copy_constructible_v cpp/experimental/type_trait_variable_templates T is_nothrow_default_constructible_v cpp/experimental/type_trait_variable_templates T is_nothrow_destructible_v cpp/experimental/type_trait_variable_templates T is_nothrow_move_assignable_v cpp/experimental/type_trait_variable_templates T is_nothrow_move_constructible_v cpp/experimental/type_trait_variable_templates T is_null_pointer_v cpp/experimental/type_trait_variable_templates T is_object_v cpp/experimental/type_trait_variable_templates T is_placeholder_v cpp/experimental/type_trait_variable_templates T is_pod_v cpp/experimental/type_trait_variable_templates T is_pointer_v cpp/experimental/type_trait_variable_templates T is_polymorphic_v cpp/experimental/type_trait_variable_templates T is_reference_v cpp/experimental/type_trait_variable_templates T is_rvalue_reference_v cpp/experimental/type_trait_variable_templates T is_same_v cpp/experimental/type_trait_variable_templates T is_scalar_v cpp/experimental/type_trait_variable_templates T is_signed_v cpp/experimental/type_trait_variable_templates T is_standard_layout_v cpp/experimental/type_trait_variable_templates T is_trivial_v cpp/experimental/type_trait_variable_templates T is_trivially_assignable_v cpp/experimental/type_trait_variable_templates T is_trivially_constructible_v cpp/experimental/type_trait_variable_templates T is_trivially_copy_assignable_v cpp/experimental/type_trait_variable_templates T is_trivially_copy_constructible_v cpp/experimental/type_trait_variable_templates T is_trivially_copyable_v cpp/experimental/type_trait_variable_templates T is_trivially_default_constructible_v cpp/experimental/type_trait_variable_templates T is_trivially_destructible_v cpp/experimental/type_trait_variable_templates T is_trivially_move_assignable_v cpp/experimental/type_trait_variable_templates T is_trivially_move_constructible_v cpp/experimental/type_trait_variable_templates T is_union_v cpp/experimental/type_trait_variable_templates T is_unsigned_v cpp/experimental/type_trait_variable_templates T is_void_v cpp/experimental/type_trait_variable_templates T is_volatile_v cpp/experimental/type_trait_variable_templates T lcm cpp/experimental/lcm (T... args) T make_array cpp/experimental/make_array (T... args) T make_boyer_moore_horspool_searcher cpp/experimental/make_boyer_moore_horspool_searcher (T... args) T make_boyer_moore_searcher cpp/experimental/make_boyer_moore_searcher (T... args) T make_default_searcher cpp/experimental/make_default_searcher (T... args) T make_optional cpp/experimental/optional/make_optional (T... args) std::experimental::nonesuch T not_fn cpp/experimental/not_fn (T... args) std::experimental::observer_ptr std::experimental::optional std::experimental::ostream_joiner std::experimental::pmr std::experimental::propagate_const T randint cpp/experimental/randint (T... args) T rank_v cpp/experimental/type_trait_variable_templates T ratio_equal_v cpp/experimental/type_trait_variable_templates T ratio_greater_equal_v cpp/experimental/type_trait_variable_templates T ratio_greater_v cpp/experimental/type_trait_variable_templates T ratio_less_equal_v cpp/experimental/type_trait_variable_templates T ratio_less_v cpp/experimental/type_trait_variable_templates T ratio_not_equal_v cpp/experimental/type_trait_variable_templates std::experimental::raw_invocation_type T reseed cpp/experimental/reseed (T... args) T sample cpp/experimental/sample (T... args) T search cpp/experimental/search (T... args) std::experimental::source_location std::experimental::string_view T to_array cpp/experimental/to_array (T... args) T treat_as_floating_point_v cpp/experimental/type_trait_variable_templates T tuple_size_v cpp/experimental/type_trait_variable_templates std::experimental::u16string_view std::experimental::u32string_view T uses_allocator_v cpp/experimental/type_trait_variable_templates std::experimental::wstring_view std::experimental::any cpp/experimental/any T any cpp/experimental/any/any (T... args) T clear cpp/experimental/any/clear (T... args) T empty cpp/experimental/any/empty (T... args) T operator= cpp/experimental/any/operator= (T... args) T swap cpp/experimental/any/swap (T... args) T type cpp/experimental/any/type (T... args) std::experimental::bad_optional_access cpp/utility/optional/bad_optional_access T bad_optional_access cpp/utility/optional/bad_optional_access (T... args) T what cpp/error/exception/what (T... args) std::experimental::basic_string_view cpp/experimental/basic_string_view T at cpp/experimental/basic_string_view/at (T... args) T back cpp/experimental/basic_string_view/back (T... args) T basic_string_view cpp/experimental/basic_string_view/basic_string_view (T... args) T begin cpp/experimental/basic_string_view/begin (T... args) T cbegin cpp/experimental/basic_string_view/begin (T... args) T cend cpp/experimental/basic_string_view/end (T... args) T compare cpp/experimental/basic_string_view/compare (T... args) T copy cpp/experimental/basic_string_view/copy (T... args) T crbegin cpp/experimental/basic_string_view/rbegin (T... args) T crend cpp/experimental/basic_string_view/rend (T... args) T data cpp/experimental/basic_string_view/data (T... args) T empty cpp/experimental/basic_string_view/empty (T... args) T end cpp/experimental/basic_string_view/end (T... args) T find cpp/experimental/basic_string_view/find (T... args) T find_first_not_of cpp/experimental/basic_string_view/find_first_not_of (T... args) T find_first_of cpp/experimental/basic_string_view/find_first_of (T... args) T find_last_not_of cpp/experimental/basic_string_view/find_last_not_of (T... args) T find_last_of cpp/experimental/basic_string_view/find_last_of (T... args) T front cpp/experimental/basic_string_view/front (T... args) T length cpp/experimental/basic_string_view/size (T... args) T max_size cpp/experimental/basic_string_view/max_size (T... args) T operator basic_string cpp/experimental/basic_string_view/to_string (T... args) T operator= cpp/experimental/basic_string_view/operator= (T... args) T operator[] cpp/experimental/basic_string_view/operator_at (T... args) T rbegin cpp/experimental/basic_string_view/rbegin (T... args) T remove_prefix cpp/experimental/basic_string_view/remove_prefix (T... args) T remove_suffix cpp/experimental/basic_string_view/remove_suffix (T... args) T rend cpp/experimental/basic_string_view/rend (T... args) T rfind cpp/experimental/basic_string_view/rfind (T... args) T size cpp/experimental/basic_string_view/size (T... args) T substr cpp/experimental/basic_string_view/substr (T... args) T swap cpp/experimental/basic_string_view/swap (T... args) T to_string cpp/experimental/basic_string_view/to_string (T... args) std::experimental::boyer_moore_horspool_searcher cpp/experimental/boyer_moore_horspool_searcher std::experimental::boyer_moore_searcher cpp/experimental/boyer_moore_searcher std::experimental::default_searcher cpp/experimental/default_searcher std::experimental::detected_or cpp/experimental/is_detected std::experimental::detected_or_t cpp/experimental/is_detected std::experimental::erased_type cpp/experimental/erased_type std::experimental::filesystem T absolute cpp/experimental/fs/absolute (T... args) T canonical cpp/experimental/fs/canonical (T... args) T copy cpp/experimental/fs/copy (T... args) T copy_file cpp/experimental/fs/copy_file (T... args) std::experimental::filesystem::copy_options T copy_symlink cpp/experimental/fs/copy_symlink (T... args) T create_directories cpp/experimental/fs/create_directory (T... args) T create_directory cpp/experimental/fs/create_directory (T... args) T create_directory_symlink cpp/experimental/fs/create_symlink (T... args) T create_hard_link cpp/experimental/fs/create_hard_link (T... args) T create_symlink cpp/experimental/fs/create_symlink (T... args) T current_path cpp/experimental/fs/current_path (T... args) std::experimental::filesystem::directory_entry std::experimental::filesystem::directory_iterator std::experimental::filesystem::directory_options T equivalent cpp/experimental/fs/equivalent (T... args) T exists cpp/experimental/fs/exists (T... args) T file_size cpp/experimental/fs/file_size (T... args) std::experimental::filesystem::file_status std::experimental::filesystem::file_time_type std::experimental::filesystem::file_type std::experimental::filesystem::filesystem_error T hard_link_count cpp/experimental/fs/hard_link_count (T... args) T is_block_file cpp/experimental/fs/is_block_file (T... args) T is_character_file cpp/experimental/fs/is_character_file (T... args) T is_directory cpp/experimental/fs/is_directory (T... args) T is_empty cpp/experimental/fs/is_empty (T... args) T is_fifo cpp/experimental/fs/is_fifo (T... args) T is_other cpp/experimental/fs/is_other (T... args) T is_regular_file cpp/experimental/fs/is_regular_file (T... args) T is_socket cpp/experimental/fs/is_socket (T... args) T is_symlink cpp/experimental/fs/is_symlink (T... args) T last_write_time cpp/experimental/fs/last_write_time (T... args) std::experimental::filesystem::path T permissions cpp/experimental/fs/permissions (T... args) std::experimental::filesystem::perms T read_symlink cpp/experimental/fs/read_symlink (T... args) std::experimental::filesystem::recursive_directory_iterator T remove cpp/experimental/fs/remove (T... args) T remove_all cpp/experimental/fs/remove (T... args) T rename cpp/experimental/fs/rename (T... args) T resize_file cpp/experimental/fs/resize_file (T... args) T space cpp/experimental/fs/space (T... args) std::experimental::filesystem::space_info T status cpp/experimental/fs/status (T... args) T status_known cpp/experimental/fs/status_known (T... args) T symlink_status cpp/experimental/fs/status (T... args) T system_complete cpp/experimental/fs/absolute (T... args) T temp_directory_path cpp/experimental/fs/temp_directory_path (T... args) std::experimental::filesystem::copy_options cpp/experimental/fs/copy_options std::experimental::filesystem::directory_entry cpp/experimental/fs/directory_entry T assign cpp/experimental/fs/directory_entry/assign (T... args) T directory_entry cpp/experimental/fs/directory_entry/directory_entry (T... args) T operator= cpp/experimental/fs/directory_entry/operator= (T... args) T path cpp/experimental/fs/directory_entry/path (T... args) T replace_filename cpp/experimental/fs/directory_entry/replace_filename (T... args) T status cpp/experimental/fs/directory_entry/status (T... args) T symlink_status cpp/experimental/fs/directory_entry/status (T... args) std::experimental::filesystem::directory_iterator cpp/experimental/fs/directory_iterator T directory_iterator cpp/experimental/fs/directory_iterator/directory_iterator (T... args) T increment cpp/experimental/fs/directory_iterator/increment (T... args) T operator* cpp/experimental/fs/directory_iterator/operator* (T... args) T operator++ cpp/experimental/fs/directory_iterator/increment (T... args) T operator-> cpp/experimental/fs/directory_iterator/operator* (T... args) T operator= cpp/experimental/fs/directory_iterator/operator= (T... args) std::experimental::filesystem::directory_options cpp/experimental/fs/directory_options std::experimental::filesystem::file_status cpp/experimental/fs/file_status T file_status cpp/experimental/fs/file_status/file_status (T... args) T operator= cpp/experimental/fs/file_status/operator= (T... args) T permissions cpp/experimental/fs/file_status/permissions (T... args) T type cpp/experimental/fs/file_status/type (T... args) std::experimental::filesystem::file_time_type cpp/experimental/fs/file_time_type std::experimental::filesystem::file_type cpp/experimental/fs/file_type std::experimental::filesystem::filesystem_error cpp/experimental/fs/filesystem_error T filesystem_error cpp/experimental/fs/filesystem_error/filesystem_error (T... args) T path1 cpp/experimental/fs/filesystem_error/path (T... args) T path2 cpp/experimental/fs/filesystem_error/path (T... args) T what cpp/experimental/fs/filesystem_error/what (T... args) std::experimental::filesystem::path cpp/experimental/fs/path T append cpp/experimental/fs/path/append (T... args) T assign cpp/experimental/fs/path/assign (T... args) T begin cpp/experimental/fs/path/begin (T... args) T c_str cpp/experimental/fs/path/native (T... args) T clear cpp/experimental/fs/path/clear (T... args) T compare cpp/experimental/fs/path/compare (T... args) T concat cpp/experimental/fs/path/concat (T... args) T empty cpp/experimental/fs/path/empty (T... args) T end cpp/experimental/fs/path/begin (T... args) T extension cpp/experimental/fs/path/extension (T... args) T filename cpp/experimental/fs/path/filename (T... args) T generic_string cpp/experimental/fs/path/generic_string (T... args) T generic_u16string cpp/experimental/fs/path/generic_string (T... args) T generic_u32string cpp/experimental/fs/path/generic_string (T... args) T generic_u8string cpp/experimental/fs/path/generic_string (T... args) T generic_wstring cpp/experimental/fs/path/generic_string (T... args) T has_extension cpp/experimental/fs/path/has_path (T... args) T has_filename cpp/experimental/fs/path/has_path (T... args) T has_parent_path cpp/experimental/fs/path/has_path (T... args) T has_relative_path cpp/experimental/fs/path/has_path (T... args) T has_root_directory cpp/experimental/fs/path/has_path (T... args) T has_root_name cpp/experimental/fs/path/has_path (T... args) T has_root_path cpp/experimental/fs/path/has_path (T... args) T has_stem cpp/experimental/fs/path/has_path (T... args) T make_preferred cpp/experimental/fs/path/make_preferred (T... args) T native cpp/experimental/fs/path/native (T... args) T operator string_type cpp/experimental/fs/path/native (T... args) T operator+= cpp/experimental/fs/path/concat (T... args) T operator/= cpp/experimental/fs/path/append (T... args) T operator= cpp/experimental/fs/path/operator= (T... args) T parent_path cpp/experimental/fs/path/parent_path (T... args) T path cpp/experimental/fs/path/path (T... args) T relative_path cpp/experimental/fs/path/relative_path (T... args) T remove_filename cpp/experimental/fs/path/remove_filename (T... args) T replace_extension cpp/experimental/fs/path/replace_extension (T... args) T replace_filename cpp/experimental/fs/path/replace_filename (T... args) T root_directory cpp/experimental/fs/path/root_directory (T... args) T root_name cpp/experimental/fs/path/root_name (T... args) T root_path cpp/experimental/fs/path/root_path (T... args) T stem cpp/experimental/fs/path/stem (T... args) T string cpp/experimental/fs/path/string (T... args) T swap cpp/experimental/fs/path/swap (T... args) T u16string cpp/experimental/fs/path/string (T... args) T u32string cpp/experimental/fs/path/string (T... args) T u8string cpp/experimental/fs/path/string (T... args) T wstring cpp/experimental/fs/path/string (T... args) T ~path cpp/experimental/fs/path/~path (T... args) std::experimental::filesystem::perms cpp/experimental/fs/perms std::experimental::filesystem::recursive_directory_iterator cpp/experimental/fs/recursive_directory_iterator T depth cpp/experimental/fs/recursive_directory_iterator/depth (T... args) T disable_recursion_pending cpp/experimental/fs/recursive_directory_iterator/disable_recursion_pending (T... args) T increment cpp/experimental/fs/recursive_directory_iterator/increment (T... args) T operator* cpp/experimental/fs/recursive_directory_iterator/operator* (T... args) T operator++ cpp/experimental/fs/recursive_directory_iterator/increment (T... args) T operator-> cpp/experimental/fs/recursive_directory_iterator/operator* (T... args) T operator= cpp/experimental/fs/recursive_directory_iterator/operator= (T... args) T options cpp/experimental/fs/recursive_directory_iterator/options (T... args) T pop cpp/experimental/fs/recursive_directory_iterator/pop (T... args) T recursion_pending cpp/experimental/fs/recursive_directory_iterator/recursion_pending (T... args) T recursive_directory_iterator cpp/experimental/fs/recursive_directory_iterator/recursive_directory_iterator (T... args) std::experimental::filesystem::space_info cpp/experimental/fs/space_info T available cpp/experimental/fs/space_info T capacity cpp/experimental/fs/space_info T free cpp/experimental/fs/space_info std::experimental::invocation_type cpp/experimental/invocation_type std::experimental::is_detected cpp/experimental/is_detected std::experimental::is_detected_convertible cpp/experimental/is_detected std::experimental::is_detected_exact cpp/experimental/is_detected std::experimental::nonesuch cpp/experimental/nonesuch std::experimental::observer_ptr cpp/experimental/observer_ptr std::experimental::optional cpp/experimental/optional T emplace cpp/experimental/optional/emplace (T... args) T operator bool cpp/experimental/optional/operator_bool (T... args) T operator* cpp/experimental/optional/operator* (T... args) T operator-> cpp/experimental/optional/operator* (T... args) T operator= cpp/experimental/optional/operator= (T... args) T optional cpp/experimental/optional/optional (T... args) T swap cpp/experimental/optional/swap (T... args) T value cpp/experimental/optional/value (T... args) T value_or cpp/experimental/optional/value_or (T... args) T ~optional cpp/experimental/optional/~optional (T... args) std::experimental::ostream_joiner cpp/experimental/ostream_joiner std::experimental::pmr T get_default_resource cpp/experimental/get_default_resource (T... args) std::experimental::pmr::memory_resource std::experimental::pmr::monotonic_buffer_resource std::experimental::pmr::new_delete_resource std::experimental::pmr::null_memory_resource std::experimental::pmr::polymorphic_allocator std::experimental::pmr::resource_adaptor T set_default_resource cpp/experimental/set_default_resource (T... args) std::experimental::pmr::synchronized_pool_resource std::experimental::pmr::unsynchronized_pool_resource std::experimental::pmr::memory_resource cpp/experimental/memory_resource T allocate cpp/experimental/memory_resource/allocate (T... args) T deallocate cpp/experimental/memory_resource/deallocate (T... args) T do_allocate cpp/experimental/memory_resource/do_allocate (T... args) T do_deallocate cpp/experimental/memory_resource/do_deallocate (T... args) T do_is_equal cpp/experimental/memory_resource/do_is_equal (T... args) T is_equal cpp/experimental/memory_resource/is_equal (T... args) T memory_resource cpp/experimental/memory_resource/memory_resource (T... args) std::experimental::pmr::monotonic_buffer_resource cpp/experimental/monotonic_buffer_resource std::experimental::pmr::new_delete_resource cpp/experimental/new_delete_resource std::experimental::pmr::null_memory_resource cpp/experimental/null_Memory_resource std::experimental::pmr::polymorphic_allocator cpp/experimental/polymorphic_allocator std::experimental::pmr::resource_adaptor cpp/experimental/resource_adaptor std::experimental::pmr::synchronized_pool_resource cpp/experimental/synchronized_pool_resource std::experimental::pmr::unsynchronized_pool_resource cpp/experimental/unsynchronized_pool_resource std::experimental::propagate_const cpp/experimental/propagate_const std::experimental::raw_invocation_type cpp/experimental/raw_invocation_type std::experimental::source_location cpp/experimental/source_location std::experimental::string_view cpp/experimental/basic_string_view T at cpp/experimental/basic_string_view/at (T... args) T back cpp/experimental/basic_string_view/back (T... args) T begin cpp/experimental/basic_string_view/begin (T... args) T cbegin cpp/experimental/basic_string_view/begin (T... args) T cend cpp/experimental/basic_string_view/end (T... args) T compare cpp/experimental/basic_string_view/compare (T... args) T copy cpp/experimental/basic_string_view/copy (T... args) T crbegin cpp/experimental/basic_string_view/rbegin (T... args) T crend cpp/experimental/basic_string_view/rend (T... args) T data cpp/experimental/basic_string_view/data (T... args) T empty cpp/experimental/basic_string_view/empty (T... args) T end cpp/experimental/basic_string_view/end (T... args) T find cpp/experimental/basic_string_view/find (T... args) T find_first_not_of cpp/experimental/basic_string_view/find_first_not_of (T... args) T find_first_of cpp/experimental/basic_string_view/find_first_of (T... args) T find_last_not_of cpp/experimental/basic_string_view/find_last_not_of (T... args) T find_last_of cpp/experimental/basic_string_view/find_last_of (T... args) T front cpp/experimental/basic_string_view/front (T... args) T length cpp/experimental/basic_string_view/size (T... args) T max_size cpp/experimental/basic_string_view/max_size (T... args) T operator basic_string cpp/experimental/basic_string_view/to_string (T... args) T operator= cpp/experimental/basic_string_view/operator= (T... args) T operator[] cpp/experimental/basic_string_view/operator_at (T... args) T rbegin cpp/experimental/basic_string_view/rbegin (T... args) T remove_prefix cpp/experimental/basic_string_view/remove_prefix (T... args) T remove_suffix cpp/experimental/basic_string_view/remove_suffix (T... args) T rend cpp/experimental/basic_string_view/rend (T... args) T rfind cpp/experimental/basic_string_view/rfind (T... args) T size cpp/experimental/basic_string_view/size (T... args) T string_view cpp/experimental/basic_string_view/basic_string_view (T... args) T substr cpp/experimental/basic_string_view/substr (T... args) T swap cpp/experimental/basic_string_view/swap (T... args) T to_string cpp/experimental/basic_string_view/to_string (T... args) std::experimental::u16string_view cpp/experimental/basic_string_view T at cpp/experimental/basic_string_view/at (T... args) T back cpp/experimental/basic_string_view/back (T... args) T begin cpp/experimental/basic_string_view/begin (T... args) T cbegin cpp/experimental/basic_string_view/begin (T... args) T cend cpp/experimental/basic_string_view/end (T... args) T compare cpp/experimental/basic_string_view/compare (T... args) T copy cpp/experimental/basic_string_view/copy (T... args) T crbegin cpp/experimental/basic_string_view/rbegin (T... args) T crend cpp/experimental/basic_string_view/rend (T... args) T data cpp/experimental/basic_string_view/data (T... args) T empty cpp/experimental/basic_string_view/empty (T... args) T end cpp/experimental/basic_string_view/end (T... args) T find cpp/experimental/basic_string_view/find (T... args) T find_first_not_of cpp/experimental/basic_string_view/find_first_not_of (T... args) T find_first_of cpp/experimental/basic_string_view/find_first_of (T... args) T find_last_not_of cpp/experimental/basic_string_view/find_last_not_of (T... args) T find_last_of cpp/experimental/basic_string_view/find_last_of (T... args) T front cpp/experimental/basic_string_view/front (T... args) T length cpp/experimental/basic_string_view/size (T... args) T max_size cpp/experimental/basic_string_view/max_size (T... args) T operator basic_string cpp/experimental/basic_string_view/to_string (T... args) T operator= cpp/experimental/basic_string_view/operator= (T... args) T operator[] cpp/experimental/basic_string_view/operator_at (T... args) T rbegin cpp/experimental/basic_string_view/rbegin (T... args) T remove_prefix cpp/experimental/basic_string_view/remove_prefix (T... args) T remove_suffix cpp/experimental/basic_string_view/remove_suffix (T... args) T rend cpp/experimental/basic_string_view/rend (T... args) T rfind cpp/experimental/basic_string_view/rfind (T... args) T size cpp/experimental/basic_string_view/size (T... args) T substr cpp/experimental/basic_string_view/substr (T... args) T swap cpp/experimental/basic_string_view/swap (T... args) T to_string cpp/experimental/basic_string_view/to_string (T... args) T u16string_view cpp/experimental/basic_string_view/basic_string_view (T... args) std::experimental::u32string_view cpp/experimental/basic_string_view T at cpp/experimental/basic_string_view/at (T... args) T back cpp/experimental/basic_string_view/back (T... args) T begin cpp/experimental/basic_string_view/begin (T... args) T cbegin cpp/experimental/basic_string_view/begin (T... args) T cend cpp/experimental/basic_string_view/end (T... args) T compare cpp/experimental/basic_string_view/compare (T... args) T copy cpp/experimental/basic_string_view/copy (T... args) T crbegin cpp/experimental/basic_string_view/rbegin (T... args) T crend cpp/experimental/basic_string_view/rend (T... args) T data cpp/experimental/basic_string_view/data (T... args) T empty cpp/experimental/basic_string_view/empty (T... args) T end cpp/experimental/basic_string_view/end (T... args) T find cpp/experimental/basic_string_view/find (T... args) T find_first_not_of cpp/experimental/basic_string_view/find_first_not_of (T... args) T find_first_of cpp/experimental/basic_string_view/find_first_of (T... args) T find_last_not_of cpp/experimental/basic_string_view/find_last_not_of (T... args) T find_last_of cpp/experimental/basic_string_view/find_last_of (T... args) T front cpp/experimental/basic_string_view/front (T... args) T length cpp/experimental/basic_string_view/size (T... args) T max_size cpp/experimental/basic_string_view/max_size (T... args) T operator basic_string cpp/experimental/basic_string_view/to_string (T... args) T operator= cpp/experimental/basic_string_view/operator= (T... args) T operator[] cpp/experimental/basic_string_view/operator_at (T... args) T rbegin cpp/experimental/basic_string_view/rbegin (T... args) T remove_prefix cpp/experimental/basic_string_view/remove_prefix (T... args) T remove_suffix cpp/experimental/basic_string_view/remove_suffix (T... args) T rend cpp/experimental/basic_string_view/rend (T... args) T rfind cpp/experimental/basic_string_view/rfind (T... args) T size cpp/experimental/basic_string_view/size (T... args) T substr cpp/experimental/basic_string_view/substr (T... args) T swap cpp/experimental/basic_string_view/swap (T... args) T to_string cpp/experimental/basic_string_view/to_string (T... args) T u32string_view cpp/experimental/basic_string_view/basic_string_view (T... args) std::experimental::wstring_view cpp/experimental/basic_string_view T at cpp/experimental/basic_string_view/at (T... args) T back cpp/experimental/basic_string_view/back (T... args) T begin cpp/experimental/basic_string_view/begin (T... args) T cbegin cpp/experimental/basic_string_view/begin (T... args) T cend cpp/experimental/basic_string_view/end (T... args) T compare cpp/experimental/basic_string_view/compare (T... args) T copy cpp/experimental/basic_string_view/copy (T... args) T crbegin cpp/experimental/basic_string_view/rbegin (T... args) T crend cpp/experimental/basic_string_view/rend (T... args) T data cpp/experimental/basic_string_view/data (T... args) T empty cpp/experimental/basic_string_view/empty (T... args) T end cpp/experimental/basic_string_view/end (T... args) T find cpp/experimental/basic_string_view/find (T... args) T find_first_not_of cpp/experimental/basic_string_view/find_first_not_of (T... args) T find_first_of cpp/experimental/basic_string_view/find_first_of (T... args) T find_last_not_of cpp/experimental/basic_string_view/find_last_not_of (T... args) T find_last_of cpp/experimental/basic_string_view/find_last_of (T... args) T front cpp/experimental/basic_string_view/front (T... args) T length cpp/experimental/basic_string_view/size (T... args) T max_size cpp/experimental/basic_string_view/max_size (T... args) T operator basic_string cpp/experimental/basic_string_view/to_string (T... args) T operator= cpp/experimental/basic_string_view/operator= (T... args) T operator[] cpp/experimental/basic_string_view/operator_at (T... args) T rbegin cpp/experimental/basic_string_view/rbegin (T... args) T remove_prefix cpp/experimental/basic_string_view/remove_prefix (T... args) T remove_suffix cpp/experimental/basic_string_view/remove_suffix (T... args) T rend cpp/experimental/basic_string_view/rend (T... args) T rfind cpp/experimental/basic_string_view/rfind (T... args) T size cpp/experimental/basic_string_view/size (T... args) T substr cpp/experimental/basic_string_view/substr (T... args) T swap cpp/experimental/basic_string_view/swap (T... args) T to_string cpp/experimental/basic_string_view/to_string (T... args) T wstring_view cpp/experimental/basic_string_view/basic_string_view (T... args) std::exponential_distribution cpp/numeric/random/exponential_distribution T exponential_distribution cpp/numeric/random/exponential_distribution/exponential_distribution (T... args) T lambda cpp/numeric/random/exponential_distribution/lambda (T... args) T max cpp/numeric/random/exponential_distribution/max (T... args) T min cpp/numeric/random/exponential_distribution/min (T... args) T operator() cpp/numeric/random/exponential_distribution/operator() (T... args) T param cpp/numeric/random/exponential_distribution/param (T... args) T reset cpp/numeric/random/exponential_distribution/reset (T... args) std::extent cpp/types/extent std::extreme_value_distribution cpp/numeric/random/extreme_value_distribution T a cpp/numeric/random/extreme_value_distribution/params (T... args) T b cpp/numeric/random/extreme_value_distribution/params (T... args) T extreme_value_distribution cpp/numeric/random/extreme_value_distribution/extreme_value_distribution (T... args) T max cpp/numeric/random/extreme_value_distribution/max (T... args) T min cpp/numeric/random/extreme_value_distribution/min (T... args) T operator() cpp/numeric/random/extreme_value_distribution/operator() (T... args) T param cpp/numeric/random/extreme_value_distribution/param (T... args) T reset cpp/numeric/random/extreme_value_distribution/reset (T... args) std::false_type cpp/types/integral_constant std::femto cpp/numeric/ratio/ratio std::filebuf cpp/io/basic_filebuf T close cpp/io/basic_filebuf/close (T... args) T eback cpp/io/basic_streambuf/gptr (T... args) T egptr cpp/io/basic_streambuf/gptr (T... args) T epptr cpp/io/basic_streambuf/pptr (T... args) T filebuf cpp/io/basic_filebuf/basic_filebuf (T... args) T gbump cpp/io/basic_streambuf/gbump (T... args) T getloc cpp/io/basic_streambuf/getloc (T... args) T gptr cpp/io/basic_streambuf/gptr (T... args) T imbue cpp/io/basic_streambuf/pubimbue (T... args) T in_avail cpp/io/basic_streambuf/in_avail (T... args) T is_open cpp/io/basic_filebuf/is_open (T... args) T open cpp/io/basic_filebuf/open (T... args) T operator= cpp/io/basic_filebuf/operator= (T... args) T overflow cpp/io/basic_streambuf/overflow (T... args) T pbackfail cpp/io/basic_streambuf/pbackfail (T... args) T pbase cpp/io/basic_streambuf/pptr (T... args) T pbump cpp/io/basic_streambuf/pbump (T... args) T pptr cpp/io/basic_streambuf/pptr (T... args) T pubimbue cpp/io/basic_streambuf/pubimbue (T... args) T pubseekoff cpp/io/basic_streambuf/pubseekoff (T... args) T pubseekpos cpp/io/basic_streambuf/pubseekpos (T... args) T pubsetbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T pubsync cpp/io/basic_streambuf/pubsync (T... args) T sbumpc cpp/io/basic_streambuf/sbumpc (T... args) T seekoff cpp/io/basic_streambuf/pubseekoff (T... args) T seekpos cpp/io/basic_streambuf/pubseekpos (T... args) T setbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T setg cpp/io/basic_streambuf/setg (T... args) T setp cpp/io/basic_streambuf/setp (T... args) T sgetc cpp/io/basic_streambuf/sgetc (T... args) T sgetn cpp/io/basic_streambuf/sgetn (T... args) T showmanyc cpp/io/basic_streambuf/showmanyc (T... args) T snextc cpp/io/basic_streambuf/snextc (T... args) T sputbackc cpp/io/basic_streambuf/sputbackc (T... args) T sputc cpp/io/basic_streambuf/sputc (T... args) T sputn cpp/io/basic_streambuf/sputn (T... args) T sungetc cpp/io/basic_streambuf/sungetc (T... args) T swap cpp/io/basic_streambuf/swap (T... args) T sync cpp/io/basic_streambuf/pubsync (T... args) T uflow cpp/io/basic_streambuf/uflow (T... args) T underflow cpp/io/basic_streambuf/underflow (T... args) T xsgetn cpp/io/basic_streambuf/sgetn (T... args) T xsputn cpp/io/basic_streambuf/sputn (T... args) T ~filebuf cpp/io/basic_filebuf/~basic_filebuf (T... args) std::filesystem T absolute cpp/filesystem/absolute (T... args) T canonical cpp/filesystem/canonical (T... args) T copy cpp/filesystem/copy (T... args) T copy_file cpp/filesystem/copy_file (T... args) std::filesystem::copy_options T copy_symlink cpp/filesystem/copy_symlink (T... args) T create_directories cpp/filesystem/create_directory (T... args) T create_directory cpp/filesystem/create_directory (T... args) T create_directory_symlink cpp/filesystem/create_symlink (T... args) T create_hard_link cpp/filesystem/create_hard_link (T... args) T create_symlink cpp/filesystem/create_symlink (T... args) T current_path cpp/filesystem/current_path (T... args) std::filesystem::directory_entry std::filesystem::directory_iterator std::filesystem::directory_options T equivalent cpp/filesystem/equivalent (T... args) T exists cpp/filesystem/exists (T... args) T file_size cpp/filesystem/file_size (T... args) std::filesystem::file_status std::filesystem::file_time_type std::filesystem::file_type std::filesystem::filesystem_error T hard_link_count cpp/filesystem/hard_link_count (T... args) T is_block_file cpp/filesystem/is_block_file (T... args) T is_character_file cpp/filesystem/is_character_file (T... args) T is_directory cpp/filesystem/is_directory (T... args) T is_empty cpp/filesystem/is_empty (T... args) T is_fifo cpp/filesystem/is_fifo (T... args) T is_other cpp/filesystem/is_other (T... args) T is_regular_file cpp/filesystem/is_regular_file (T... args) T is_socket cpp/filesystem/is_socket (T... args) T is_symlink cpp/filesystem/is_symlink (T... args) T last_write_time cpp/filesystem/last_write_time (T... args) std::filesystem::path T permissions cpp/filesystem/permissions (T... args) std::filesystem::perms T proximate cpp/filesystem/relative (T... args) T read_symlink cpp/filesystem/read_symlink (T... args) std::filesystem::recursive_directory_iterator T relative cpp/filesystem/relative (T... args) T remove cpp/filesystem/remove (T... args) T remove_all cpp/filesystem/remove (T... args) T rename cpp/filesystem/rename (T... args) T resize_file cpp/filesystem/resize_file (T... args) T space cpp/filesystem/space (T... args) std::filesystem::space_info T status cpp/filesystem/status (T... args) T status_known cpp/filesystem/status_known (T... args) T symlink_status cpp/filesystem/status (T... args) T system_complete cpp/filesystem/absolute (T... args) T temp_directory_path cpp/filesystem/temp_directory_path (T... args) T u8path cpp/filesystem/path/u8path (T... args) T weakly_canonical cpp/filesystem/canonical (T... args) std::filesystem::copy_options cpp/filesystem/copy_options std::filesystem::directory_entry cpp/filesystem/directory_entry T assign cpp/filesystem/directory_entry/assign (T... args) T directory_entry cpp/filesystem/directory_entry/directory_entry (T... args) T operator= cpp/filesystem/directory_entry/operator= (T... args) T path cpp/filesystem/directory_entry/path (T... args) T replace_filename cpp/filesystem/directory_entry/replace_filename (T... args) T status cpp/filesystem/directory_entry/status (T... args) T symlink_status cpp/filesystem/directory_entry/status (T... args) std::filesystem::directory_iterator cpp/filesystem/directory_iterator T directory_iterator cpp/filesystem/directory_iterator/directory_iterator (T... args) T increment cpp/filesystem/directory_iterator/increment (T... args) T operator* cpp/filesystem/directory_iterator/operator* (T... args) T operator++ cpp/filesystem/directory_iterator/increment (T... args) T operator-> cpp/filesystem/directory_iterator/operator* (T... args) T operator= cpp/filesystem/directory_iterator/operator= (T... args) std::filesystem::directory_options cpp/filesystem/directory_options std::filesystem::file_status cpp/filesystem/file_status T file_status cpp/filesystem/file_status/file_status (T... args) T operator= cpp/filesystem/file_status/operator= (T... args) T permissions cpp/filesystem/file_status/permissions (T... args) T type cpp/filesystem/file_status/type (T... args) T ~file_status cpp/filesystem/file_status/~file_status (T... args) std::filesystem::file_time_type cpp/filesystem/file_time_type std::filesystem::file_type cpp/filesystem/file_type std::filesystem::filesystem_error cpp/filesystem/filesystem_error T filesystem_error cpp/filesystem/filesystem_error/filesystem_error (T... args) T path1 cpp/filesystem/filesystem_error/path (T... args) T path2 cpp/filesystem/filesystem_error/path (T... args) T what cpp/filesystem/filesystem_error/what (T... args) std::filesystem::path cpp/filesystem/path T append cpp/filesystem/path/append (T... args) T assign cpp/filesystem/path/assign (T... args) T begin cpp/filesystem/path/begin (T... args) T c_str cpp/filesystem/path/native (T... args) T clear cpp/filesystem/path/clear (T... args) T compare cpp/filesystem/path/compare (T... args) T concat cpp/filesystem/path/concat (T... args) T empty cpp/filesystem/path/empty (T... args) T end cpp/filesystem/path/begin (T... args) T extension cpp/filesystem/path/extension (T... args) T filename cpp/filesystem/path/filename (T... args) T generic_string cpp/filesystem/path/generic_string (T... args) T generic_u16string cpp/filesystem/path/generic_string (T... args) T generic_u32string cpp/filesystem/path/generic_string (T... args) T generic_u8string cpp/filesystem/path/generic_string (T... args) T generic_wstring cpp/filesystem/path/generic_string (T... args) T has_extension cpp/filesystem/path/has_path (T... args) T has_filename cpp/filesystem/path/has_path (T... args) T has_parent_path cpp/filesystem/path/has_path (T... args) T has_relative_path cpp/filesystem/path/has_path (T... args) T has_root_directory cpp/filesystem/path/has_path (T... args) T has_root_name cpp/filesystem/path/has_path (T... args) T has_root_path cpp/filesystem/path/has_path (T... args) T has_stem cpp/filesystem/path/has_path (T... args) T is_absolute cpp/filesystem/path/is_absrel (T... args) T is_relative cpp/filesystem/path/is_absrel (T... args) T lexically_normal cpp/filesystem/path/lexically_normal (T... args) T lexically_proximate cpp/filesystem/path/lexically_normal (T... args) T lexically_relative cpp/filesystem/path/lexically_normal (T... args) T make_preferred cpp/filesystem/path/make_preferred (T... args) T native cpp/filesystem/path/native (T... args) T operator string_type cpp/filesystem/path/native (T... args) T operator+= cpp/filesystem/path/concat (T... args) T operator/= cpp/filesystem/path/append (T... args) T operator= cpp/filesystem/path/operator= (T... args) T parent_path cpp/filesystem/path/parent_path (T... args) T path cpp/filesystem/path/path (T... args) T relative_path cpp/filesystem/path/relative_path (T... args) T remove_filename cpp/filesystem/path/remove_filename (T... args) T replace_extension cpp/filesystem/path/replace_extension (T... args) T replace_filename cpp/filesystem/path/replace_filename (T... args) T root_directory cpp/filesystem/path/root_directory (T... args) T root_name cpp/filesystem/path/root_name (T... args) T root_path cpp/filesystem/path/root_path (T... args) T stem cpp/filesystem/path/stem (T... args) T string cpp/filesystem/path/string (T... args) T swap cpp/filesystem/path/swap (T... args) T u16string cpp/filesystem/path/string (T... args) T u32string cpp/filesystem/path/string (T... args) T u8string cpp/filesystem/path/string (T... args) T wstring cpp/filesystem/path/string (T... args) T ~path cpp/filesystem/path/~path (T... args) std::filesystem::perms cpp/filesystem/perms std::filesystem::recursive_directory_iterator cpp/filesystem/recursive_directory_iterator T depth cpp/filesystem/recursive_directory_iterator/depth (T... args) T disable_recursion_pending cpp/filesystem/recursive_directory_iterator/disable_recursion_pending (T... args) T increment cpp/filesystem/recursive_directory_iterator/increment (T... args) T operator* cpp/filesystem/recursive_directory_iterator/operator* (T... args) T operator++ cpp/filesystem/recursive_directory_iterator/increment (T... args) T operator-> cpp/filesystem/recursive_directory_iterator/operator* (T... args) T operator= cpp/filesystem/recursive_directory_iterator/operator= (T... args) T options cpp/filesystem/recursive_directory_iterator/options (T... args) T pop cpp/filesystem/recursive_directory_iterator/pop (T... args) T recursion_pending cpp/filesystem/recursive_directory_iterator/recursion_pending (T... args) T recursive_directory_iterator cpp/filesystem/recursive_directory_iterator/recursive_directory_iterator (T... args) std::filesystem::space_info cpp/filesystem/space_info T available cpp/filesystem/space_info T capacity cpp/filesystem/space_info T free cpp/filesystem/space_info std::fisher_f_distribution cpp/numeric/random/fisher_f_distribution T fisher_f_distribution cpp/numeric/random/fisher_f_distribution/fisher_f_distribution (T... args) T m cpp/numeric/random/fisher_f_distribution/params (T... args) T max cpp/numeric/random/fisher_f_distribution/max (T... args) T min cpp/numeric/random/fisher_f_distribution/min (T... args) T n cpp/numeric/random/fisher_f_distribution/params (T... args) T operator() cpp/numeric/random/fisher_f_distribution/operator() (T... args) T param cpp/numeric/random/fisher_f_distribution/param (T... args) T reset cpp/numeric/random/fisher_f_distribution/reset (T... args) std::forward_iterator_tag cpp/iterator/iterator_tags std::forward_list cpp/container/forward_list T assign cpp/container/forward_list/assign (T... args) T before_begin cpp/container/forward_list/before_begin (T... args) T begin cpp/container/forward_list/begin (T... args) T cbefore_begin cpp/container/forward_list/before_begin (T... args) T cbegin cpp/container/forward_list/begin (T... args) T cend cpp/container/forward_list/end (T... args) T clear cpp/container/forward_list/clear (T... args) T emplace_after cpp/container/forward_list/emplace_after (T... args) T emplace_front cpp/container/forward_list/emplace_front (T... args) T empty cpp/container/forward_list/empty (T... args) T end cpp/container/forward_list/end (T... args) T erase_after cpp/container/forward_list/erase_after (T... args) T forward_list cpp/container/forward_list/forward_list (T... args) T front cpp/container/forward_list/front (T... args) T get_allocator cpp/container/forward_list/get_allocator (T... args) T insert_after cpp/container/forward_list/insert_after (T... args) T max_size cpp/container/forward_list/max_size (T... args) T merge cpp/container/forward_list/merge (T... args) T operator= cpp/container/forward_list/operator= (T... args) T pop_front cpp/container/forward_list/pop_front (T... args) T push_front cpp/container/forward_list/push_front (T... args) T remove cpp/container/forward_list/remove (T... args) T remove_if cpp/container/forward_list/remove (T... args) T resize cpp/container/forward_list/resize (T... args) T reverse cpp/container/forward_list/reverse (T... args) T sort cpp/container/forward_list/sort (T... args) T splice_after cpp/container/forward_list/splice_after (T... args) T swap cpp/container/forward_list/swap (T... args) T unique cpp/container/forward_list/unique (T... args) T ~forward_list cpp/container/forward_list/~forward_list (T... args) std::fpos cpp/io/fpos T state cpp/io/fpos/state (T... args) std::fpos_t cpp/io/c std::front_insert_iterator cpp/iterator/front_insert_iterator std::fstream cpp/io/basic_fstream std::fstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T close cpp/io/basic_fstream/close (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::fstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::fstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T fstream cpp/io/basic_fstream/basic_fstream (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T is_open cpp/io/basic_fstream/is_open (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T open cpp/io/basic_fstream/open (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator= cpp/io/basic_fstream/operator= (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::fstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::fstream::Init cpp/io/ios_base/Init std::fstream::event_callback cpp/io/ios_base/event_callback std::fstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::fstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::function cpp/utility/functional/function T assign cpp/utility/functional/function/assign (T... args) T function cpp/utility/functional/function/function (T... args) T operator bool cpp/utility/functional/function/operator_bool (T... args) T operator() cpp/utility/functional/function/operator() (T... args) T operator= cpp/utility/functional/function/operator= (T... args) T swap cpp/utility/functional/function/swap (T... args) T target cpp/utility/functional/function/target (T... args) T target_type cpp/utility/functional/function/target_type (T... args) T ~function cpp/utility/functional/function/~function (T... args) std::future cpp/thread/future T future cpp/thread/future/future (T... args) T get cpp/thread/future/get (T... args) T operator= cpp/thread/future/operator= (T... args) T share cpp/thread/future/share (T... args) T valid cpp/thread/future/valid (T... args) T wait cpp/thread/future/wait (T... args) T wait_for cpp/thread/future/wait_for (T... args) T wait_until cpp/thread/future/wait_until (T... args) T ~future cpp/thread/future/~future (T... args) std::future_error cpp/thread/future_error T code cpp/thread/future_error/code (T... args) T future_error cpp/thread/future_error/future_error (T... args) T what cpp/error/exception/what (T... args) std::gamma_distribution cpp/numeric/random/gamma_distribution T alpha cpp/numeric/random/gamma_distribution/params (T... args) T beta cpp/numeric/random/gamma_distribution/params (T... args) T gamma_distribution cpp/numeric/random/gamma_distribution/gamma_distribution (T... args) T max cpp/numeric/random/gamma_distribution/max (T... args) T min cpp/numeric/random/gamma_distribution/min (T... args) T operator() cpp/numeric/random/gamma_distribution/operator() (T... args) T param cpp/numeric/random/gamma_distribution/param (T... args) T reset cpp/numeric/random/gamma_distribution/reset (T... args) std::geometric_distribution cpp/numeric/random/geometric_distribution T geometric_distribution cpp/numeric/random/geometric_distribution/geometric_distribution (T... args) T max cpp/numeric/random/geometric_distribution/max (T... args) T min cpp/numeric/random/geometric_distribution/min (T... args) T p cpp/numeric/random/geometric_distribution/p (T... args) T param cpp/numeric/random/geometric_distribution/param (T... args) T reset cpp/numeric/random/geometric_distribution/reset (T... args) std::giga cpp/numeric/ratio/ratio std::greater cpp/utility/functional/greater T operator() cpp/utility/functional/greater (T... args) std::greater_equal cpp/utility/functional/greater_equal T operator() cpp/utility/functional/greater_equal (T... args) std::gslice cpp/numeric/valarray/gslice std::gslice_array cpp/numeric/valarray/gslice_array std::has_unique_object_representations cpp/types/has_unique_object_representations std::has_virtual_destructor cpp/types/has_virtual_destructor std::hash cpp/utility/hash T hash cpp/utility/hash/hash (T... args) T operator() cpp/utility/hash/operator() (T... args) std::hecto cpp/numeric/ratio/ratio std::ifstream cpp/io/basic_ifstream std::ifstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T close cpp/io/basic_ifstream/close (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::ifstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::ifstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ifstream cpp/io/basic_ifstream/basic_ifstream (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T is_open cpp/io/basic_ifstream/is_open (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T open cpp/io/basic_ifstream/open (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator= cpp/io/basic_ifstream/operator= (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) std::ifstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::ifstream::Init cpp/io/ios_base/Init std::ifstream::event_callback cpp/io/ios_base/event_callback std::ifstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::ifstream::sentry cpp/io/basic_istream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::imaxdiv_t cpp/numeric/math/div T quot cpp/numeric/math/div T rem cpp/numeric/math/div std::in_place_index_t cpp/utility/in_place std::in_place_t cpp/utility/in_place std::in_place_tag cpp/utility/in_place_tag std::in_place_type_t cpp/utility/in_place std::independent_bits_engine cpp/numeric/random/independent_bits_engine T base cpp/numeric/random/independent_bits_engine/base (T... args) T discard cpp/numeric/random/independent_bits_engine/discard (T... args) T independent_bits_engine cpp/numeric/random/independent_bits_engine/independent_bits_engine (T... args) T max cpp/numeric/random/independent_bits_engine/max (T... args) T min cpp/numeric/random/independent_bits_engine/min (T... args) T operator() cpp/numeric/random/independent_bits_engine/operator() (T... args) T seed cpp/numeric/random/independent_bits_engine/seed (T... args) std::index_sequence cpp/utility/integer_sequence std::index_sequence_for cpp/utility/integer_sequence std::indirect_array cpp/numeric/valarray/indirect_array std::initializer_list cpp/utility/initializer_list T begin cpp/utility/initializer_list/begin (T... args) T end cpp/utility/initializer_list/end (T... args) T initializer_list cpp/utility/initializer_list/initializer_list (T... args) T size cpp/utility/initializer_list/size (T... args) std::input_iterator_tag cpp/iterator/iterator_tags std::insert_iterator cpp/iterator/insert_iterator std::int16_t cpp/types/integer std::int32_t cpp/types/integer std::int64_t cpp/types/integer std::int8_t cpp/types/integer std::int_fast16_t cpp/types/integer std::int_fast32_t cpp/types/integer std::int_fast64_t cpp/types/integer std::int_fast8_t cpp/types/integer std::int_least16_t cpp/types/integer std::int_least32_t cpp/types/integer std::int_least64_t cpp/types/integer std::int_least8_t cpp/types/integer std::integer_sequence cpp/utility/integer_sequence std::integral_constant cpp/types/integral_constant std::intmax_t cpp/types/integer std::intptr_t cpp/types/integer std::invalid_argument cpp/error/invalid_argument T invalid_argument cpp/error/invalid_argument (T... args) T what cpp/error/exception/what (T... args) std::ios_base cpp/io/ios_base std::ios_base::Init std::ios_base::event_callback std::ios_base::failure T flags cpp/io/ios_base/flags (T... args) T getloc cpp/io/ios_base/getloc (T... args) T imbue cpp/io/ios_base/imbue (T... args) T ios_base cpp/io/ios_base/ios_base (T... args) T iword cpp/io/ios_base/iword (T... args) T precision cpp/io/ios_base/precision (T... args) T pword cpp/io/ios_base/pword (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T setf cpp/io/ios_base/setf (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T width cpp/io/ios_base/width (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~ios_base cpp/io/ios_base/~ios_base (T... args) std::ios_base::Init cpp/io/ios_base/Init std::ios_base::event_callback cpp/io/ios_base/event_callback std::ios_base::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::iostream cpp/io/basic_iostream std::iostream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::iostream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::iostream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iostream cpp/io/basic_iostream/basic_iostream (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::iostream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~iostream cpp/io/basic_iostream/~basic_iostream (T... args) std::iostream::Init cpp/io/ios_base/Init std::iostream::event_callback cpp/io/ios_base/event_callback std::iostream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::iostream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::is_abstract cpp/types/is_abstract std::is_arithmetic cpp/types/is_arithmetic std::is_array cpp/types/is_array std::is_assignable cpp/types/is_assignable std::is_base_of cpp/types/is_base_of std::is_bind_expression cpp/utility/functional/is_bind_expression std::is_callable cpp/types/is_callable std::is_class cpp/types/is_class std::is_compound cpp/types/is_compound std::is_const cpp/types/is_const std::is_constructible cpp/types/is_constructible std::is_convertible cpp/types/is_convertible std::is_copy_assignable cpp/types/is_copy_assignable std::is_copy_constructible cpp/types/is_copy_constructible std::is_default_constructible cpp/types/is_default_constructible std::is_destructible cpp/types/is_destructible std::is_empty cpp/types/is_empty std::is_enum cpp/types/is_enum std::is_error_code_enum cpp/error/error_code/is_error_code_enum std::is_error_code_enum_v cpp/error/error_code/is_error_code_enum std::is_error_condition_enum cpp/error/error_condition/is_error_condition_enum std::is_execution_policy cpp/algorithm/is_execution_policy std::is_final cpp/types/is_final std::is_floating_point cpp/types/is_floating_point std::is_function cpp/types/is_function std::is_fundamental cpp/types/is_fundamental std::is_integral cpp/types/is_integral std::is_literal_type cpp/types/is_literal_type std::is_lvalue_reference cpp/types/is_lvalue_reference std::is_member_function_pointer cpp/types/is_member_function_pointer std::is_member_object_pointer cpp/types/is_member_object_pointer std::is_member_pointer cpp/types/is_member_pointer std::is_move_assignable cpp/types/is_move_assignable std::is_move_constructible cpp/types/is_move_constructible std::is_nothrow_assignable cpp/types/is_assignable std::is_nothrow_callable cpp/types/is_callable std::is_nothrow_constructible cpp/types/is_constructible std::is_nothrow_copy_assignable cpp/types/is_copy_assignable std::is_nothrow_copy_constructible cpp/types/is_copy_constructible std::is_nothrow_default_constructible cpp/types/is_default_constructible std::is_nothrow_destructible cpp/types/is_destructible std::is_nothrow_move_assignable cpp/types/is_move_assignable std::is_nothrow_move_constructible cpp/types/is_move_constructible std::is_nothrow_swappable cpp/types/is_swappable std::is_nothrow_swappable_with cpp/types/is_swappable_with std::is_null_pointer cpp/types/is_null_pointer std::is_object cpp/types/is_object std::is_placeholder cpp/utility/functional/is_placeholder std::is_pod cpp/types/is_pod std::is_pointer cpp/types/is_pointer std::is_polymorphic cpp/types/is_polymorphic std::is_reference cpp/types/is_reference std::is_rvalue_reference cpp/types/is_rvalue_reference std::is_same cpp/types/is_same std::is_scalar cpp/types/is_scalar std::is_signed cpp/types/is_signed std::is_standard_layout cpp/types/is_standard_layout std::is_swappable cpp/types/is_swappable std::is_swappable_with cpp/types/is_swappable_with std::is_trivial cpp/types/is_trivial std::is_trivially_assignable cpp/types/is_assignable std::is_trivially_constructible cpp/types/is_constructible std::is_trivially_copy_assignable cpp/types/is_copy_assignable std::is_trivially_copy_constructible cpp/types/is_copy_constructible std::is_trivially_copyable cpp/types/is_trivially_copyable std::is_trivially_default_constructible cpp/types/is_default_constructible std::is_trivially_destructible cpp/types/is_destructible std::is_trivially_move_assignable cpp/types/is_move_assignable std::is_trivially_move_constructible cpp/types/is_move_constructible std::is_union cpp/types/is_union std::is_unsigned cpp/types/is_unsigned std::is_void cpp/types/is_void std::is_volatile cpp/types/is_volatile std::istream cpp/io/basic_istream std::istream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::istream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::istream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T istream cpp/io/basic_istream/basic_istream (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) std::istream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~istream cpp/io/basic_istream/~basic_istream (T... args) std::istream::Init cpp/io/ios_base/Init std::istream::event_callback cpp/io/ios_base/event_callback std::istream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::istream::sentry cpp/io/basic_istream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::istream_iterator cpp/iterator/istream_iterator std::istreambuf_iterator cpp/iterator/istreambuf_iterator std::istringstream cpp/io/basic_istringstream std::istringstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::istringstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::istringstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T istringstream cpp/io/basic_istringstream/basic_istringstream (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator= cpp/io/basic_istringstream/operator= (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) std::istringstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T str cpp/io/basic_istringstream/str (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::istringstream::Init cpp/io/ios_base/Init std::istringstream::event_callback cpp/io/ios_base/event_callback std::istringstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::istringstream::sentry cpp/io/basic_istream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::istrstream cpp/io/istrstream std::istrstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::istrstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::istrstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T istrstream cpp/io/istrstream/istrstream (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) std::istrstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T str cpp/io/istrstream/str (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~istrstream cpp/io/istrstream/~istrstream (T... args) std::istrstream::Init cpp/io/ios_base/Init std::istrstream::event_callback cpp/io/ios_base/event_callback std::istrstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::istrstream::sentry cpp/io/basic_istream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::iterator cpp/iterator/iterator std::iterator_traits cpp/iterator/iterator_traits std::jmp_buf cpp/utility/program/jmp_buf std::kilo cpp/numeric/ratio/ratio std::knuth_b cpp/numeric/random/shuffle_order_engine T base cpp/numeric/random/shuffle_order_engine/base (T... args) T discard cpp/numeric/random/shuffle_order_engine/discard (T... args) T knuth_b cpp/numeric/random/shuffle_order_engine/shuffle_order_engine (T... args) T max cpp/numeric/random/shuffle_order_engine/max (T... args) T min cpp/numeric/random/shuffle_order_engine/min (T... args) T operator() cpp/numeric/random/shuffle_order_engine/operator() (T... args) T seed cpp/numeric/random/shuffle_order_engine/seed (T... args) std::lconv cpp/locale/lconv std::ldiv_t cpp/numeric/math/div T quot cpp/numeric/math/div T rem cpp/numeric/math/div std::length_error cpp/error/length_error T length_error cpp/error/length_error (T... args) T what cpp/error/exception/what (T... args) std::less cpp/utility/functional/less T operator() cpp/utility/functional/less (T... args) std::less_equal cpp/utility/functional/less_equal T operator() cpp/utility/functional/less_equal (T... args) std::linear_congruential_engine cpp/numeric/random/linear_congruential_engine T discard cpp/numeric/random/linear_congruential_engine/discard (T... args) T linear_congruential_engine cpp/numeric/random/linear_congruential_engine/linear_congruential_engine (T... args) T max cpp/numeric/random/linear_congruential_engine/max (T... args) T min cpp/numeric/random/linear_congruential_engine/min (T... args) T operator() cpp/numeric/random/linear_congruential_engine/operator() (T... args) T seed cpp/numeric/random/linear_congruential_engine/seed (T... args) std::list cpp/container/list T assign cpp/container/list/assign (T... args) T back cpp/container/list/back (T... args) T begin cpp/container/list/begin (T... args) T cbegin cpp/container/list/begin (T... args) T cend cpp/container/list/end (T... args) T clear cpp/container/list/clear (T... args) T crbegin cpp/container/list/rbegin (T... args) T crend cpp/container/list/rend (T... args) T emplace cpp/container/list/emplace (T... args) T emplace_back cpp/container/list/emplace_back (T... args) T emplace_front cpp/container/list/emplace_front (T... args) T empty cpp/container/list/empty (T... args) T end cpp/container/list/end (T... args) T erase cpp/container/list/erase (T... args) T front cpp/container/list/front (T... args) T get_allocator cpp/container/list/get_allocator (T... args) T insert cpp/container/list/insert (T... args) T list cpp/container/list/list (T... args) T max_size cpp/container/list/max_size (T... args) T merge cpp/container/list/merge (T... args) T operator= cpp/container/list/operator= (T... args) T pop_back cpp/container/list/pop_back (T... args) T pop_front cpp/container/list/pop_front (T... args) T push_back cpp/container/list/push_back (T... args) T push_front cpp/container/list/push_front (T... args) T rbegin cpp/container/list/rbegin (T... args) T remove cpp/container/list/remove (T... args) T remove_if cpp/container/list/remove (T... args) T rend cpp/container/list/rend (T... args) T resize cpp/container/list/resize (T... args) T reverse cpp/container/list/reverse (T... args) T size cpp/container/list/size (T... args) T sort cpp/container/list/sort (T... args) T splice cpp/container/list/splice (T... args) T swap cpp/container/list/swap (T... args) T unique cpp/container/list/unique (T... args) T ~list cpp/container/list/~list (T... args) std::lldiv_t cpp/numeric/math/div T quot cpp/numeric/math/div T rem cpp/numeric/math/div std::locale cpp/locale/locale T classic cpp/locale/locale/classic (T... args) T combine cpp/locale/locale/combine (T... args) std::locale::facet T global cpp/locale/locale/global (T... args) std::locale::id T locale cpp/locale/locale/locale (T... args) T name cpp/locale/locale/name (T... args) T operator!= cpp/locale/locale/operator_cmp (T... args) T operator() cpp/locale/locale/operator() (T... args) T operator= cpp/locale/locale/operator= (T... args) T operator== cpp/locale/locale/operator_cmp (T... args) T ~locale cpp/locale/locale/~locale (T... args) std::locale::facet cpp/locale/locale/facet T facet cpp/locale/locale/facet/facet (T... args) std::locale::id cpp/locale/locale/id T id cpp/locale/locale/id/id (T... args) std::lock_guard cpp/thread/lock_guard T lock_guard cpp/thread/lock_guard/lock_guard (T... args) T ~lock_guard cpp/thread/lock_guard/~lock_guard (T... args) std::logic_error cpp/error/logic_error T logic_error cpp/error/logic_error (T... args) T what cpp/error/exception/what (T... args) std::logical_and cpp/utility/functional/logical_and T operator() cpp/utility/functional/logical_and (T... args) std::logical_not cpp/utility/functional/logical_not T operator() cpp/utility/functional/logical_not (T... args) std::logical_or cpp/utility/functional/logical_or T operator() cpp/utility/functional/logical_or (T... args) std::lognormal_distribution cpp/numeric/random/lognormal_distribution T lognormal_distribution cpp/numeric/random/lognormal_distribution/lognormal_distribution (T... args) T m cpp/numeric/random/lognormal_distribution/params (T... args) T max cpp/numeric/random/lognormal_distribution/max (T... args) T min cpp/numeric/random/lognormal_distribution/min (T... args) T operator() cpp/numeric/random/lognormal_distribution/operator() (T... args) T param cpp/numeric/random/lognormal_distribution/param (T... args) T reset cpp/numeric/random/lognormal_distribution/reset (T... args) T s cpp/numeric/random/lognormal_distribution/params (T... args) std::make_boyer_moore_horspool_searcher cpp/utility/functional/boyer_moore_horspool_searcher std::make_boyer_moore_searcher cpp/utility/functional/boyer_moore_searcher std::make_default_searcher cpp/utility/functional/default_searcher std::make_index_sequence cpp/utility/integer_sequence std::make_integer_sequence cpp/utility/integer_sequence std::make_signed cpp/types/make_signed std::make_signed_t cpp/types/make_signed std::make_unsigned cpp/types/make_unsigned std::make_unsigned_t cpp/types/make_unsigned std::map cpp/container/map T at cpp/container/map/at (T... args) T begin cpp/container/map/begin (T... args) T cbegin cpp/container/map/begin (T... args) T cend cpp/container/map/end (T... args) T clear cpp/container/map/clear (T... args) T count cpp/container/map/count (T... args) T crbegin cpp/container/map/rbegin (T... args) T crend cpp/container/map/rend (T... args) T emplace cpp/container/map/emplace (T... args) T emplace_hint cpp/container/map/emplace_hint (T... args) T empty cpp/container/map/empty (T... args) T end cpp/container/map/end (T... args) T equal_range cpp/container/map/equal_range (T... args) T erase cpp/container/map/erase (T... args) T extract cpp/container/map/extract (T... args) T find cpp/container/map/find (T... args) T get_allocator cpp/container/map/get_allocator (T... args) T insert cpp/container/map/insert (T... args) T insert_or_assign cpp/container/map/insert_or_assign (T... args) T key_comp cpp/container/map/key_comp (T... args) T lower_bound cpp/container/map/lower_bound (T... args) T map cpp/container/map/map (T... args) T max_size cpp/container/map/max_size (T... args) T merge cpp/container/map/merge (T... args) T operator= cpp/container/map/operator= (T... args) T operator[] cpp/container/map/operator_at (T... args) T rbegin cpp/container/map/rbegin (T... args) T rend cpp/container/map/rend (T... args) T size cpp/container/map/size (T... args) T swap cpp/container/map/swap (T... args) T try_emplace cpp/container/map/try_emplace (T... args) T upper_bound cpp/container/map/upper_bound (T... args) T value_comp cpp/container/map/value_comp (T... args) std::map::value_compare T ~map cpp/container/map/~map (T... args) std::map::value_compare cpp/container/map/value_compare std::mask_array cpp/numeric/valarray/mask_array std::match_results cpp/regex/match_results T begin cpp/regex/match_results/begin (T... args) T cbegin cpp/regex/match_results/begin (T... args) T cend cpp/regex/match_results/end (T... args) T empty cpp/regex/match_results/empty (T... args) T end cpp/regex/match_results/end (T... args) T format cpp/regex/match_results/format (T... args) T get_allocator cpp/regex/match_results/get_allocator (T... args) T length cpp/regex/match_results/length (T... args) T match_results cpp/regex/match_results/match_results (T... args) T max_size cpp/regex/match_results/max_size (T... args) T operator[] cpp/regex/match_results/operator_at (T... args) T position cpp/regex/match_results/position (T... args) T prefix cpp/regex/match_results/prefix (T... args) T ready cpp/regex/match_results/ready (T... args) T size cpp/regex/match_results/size (T... args) T str cpp/regex/match_results/str (T... args) T suffix cpp/regex/match_results/suffix (T... args) T swap cpp/regex/match_results/swap (T... args) T ~match_results cpp/regex/match_results/~match_results (T... args) std::max_align_t cpp/types/max_align_t std::mbstate_t cpp/string/multibyte/mbstate_t std::mega cpp/numeric/ratio/ratio std::mersenne_twister_engine cpp/numeric/random/mersenne_twister_engine T discard cpp/numeric/random/mersenne_twister_engine/discard (T... args) T max cpp/numeric/random/mersenne_twister_engine/max (T... args) T mersenne_twister_engine cpp/numeric/random/mersenne_twister_engine/mersenne_twister_engine (T... args) T min cpp/numeric/random/mersenne_twister_engine/min (T... args) T operator() cpp/numeric/random/mersenne_twister_engine/operator() (T... args) T seed cpp/numeric/random/mersenne_twister_engine/seed (T... args) std::messages cpp/locale/messages std::messages::catalog std::messages::char_type T close cpp/locale/messages/close (T... args) T do_close cpp/locale/messages/close (T... args) T do_get cpp/locale/messages/get (T... args) T do_open cpp/locale/messages/open (T... args) T get cpp/locale/messages/get (T... args) T messages cpp/locale/messages/messages (T... args) T open cpp/locale/messages/open (T... args) std::messages::string_type T ~messages cpp/locale/messages/~messages (T... args) std::messages::catalog cpp/locale/messages_base std::messages::char_type cpp/locale/messages std::messages::string_type cpp/locale/messages std::messages_base cpp/locale/messages_base std::messages_base::catalog std::messages_base::catalog cpp/locale/messages_base std::messages_byname cpp/locale/messages_byname std::messages_byname::catalog std::messages_byname::char_type T close cpp/locale/messages/close (T... args) T do_close cpp/locale/messages/close (T... args) T do_get cpp/locale/messages/get (T... args) T do_open cpp/locale/messages/open (T... args) T get cpp/locale/messages/get (T... args) T messages_byname cpp/locale/messages_byname (T... args) T open cpp/locale/messages/open (T... args) std::messages_byname::string_type T ~messages_byname cpp/locale/messages_byname (T... args) std::messages_byname::catalog cpp/locale/messages_base std::messages_byname::char_type cpp/locale/messages std::messages_byname::string_type cpp/locale/messages std::micro cpp/numeric/ratio/ratio std::milli cpp/numeric/ratio/ratio std::minstd_rand cpp/numeric/random/linear_congruential_engine T discard cpp/numeric/random/linear_congruential_engine/discard (T... args) T max cpp/numeric/random/linear_congruential_engine/max (T... args) T min cpp/numeric/random/linear_congruential_engine/min (T... args) T minstd_rand cpp/numeric/random/linear_congruential_engine/linear_congruential_engine (T... args) T operator() cpp/numeric/random/linear_congruential_engine/operator() (T... args) T seed cpp/numeric/random/linear_congruential_engine/seed (T... args) std::minstd_rand0 cpp/numeric/random/linear_congruential_engine T discard cpp/numeric/random/linear_congruential_engine/discard (T... args) T max cpp/numeric/random/linear_congruential_engine/max (T... args) T min cpp/numeric/random/linear_congruential_engine/min (T... args) T minstd_rand0 cpp/numeric/random/linear_congruential_engine/linear_congruential_engine (T... args) T operator() cpp/numeric/random/linear_congruential_engine/operator() (T... args) T seed cpp/numeric/random/linear_congruential_engine/seed (T... args) std::minus cpp/utility/functional/minus T operator() cpp/utility/functional/minus (T... args) std::modulus cpp/utility/functional/modulus T operator() cpp/utility/functional/modulus (T... args) std::money_base cpp/locale/money_base std::money_base::pattern std::money_base::pattern cpp/locale/money_base std::money_get cpp/locale/money_get std::money_get::char_type T do_get cpp/locale/money_get/get (T... args) T get cpp/locale/money_get/get (T... args) std::money_get::iter_type T money_get cpp/locale/money_get/money_get (T... args) std::money_get::pattern std::money_get::string_type T ~money_get cpp/locale/money_get/~money_get (T... args) std::money_get::char_type cpp/locale/money_get std::money_get::iter_type cpp/locale/money_get std::money_get::pattern cpp/locale/money_base std::money_get::string_type cpp/locale/money_get std::money_put cpp/locale/money_put std::money_put::char_type T do_put cpp/locale/money_put/put (T... args) std::money_put::iter_type T money_put cpp/locale/money_put/money_put (T... args) std::money_put::pattern T put cpp/locale/money_put/put (T... args) std::money_put::string_type T ~money_put cpp/locale/money_put/~money_put (T... args) std::money_put::char_type cpp/locale/money_put std::money_put::iter_type cpp/locale/money_put std::money_put::pattern cpp/locale/money_base std::money_put::string_type cpp/locale/money_put std::moneypunct cpp/locale/moneypunct std::moneypunct::char_type T curr_symbol cpp/locale/moneypunct/curr_symbol (T... args) T decimal_point cpp/locale/moneypunct/decimal_point (T... args) T do_curr_symbol cpp/locale/moneypunct/curr_symbol (T... args) T do_decimal_point cpp/locale/moneypunct/decimal_point (T... args) T do_frac_digits cpp/locale/moneypunct/frac_digits (T... args) T do_grouping cpp/locale/moneypunct/grouping (T... args) T do_neg_format cpp/locale/moneypunct/pos_format (T... args) T do_negative_sign cpp/locale/moneypunct/positive_sign (T... args) T do_pos_format cpp/locale/moneypunct/pos_format (T... args) T do_positive_sign cpp/locale/moneypunct/positive_sign (T... args) T do_thousands_sep cpp/locale/moneypunct/thousands_sep (T... args) T frac_digits cpp/locale/moneypunct/frac_digits (T... args) T grouping cpp/locale/moneypunct/grouping (T... args) T moneypunct cpp/locale/moneypunct/moneypunct (T... args) T neg_format cpp/locale/moneypunct/pos_format (T... args) T negative_sign cpp/locale/moneypunct/positive_sign (T... args) std::moneypunct::pattern T pos_format cpp/locale/moneypunct/pos_format (T... args) T positive_sign cpp/locale/moneypunct/positive_sign (T... args) std::moneypunct::string_type T thousands_sep cpp/locale/moneypunct/thousands_sep (T... args) T ~moneypunct cpp/locale/moneypunct/~moneypunct (T... args) std::moneypunct::char_type cpp/locale/moneypunct std::moneypunct::pattern cpp/locale/money_base std::moneypunct::string_type cpp/locale/moneypunct std::moneypunct_byname cpp/locale/moneypunct_byname std::moneypunct_byname::char_type T curr_symbol cpp/locale/moneypunct/curr_symbol (T... args) T decimal_point cpp/locale/moneypunct/decimal_point (T... args) T do_curr_symbol cpp/locale/moneypunct/curr_symbol (T... args) T do_decimal_point cpp/locale/moneypunct/decimal_point (T... args) T do_frac_digits cpp/locale/moneypunct/frac_digits (T... args) T do_grouping cpp/locale/moneypunct/grouping (T... args) T do_neg_format cpp/locale/moneypunct/pos_format (T... args) T do_negative_sign cpp/locale/moneypunct/positive_sign (T... args) T do_pos_format cpp/locale/moneypunct/pos_format (T... args) T do_positive_sign cpp/locale/moneypunct/positive_sign (T... args) T do_thousands_sep cpp/locale/moneypunct/thousands_sep (T... args) T frac_digits cpp/locale/moneypunct/frac_digits (T... args) T grouping cpp/locale/moneypunct/grouping (T... args) T moneypunct_byname cpp/locale/moneypunct_byname (T... args) T neg_format cpp/locale/moneypunct/pos_format (T... args) T negative_sign cpp/locale/moneypunct/positive_sign (T... args) std::moneypunct_byname::pattern T pos_format cpp/locale/moneypunct/pos_format (T... args) T positive_sign cpp/locale/moneypunct/positive_sign (T... args) std::moneypunct_byname::string_type T thousands_sep cpp/locale/moneypunct/thousands_sep (T... args) T ~moneypunct_byname cpp/locale/moneypunct_byname (T... args) std::moneypunct_byname::char_type cpp/locale/moneypunct std::moneypunct_byname::pattern cpp/locale/money_base std::moneypunct_byname::string_type cpp/locale/moneypunct std::monostate cpp/utility/variant/monostate T monostate cpp/utility/variant/monostate/monostate (T... args) T operator= cpp/utility/variant/monostate/operator= (T... args) T ~monostate cpp/utility/variant/monostate/~monostate (T... args) std::move_iterator cpp/iterator/move_iterator std::mt19937 cpp/numeric/random/mersenne_twister_engine T discard cpp/numeric/random/mersenne_twister_engine/discard (T... args) T max cpp/numeric/random/mersenne_twister_engine/max (T... args) T min cpp/numeric/random/mersenne_twister_engine/min (T... args) T mt19937 cpp/numeric/random/mersenne_twister_engine/mersenne_twister_engine (T... args) T operator() cpp/numeric/random/mersenne_twister_engine/operator() (T... args) T seed cpp/numeric/random/mersenne_twister_engine/seed (T... args) std::mt19937_64 cpp/numeric/random/mersenne_twister_engine T discard cpp/numeric/random/mersenne_twister_engine/discard (T... args) T max cpp/numeric/random/mersenne_twister_engine/max (T... args) T min cpp/numeric/random/mersenne_twister_engine/min (T... args) T mt19937_64 cpp/numeric/random/mersenne_twister_engine/mersenne_twister_engine (T... args) T operator() cpp/numeric/random/mersenne_twister_engine/operator() (T... args) T seed cpp/numeric/random/mersenne_twister_engine/seed (T... args) std::multimap cpp/container/multimap T begin cpp/container/multimap/begin (T... args) T cbegin cpp/container/multimap/begin (T... args) T cend cpp/container/multimap/end (T... args) T clear cpp/container/multimap/clear (T... args) T count cpp/container/multimap/count (T... args) T crbegin cpp/container/multimap/rbegin (T... args) T crend cpp/container/multimap/rend (T... args) T emplace cpp/container/multimap/emplace (T... args) T emplace_hint cpp/container/multimap/emplace_hint (T... args) T empty cpp/container/multimap/empty (T... args) T end cpp/container/multimap/end (T... args) T equal_range cpp/container/multimap/equal_range (T... args) T erase cpp/container/multimap/erase (T... args) T extract cpp/container/multimap/extract (T... args) T find cpp/container/multimap/find (T... args) T get_allocator cpp/container/multimap/get_allocator (T... args) T insert cpp/container/multimap/insert (T... args) T key_comp cpp/container/multimap/key_comp (T... args) T lower_bound cpp/container/multimap/lower_bound (T... args) T max_size cpp/container/multimap/max_size (T... args) T merge cpp/container/multimap/merge (T... args) T multimap cpp/container/multimap/multimap (T... args) T operator= cpp/container/multimap/operator= (T... args) T rbegin cpp/container/multimap/rbegin (T... args) T rend cpp/container/multimap/rend (T... args) T size cpp/container/multimap/size (T... args) T swap cpp/container/multimap/swap (T... args) T upper_bound cpp/container/multimap/upper_bound (T... args) T value_comp cpp/container/multimap/value_comp (T... args) std::multimap::value_compare T ~multimap cpp/container/multimap/~multimap (T... args) std::multimap::value_compare cpp/container/multimap/value_compare std::multiplies cpp/utility/functional/multiplies T operator() cpp/utility/functional/multiplies (T... args) std::multiset cpp/container/multiset T begin cpp/container/multiset/begin (T... args) T cbegin cpp/container/multiset/begin (T... args) T cend cpp/container/multiset/end (T... args) T clear cpp/container/multiset/clear (T... args) T count cpp/container/multiset/count (T... args) T crbegin cpp/container/multiset/rbegin (T... args) T crend cpp/container/multiset/rend (T... args) T emplace cpp/container/multiset/emplace (T... args) T emplace_hint cpp/container/multiset/emplace_hint (T... args) T empty cpp/container/multiset/empty (T... args) T end cpp/container/multiset/end (T... args) T equal_range cpp/container/multiset/equal_range (T... args) T erase cpp/container/multiset/erase (T... args) T extract cpp/container/multiset/extract (T... args) T find cpp/container/multiset/find (T... args) T get_allocator cpp/container/multiset/get_allocator (T... args) T insert cpp/container/multiset/insert (T... args) T key_comp cpp/container/multiset/key_comp (T... args) T lower_bound cpp/container/multiset/lower_bound (T... args) T max_size cpp/container/multiset/max_size (T... args) T merge cpp/container/multiset/merge (T... args) T multiset cpp/container/multiset/multiset (T... args) T operator= cpp/container/multiset/operator= (T... args) T rbegin cpp/container/multiset/rbegin (T... args) T rend cpp/container/multiset/rend (T... args) T size cpp/container/multiset/size (T... args) T swap cpp/container/multiset/swap (T... args) T upper_bound cpp/container/multiset/upper_bound (T... args) T value_comp cpp/container/multiset/value_comp (T... args) T ~multiset cpp/container/multiset/~multiset (T... args) std::mutex cpp/thread/mutex T lock cpp/thread/mutex/lock (T... args) T mutex cpp/thread/mutex/mutex (T... args) T native_handle cpp/thread/mutex/native_handle (T... args) T try_lock cpp/thread/mutex/try_lock (T... args) T unlock cpp/thread/mutex/unlock (T... args) std::nano cpp/numeric/ratio/ratio std::negate cpp/utility/functional/negate T operator() cpp/utility/functional/negate (T... args) std::negation cpp/types/negation std::negative_binomial_distribution cpp/numeric/random/negative_binomial_distribution T k cpp/numeric/random/negative_binomial_distribution/params (T... args) T max cpp/numeric/random/negative_binomial_distribution/max (T... args) T min cpp/numeric/random/negative_binomial_distribution/min (T... args) T negative_binomial_distribution cpp/numeric/random/negative_binomial_distribution/negative_binomial_distribution (T... args) T p cpp/numeric/random/negative_binomial_distribution/params (T... args) T param cpp/numeric/random/negative_binomial_distribution/param (T... args) T reset cpp/numeric/random/negative_binomial_distribution/reset (T... args) std::nested_exception cpp/error/nested_exception T nested_exception cpp/error/nested_exception/nested_exception (T... args) T nested_ptr cpp/error/nested_exception/nested_ptr (T... args) T operator= cpp/error/nested_exception/operator= (T... args) T rethrow_nested cpp/error/nested_exception/rethrow_nested (T... args) T ~nested_exception cpp/error/nested_exception/~nested_exception (T... args) std::new_handler cpp/memory/new/new_handler std::normal_distribution cpp/numeric/random/normal_distribution T max cpp/numeric/random/normal_distribution/max (T... args) T mean cpp/numeric/random/normal_distribution/params (T... args) T min cpp/numeric/random/normal_distribution/min (T... args) T normal_distribution cpp/numeric/random/normal_distribution/normal_distribution (T... args) T operator() cpp/numeric/random/normal_distribution/operator() (T... args) T param cpp/numeric/random/normal_distribution/param (T... args) T reset cpp/numeric/random/normal_distribution/reset (T... args) T stddev cpp/numeric/random/normal_distribution/params (T... args) std::not_equal_to cpp/utility/functional/not_equal_to T operator() cpp/utility/functional/not_equal_to (T... args) std::nothrow_t cpp/memory/new/nothrow_t std::nullopt_t cpp/utility/optional/nullopt_t std::nullptr_t cpp/types/nullptr_t std::num_get cpp/locale/num_get std::num_get::char_type T do_get cpp/locale/num_get/get (T... args) T get cpp/locale/num_get/get (T... args) std::num_get::iter_type T num_get cpp/locale/num_get/num_get (T... args) T ~num_get cpp/locale/num_get/~num_get (T... args) std::num_get::char_type cpp/locale/num_get std::num_get::iter_type cpp/locale/num_get std::num_put cpp/locale/num_put std::num_put::char_type T do_put cpp/locale/num_put/put (T... args) std::num_put::iter_type T num_put cpp/locale/num_put/num_put (T... args) T put cpp/locale/num_put/put (T... args) T ~num_put cpp/locale/num_put/~num_put (T... args) std::num_put::char_type cpp/locale/num_put std::num_put::iter_type cpp/locale/num_put std::numeric_limits cpp/types/numeric_limits T denorm_min cpp/types/numeric_limits/denorm_min (T... args) T epsilon cpp/types/numeric_limits/epsilon (T... args) T infinity cpp/types/numeric_limits/infinity (T... args) T lowest cpp/types/numeric_limits/lowest (T... args) T max cpp/types/numeric_limits/max (T... args) T min cpp/types/numeric_limits/min (T... args) T quiet_NaN cpp/types/numeric_limits/quiet_NaN (T... args) T round_error cpp/types/numeric_limits/round_error (T... args) T signaling_NaN cpp/types/numeric_limits/signaling_NaN (T... args) std::numpunct cpp/locale/numpunct std::numpunct::char_type T decimal_point cpp/locale/numpunct/decimal_point (T... args) T do_decimal_point cpp/locale/numpunct/decimal_point (T... args) T do_falsename cpp/locale/numpunct/truefalsename (T... args) T do_grouping cpp/locale/numpunct/grouping (T... args) T do_thousands_sep cpp/locale/numpunct/thousands_sep (T... args) T do_truename cpp/locale/numpunct/truefalsename (T... args) T falsename cpp/locale/numpunct/truefalsename (T... args) T grouping cpp/locale/numpunct/grouping (T... args) T numpunct cpp/locale/numpunct/numpunct (T... args) std::numpunct::string_type T thousands_sep cpp/locale/numpunct/thousands_sep (T... args) T truename cpp/locale/numpunct/truefalsename (T... args) T ~numpunct cpp/locale/numpunct/~numpunct (T... args) std::numpunct::char_type cpp/locale/numpunct std::numpunct::string_type cpp/locale/numpunct std::numpunct_byname cpp/locale/numpunct_byname std::numpunct_byname::char_type T decimal_point cpp/locale/numpunct/decimal_point (T... args) T do_decimal_point cpp/locale/numpunct/decimal_point (T... args) T do_falsename cpp/locale/numpunct/truefalsename (T... args) T do_grouping cpp/locale/numpunct/grouping (T... args) T do_thousands_sep cpp/locale/numpunct/thousands_sep (T... args) T do_truename cpp/locale/numpunct/truefalsename (T... args) T falsename cpp/locale/numpunct/truefalsename (T... args) T grouping cpp/locale/numpunct/grouping (T... args) T numpunct_byname cpp/locale/numpunct_byname (T... args) std::numpunct_byname::string_type T thousands_sep cpp/locale/numpunct/thousands_sep (T... args) T truename cpp/locale/numpunct/truefalsename (T... args) T ~numpunct_byname cpp/locale/numpunct_byname (T... args) std::numpunct_byname::char_type cpp/locale/numpunct std::numpunct_byname::string_type cpp/locale/numpunct std::ofstream cpp/io/basic_ofstream std::ofstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T close cpp/io/basic_ofstream/close (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::ofstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::ofstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T is_open cpp/io/basic_ofstream/is_open (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T ofstream cpp/io/basic_ofstream/basic_ofstream (T... args) T open cpp/io/basic_ofstream/open (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator= cpp/io/basic_ofstream/operator= (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::ofstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::ofstream::Init cpp/io/ios_base/Init std::ofstream::event_callback cpp/io/ios_base/event_callback std::ofstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::ofstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_ostream/sentry (T... args) T sentry cpp/io/basic_ostream/sentry (T... args) T ~sentry cpp/io/basic_ostream/sentry (T... args) std::once_flag cpp/thread/once_flag T once_flag cpp/thread/once_flag (T... args) std::optional cpp/utility/optional T emplace cpp/utility/optional/emplace (T... args) T has_value cpp/utility/optional/operator_bool (T... args) T operator bool cpp/utility/optional/operator_bool (T... args) T operator* cpp/utility/optional/operator* (T... args) T operator-> cpp/utility/optional/operator* (T... args) T operator= cpp/utility/optional/operator= (T... args) T optional cpp/utility/optional/optional (T... args) T reset cpp/utility/optional/reset (T... args) T swap cpp/utility/optional/swap (T... args) T value cpp/utility/optional/value (T... args) T value_or cpp/utility/optional/value_or (T... args) T ~optional cpp/utility/optional/~optional (T... args) std::ostream cpp/io/basic_ostream std::ostream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::ostream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::ostream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T ostream cpp/io/basic_ostream/basic_ostream (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::ostream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~ostream cpp/io/basic_ostream/~basic_ostream (T... args) std::ostream::Init cpp/io/ios_base/Init std::ostream::event_callback cpp/io/ios_base/event_callback std::ostream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::ostream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_ostream/sentry (T... args) T sentry cpp/io/basic_ostream/sentry (T... args) T ~sentry cpp/io/basic_ostream/sentry (T... args) std::ostream_iterator cpp/iterator/ostream_iterator std::ostreambuf_iterator cpp/iterator/ostreambuf_iterator std::ostringstream cpp/io/basic_ostringstream std::ostringstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::ostringstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::ostringstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator= cpp/io/basic_ostringstream/operator= (T... args) T ostringstream cpp/io/basic_ostringstream/basic_ostringstream (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::ostringstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T str cpp/io/basic_ostringstream/str (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::ostringstream::Init cpp/io/ios_base/Init std::ostringstream::event_callback cpp/io/ios_base/event_callback std::ostringstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::ostringstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_ostream/sentry (T... args) T sentry cpp/io/basic_ostream/sentry (T... args) T ~sentry cpp/io/basic_ostream/sentry (T... args) std::ostrstream cpp/io/ostrstream std::ostrstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::ostrstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::ostrstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T freeze cpp/io/ostrstream/freeze (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T ostrstream cpp/io/ostrstream/ostrstream (T... args) T pcount cpp/io/ostrstream/pcount (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::ostrstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T str cpp/io/ostrstream/str (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~ostrstream cpp/io/ostrstream/~ostrstream (T... args) std::ostrstream::Init cpp/io/ios_base/Init std::ostrstream::event_callback cpp/io/ios_base/event_callback std::ostrstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::ostrstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_ostream/sentry (T... args) T sentry cpp/io/basic_ostream/sentry (T... args) T ~sentry cpp/io/basic_ostream/sentry (T... args) std::out_of_range cpp/error/out_of_range T out_of_range cpp/error/out_of_range (T... args) T what cpp/error/exception/what (T... args) std::output_iterator_tag cpp/iterator/iterator_tags std::overflow_error cpp/error/overflow_error T overflow_error cpp/error/overflow_error (T... args) T what cpp/error/exception/what (T... args) std::owner_less cpp/memory/owner_less T operator() cpp/memory/owner_less (T... args) std::packaged_task cpp/thread/packaged_task T get_future cpp/thread/packaged_task/get_future (T... args) T make_ready_at_thread_exit cpp/thread/packaged_task/make_ready_at_thread_exit (T... args) T operator() cpp/thread/packaged_task/operator() (T... args) T operator= cpp/thread/packaged_task/operator= (T... args) T packaged_task cpp/thread/packaged_task/packaged_task (T... args) T reset cpp/thread/packaged_task/reset (T... args) T swap cpp/thread/packaged_task/swap (T... args) T valid cpp/thread/packaged_task/valid (T... args) T ~packaged_task cpp/thread/packaged_task/~packaged_task (T... args) std::pair cpp/utility/pair T first cpp/utility/pair T operator= cpp/utility/pair/operator= (T... args) T pair cpp/utility/pair/pair (T... args) T second cpp/utility/pair T swap cpp/utility/pair/swap (T... args) std::peta cpp/numeric/ratio/ratio std::pico cpp/numeric/ratio/ratio std::piecewise_constant_distribution cpp/numeric/random/piecewise_constant_distribution T densities cpp/numeric/random/piecewise_constant_distribution/params (T... args) T intervals cpp/numeric/random/piecewise_constant_distribution/params (T... args) T max cpp/numeric/random/piecewise_constant_distribution/max (T... args) T min cpp/numeric/random/piecewise_constant_distribution/min (T... args) T operator() cpp/numeric/random/piecewise_constant_distribution/operator() (T... args) T param cpp/numeric/random/piecewise_constant_distribution/param (T... args) T piecewise_constant_distribution cpp/numeric/random/piecewise_constant_distribution/piecewise_constant_distribution (T... args) T reset cpp/numeric/random/piecewise_constant_distribution/reset (T... args) std::piecewise_construct_t cpp/utility/piecewise_construct_t std::piecewise_linear_distribution cpp/numeric/random/piecewise_linear_distribution T densities cpp/numeric/random/piecewise_linear_distribution/params (T... args) T intervals cpp/numeric/random/piecewise_linear_distribution/params (T... args) T max cpp/numeric/random/piecewise_linear_distribution/max (T... args) T min cpp/numeric/random/piecewise_linear_distribution/min (T... args) T operator() cpp/numeric/random/piecewise_linear_distribution/operator() (T... args) T param cpp/numeric/random/piecewise_linear_distribution/param (T... args) T piecewise_linear_distribution cpp/numeric/random/piecewise_linear_distribution/piecewise_linear_distribution (T... args) T reset cpp/numeric/random/piecewise_linear_distribution/reset (T... args) std::placeholders cpp/utility/functional/placeholders std::plus cpp/utility/functional/plus T operator() cpp/utility/functional/plus (T... args) std::pmr std::pmr::deque std::pmr::forward_list T get_default_resource cpp/memory/get_default_resource (T... args) std::pmr::list std::pmr::map std::pmr::memory_resource std::pmr::monotonic_buffer_resource std::pmr::multimap std::pmr::multiset T new_delete_resource cpp/memory/new_delete_resource (T... args) T null_memory_resource cpp/memory/null_memory_resource (T... args) std::pmr::polymorphic_allocator std::pmr::pool_options std::pmr::set T set_default_resource cpp/memory/set_default_resource (T... args) std::pmr::string std::pmr::synchronized_pool_resource std::pmr::u16string std::pmr::u32string std::pmr::unordered_map std::pmr::unordered_multimap std::pmr::unordered_multiset std::pmr::unordered_set std::pmr::unsynchronized_pool_resource std::pmr::vector std::pmr::wstring std::pmr::deque cpp/container/deque T assign cpp/container/deque/assign (T... args) T at cpp/container/deque/at (T... args) T back cpp/container/deque/back (T... args) T begin cpp/container/deque/begin (T... args) T cbegin cpp/container/deque/begin (T... args) T cend cpp/container/deque/end (T... args) T clear cpp/container/deque/clear (T... args) T crbegin cpp/container/deque/rbegin (T... args) T crend cpp/container/deque/rend (T... args) T deque cpp/container/deque/deque (T... args) T emplace cpp/container/deque/emplace (T... args) T emplace_back cpp/container/deque/emplace_back (T... args) T emplace_front cpp/container/deque/emplace_front (T... args) T empty cpp/container/deque/empty (T... args) T end cpp/container/deque/end (T... args) T erase cpp/container/deque/erase (T... args) T front cpp/container/deque/front (T... args) T get_allocator cpp/container/deque/get_allocator (T... args) T insert cpp/container/deque/insert (T... args) T max_size cpp/container/deque/max_size (T... args) T operator= cpp/container/deque/operator= (T... args) T operator[] cpp/container/deque/operator_at (T... args) T pop_back cpp/container/deque/pop_back (T... args) T pop_front cpp/container/deque/pop_front (T... args) T push_back cpp/container/deque/push_back (T... args) T push_front cpp/container/deque/push_front (T... args) T rbegin cpp/container/deque/rbegin (T... args) T rend cpp/container/deque/rend (T... args) T resize cpp/container/deque/resize (T... args) T shrink_to_fit cpp/container/deque/shrink_to_fit (T... args) T size cpp/container/deque/size (T... args) T swap cpp/container/deque/swap (T... args) T ~deque cpp/container/deque/~deque (T... args) std::pmr::forward_list cpp/container/forward_list T assign cpp/container/forward_list/assign (T... args) T before_begin cpp/container/forward_list/before_begin (T... args) T begin cpp/container/forward_list/begin (T... args) T cbefore_begin cpp/container/forward_list/before_begin (T... args) T cbegin cpp/container/forward_list/begin (T... args) T cend cpp/container/forward_list/end (T... args) T clear cpp/container/forward_list/clear (T... args) T emplace_after cpp/container/forward_list/emplace_after (T... args) T emplace_front cpp/container/forward_list/emplace_front (T... args) T empty cpp/container/forward_list/empty (T... args) T end cpp/container/forward_list/end (T... args) T erase_after cpp/container/forward_list/erase_after (T... args) T forward_list cpp/container/forward_list/forward_list (T... args) T front cpp/container/forward_list/front (T... args) T get_allocator cpp/container/forward_list/get_allocator (T... args) T insert_after cpp/container/forward_list/insert_after (T... args) T max_size cpp/container/forward_list/max_size (T... args) T merge cpp/container/forward_list/merge (T... args) T operator= cpp/container/forward_list/operator= (T... args) T pop_front cpp/container/forward_list/pop_front (T... args) T push_front cpp/container/forward_list/push_front (T... args) T remove cpp/container/forward_list/remove (T... args) T remove_if cpp/container/forward_list/remove (T... args) T resize cpp/container/forward_list/resize (T... args) T reverse cpp/container/forward_list/reverse (T... args) T sort cpp/container/forward_list/sort (T... args) T splice_after cpp/container/forward_list/splice_after (T... args) T swap cpp/container/forward_list/swap (T... args) T unique cpp/container/forward_list/unique (T... args) T ~forward_list cpp/container/forward_list/~forward_list (T... args) std::pmr::list cpp/container/list T assign cpp/container/list/assign (T... args) T back cpp/container/list/back (T... args) T begin cpp/container/list/begin (T... args) T cbegin cpp/container/list/begin (T... args) T cend cpp/container/list/end (T... args) T clear cpp/container/list/clear (T... args) T crbegin cpp/container/list/rbegin (T... args) T crend cpp/container/list/rend (T... args) T emplace cpp/container/list/emplace (T... args) T emplace_back cpp/container/list/emplace_back (T... args) T emplace_front cpp/container/list/emplace_front (T... args) T empty cpp/container/list/empty (T... args) T end cpp/container/list/end (T... args) T erase cpp/container/list/erase (T... args) T front cpp/container/list/front (T... args) T get_allocator cpp/container/list/get_allocator (T... args) T insert cpp/container/list/insert (T... args) T list cpp/container/list/list (T... args) T max_size cpp/container/list/max_size (T... args) T merge cpp/container/list/merge (T... args) T operator= cpp/container/list/operator= (T... args) T pop_back cpp/container/list/pop_back (T... args) T pop_front cpp/container/list/pop_front (T... args) T push_back cpp/container/list/push_back (T... args) T push_front cpp/container/list/push_front (T... args) T rbegin cpp/container/list/rbegin (T... args) T remove cpp/container/list/remove (T... args) T remove_if cpp/container/list/remove (T... args) T rend cpp/container/list/rend (T... args) T resize cpp/container/list/resize (T... args) T reverse cpp/container/list/reverse (T... args) T size cpp/container/list/size (T... args) T sort cpp/container/list/sort (T... args) T splice cpp/container/list/splice (T... args) T swap cpp/container/list/swap (T... args) T unique cpp/container/list/unique (T... args) T ~list cpp/container/list/~list (T... args) std::pmr::map cpp/container/map T at cpp/container/map/at (T... args) T begin cpp/container/map/begin (T... args) T cbegin cpp/container/map/begin (T... args) T cend cpp/container/map/end (T... args) T clear cpp/container/map/clear (T... args) T count cpp/container/map/count (T... args) T crbegin cpp/container/map/rbegin (T... args) T crend cpp/container/map/rend (T... args) T emplace cpp/container/map/emplace (T... args) T emplace_hint cpp/container/map/emplace_hint (T... args) T empty cpp/container/map/empty (T... args) T end cpp/container/map/end (T... args) T equal_range cpp/container/map/equal_range (T... args) T erase cpp/container/map/erase (T... args) T extract cpp/container/map/extract (T... args) T find cpp/container/map/find (T... args) T get_allocator cpp/container/map/get_allocator (T... args) T insert cpp/container/map/insert (T... args) T insert_or_assign cpp/container/map/insert_or_assign (T... args) T key_comp cpp/container/map/key_comp (T... args) T lower_bound cpp/container/map/lower_bound (T... args) T map cpp/container/map/map (T... args) T max_size cpp/container/map/max_size (T... args) T merge cpp/container/map/merge (T... args) T operator= cpp/container/map/operator= (T... args) T operator[] cpp/container/map/operator_at (T... args) T rbegin cpp/container/map/rbegin (T... args) T rend cpp/container/map/rend (T... args) T size cpp/container/map/size (T... args) T swap cpp/container/map/swap (T... args) T try_emplace cpp/container/map/try_emplace (T... args) T upper_bound cpp/container/map/upper_bound (T... args) T value_comp cpp/container/map/value_comp (T... args) std::pmr::map::value_compare T ~map cpp/container/map/~map (T... args) std::pmr::map::value_compare cpp/container/map/value_compare std::pmr::memory_resource cpp/memory/memory_resource T allocate cpp/memory/memory_resource/allocate (T... args) T deallocate cpp/memory/memory_resource/deallocate (T... args) T do_allocate cpp/memory/memory_resource/do_allocate (T... args) T do_deallocate cpp/memory/memory_resource/do_deallocate (T... args) T do_is_equal cpp/memory/memory_resource/do_is_equal (T... args) T is_equal cpp/memory/memory_resource/is_equal (T... args) T memory_resource cpp/memory/memory_resource/memory_resource (T... args) std::pmr::monotonic_buffer_resource cpp/memory/monotonic_buffer_resource T allocate cpp/memory/memory_resource/allocate (T... args) T deallocate cpp/memory/memory_resource/deallocate (T... args) T do_allocate cpp/memory/memory_resource/do_allocate (T... args) T do_deallocate cpp/memory/memory_resource/do_deallocate (T... args) T do_is_equal cpp/memory/memory_resource/do_is_equal (T... args) T is_equal cpp/memory/memory_resource/is_equal (T... args) T monotonic_buffer_resource cpp/memory/monotonic_buffer_resource/monotonic_buffer_resource (T... args) T release cpp/memory/monotonic_buffer_resource/release (T... args) T upstream_resource cpp/memory/monotonic_buffer_resource/upstream_resource (T... args) T ~monotonic_buffer_resource cpp/memory/monotonic_buffer_resource (T... args) std::pmr::multimap cpp/container/multimap T begin cpp/container/multimap/begin (T... args) T cbegin cpp/container/multimap/begin (T... args) T cend cpp/container/multimap/end (T... args) T clear cpp/container/multimap/clear (T... args) T count cpp/container/multimap/count (T... args) T crbegin cpp/container/multimap/rbegin (T... args) T crend cpp/container/multimap/rend (T... args) T emplace cpp/container/multimap/emplace (T... args) T emplace_hint cpp/container/multimap/emplace_hint (T... args) T empty cpp/container/multimap/empty (T... args) T end cpp/container/multimap/end (T... args) T equal_range cpp/container/multimap/equal_range (T... args) T erase cpp/container/multimap/erase (T... args) T extract cpp/container/multimap/extract (T... args) T find cpp/container/multimap/find (T... args) T get_allocator cpp/container/multimap/get_allocator (T... args) T insert cpp/container/multimap/insert (T... args) T key_comp cpp/container/multimap/key_comp (T... args) T lower_bound cpp/container/multimap/lower_bound (T... args) T max_size cpp/container/multimap/max_size (T... args) T merge cpp/container/multimap/merge (T... args) T multimap cpp/container/multimap/multimap (T... args) T operator= cpp/container/multimap/operator= (T... args) T rbegin cpp/container/multimap/rbegin (T... args) T rend cpp/container/multimap/rend (T... args) T size cpp/container/multimap/size (T... args) T swap cpp/container/multimap/swap (T... args) T upper_bound cpp/container/multimap/upper_bound (T... args) T value_comp cpp/container/multimap/value_comp (T... args) std::pmr::multimap::value_compare T ~multimap cpp/container/multimap/~multimap (T... args) std::pmr::multimap::value_compare cpp/container/multimap/value_compare std::pmr::multiset cpp/container/multiset T begin cpp/container/multiset/begin (T... args) T cbegin cpp/container/multiset/begin (T... args) T cend cpp/container/multiset/end (T... args) T clear cpp/container/multiset/clear (T... args) T count cpp/container/multiset/count (T... args) T crbegin cpp/container/multiset/rbegin (T... args) T crend cpp/container/multiset/rend (T... args) T emplace cpp/container/multiset/emplace (T... args) T emplace_hint cpp/container/multiset/emplace_hint (T... args) T empty cpp/container/multiset/empty (T... args) T end cpp/container/multiset/end (T... args) T equal_range cpp/container/multiset/equal_range (T... args) T erase cpp/container/multiset/erase (T... args) T extract cpp/container/multiset/extract (T... args) T find cpp/container/multiset/find (T... args) T get_allocator cpp/container/multiset/get_allocator (T... args) T insert cpp/container/multiset/insert (T... args) T key_comp cpp/container/multiset/key_comp (T... args) T lower_bound cpp/container/multiset/lower_bound (T... args) T max_size cpp/container/multiset/max_size (T... args) T merge cpp/container/multiset/merge (T... args) T multiset cpp/container/multiset/multiset (T... args) T operator= cpp/container/multiset/operator= (T... args) T rbegin cpp/container/multiset/rbegin (T... args) T rend cpp/container/multiset/rend (T... args) T size cpp/container/multiset/size (T... args) T swap cpp/container/multiset/swap (T... args) T upper_bound cpp/container/multiset/upper_bound (T... args) T value_comp cpp/container/multiset/value_comp (T... args) T ~multiset cpp/container/multiset/~multiset (T... args) std::pmr::polymorphic_allocator cpp/memory/polymorphic_allocator T allocate cpp/memory/polymorphic_allocator/allocate (T... args) T construct cpp/memory/polymorphic_allocator/construct (T... args) T deallocate cpp/memory/polymorphic_allocator/deallocate (T... args) T destroy cpp/memory/polymorphic_allocator/destroy (T... args) T polymorphic_allocator cpp/memory/polymorphic_allocator/polymorphic_allocator (T... args) T resource cpp/memory/polymorphic_allocator/resource (T... args) T select_on_container_copy_contruction cpp/memory/polymorphic_allocator/select_on_container_copy_contruction (T... args) T ~polymorphic_allocator cpp/memory/polymorphic_allocator (T... args) std::pmr::pool_options cpp/memory/pool_options T largest_required_pool_block cpp/memory/pool_options T max_blocks_per_chunk cpp/memory/pool_options std::pmr::set cpp/container/set T begin cpp/container/set/begin (T... args) T cbegin cpp/container/set/begin (T... args) T cend cpp/container/set/end (T... args) T clear cpp/container/set/clear (T... args) T count cpp/container/set/count (T... args) T crbegin cpp/container/set/rbegin (T... args) T crend cpp/container/set/rend (T... args) T emplace cpp/container/set/emplace (T... args) T emplace_hint cpp/container/set/emplace_hint (T... args) T empty cpp/container/set/empty (T... args) T end cpp/container/set/end (T... args) T equal_range cpp/container/set/equal_range (T... args) T erase cpp/container/set/erase (T... args) T extract cpp/container/set/extract (T... args) T find cpp/container/set/find (T... args) T get_allocator cpp/container/set/get_allocator (T... args) T insert cpp/container/set/insert (T... args) T key_comp cpp/container/set/key_comp (T... args) T lower_bound cpp/container/set/lower_bound (T... args) T max_size cpp/container/set/max_size (T... args) T merge cpp/container/set/merge (T... args) T operator= cpp/container/set/operator= (T... args) T rbegin cpp/container/set/rbegin (T... args) T rend cpp/container/set/rend (T... args) T set cpp/container/set/set (T... args) T size cpp/container/set/size (T... args) T swap cpp/container/set/swap (T... args) T upper_bound cpp/container/set/upper_bound (T... args) T value_comp cpp/container/set/value_comp (T... args) T ~set cpp/container/set/~set (T... args) std::pmr::string cpp/string/basic_string T append cpp/string/basic_string/append (T... args) T assign cpp/string/basic_string/assign (T... args) T at cpp/string/basic_string/at (T... args) T back cpp/string/basic_string/back (T... args) T begin cpp/string/basic_string/begin (T... args) T c_str cpp/string/basic_string/c_str (T... args) T capacity cpp/string/basic_string/capacity (T... args) T cbegin cpp/string/basic_string/begin (T... args) T cend cpp/string/basic_string/end (T... args) T clear cpp/string/basic_string/clear (T... args) T compare cpp/string/basic_string/compare (T... args) T copy cpp/string/basic_string/copy (T... args) T crbegin cpp/string/basic_string/rbegin (T... args) T crend cpp/string/basic_string/rend (T... args) T data cpp/string/basic_string/data (T... args) T empty cpp/string/basic_string/empty (T... args) T end cpp/string/basic_string/end (T... args) T erase cpp/string/basic_string/erase (T... args) T find cpp/string/basic_string/find (T... args) T find_first_not_of cpp/string/basic_string/find_first_not_of (T... args) T find_first_of cpp/string/basic_string/find_first_of (T... args) T find_last_not_of cpp/string/basic_string/find_last_not_of (T... args) T find_last_of cpp/string/basic_string/find_last_of (T... args) T front cpp/string/basic_string/front (T... args) T get_allocator cpp/string/basic_string/get_allocator (T... args) T insert cpp/string/basic_string/insert (T... args) T length cpp/string/basic_string/size (T... args) T max_size cpp/string/basic_string/max_size (T... args) T operator= cpp/string/basic_string/operator= (T... args) T operator[] cpp/string/basic_string/operator_at (T... args) T pop_back cpp/string/basic_string/pop_back (T... args) T push_back cpp/string/basic_string/push_back (T... args) T rbegin cpp/string/basic_string/rbegin (T... args) T rend cpp/string/basic_string/rend (T... args) T replace cpp/string/basic_string/replace (T... args) T reserve cpp/string/basic_string/reserve (T... args) T resize cpp/string/basic_string/resize (T... args) T rfind cpp/string/basic_string/rfind (T... args) T shrink_to_fit cpp/string/basic_string/shrink_to_fit (T... args) T size cpp/string/basic_string/size (T... args) T string cpp/string/basic_string/basic_string (T... args) T substr cpp/string/basic_string/substr (T... args) T swap cpp/string/basic_string/swap (T... args) std::pmr::synchronized_pool_resource cpp/memory/synchronized_pool_resource T allocate cpp/memory/memory_resource/allocate (T... args) T deallocate cpp/memory/memory_resource/deallocate (T... args) T do_allocate cpp/memory/memory_resource/do_allocate (T... args) T do_deallocate cpp/memory/memory_resource/do_deallocate (T... args) T do_is_equal cpp/memory/memory_resource/do_is_equal (T... args) T is_equal cpp/memory/memory_resource/is_equal (T... args) T options cpp/memory/synchronized_pool_resource/options (T... args) T release cpp/memory/synchronized_pool_resource/release (T... args) T synchronized_pool_resource cpp/memory/synchronized_pool_resource/synchronized_pool_resource (T... args) T upstream_resource cpp/memory/synchronized_pool_resource/upstream_resource (T... args) T ~synchronized_pool_resource cpp/memory/synchronized_pool_resource (T... args) std::pmr::u16string cpp/string/basic_string T append cpp/string/basic_string/append (T... args) T assign cpp/string/basic_string/assign (T... args) T at cpp/string/basic_string/at (T... args) T back cpp/string/basic_string/back (T... args) T begin cpp/string/basic_string/begin (T... args) T c_str cpp/string/basic_string/c_str (T... args) T capacity cpp/string/basic_string/capacity (T... args) T cbegin cpp/string/basic_string/begin (T... args) T cend cpp/string/basic_string/end (T... args) T clear cpp/string/basic_string/clear (T... args) T compare cpp/string/basic_string/compare (T... args) T copy cpp/string/basic_string/copy (T... args) T crbegin cpp/string/basic_string/rbegin (T... args) T crend cpp/string/basic_string/rend (T... args) T data cpp/string/basic_string/data (T... args) T empty cpp/string/basic_string/empty (T... args) T end cpp/string/basic_string/end (T... args) T erase cpp/string/basic_string/erase (T... args) T find cpp/string/basic_string/find (T... args) T find_first_not_of cpp/string/basic_string/find_first_not_of (T... args) T find_first_of cpp/string/basic_string/find_first_of (T... args) T find_last_not_of cpp/string/basic_string/find_last_not_of (T... args) T find_last_of cpp/string/basic_string/find_last_of (T... args) T front cpp/string/basic_string/front (T... args) T get_allocator cpp/string/basic_string/get_allocator (T... args) T insert cpp/string/basic_string/insert (T... args) T length cpp/string/basic_string/size (T... args) T max_size cpp/string/basic_string/max_size (T... args) T operator= cpp/string/basic_string/operator= (T... args) T operator[] cpp/string/basic_string/operator_at (T... args) T pop_back cpp/string/basic_string/pop_back (T... args) T push_back cpp/string/basic_string/push_back (T... args) T rbegin cpp/string/basic_string/rbegin (T... args) T rend cpp/string/basic_string/rend (T... args) T replace cpp/string/basic_string/replace (T... args) T reserve cpp/string/basic_string/reserve (T... args) T resize cpp/string/basic_string/resize (T... args) T rfind cpp/string/basic_string/rfind (T... args) T shrink_to_fit cpp/string/basic_string/shrink_to_fit (T... args) T size cpp/string/basic_string/size (T... args) T substr cpp/string/basic_string/substr (T... args) T swap cpp/string/basic_string/swap (T... args) T u16string cpp/string/basic_string/basic_string (T... args) std::pmr::u32string cpp/string/basic_string T append cpp/string/basic_string/append (T... args) T assign cpp/string/basic_string/assign (T... args) T at cpp/string/basic_string/at (T... args) T back cpp/string/basic_string/back (T... args) T begin cpp/string/basic_string/begin (T... args) T c_str cpp/string/basic_string/c_str (T... args) T capacity cpp/string/basic_string/capacity (T... args) T cbegin cpp/string/basic_string/begin (T... args) T cend cpp/string/basic_string/end (T... args) T clear cpp/string/basic_string/clear (T... args) T compare cpp/string/basic_string/compare (T... args) T copy cpp/string/basic_string/copy (T... args) T crbegin cpp/string/basic_string/rbegin (T... args) T crend cpp/string/basic_string/rend (T... args) T data cpp/string/basic_string/data (T... args) T empty cpp/string/basic_string/empty (T... args) T end cpp/string/basic_string/end (T... args) T erase cpp/string/basic_string/erase (T... args) T find cpp/string/basic_string/find (T... args) T find_first_not_of cpp/string/basic_string/find_first_not_of (T... args) T find_first_of cpp/string/basic_string/find_first_of (T... args) T find_last_not_of cpp/string/basic_string/find_last_not_of (T... args) T find_last_of cpp/string/basic_string/find_last_of (T... args) T front cpp/string/basic_string/front (T... args) T get_allocator cpp/string/basic_string/get_allocator (T... args) T insert cpp/string/basic_string/insert (T... args) T length cpp/string/basic_string/size (T... args) T max_size cpp/string/basic_string/max_size (T... args) T operator= cpp/string/basic_string/operator= (T... args) T operator[] cpp/string/basic_string/operator_at (T... args) T pop_back cpp/string/basic_string/pop_back (T... args) T push_back cpp/string/basic_string/push_back (T... args) T rbegin cpp/string/basic_string/rbegin (T... args) T rend cpp/string/basic_string/rend (T... args) T replace cpp/string/basic_string/replace (T... args) T reserve cpp/string/basic_string/reserve (T... args) T resize cpp/string/basic_string/resize (T... args) T rfind cpp/string/basic_string/rfind (T... args) T shrink_to_fit cpp/string/basic_string/shrink_to_fit (T... args) T size cpp/string/basic_string/size (T... args) T substr cpp/string/basic_string/substr (T... args) T swap cpp/string/basic_string/swap (T... args) T u32string cpp/string/basic_string/basic_string (T... args) std::pmr::unordered_map cpp/container/unordered_map T at cpp/container/unordered_map/at (T... args) T begin cpp/container/unordered_map/begin (T... args) T begin(int) cpp/container/unordered_map/begin2 (T... args) T bucket cpp/container/unordered_map/bucket (T... args) T bucket_count cpp/container/unordered_map/bucket_count (T... args) T bucket_size cpp/container/unordered_map/bucket_size (T... args) T cbegin cpp/container/unordered_map/begin (T... args) T cbegin(int) cpp/container/unordered_map/begin2 (T... args) T cend cpp/container/unordered_map/end (T... args) T cend(int) cpp/container/unordered_map/end2 (T... args) T clear cpp/container/unordered_map/clear (T... args) T count cpp/container/unordered_map/count (T... args) T emplace cpp/container/unordered_map/emplace (T... args) T emplace_hint cpp/container/unordered_map/emplace_hint (T... args) T empty cpp/container/unordered_map/empty (T... args) T end cpp/container/unordered_map/end (T... args) T end(int) cpp/container/unordered_map/end2 (T... args) T equal_range cpp/container/unordered_map/equal_range (T... args) T erase cpp/container/unordered_map/erase (T... args) T extract cpp/container/unordered_map/extract (T... args) T find cpp/container/unordered_map/find (T... args) T get_allocator cpp/container/unordered_map/get_allocator (T... args) T hash_function cpp/container/unordered_map/hash_function (T... args) T insert cpp/container/unordered_map/insert (T... args) T insert_or_assign cpp/container/unordered_map/insert_or_assign (T... args) T key_eq cpp/container/unordered_map/key_eq (T... args) T load_factor cpp/container/unordered_map/load_factor (T... args) T max_bucket_count cpp/container/unordered_map/max_bucket_count (T... args) T max_load_factor cpp/container/unordered_map/max_load_factor (T... args) T max_size cpp/container/unordered_map/max_size (T... args) T merge cpp/container/unordered_map/merge (T... args) T operator= cpp/container/unordered_map/operator= (T... args) T operator[] cpp/container/unordered_map/operator_at (T... args) T rehash cpp/container/unordered_map/rehash (T... args) T reserve cpp/container/unordered_map/reserve (T... args) T size cpp/container/unordered_map/size (T... args) T swap cpp/container/unordered_map/swap (T... args) T try_emplace cpp/container/unordered_map/try_emplace (T... args) T unordered_map cpp/container/unordered_map/unordered_map (T... args) T ~unordered_map cpp/container/unordered_map/~unordered_map (T... args) std::pmr::unordered_multimap cpp/container/unordered_multimap T begin cpp/container/unordered_multimap/begin (T... args) T begin(int) cpp/container/unordered_multimap/begin2 (T... args) T bucket cpp/container/unordered_multimap/bucket (T... args) T bucket_count cpp/container/unordered_multimap/bucket_count (T... args) T bucket_size cpp/container/unordered_multimap/bucket_size (T... args) T cbegin cpp/container/unordered_multimap/begin (T... args) T cbegin(int) cpp/container/unordered_multimap/begin2 (T... args) T cend cpp/container/unordered_multimap/end (T... args) T cend(int) cpp/container/unordered_multimap/end2 (T... args) T clear cpp/container/unordered_multimap/clear (T... args) T count cpp/container/unordered_multimap/count (T... args) T emplace cpp/container/unordered_multimap/emplace (T... args) T emplace_hint cpp/container/unordered_multimap/emplace_hint (T... args) T empty cpp/container/unordered_multimap/empty (T... args) T end cpp/container/unordered_multimap/end (T... args) T end(int) cpp/container/unordered_multimap/end2 (T... args) T equal_range cpp/container/unordered_multimap/equal_range (T... args) T erase cpp/container/unordered_multimap/erase (T... args) T extract cpp/container/unordered_multimap/extract (T... args) T find cpp/container/unordered_multimap/find (T... args) T get_allocator cpp/container/unordered_multimap/get_allocator (T... args) T hash_function cpp/container/unordered_multimap/hash_function (T... args) T insert cpp/container/unordered_multimap/insert (T... args) T key_eq cpp/container/unordered_multimap/key_eq (T... args) T load_factor cpp/container/unordered_multimap/load_factor (T... args) T max_bucket_count cpp/container/unordered_multimap/max_bucket_count (T... args) T max_load_factor cpp/container/unordered_multimap/max_load_factor (T... args) T max_size cpp/container/unordered_multimap/max_size (T... args) T merge cpp/container/unordered_multimap/merge (T... args) T operator= cpp/container/unordered_multimap/operator= (T... args) T rehash cpp/container/unordered_multimap/rehash (T... args) T reserve cpp/container/unordered_multimap/reserve (T... args) T size cpp/container/unordered_multimap/size (T... args) T swap cpp/container/unordered_multimap/swap (T... args) T unordered_multimap cpp/container/unordered_multimap/unordered_multimap (T... args) T ~unordered_multimap cpp/container/unordered_multimap/~unordered_multimap (T... args) std::pmr::unordered_multiset cpp/container/unordered_multiset T begin cpp/container/unordered_multiset/begin (T... args) T begin(int) cpp/container/unordered_multiset/begin2 (T... args) T bucket cpp/container/unordered_multiset/bucket (T... args) T bucket_count cpp/container/unordered_multiset/bucket_count (T... args) T bucket_size cpp/container/unordered_multiset/bucket_size (T... args) T cbegin cpp/container/unordered_multiset/begin (T... args) T cbegin(int) cpp/container/unordered_multiset/begin2 (T... args) T cend cpp/container/unordered_multiset/end (T... args) T cend(int) cpp/container/unordered_multiset/end2 (T... args) T clear cpp/container/unordered_multiset/clear (T... args) T count cpp/container/unordered_multiset/count (T... args) T emplace cpp/container/unordered_multiset/emplace (T... args) T emplace_hint cpp/container/unordered_multiset/emplace_hint (T... args) T empty cpp/container/unordered_multiset/empty (T... args) T end cpp/container/unordered_multiset/end (T... args) T end(int) cpp/container/unordered_multiset/end2 (T... args) T equal_range cpp/container/unordered_multiset/equal_range (T... args) T erase cpp/container/unordered_multiset/erase (T... args) T extract cpp/container/unordered_multiset/extract (T... args) T find cpp/container/unordered_multiset/find (T... args) T get_allocator cpp/container/unordered_multiset/get_allocator (T... args) T hash_function cpp/container/unordered_multiset/hash_function (T... args) T insert cpp/container/unordered_multiset/insert (T... args) T key_eq cpp/container/unordered_multiset/key_eq (T... args) T load_factor cpp/container/unordered_multiset/load_factor (T... args) T max_bucket_count cpp/container/unordered_multiset/max_bucket_count (T... args) T max_load_factor cpp/container/unordered_multiset/max_load_factor (T... args) T max_size cpp/container/unordered_multiset/max_size (T... args) T merge cpp/container/unordered_multiset/merge (T... args) T operator= cpp/container/unordered_multiset/operator= (T... args) T rehash cpp/container/unordered_multiset/rehash (T... args) T reserve cpp/container/unordered_multiset/reserve (T... args) T size cpp/container/unordered_multiset/size (T... args) T swap cpp/container/unordered_multiset/swap (T... args) T unordered_multiset cpp/container/unordered_multiset/unordered_multiset (T... args) T ~unordered_multiset cpp/container/unordered_multiset/~unordered_multiset (T... args) std::pmr::unordered_set cpp/container/unordered_set T begin cpp/container/unordered_set/begin (T... args) T begin(int) cpp/container/unordered_set/begin2 (T... args) T bucket cpp/container/unordered_set/bucket (T... args) T bucket_count cpp/container/unordered_set/bucket_count (T... args) T bucket_size cpp/container/unordered_set/bucket_size (T... args) T cbegin cpp/container/unordered_set/begin (T... args) T cbegin(int) cpp/container/unordered_set/begin2 (T... args) T cend cpp/container/unordered_set/end (T... args) T cend(int) cpp/container/unordered_set/end2 (T... args) T clear cpp/container/unordered_set/clear (T... args) T count cpp/container/unordered_set/count (T... args) T emplace cpp/container/unordered_set/emplace (T... args) T emplace_hint cpp/container/unordered_set/emplace_hint (T... args) T empty cpp/container/unordered_set/empty (T... args) T end cpp/container/unordered_set/end (T... args) T end(int) cpp/container/unordered_set/end2 (T... args) T equal_range cpp/container/unordered_set/equal_range (T... args) T erase cpp/container/unordered_set/erase (T... args) T extract cpp/container/unordered_set/extract (T... args) T find cpp/container/unordered_set/find (T... args) T get_allocator cpp/container/unordered_set/get_allocator (T... args) T hash_function cpp/container/unordered_set/hash_function (T... args) T insert cpp/container/unordered_set/insert (T... args) T key_eq cpp/container/unordered_set/key_eq (T... args) T load_factor cpp/container/unordered_set/load_factor (T... args) T max_bucket_count cpp/container/unordered_set/max_bucket_count (T... args) T max_load_factor cpp/container/unordered_set/max_load_factor (T... args) T max_size cpp/container/unordered_set/max_size (T... args) T merge cpp/container/unordered_set/merge (T... args) T operator= cpp/container/unordered_set/operator= (T... args) T rehash cpp/container/unordered_set/rehash (T... args) T reserve cpp/container/unordered_set/reserve (T... args) T size cpp/container/unordered_set/size (T... args) T swap cpp/container/unordered_set/swap (T... args) T unordered_set cpp/container/unordered_set/unordered_set (T... args) T ~unordered_set cpp/container/unordered_set/~unordered_set (T... args) std::pmr::unsynchronized_pool_resource cpp/memory/unsynchronized_pool_resource T allocate cpp/memory/memory_resource/allocate (T... args) T deallocate cpp/memory/memory_resource/deallocate (T... args) T do_allocate cpp/memory/memory_resource/do_allocate (T... args) T do_deallocate cpp/memory/memory_resource/do_deallocate (T... args) T do_is_equal cpp/memory/memory_resource/do_is_equal (T... args) T is_equal cpp/memory/memory_resource/is_equal (T... args) T options cpp/memory/unsynchronized_pool_resource/options (T... args) T release cpp/memory/unsynchronized_pool_resource/release (T... args) T unsynchronized_pool_resource cpp/memory/unsynchronized_pool_resource/unsynchronized_pool_resource (T... args) T upstream_resource cpp/memory/unsynchronized_pool_resource/upstream_resource (T... args) T ~unsynchronized_pool_resource cpp/memory/unsynchronized_pool_resource (T... args) std::pmr::vector cpp/container/vector T assign cpp/container/vector/assign (T... args) T at cpp/container/vector/at (T... args) T back cpp/container/vector/back (T... args) T begin cpp/container/vector/begin (T... args) T capacity cpp/container/vector/capacity (T... args) T cbegin cpp/container/vector/begin (T... args) T cend cpp/container/vector/end (T... args) T clear cpp/container/vector/clear (T... args) T crbegin cpp/container/vector/rbegin (T... args) T crend cpp/container/vector/rend (T... args) T data cpp/container/vector/data (T... args) T emplace cpp/container/vector/emplace (T... args) T emplace_back cpp/container/vector/emplace_back (T... args) T empty cpp/container/vector/empty (T... args) T end cpp/container/vector/end (T... args) T erase cpp/container/vector/erase (T... args) T front cpp/container/vector/front (T... args) T get_allocator cpp/container/vector/get_allocator (T... args) T insert cpp/container/vector/insert (T... args) T max_size cpp/container/vector/max_size (T... args) T operator= cpp/container/vector/operator= (T... args) T operator[] cpp/container/vector/operator_at (T... args) T pop_back cpp/container/vector/pop_back (T... args) T push_back cpp/container/vector/push_back (T... args) T rbegin cpp/container/vector/rbegin (T... args) T rend cpp/container/vector/rend (T... args) T reserve cpp/container/vector/reserve (T... args) T resize cpp/container/vector/resize (T... args) T shrink_to_fit cpp/container/vector/shrink_to_fit (T... args) T size cpp/container/vector/size (T... args) T swap cpp/container/vector/swap (T... args) T vector cpp/container/vector/vector (T... args) T ~vector cpp/container/vector/~vector (T... args) std::pmr::wstring cpp/string/basic_string T append cpp/string/basic_string/append (T... args) T assign cpp/string/basic_string/assign (T... args) T at cpp/string/basic_string/at (T... args) T back cpp/string/basic_string/back (T... args) T begin cpp/string/basic_string/begin (T... args) T c_str cpp/string/basic_string/c_str (T... args) T capacity cpp/string/basic_string/capacity (T... args) T cbegin cpp/string/basic_string/begin (T... args) T cend cpp/string/basic_string/end (T... args) T clear cpp/string/basic_string/clear (T... args) T compare cpp/string/basic_string/compare (T... args) T copy cpp/string/basic_string/copy (T... args) T crbegin cpp/string/basic_string/rbegin (T... args) T crend cpp/string/basic_string/rend (T... args) T data cpp/string/basic_string/data (T... args) T empty cpp/string/basic_string/empty (T... args) T end cpp/string/basic_string/end (T... args) T erase cpp/string/basic_string/erase (T... args) T find cpp/string/basic_string/find (T... args) T find_first_not_of cpp/string/basic_string/find_first_not_of (T... args) T find_first_of cpp/string/basic_string/find_first_of (T... args) T find_last_not_of cpp/string/basic_string/find_last_not_of (T... args) T find_last_of cpp/string/basic_string/find_last_of (T... args) T front cpp/string/basic_string/front (T... args) T get_allocator cpp/string/basic_string/get_allocator (T... args) T insert cpp/string/basic_string/insert (T... args) T length cpp/string/basic_string/size (T... args) T max_size cpp/string/basic_string/max_size (T... args) T operator= cpp/string/basic_string/operator= (T... args) T operator[] cpp/string/basic_string/operator_at (T... args) T pop_back cpp/string/basic_string/pop_back (T... args) T push_back cpp/string/basic_string/push_back (T... args) T rbegin cpp/string/basic_string/rbegin (T... args) T rend cpp/string/basic_string/rend (T... args) T replace cpp/string/basic_string/replace (T... args) T reserve cpp/string/basic_string/reserve (T... args) T resize cpp/string/basic_string/resize (T... args) T rfind cpp/string/basic_string/rfind (T... args) T shrink_to_fit cpp/string/basic_string/shrink_to_fit (T... args) T size cpp/string/basic_string/size (T... args) T substr cpp/string/basic_string/substr (T... args) T swap cpp/string/basic_string/swap (T... args) T wstring cpp/string/basic_string/basic_string (T... args) std::pointer_safety cpp/memory/gc/pointer_safety std::pointer_traits cpp/memory/pointer_traits T pointer_to cpp/memory/pointer_traits/pointer_to (T... args) std::poisson_distribution cpp/numeric/random/poisson_distribution T max cpp/numeric/random/poisson_distribution/max (T... args) T mean cpp/numeric/random/poisson_distribution/mean (T... args) T min cpp/numeric/random/poisson_distribution/min (T... args) T param cpp/numeric/random/poisson_distribution/param (T... args) T poisson_distribution cpp/numeric/random/poisson_distribution/poisson_distribution (T... args) T reset cpp/numeric/random/poisson_distribution/reset (T... args) std::priority_queue cpp/container/priority_queue T emplace cpp/container/priority_queue/emplace (T... args) T empty cpp/container/priority_queue/empty (T... args) T operator= cpp/container/priority_queue/operator= (T... args) T pop cpp/container/priority_queue/pop (T... args) T priority_queue cpp/container/priority_queue/priority_queue (T... args) T push cpp/container/priority_queue/push (T... args) T size cpp/container/priority_queue/size (T... args) T swap cpp/container/priority_queue/swap (T... args) T top cpp/container/priority_queue/top (T... args) T ~priority_queue cpp/container/priority_queue/~priority_queue (T... args) std::promise cpp/thread/promise T get_future cpp/thread/promise/get_future (T... args) T operator= cpp/thread/promise/operator= (T... args) T promise cpp/thread/promise/promise (T... args) T set_exception cpp/thread/promise/set_exception (T... args) T set_exception_at_thread_exit cpp/thread/promise/set_exception_at_thread_exit (T... args) T set_value cpp/thread/promise/set_value (T... args) T set_value_at_thread_exit cpp/thread/promise/set_value_at_thread_exit (T... args) T swap cpp/thread/promise/swap (T... args) T ~promise cpp/thread/promise/~promise (T... args) std::ptrdiff_t cpp/types/ptrdiff_t std::queue cpp/container/queue T back cpp/container/queue/back (T... args) T emplace cpp/container/queue/emplace (T... args) T empty cpp/container/queue/empty (T... args) T front cpp/container/queue/front (T... args) T operator= cpp/container/queue/operator= (T... args) T pop cpp/container/queue/pop (T... args) T push cpp/container/queue/push (T... args) T queue cpp/container/queue/queue (T... args) T size cpp/container/queue/size (T... args) T swap cpp/container/queue/swap (T... args) T ~queue cpp/container/queue/~queue (T... args) std::random_access_iterator_tag cpp/iterator/iterator_tags std::random_device cpp/numeric/random/random_device T entropy cpp/numeric/random/random_device/entropy (T... args) T max cpp/numeric/random/random_device/max (T... args) T min cpp/numeric/random/random_device/min (T... args) T operator() cpp/numeric/random/random_device/operator() (T... args) T random_device cpp/numeric/random/random_device/random_device (T... args) std::range_error cpp/error/range_error T range_error cpp/error/range_error (T... args) T what cpp/error/exception/what (T... args) std::rank cpp/types/rank std::ranlux24 cpp/numeric/random/discard_block_engine T base cpp/numeric/random/discard_block_engine/base (T... args) T discard cpp/numeric/random/discard_block_engine/discard (T... args) T max cpp/numeric/random/discard_block_engine/max (T... args) T min cpp/numeric/random/discard_block_engine/min (T... args) T operator() cpp/numeric/random/discard_block_engine/operator() (T... args) T ranlux24 cpp/numeric/random/discard_block_engine/discard_block_engine (T... args) T seed cpp/numeric/random/discard_block_engine/seed (T... args) std::ranlux24_base cpp/numeric/random/subtract_with_carry_engine T discard cpp/numeric/random/subtract_with_carry_engine/discard (T... args) T max cpp/numeric/random/subtract_with_carry_engine/max (T... args) T min cpp/numeric/random/subtract_with_carry_engine/min (T... args) T operator() cpp/numeric/random/subtract_with_carry_engine/operator() (T... args) T ranlux24_base cpp/numeric/random/subtract_with_carry_engine/subtract_with_carry_engine (T... args) T seed cpp/numeric/random/subtract_with_carry_engine/seed (T... args) std::ranlux48 cpp/numeric/random/discard_block_engine T base cpp/numeric/random/discard_block_engine/base (T... args) T discard cpp/numeric/random/discard_block_engine/discard (T... args) T max cpp/numeric/random/discard_block_engine/max (T... args) T min cpp/numeric/random/discard_block_engine/min (T... args) T operator() cpp/numeric/random/discard_block_engine/operator() (T... args) T ranlux48 cpp/numeric/random/discard_block_engine/discard_block_engine (T... args) T seed cpp/numeric/random/discard_block_engine/seed (T... args) std::ranlux48_base cpp/numeric/random/subtract_with_carry_engine T discard cpp/numeric/random/subtract_with_carry_engine/discard (T... args) T max cpp/numeric/random/subtract_with_carry_engine/max (T... args) T min cpp/numeric/random/subtract_with_carry_engine/min (T... args) T operator() cpp/numeric/random/subtract_with_carry_engine/operator() (T... args) T ranlux48_base cpp/numeric/random/subtract_with_carry_engine/subtract_with_carry_engine (T... args) T seed cpp/numeric/random/subtract_with_carry_engine/seed (T... args) std::ratio cpp/numeric/ratio/ratio std::ratio_add cpp/numeric/ratio/ratio_add std::ratio_divide cpp/numeric/ratio/ratio_divide std::ratio_equal cpp/numeric/ratio/ratio_equal std::ratio_greater cpp/numeric/ratio/ratio_greater std::ratio_greater_equal cpp/numeric/ratio/ratio_greater_equal std::ratio_less cpp/numeric/ratio/ratio_less std::ratio_less_equal cpp/numeric/ratio/ratio_less_equal std::ratio_multiply cpp/numeric/ratio/ratio_multiply std::ratio_not_equal cpp/numeric/ratio/ratio_not_equal std::ratio_subtract cpp/numeric/ratio/ratio_subtract std::raw_storage_iterator cpp/memory/raw_storage_iterator T operator* cpp/memory/raw_storage_iterator/operator* (T... args) T operator++ cpp/memory/raw_storage_iterator/operator_arith (T... args) T operator= cpp/memory/raw_storage_iterator/operator= (T... args) T raw_storage_iterator cpp/memory/raw_storage_iterator/raw_storage_iterator (T... args) std::recursive_mutex cpp/thread/recursive_mutex T lock cpp/thread/recursive_mutex/lock (T... args) T native_handle cpp/thread/recursive_mutex/native_handle (T... args) T recursive_mutex cpp/thread/recursive_mutex/recursive_mutex (T... args) T try_lock cpp/thread/recursive_mutex/try_lock (T... args) T unlock cpp/thread/recursive_mutex/unlock (T... args) std::recursive_timed_mutex cpp/thread/recursive_timed_mutex T lock cpp/thread/recursive_timed_mutex/lock (T... args) T native_handle cpp/thread/recursive_timed_mutex/native_handle (T... args) T recursive_timed_mutex cpp/thread/recursive_timed_mutex/recursive_timed_mutex (T... args) T try_lock cpp/thread/recursive_timed_mutex/try_lock (T... args) T try_lock_for cpp/thread/recursive_timed_mutex/try_lock_for (T... args) T try_lock_until cpp/thread/recursive_timed_mutex/try_lock_until (T... args) T unlock cpp/thread/recursive_timed_mutex/unlock (T... args) std::reference_wrapper cpp/utility/functional/reference_wrapper T get cpp/utility/functional/reference_wrapper/get (T... args) T operator T& cpp/utility/functional/reference_wrapper/get (T... args) T operator() cpp/utility/functional/reference_wrapper/operator() (T... args) T operator= cpp/utility/functional/reference_wrapper/operator= (T... args) T reference_wrapper cpp/utility/functional/reference_wrapper/reference_wrapper (T... args) std::regex cpp/regex/basic_regex T assign cpp/regex/basic_regex/assign (T... args) T flags cpp/regex/basic_regex/flags (T... args) T getloc cpp/regex/basic_regex/getloc (T... args) T imbue cpp/regex/basic_regex/imbue (T... args) T mark_count cpp/regex/basic_regex/mark_count (T... args) T operator= cpp/regex/basic_regex/operator= (T... args) T regex cpp/regex/basic_regex/basic_regex (T... args) T swap cpp/regex/basic_regex/swap (T... args) T ~regex cpp/regex/basic_regex/~basic_regex (T... args) std::regex_constants std::regex_error cpp/regex/regex_error T code cpp/regex/regex_error/code (T... args) T regex_error cpp/regex/regex_error/regex_error (T... args) T what cpp/error/exception/what (T... args) std::regex_iterator cpp/regex/regex_iterator T operator!= cpp/regex/regex_iterator/operator_cmp (T... args) T operator* cpp/regex/regex_iterator/operator* (T... args) T operator++ cpp/regex/regex_iterator/operator_arith (T... args) T operator++(int) cpp/regex/regex_iterator/operator_arith (T... args) T operator-> cpp/regex/regex_iterator/operator* (T... args) T operator= cpp/regex/regex_iterator/operator= (T... args) T operator== cpp/regex/regex_iterator/operator_cmp (T... args) T regex_iterator cpp/regex/regex_iterator/regex_iterator (T... args) std::regex_token_iterator cpp/regex/regex_token_iterator T operator!= cpp/regex/regex_token_iterator/operator_cmp (T... args) T operator* cpp/regex/regex_token_iterator/operator* (T... args) T operator++ cpp/regex/regex_token_iterator/operator_arith (T... args) T operator++(int) cpp/regex/regex_token_iterator/operator_arith (T... args) T operator-> cpp/regex/regex_token_iterator/operator* (T... args) T operator= cpp/regex/regex_token_iterator/operator= (T... args) T operator== cpp/regex/regex_token_iterator/operator_cmp (T... args) T regex_token_iterator cpp/regex/regex_token_iterator/regex_token_iterator (T... args) std::regex_traits cpp/regex/regex_traits T getloc cpp/regex/regex_traits/getloc (T... args) T imbue cpp/regex/regex_traits/imbue (T... args) T isctype cpp/regex/regex_traits/isctype (T... args) T length cpp/regex/regex_traits/length (T... args) T lookup_classname cpp/regex/regex_traits/lookup_classname (T... args) T lookup_collatename cpp/regex/regex_traits/lookup_collatename (T... args) T regex_traits cpp/regex/regex_traits/regex_traits (T... args) T transform cpp/regex/regex_traits/transform (T... args) T transform_primary cpp/regex/regex_traits/transform_primary (T... args) T translate cpp/regex/regex_traits/translate (T... args) T translate_nocase cpp/regex/regex_traits/translate_nocase (T... args) T value cpp/regex/regex_traits/value (T... args) std::rel_ops T operator!= cpp/utility/rel_ops/operator_cmp (T... args) T operator<= cpp/utility/rel_ops/operator_cmp (T... args) T operator> cpp/utility/rel_ops/operator_cmp (T... args) T operator>= cpp/utility/rel_ops/operator_cmp (T... args) std::remove_all_extents cpp/types/remove_all_extents std::remove_all_extents_t cpp/types/remove_all_extents std::remove_const cpp/types/remove_cv std::remove_const_t cpp/types/remove_cv std::remove_cv cpp/types/remove_cv std::remove_cv_t cpp/types/remove_cv std::remove_extent cpp/types/remove_extent std::remove_extent_t cpp/types/remove_extent std::remove_pointer cpp/types/remove_pointer std::remove_pointer_t cpp/types/remove_pointer std::remove_reference cpp/types/remove_reference std::remove_reference_t cpp/types/remove_reference std::remove_volatile cpp/types/remove_cv std::remove_volatile_t cpp/types/remove_cv std::result_of cpp/types/result_of std::result_of_t cpp/types/result_of std::reverse_iterator cpp/iterator/reverse_iterator std::runtime_error cpp/error/runtime_error T runtime_error cpp/error/runtime_error (T... args) T what cpp/error/exception/what (T... args) std::scoped_allocator_adaptor cpp/memory/scoped_allocator_adaptor T allocate cpp/memory/scoped_allocator_adaptor/allocate (T... args) T construct cpp/memory/scoped_allocator_adaptor/construct (T... args) T deallocate cpp/memory/scoped_allocator_adaptor/deallocate (T... args) T destroy cpp/memory/scoped_allocator_adaptor/destroy (T... args) T inner_allocator cpp/memory/scoped_allocator_adaptor/inner_allocator (T... args) T max_size cpp/memory/scoped_allocator_adaptor/max_size (T... args) T outer_allocator cpp/memory/scoped_allocator_adaptor/outer_allocator (T... args) T scoped_allocator_adaptor cpp/memory/scoped_allocator_adaptor/scoped_allocator_adaptor (T... args) T select_on_container_copy_construction cpp/memory/scoped_allocator_adaptor/select_on_container_copy_construction (T... args) T ~scoped_allocator_adaptor cpp/memory/scoped_allocator_adaptor/~scoped_allocator_adaptor (T... args) std::seed_seq cpp/numeric/random/seed_seq T generate cpp/numeric/random/seed_seq/generate (T... args) T param cpp/numeric/random/seed_seq/param (T... args) T seed_seq cpp/numeric/random/seed_seq/seed_seq (T... args) T size cpp/numeric/random/seed_seq/size (T... args) std::set cpp/container/set T begin cpp/container/set/begin (T... args) T cbegin cpp/container/set/begin (T... args) T cend cpp/container/set/end (T... args) T clear cpp/container/set/clear (T... args) T count cpp/container/set/count (T... args) T crbegin cpp/container/set/rbegin (T... args) T crend cpp/container/set/rend (T... args) T emplace cpp/container/set/emplace (T... args) T emplace_hint cpp/container/set/emplace_hint (T... args) T empty cpp/container/set/empty (T... args) T end cpp/container/set/end (T... args) T equal_range cpp/container/set/equal_range (T... args) T erase cpp/container/set/erase (T... args) T extract cpp/container/set/extract (T... args) T find cpp/container/set/find (T... args) T get_allocator cpp/container/set/get_allocator (T... args) T insert cpp/container/set/insert (T... args) T key_comp cpp/container/set/key_comp (T... args) T lower_bound cpp/container/set/lower_bound (T... args) T max_size cpp/container/set/max_size (T... args) T merge cpp/container/set/merge (T... args) T operator= cpp/container/set/operator= (T... args) T rbegin cpp/container/set/rbegin (T... args) T rend cpp/container/set/rend (T... args) T set cpp/container/set/set (T... args) T size cpp/container/set/size (T... args) T swap cpp/container/set/swap (T... args) T upper_bound cpp/container/set/upper_bound (T... args) T value_comp cpp/container/set/value_comp (T... args) T ~set cpp/container/set/~set (T... args) std::shared_future cpp/thread/shared_future T get cpp/thread/shared_future/get (T... args) T operator= cpp/thread/shared_future/operator= (T... args) T shared_future cpp/thread/shared_future/shared_future (T... args) T valid cpp/thread/shared_future/valid (T... args) T wait cpp/thread/shared_future/wait (T... args) T wait_for cpp/thread/shared_future/wait_for (T... args) T wait_until cpp/thread/shared_future/wait_until (T... args) T ~shared_future cpp/thread/shared_future/~shared_future (T... args) std::shared_lock cpp/thread/shared_lock T lock cpp/thread/shared_lock/lock (T... args) T mutex cpp/thread/shared_lock/mutex (T... args) T operator bool cpp/thread/shared_lock/operator_bool (T... args) T operator= cpp/thread/shared_lock/operator= (T... args) T owns_lock cpp/thread/shared_lock/owns_lock (T... args) T release cpp/thread/shared_lock/release (T... args) T shared_lock cpp/thread/shared_lock/shared_lock (T... args) T swap cpp/thread/shared_lock/swap (T... args) T try_lock cpp/thread/shared_lock/try_lock (T... args) T try_lock_for cpp/thread/shared_lock/try_lock_for (T... args) T try_lock_until cpp/thread/shared_lock/try_lock_until (T... args) T unlock cpp/thread/shared_lock/unlock (T... args) T ~shared_lock cpp/thread/shared_lock/~shared_lock (T... args) std::shared_mutex cpp/thread/shared_mutex T lock cpp/thread/shared_mutex/lock (T... args) T lock_shared cpp/thread/shared_mutex/lock_shared (T... args) T native_handle cpp/thread/shared_mutex/native_handle (T... args) T shared_mutex cpp/thread/shared_mutex/shared_mutex (T... args) T try_lock cpp/thread/shared_mutex/try_lock (T... args) T try_lock_shared cpp/thread/shared_mutex/try_lock_shared (T... args) T unlock cpp/thread/shared_mutex/unlock (T... args) T unlock_shared cpp/thread/shared_mutex/unlock_shared (T... args) std::shared_ptr cpp/memory/shared_ptr T get cpp/memory/shared_ptr/get (T... args) T operator bool cpp/memory/shared_ptr/operator_bool (T... args) T operator* cpp/memory/shared_ptr/operator* (T... args) T operator-> cpp/memory/shared_ptr/operator* (T... args) T operator= cpp/memory/shared_ptr/operator= (T... args) T operator[] cpp/memory/shared_ptr/operator_at (T... args) T owner_before cpp/memory/shared_ptr/owner_before (T... args) T reset cpp/memory/shared_ptr/reset (T... args) T shared_ptr cpp/memory/shared_ptr/shared_ptr (T... args) T swap cpp/memory/shared_ptr/swap (T... args) T unique cpp/memory/shared_ptr/unique (T... args) T use_count cpp/memory/shared_ptr/use_count (T... args) T ~shared_ptr cpp/memory/shared_ptr/~shared_ptr (T... args) std::shared_timed_mutex cpp/thread/shared_timed_mutex T lock cpp/thread/shared_timed_mutex/lock (T... args) T lock_shared cpp/thread/shared_timed_mutex/lock_shared (T... args) T shared_timed_mutex cpp/thread/shared_timed_mutex/shared_timed_mutex (T... args) T try_lock cpp/thread/shared_timed_mutex/try_lock (T... args) T try_lock_for cpp/thread/shared_timed_mutex/try_lock_for (T... args) T try_lock_shared cpp/thread/shared_timed_mutex/try_lock_shared (T... args) T try_lock_shared_for cpp/thread/shared_timed_mutex/try_lock_shared_for (T... args) T try_lock_shared_until cpp/thread/shared_timed_mutex/try_lock_shared_until (T... args) T try_lock_until cpp/thread/shared_timed_mutex/try_lock_until (T... args) T unlock cpp/thread/shared_timed_mutex/unlock (T... args) T unlock_shared cpp/thread/shared_timed_mutex/unlock_shared (T... args) std::shuffle_order_engine cpp/numeric/random/shuffle_order_engine T base cpp/numeric/random/shuffle_order_engine/base (T... args) T discard cpp/numeric/random/shuffle_order_engine/discard (T... args) T max cpp/numeric/random/shuffle_order_engine/max (T... args) T min cpp/numeric/random/shuffle_order_engine/min (T... args) T operator() cpp/numeric/random/shuffle_order_engine/operator() (T... args) T seed cpp/numeric/random/shuffle_order_engine/seed (T... args) T shuffle_order_engine cpp/numeric/random/shuffle_order_engine/shuffle_order_engine (T... args) std::sig_atomic_t cpp/utility/program/sig_atomic_t std::size_t cpp/types/size_t std::slice cpp/numeric/valarray/slice std::slice_array cpp/numeric/valarray/slice_array std::smatch cpp/regex/match_results T begin cpp/regex/match_results/begin (T... args) T cbegin cpp/regex/match_results/begin (T... args) T cend cpp/regex/match_results/end (T... args) T empty cpp/regex/match_results/empty (T... args) T end cpp/regex/match_results/end (T... args) T format cpp/regex/match_results/format (T... args) T get_allocator cpp/regex/match_results/get_allocator (T... args) T length cpp/regex/match_results/length (T... args) T max_size cpp/regex/match_results/max_size (T... args) T operator[] cpp/regex/match_results/operator_at (T... args) T position cpp/regex/match_results/position (T... args) T prefix cpp/regex/match_results/prefix (T... args) T ready cpp/regex/match_results/ready (T... args) T size cpp/regex/match_results/size (T... args) T smatch cpp/regex/match_results/match_results (T... args) T str cpp/regex/match_results/str (T... args) T suffix cpp/regex/match_results/suffix (T... args) T swap cpp/regex/match_results/swap (T... args) T ~smatch cpp/regex/match_results/~match_results (T... args) std::sregex_iterator cpp/regex/regex_iterator T operator!= cpp/regex/regex_iterator/operator_cmp (T... args) T operator* cpp/regex/regex_iterator/operator* (T... args) T operator++ cpp/regex/regex_iterator/operator_arith (T... args) T operator++(int) cpp/regex/regex_iterator/operator_arith (T... args) T operator-> cpp/regex/regex_iterator/operator* (T... args) T operator= cpp/regex/regex_iterator/operator= (T... args) T operator== cpp/regex/regex_iterator/operator_cmp (T... args) T sregex_iterator cpp/regex/regex_iterator/regex_iterator (T... args) std::sregex_token_iterator cpp/regex/regex_token_iterator T operator!= cpp/regex/regex_token_iterator/operator_cmp (T... args) T operator* cpp/regex/regex_token_iterator/operator* (T... args) T operator++ cpp/regex/regex_token_iterator/operator_arith (T... args) T operator++(int) cpp/regex/regex_token_iterator/operator_arith (T... args) T operator-> cpp/regex/regex_token_iterator/operator* (T... args) T operator= cpp/regex/regex_token_iterator/operator= (T... args) T operator== cpp/regex/regex_token_iterator/operator_cmp (T... args) T sregex_token_iterator cpp/regex/regex_token_iterator/regex_token_iterator (T... args) std::ssub_match cpp/regex/sub_match T compare cpp/regex/sub_match/compare (T... args) T length cpp/regex/sub_match/length (T... args) T operator string_type cpp/regex/sub_match/str (T... args) T ssub_match cpp/regex/sub_match/sub_match (T... args) T str cpp/regex/sub_match/str (T... args) std::stack cpp/container/stack T emplace cpp/container/stack/emplace (T... args) T empty cpp/container/stack/empty (T... args) T operator= cpp/container/stack/operator= (T... args) T pop cpp/container/stack/pop (T... args) T push cpp/container/stack/push (T... args) T size cpp/container/stack/size (T... args) T stack cpp/container/stack/stack (T... args) T swap cpp/container/stack/swap (T... args) T top cpp/container/stack/top (T... args) T ~stack cpp/container/stack/~stack (T... args) std::streambuf cpp/io/basic_streambuf T eback cpp/io/basic_streambuf/gptr (T... args) T egptr cpp/io/basic_streambuf/gptr (T... args) T epptr cpp/io/basic_streambuf/pptr (T... args) T gbump cpp/io/basic_streambuf/gbump (T... args) T getloc cpp/io/basic_streambuf/getloc (T... args) T gptr cpp/io/basic_streambuf/gptr (T... args) T imbue cpp/io/basic_streambuf/pubimbue (T... args) T in_avail cpp/io/basic_streambuf/in_avail (T... args) T operator= cpp/io/basic_streambuf/operator= (T... args) T overflow cpp/io/basic_streambuf/overflow (T... args) T pbackfail cpp/io/basic_streambuf/pbackfail (T... args) T pbase cpp/io/basic_streambuf/pptr (T... args) T pbump cpp/io/basic_streambuf/pbump (T... args) T pptr cpp/io/basic_streambuf/pptr (T... args) T pubimbue cpp/io/basic_streambuf/pubimbue (T... args) T pubseekoff cpp/io/basic_streambuf/pubseekoff (T... args) T pubseekpos cpp/io/basic_streambuf/pubseekpos (T... args) T pubsetbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T pubsync cpp/io/basic_streambuf/pubsync (T... args) T sbumpc cpp/io/basic_streambuf/sbumpc (T... args) T seekoff cpp/io/basic_streambuf/pubseekoff (T... args) T seekpos cpp/io/basic_streambuf/pubseekpos (T... args) T setbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T setg cpp/io/basic_streambuf/setg (T... args) T setp cpp/io/basic_streambuf/setp (T... args) T sgetc cpp/io/basic_streambuf/sgetc (T... args) T sgetn cpp/io/basic_streambuf/sgetn (T... args) T showmanyc cpp/io/basic_streambuf/showmanyc (T... args) T snextc cpp/io/basic_streambuf/snextc (T... args) T sputbackc cpp/io/basic_streambuf/sputbackc (T... args) T sputc cpp/io/basic_streambuf/sputc (T... args) T sputn cpp/io/basic_streambuf/sputn (T... args) T streambuf cpp/io/basic_streambuf/basic_streambuf (T... args) T sungetc cpp/io/basic_streambuf/sungetc (T... args) T swap cpp/io/basic_streambuf/swap (T... args) T sync cpp/io/basic_streambuf/pubsync (T... args) T uflow cpp/io/basic_streambuf/uflow (T... args) T underflow cpp/io/basic_streambuf/underflow (T... args) T xsgetn cpp/io/basic_streambuf/sgetn (T... args) T xsputn cpp/io/basic_streambuf/sputn (T... args) T ~streambuf cpp/io/basic_streambuf/~basic_streambuf (T... args) std::streamoff cpp/io/streamoff std::streampos cpp/io/fpos T state cpp/io/fpos/state (T... args) std::streamsize cpp/io/streamsize std::string cpp/string/basic_string T append cpp/string/basic_string/append (T... args) T assign cpp/string/basic_string/assign (T... args) T at cpp/string/basic_string/at (T... args) T back cpp/string/basic_string/back (T... args) T begin cpp/string/basic_string/begin (T... args) T c_str cpp/string/basic_string/c_str (T... args) T capacity cpp/string/basic_string/capacity (T... args) T cbegin cpp/string/basic_string/begin (T... args) T cend cpp/string/basic_string/end (T... args) T clear cpp/string/basic_string/clear (T... args) T compare cpp/string/basic_string/compare (T... args) T copy cpp/string/basic_string/copy (T... args) T crbegin cpp/string/basic_string/rbegin (T... args) T crend cpp/string/basic_string/rend (T... args) T data cpp/string/basic_string/data (T... args) T empty cpp/string/basic_string/empty (T... args) T end cpp/string/basic_string/end (T... args) T erase cpp/string/basic_string/erase (T... args) T find cpp/string/basic_string/find (T... args) T find_first_not_of cpp/string/basic_string/find_first_not_of (T... args) T find_first_of cpp/string/basic_string/find_first_of (T... args) T find_last_not_of cpp/string/basic_string/find_last_not_of (T... args) T find_last_of cpp/string/basic_string/find_last_of (T... args) T front cpp/string/basic_string/front (T... args) T get_allocator cpp/string/basic_string/get_allocator (T... args) T insert cpp/string/basic_string/insert (T... args) T length cpp/string/basic_string/size (T... args) T max_size cpp/string/basic_string/max_size (T... args) T operator= cpp/string/basic_string/operator= (T... args) T operator[] cpp/string/basic_string/operator_at (T... args) T pop_back cpp/string/basic_string/pop_back (T... args) T push_back cpp/string/basic_string/push_back (T... args) T rbegin cpp/string/basic_string/rbegin (T... args) T rend cpp/string/basic_string/rend (T... args) T replace cpp/string/basic_string/replace (T... args) T reserve cpp/string/basic_string/reserve (T... args) T resize cpp/string/basic_string/resize (T... args) T rfind cpp/string/basic_string/rfind (T... args) T shrink_to_fit cpp/string/basic_string/shrink_to_fit (T... args) T size cpp/string/basic_string/size (T... args) T string cpp/string/basic_string/basic_string (T... args) T substr cpp/string/basic_string/substr (T... args) T swap cpp/string/basic_string/swap (T... args) std::string_view cpp/string/basic_string_view T at cpp/string/basic_string_view/at (T... args) T back cpp/string/basic_string_view/back (T... args) T begin cpp/string/basic_string_view/begin (T... args) T cbegin cpp/string/basic_string_view/begin (T... args) T cend cpp/string/basic_string_view/end (T... args) T compare cpp/string/basic_string_view/compare (T... args) T copy cpp/string/basic_string_view/copy (T... args) T crbegin cpp/string/basic_string_view/rbegin (T... args) T crend cpp/string/basic_string_view/rend (T... args) T data cpp/string/basic_string_view/data (T... args) T empty cpp/string/basic_string_view/empty (T... args) T end cpp/string/basic_string_view/end (T... args) T find cpp/string/basic_string_view/find (T... args) T find_first_not_of cpp/string/basic_string_view/find_first_not_of (T... args) T find_first_of cpp/string/basic_string_view/find_first_of (T... args) T find_last_not_of cpp/string/basic_string_view/find_last_not_of (T... args) T find_last_of cpp/string/basic_string_view/find_last_of (T... args) T front cpp/string/basic_string_view/front (T... args) T length cpp/string/basic_string_view/size (T... args) T max_size cpp/string/basic_string_view/max_size (T... args) T operator= cpp/string/basic_string_view/operator= (T... args) T operator[] cpp/string/basic_string_view/operator_at (T... args) T rbegin cpp/string/basic_string_view/rbegin (T... args) T remove_prefix cpp/string/basic_string_view/remove_prefix (T... args) T remove_suffix cpp/string/basic_string_view/remove_suffix (T... args) T rend cpp/string/basic_string_view/rend (T... args) T rfind cpp/string/basic_string_view/rfind (T... args) T size cpp/string/basic_string_view/size (T... args) T string_view cpp/string/basic_string_view/basic_string_view (T... args) T substr cpp/string/basic_string_view/substr (T... args) T swap cpp/string/basic_string_view/swap (T... args) std::stringbuf cpp/io/basic_stringbuf T eback cpp/io/basic_streambuf/gptr (T... args) T egptr cpp/io/basic_streambuf/gptr (T... args) T epptr cpp/io/basic_streambuf/pptr (T... args) T gbump cpp/io/basic_streambuf/gbump (T... args) T getloc cpp/io/basic_streambuf/getloc (T... args) T gptr cpp/io/basic_streambuf/gptr (T... args) T imbue cpp/io/basic_streambuf/pubimbue (T... args) T in_avail cpp/io/basic_streambuf/in_avail (T... args) T operator= cpp/io/basic_stringbuf/operator= (T... args) T overflow cpp/io/basic_streambuf/overflow (T... args) T pbackfail cpp/io/basic_streambuf/pbackfail (T... args) T pbase cpp/io/basic_streambuf/pptr (T... args) T pbump cpp/io/basic_streambuf/pbump (T... args) T pptr cpp/io/basic_streambuf/pptr (T... args) T pubimbue cpp/io/basic_streambuf/pubimbue (T... args) T pubseekoff cpp/io/basic_streambuf/pubseekoff (T... args) T pubseekpos cpp/io/basic_streambuf/pubseekpos (T... args) T pubsetbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T pubsync cpp/io/basic_streambuf/pubsync (T... args) T sbumpc cpp/io/basic_streambuf/sbumpc (T... args) T seekoff cpp/io/basic_streambuf/pubseekoff (T... args) T seekpos cpp/io/basic_streambuf/pubseekpos (T... args) T setbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T setg cpp/io/basic_streambuf/setg (T... args) T setp cpp/io/basic_streambuf/setp (T... args) T sgetc cpp/io/basic_streambuf/sgetc (T... args) T sgetn cpp/io/basic_streambuf/sgetn (T... args) T showmanyc cpp/io/basic_streambuf/showmanyc (T... args) T snextc cpp/io/basic_streambuf/snextc (T... args) T sputbackc cpp/io/basic_streambuf/sputbackc (T... args) T sputc cpp/io/basic_streambuf/sputc (T... args) T sputn cpp/io/basic_streambuf/sputn (T... args) T str cpp/io/basic_stringbuf/str (T... args) T stringbuf cpp/io/basic_stringbuf/basic_stringbuf (T... args) T sungetc cpp/io/basic_streambuf/sungetc (T... args) T swap cpp/io/basic_streambuf/swap (T... args) T sync cpp/io/basic_streambuf/pubsync (T... args) T uflow cpp/io/basic_streambuf/uflow (T... args) T underflow cpp/io/basic_streambuf/underflow (T... args) T xsgetn cpp/io/basic_streambuf/sgetn (T... args) T xsputn cpp/io/basic_streambuf/sputn (T... args) std::stringstream cpp/io/basic_stringstream std::stringstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::stringstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::stringstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator= cpp/io/basic_stringstream/operator= (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::stringstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T str cpp/io/basic_stringstream/str (T... args) T stringstream cpp/io/basic_stringstream/basic_stringstream (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::stringstream::Init cpp/io/ios_base/Init std::stringstream::event_callback cpp/io/ios_base/event_callback std::stringstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::stringstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::strstream cpp/io/strstream std::strstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::strstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::strstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T freeze cpp/io/strstream/freeze (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T pcount cpp/io/strstream/pcount (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::strstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T str cpp/io/strstream/str (T... args) T strstream cpp/io/strstream/strstream (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~strstream cpp/io/strstream/~strstream (T... args) std::strstream::Init cpp/io/ios_base/Init std::strstream::event_callback cpp/io/ios_base/event_callback std::strstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::strstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::strstreambuf cpp/io/strstreambuf T eback cpp/io/basic_streambuf/gptr (T... args) T egptr cpp/io/basic_streambuf/gptr (T... args) T epptr cpp/io/basic_streambuf/pptr (T... args) T freeze cpp/io/strstreambuf/freeze (T... args) T gbump cpp/io/basic_streambuf/gbump (T... args) T getloc cpp/io/basic_streambuf/getloc (T... args) T gptr cpp/io/basic_streambuf/gptr (T... args) T imbue cpp/io/basic_streambuf/pubimbue (T... args) T in_avail cpp/io/basic_streambuf/in_avail (T... args) T overflow cpp/io/basic_streambuf/overflow (T... args) T pbackfail cpp/io/basic_streambuf/pbackfail (T... args) T pbase cpp/io/basic_streambuf/pptr (T... args) T pbump cpp/io/basic_streambuf/pbump (T... args) T pcount cpp/io/strstreambuf/pcount (T... args) T pptr cpp/io/basic_streambuf/pptr (T... args) T pubimbue cpp/io/basic_streambuf/pubimbue (T... args) T pubseekoff cpp/io/basic_streambuf/pubseekoff (T... args) T pubseekpos cpp/io/basic_streambuf/pubseekpos (T... args) T pubsetbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T pubsync cpp/io/basic_streambuf/pubsync (T... args) T sbumpc cpp/io/basic_streambuf/sbumpc (T... args) T seekoff cpp/io/basic_streambuf/pubseekoff (T... args) T seekpos cpp/io/basic_streambuf/pubseekpos (T... args) T setbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T setg cpp/io/basic_streambuf/setg (T... args) T setp cpp/io/basic_streambuf/setp (T... args) T sgetc cpp/io/basic_streambuf/sgetc (T... args) T sgetn cpp/io/basic_streambuf/sgetn (T... args) T showmanyc cpp/io/basic_streambuf/showmanyc (T... args) T snextc cpp/io/basic_streambuf/snextc (T... args) T sputbackc cpp/io/basic_streambuf/sputbackc (T... args) T sputc cpp/io/basic_streambuf/sputc (T... args) T sputn cpp/io/basic_streambuf/sputn (T... args) T str cpp/io/strstreambuf/str (T... args) T strstreambuf cpp/io/strstreambuf/strstreambuf (T... args) T sungetc cpp/io/basic_streambuf/sungetc (T... args) T swap cpp/io/basic_streambuf/swap (T... args) T sync cpp/io/basic_streambuf/pubsync (T... args) T uflow cpp/io/basic_streambuf/uflow (T... args) T underflow cpp/io/basic_streambuf/underflow (T... args) T xsgetn cpp/io/basic_streambuf/sgetn (T... args) T xsputn cpp/io/basic_streambuf/sputn (T... args) T ~strstreambuf cpp/io/strstreambuf/~strstreambuf (T... args) std::student_t_distribution cpp/numeric/random/student_t_distribution T max cpp/numeric/random/student_t_distribution/max (T... args) T min cpp/numeric/random/student_t_distribution/min (T... args) T n cpp/numeric/random/student_t_distribution/n (T... args) T operator() cpp/numeric/random/student_t_distribution/operator() (T... args) T param cpp/numeric/random/student_t_distribution/param (T... args) T reset cpp/numeric/random/student_t_distribution/reset (T... args) T student_t_distribution cpp/numeric/random/student_t_distribution/student_t_distribution (T... args) std::sub_match cpp/regex/sub_match T compare cpp/regex/sub_match/compare (T... args) T length cpp/regex/sub_match/length (T... args) T operator string_type cpp/regex/sub_match/str (T... args) T str cpp/regex/sub_match/str (T... args) T sub_match cpp/regex/sub_match/sub_match (T... args) std::subtract_with_carry_engine cpp/numeric/random/subtract_with_carry_engine T discard cpp/numeric/random/subtract_with_carry_engine/discard (T... args) T max cpp/numeric/random/subtract_with_carry_engine/max (T... args) T min cpp/numeric/random/subtract_with_carry_engine/min (T... args) T operator() cpp/numeric/random/subtract_with_carry_engine/operator() (T... args) T seed cpp/numeric/random/subtract_with_carry_engine/seed (T... args) T subtract_with_carry_engine cpp/numeric/random/subtract_with_carry_engine/subtract_with_carry_engine (T... args) std::system_error cpp/error/system_error T code cpp/error/system_error/code (T... args) T system_error cpp/error/system_error/system_error (T... args) T what cpp/error/exception/what (T... args) std::tera cpp/numeric/ratio/ratio std::terminate_handler cpp/error/terminate_handler std::this_thread T get_id cpp/thread/get_id (T... args) T sleep_for cpp/thread/sleep_for (T... args) T sleep_until cpp/thread/sleep_until (T... args) T yield cpp/thread/yield (T... args) std::thread cpp/thread/thread T detach cpp/thread/thread/detach (T... args) T get_id cpp/thread/thread/get_id (T... args) T hardware_concurrency cpp/thread/thread/hardware_concurrency (T... args) std::thread::id T join cpp/thread/thread/join (T... args) T joinable cpp/thread/thread/joinable (T... args) T native_handle cpp/thread/thread/native_handle (T... args) T operator= cpp/thread/thread/operator= (T... args) T swap cpp/thread/thread/swap (T... args) T thread cpp/thread/thread/thread (T... args) T ~thread cpp/thread/thread/~thread (T... args) std::thread::id cpp/thread/thread/id T id cpp/thread/thread/id/id (T... args) T operator!= cpp/thread/thread/id/operator_cmp (T... args) T operator< cpp/thread/thread/id/operator_cmp (T... args) T operator<< cpp/thread/thread/id/operator_ltlt (T... args) T operator<= cpp/thread/thread/id/operator_cmp (T... args) T operator== cpp/thread/thread/id/operator_cmp (T... args) T operator> cpp/thread/thread/id/operator_cmp (T... args) T operator>= cpp/thread/thread/id/operator_cmp (T... args) std::time_base cpp/locale/time_base std::time_get cpp/locale/time_get std::time_get::char_type T date_order cpp/locale/time_get/date_order (T... args) T do_date_order cpp/locale/time_get/date_order (T... args) T do_get cpp/locale/time_get/get (T... args) T do_get_date cpp/locale/time_get/get_date (T... args) T do_get_monthname cpp/locale/time_get/get_monthname (T... args) T do_get_time cpp/locale/time_get/get_time (T... args) T do_get_weekday cpp/locale/time_get/get_weekday (T... args) T do_get_year cpp/locale/time_get/get_year (T... args) T get cpp/locale/time_get/get (T... args) T get_date cpp/locale/time_get/get_date (T... args) T get_monthname cpp/locale/time_get/get_monthname (T... args) T get_time cpp/locale/time_get/get_time (T... args) T get_weekday cpp/locale/time_get/get_weekday (T... args) T get_year cpp/locale/time_get/get_year (T... args) std::time_get::iter_type T time_get cpp/locale/time_get/time_get (T... args) T ~time_get cpp/locale/time_get/~time_get (T... args) std::time_get::char_type cpp/locale/time_get std::time_get::iter_type cpp/locale/time_get std::time_get_byname cpp/locale/time_get_byname std::time_get_byname::char_type T date_order cpp/locale/time_get/date_order (T... args) T do_date_order cpp/locale/time_get/date_order (T... args) T do_get cpp/locale/time_get/get (T... args) T do_get_date cpp/locale/time_get/get_date (T... args) T do_get_monthname cpp/locale/time_get/get_monthname (T... args) T do_get_time cpp/locale/time_get/get_time (T... args) T do_get_weekday cpp/locale/time_get/get_weekday (T... args) T do_get_year cpp/locale/time_get/get_year (T... args) T get cpp/locale/time_get/get (T... args) T get_date cpp/locale/time_get/get_date (T... args) T get_monthname cpp/locale/time_get/get_monthname (T... args) T get_time cpp/locale/time_get/get_time (T... args) T get_weekday cpp/locale/time_get/get_weekday (T... args) T get_year cpp/locale/time_get/get_year (T... args) std::time_get_byname::iter_type T time_get_byname cpp/locale/time_get_byname (T... args) T ~time_get_byname cpp/locale/time_get_byname (T... args) std::time_get_byname::char_type cpp/locale/time_get std::time_get_byname::iter_type cpp/locale/time_get std::time_put cpp/locale/time_put std::time_put::char_type T do_put cpp/locale/time_put/put (T... args) std::time_put::iter_type T put cpp/locale/time_put/put (T... args) T time_put cpp/locale/time_put/time_put (T... args) T ~time_put cpp/locale/time_put/~time_put (T... args) std::time_put::char_type cpp/locale/time_put std::time_put::iter_type cpp/locale/time_put std::time_put_byname cpp/locale/time_put_byname std::time_put_byname::char_type T do_put cpp/locale/time_put/put (T... args) std::time_put_byname::iter_type T put cpp/locale/time_put/put (T... args) T time_put_byname cpp/locale/time_put_byname (T... args) T ~time_put_byname cpp/locale/time_put_byname (T... args) std::time_put_byname::char_type cpp/locale/time_put std::time_put_byname::iter_type cpp/locale/time_put std::time_t cpp/chrono/c/time_t std::timed_mutex cpp/thread/timed_mutex T lock cpp/thread/timed_mutex/lock (T... args) T native_handle cpp/thread/timed_mutex/native_handle (T... args) T timed_mutex cpp/thread/timed_mutex/timed_mutex (T... args) T try_lock cpp/thread/timed_mutex/try_lock (T... args) T try_lock_for cpp/thread/timed_mutex/try_lock_for (T... args) T try_lock_until cpp/thread/timed_mutex/try_lock_until (T... args) T unlock cpp/thread/timed_mutex/unlock (T... args) std::tm cpp/chrono/c/tm std::true_type cpp/types/integral_constant std::try_to_lock_t cpp/thread/lock_tag_t std::tuple cpp/utility/tuple T operator= cpp/utility/tuple/operator= (T... args) T swap cpp/utility/tuple/swap (T... args) T tuple cpp/utility/tuple/tuple (T... args) std::type_index cpp/types/type_index T hash_code cpp/types/type_index/hash_code (T... args) T name cpp/types/type_index/name (T... args) T operator!= cpp/types/type_index/operator_cmp (T... args) T operator< cpp/types/type_index/operator_cmp (T... args) T operator<= cpp/types/type_index/operator_cmp (T... args) T operator== cpp/types/type_index/operator_cmp (T... args) T operator> cpp/types/type_index/operator_cmp (T... args) T operator>= cpp/types/type_index/operator_cmp (T... args) T type_index cpp/types/type_index/type_index (T... args) std::type_info cpp/types/type_info T before cpp/types/type_info/before (T... args) T hash_code cpp/types/type_info/hash_code (T... args) T name cpp/types/type_info/name (T... args) T operator!= cpp/types/type_info/operator_cmp (T... args) T operator== cpp/types/type_info/operator_cmp (T... args) std::u16streampos cpp/io/fpos T state cpp/io/fpos/state (T... args) std::u16string cpp/string/basic_string T append cpp/string/basic_string/append (T... args) T assign cpp/string/basic_string/assign (T... args) T at cpp/string/basic_string/at (T... args) T back cpp/string/basic_string/back (T... args) T begin cpp/string/basic_string/begin (T... args) T c_str cpp/string/basic_string/c_str (T... args) T capacity cpp/string/basic_string/capacity (T... args) T cbegin cpp/string/basic_string/begin (T... args) T cend cpp/string/basic_string/end (T... args) T clear cpp/string/basic_string/clear (T... args) T compare cpp/string/basic_string/compare (T... args) T copy cpp/string/basic_string/copy (T... args) T crbegin cpp/string/basic_string/rbegin (T... args) T crend cpp/string/basic_string/rend (T... args) T data cpp/string/basic_string/data (T... args) T empty cpp/string/basic_string/empty (T... args) T end cpp/string/basic_string/end (T... args) T erase cpp/string/basic_string/erase (T... args) T find cpp/string/basic_string/find (T... args) T find_first_not_of cpp/string/basic_string/find_first_not_of (T... args) T find_first_of cpp/string/basic_string/find_first_of (T... args) T find_last_not_of cpp/string/basic_string/find_last_not_of (T... args) T find_last_of cpp/string/basic_string/find_last_of (T... args) T front cpp/string/basic_string/front (T... args) T get_allocator cpp/string/basic_string/get_allocator (T... args) T insert cpp/string/basic_string/insert (T... args) T length cpp/string/basic_string/size (T... args) T max_size cpp/string/basic_string/max_size (T... args) T operator= cpp/string/basic_string/operator= (T... args) T operator[] cpp/string/basic_string/operator_at (T... args) T pop_back cpp/string/basic_string/pop_back (T... args) T push_back cpp/string/basic_string/push_back (T... args) T rbegin cpp/string/basic_string/rbegin (T... args) T rend cpp/string/basic_string/rend (T... args) T replace cpp/string/basic_string/replace (T... args) T reserve cpp/string/basic_string/reserve (T... args) T resize cpp/string/basic_string/resize (T... args) T rfind cpp/string/basic_string/rfind (T... args) T shrink_to_fit cpp/string/basic_string/shrink_to_fit (T... args) T size cpp/string/basic_string/size (T... args) T substr cpp/string/basic_string/substr (T... args) T swap cpp/string/basic_string/swap (T... args) T u16string cpp/string/basic_string/basic_string (T... args) std::u16string_view cpp/string/basic_string_view T at cpp/string/basic_string_view/at (T... args) T back cpp/string/basic_string_view/back (T... args) T begin cpp/string/basic_string_view/begin (T... args) T cbegin cpp/string/basic_string_view/begin (T... args) T cend cpp/string/basic_string_view/end (T... args) T compare cpp/string/basic_string_view/compare (T... args) T copy cpp/string/basic_string_view/copy (T... args) T crbegin cpp/string/basic_string_view/rbegin (T... args) T crend cpp/string/basic_string_view/rend (T... args) T data cpp/string/basic_string_view/data (T... args) T empty cpp/string/basic_string_view/empty (T... args) T end cpp/string/basic_string_view/end (T... args) T find cpp/string/basic_string_view/find (T... args) T find_first_not_of cpp/string/basic_string_view/find_first_not_of (T... args) T find_first_of cpp/string/basic_string_view/find_first_of (T... args) T find_last_not_of cpp/string/basic_string_view/find_last_not_of (T... args) T find_last_of cpp/string/basic_string_view/find_last_of (T... args) T front cpp/string/basic_string_view/front (T... args) T length cpp/string/basic_string_view/size (T... args) T max_size cpp/string/basic_string_view/max_size (T... args) T operator= cpp/string/basic_string_view/operator= (T... args) T operator[] cpp/string/basic_string_view/operator_at (T... args) T rbegin cpp/string/basic_string_view/rbegin (T... args) T remove_prefix cpp/string/basic_string_view/remove_prefix (T... args) T remove_suffix cpp/string/basic_string_view/remove_suffix (T... args) T rend cpp/string/basic_string_view/rend (T... args) T rfind cpp/string/basic_string_view/rfind (T... args) T size cpp/string/basic_string_view/size (T... args) T substr cpp/string/basic_string_view/substr (T... args) T swap cpp/string/basic_string_view/swap (T... args) T u16string_view cpp/string/basic_string_view/basic_string_view (T... args) std::u32streampos cpp/io/fpos T state cpp/io/fpos/state (T... args) std::u32string cpp/string/basic_string T append cpp/string/basic_string/append (T... args) T assign cpp/string/basic_string/assign (T... args) T at cpp/string/basic_string/at (T... args) T back cpp/string/basic_string/back (T... args) T begin cpp/string/basic_string/begin (T... args) T c_str cpp/string/basic_string/c_str (T... args) T capacity cpp/string/basic_string/capacity (T... args) T cbegin cpp/string/basic_string/begin (T... args) T cend cpp/string/basic_string/end (T... args) T clear cpp/string/basic_string/clear (T... args) T compare cpp/string/basic_string/compare (T... args) T copy cpp/string/basic_string/copy (T... args) T crbegin cpp/string/basic_string/rbegin (T... args) T crend cpp/string/basic_string/rend (T... args) T data cpp/string/basic_string/data (T... args) T empty cpp/string/basic_string/empty (T... args) T end cpp/string/basic_string/end (T... args) T erase cpp/string/basic_string/erase (T... args) T find cpp/string/basic_string/find (T... args) T find_first_not_of cpp/string/basic_string/find_first_not_of (T... args) T find_first_of cpp/string/basic_string/find_first_of (T... args) T find_last_not_of cpp/string/basic_string/find_last_not_of (T... args) T find_last_of cpp/string/basic_string/find_last_of (T... args) T front cpp/string/basic_string/front (T... args) T get_allocator cpp/string/basic_string/get_allocator (T... args) T insert cpp/string/basic_string/insert (T... args) T length cpp/string/basic_string/size (T... args) T max_size cpp/string/basic_string/max_size (T... args) T operator= cpp/string/basic_string/operator= (T... args) T operator[] cpp/string/basic_string/operator_at (T... args) T pop_back cpp/string/basic_string/pop_back (T... args) T push_back cpp/string/basic_string/push_back (T... args) T rbegin cpp/string/basic_string/rbegin (T... args) T rend cpp/string/basic_string/rend (T... args) T replace cpp/string/basic_string/replace (T... args) T reserve cpp/string/basic_string/reserve (T... args) T resize cpp/string/basic_string/resize (T... args) T rfind cpp/string/basic_string/rfind (T... args) T shrink_to_fit cpp/string/basic_string/shrink_to_fit (T... args) T size cpp/string/basic_string/size (T... args) T substr cpp/string/basic_string/substr (T... args) T swap cpp/string/basic_string/swap (T... args) T u32string cpp/string/basic_string/basic_string (T... args) std::u32string_view cpp/string/basic_string_view T at cpp/string/basic_string_view/at (T... args) T back cpp/string/basic_string_view/back (T... args) T begin cpp/string/basic_string_view/begin (T... args) T cbegin cpp/string/basic_string_view/begin (T... args) T cend cpp/string/basic_string_view/end (T... args) T compare cpp/string/basic_string_view/compare (T... args) T copy cpp/string/basic_string_view/copy (T... args) T crbegin cpp/string/basic_string_view/rbegin (T... args) T crend cpp/string/basic_string_view/rend (T... args) T data cpp/string/basic_string_view/data (T... args) T empty cpp/string/basic_string_view/empty (T... args) T end cpp/string/basic_string_view/end (T... args) T find cpp/string/basic_string_view/find (T... args) T find_first_not_of cpp/string/basic_string_view/find_first_not_of (T... args) T find_first_of cpp/string/basic_string_view/find_first_of (T... args) T find_last_not_of cpp/string/basic_string_view/find_last_not_of (T... args) T find_last_of cpp/string/basic_string_view/find_last_of (T... args) T front cpp/string/basic_string_view/front (T... args) T length cpp/string/basic_string_view/size (T... args) T max_size cpp/string/basic_string_view/max_size (T... args) T operator= cpp/string/basic_string_view/operator= (T... args) T operator[] cpp/string/basic_string_view/operator_at (T... args) T rbegin cpp/string/basic_string_view/rbegin (T... args) T remove_prefix cpp/string/basic_string_view/remove_prefix (T... args) T remove_suffix cpp/string/basic_string_view/remove_suffix (T... args) T rend cpp/string/basic_string_view/rend (T... args) T rfind cpp/string/basic_string_view/rfind (T... args) T size cpp/string/basic_string_view/size (T... args) T substr cpp/string/basic_string_view/substr (T... args) T swap cpp/string/basic_string_view/swap (T... args) T u32string_view cpp/string/basic_string_view/basic_string_view (T... args) std::uint16_t cpp/types/integer std::uint32_t cpp/types/integer std::uint64_t cpp/types/integer std::uint8_t cpp/types/integer std::uint_fast16_t cpp/types/integer std::uint_fast32_t cpp/types/integer std::uint_fast64_t cpp/types/integer std::uint_fast8_t cpp/types/integer std::uint_least16_t cpp/types/integer std::uint_least32_t cpp/types/integer std::uint_least64_t cpp/types/integer std::uint_least8_t cpp/types/integer std::uintmax_t cpp/types/integer std::uintptr_t cpp/types/integer std::unary_function cpp/utility/functional/unary_function std::unary_negate cpp/utility/functional/unary_negate T operator() cpp/utility/functional/unary_negate (T... args) T unary_negate cpp/utility/functional/unary_negate (T... args) std::underflow_error cpp/error/underflow_error T underflow_error cpp/error/underflow_error (T... args) T what cpp/error/exception/what (T... args) std::underlying_type cpp/types/underlying_type std::underlying_type_t cpp/types/underlying_type std::unexpected_handler cpp/error/unexpected_handler std::uniform_int_distribution cpp/numeric/random/uniform_int_distribution T a cpp/numeric/random/uniform_int_distribution/params (T... args) T b cpp/numeric/random/uniform_int_distribution/params (T... args) T max cpp/numeric/random/uniform_int_distribution/max (T... args) T min cpp/numeric/random/uniform_int_distribution/min (T... args) T operator() cpp/numeric/random/uniform_int_distribution/operator() (T... args) T param cpp/numeric/random/uniform_int_distribution/param (T... args) T reset cpp/numeric/random/uniform_int_distribution/reset (T... args) T uniform_int_distribution cpp/numeric/random/uniform_int_distribution/uniform_int_distribution (T... args) std::uniform_real_distribution cpp/numeric/random/uniform_real_distribution T a cpp/numeric/random/uniform_real_distribution/params (T... args) T b cpp/numeric/random/uniform_real_distribution/params (T... args) T max cpp/numeric/random/uniform_real_distribution/max (T... args) T min cpp/numeric/random/uniform_real_distribution/min (T... args) T param cpp/numeric/random/uniform_real_distribution/param (T... args) T reset cpp/numeric/random/uniform_real_distribution/reset (T... args) T uniform_real_distribution cpp/numeric/random/uniform_real_distribution/uniform_real_distribution (T... args) std::unique_lock cpp/thread/unique_lock T lock cpp/thread/unique_lock/lock (T... args) T mutex cpp/thread/unique_lock/mutex (T... args) T operator bool cpp/thread/unique_lock/operator_bool (T... args) T operator= cpp/thread/unique_lock/operator= (T... args) T owns_lock cpp/thread/unique_lock/owns_lock (T... args) T release cpp/thread/unique_lock/release (T... args) T swap cpp/thread/unique_lock/swap (T... args) T try_lock cpp/thread/unique_lock/try_lock (T... args) T try_lock_for cpp/thread/unique_lock/try_lock_for (T... args) T try_lock_until cpp/thread/unique_lock/try_lock_until (T... args) T unique_lock cpp/thread/unique_lock/unique_lock (T... args) T unlock cpp/thread/unique_lock/unlock (T... args) T ~unique_lock cpp/thread/unique_lock/~unique_lock (T... args) std::unique_ptr cpp/memory/unique_ptr T get cpp/memory/unique_ptr/get (T... args) T get_deleter cpp/memory/unique_ptr/get_deleter (T... args) T operator bool cpp/memory/unique_ptr/operator_bool (T... args) T operator* cpp/memory/unique_ptr/operator* (T... args) T operator-> cpp/memory/unique_ptr/operator* (T... args) T operator= cpp/memory/unique_ptr/operator= (T... args) T release cpp/memory/unique_ptr/release (T... args) T reset cpp/memory/unique_ptr/reset (T... args) T swap cpp/memory/unique_ptr/swap (T... args) T unique_ptr cpp/memory/unique_ptr/unique_ptr (T... args) T ~unique_ptr cpp/memory/unique_ptr/~unique_ptr (T... args) std::unordered_map cpp/container/unordered_map T at cpp/container/unordered_map/at (T... args) T begin cpp/container/unordered_map/begin (T... args) T begin(int) cpp/container/unordered_map/begin2 (T... args) T bucket cpp/container/unordered_map/bucket (T... args) T bucket_count cpp/container/unordered_map/bucket_count (T... args) T bucket_size cpp/container/unordered_map/bucket_size (T... args) T cbegin cpp/container/unordered_map/begin (T... args) T cbegin(int) cpp/container/unordered_map/begin2 (T... args) T cend cpp/container/unordered_map/end (T... args) T cend(int) cpp/container/unordered_map/end2 (T... args) T clear cpp/container/unordered_map/clear (T... args) T count cpp/container/unordered_map/count (T... args) T emplace cpp/container/unordered_map/emplace (T... args) T emplace_hint cpp/container/unordered_map/emplace_hint (T... args) T empty cpp/container/unordered_map/empty (T... args) T end cpp/container/unordered_map/end (T... args) T end(int) cpp/container/unordered_map/end2 (T... args) T equal_range cpp/container/unordered_map/equal_range (T... args) T erase cpp/container/unordered_map/erase (T... args) T extract cpp/container/unordered_map/extract (T... args) T find cpp/container/unordered_map/find (T... args) T get_allocator cpp/container/unordered_map/get_allocator (T... args) T hash_function cpp/container/unordered_map/hash_function (T... args) T insert cpp/container/unordered_map/insert (T... args) T insert_or_assign cpp/container/unordered_map/insert_or_assign (T... args) T key_eq cpp/container/unordered_map/key_eq (T... args) T load_factor cpp/container/unordered_map/load_factor (T... args) T max_bucket_count cpp/container/unordered_map/max_bucket_count (T... args) T max_load_factor cpp/container/unordered_map/max_load_factor (T... args) T max_size cpp/container/unordered_map/max_size (T... args) T merge cpp/container/unordered_map/merge (T... args) T operator= cpp/container/unordered_map/operator= (T... args) T operator[] cpp/container/unordered_map/operator_at (T... args) T rehash cpp/container/unordered_map/rehash (T... args) T reserve cpp/container/unordered_map/reserve (T... args) T size cpp/container/unordered_map/size (T... args) T swap cpp/container/unordered_map/swap (T... args) T try_emplace cpp/container/unordered_map/try_emplace (T... args) T unordered_map cpp/container/unordered_map/unordered_map (T... args) T ~unordered_map cpp/container/unordered_map/~unordered_map (T... args) std::unordered_multimap cpp/container/unordered_multimap T begin cpp/container/unordered_multimap/begin (T... args) T begin(int) cpp/container/unordered_multimap/begin2 (T... args) T bucket cpp/container/unordered_multimap/bucket (T... args) T bucket_count cpp/container/unordered_multimap/bucket_count (T... args) T bucket_size cpp/container/unordered_multimap/bucket_size (T... args) T cbegin cpp/container/unordered_multimap/begin (T... args) T cbegin(int) cpp/container/unordered_multimap/begin2 (T... args) T cend cpp/container/unordered_multimap/end (T... args) T cend(int) cpp/container/unordered_multimap/end2 (T... args) T clear cpp/container/unordered_multimap/clear (T... args) T count cpp/container/unordered_multimap/count (T... args) T emplace cpp/container/unordered_multimap/emplace (T... args) T emplace_hint cpp/container/unordered_multimap/emplace_hint (T... args) T empty cpp/container/unordered_multimap/empty (T... args) T end cpp/container/unordered_multimap/end (T... args) T end(int) cpp/container/unordered_multimap/end2 (T... args) T equal_range cpp/container/unordered_multimap/equal_range (T... args) T erase cpp/container/unordered_multimap/erase (T... args) T extract cpp/container/unordered_multimap/extract (T... args) T find cpp/container/unordered_multimap/find (T... args) T get_allocator cpp/container/unordered_multimap/get_allocator (T... args) T hash_function cpp/container/unordered_multimap/hash_function (T... args) T insert cpp/container/unordered_multimap/insert (T... args) T key_eq cpp/container/unordered_multimap/key_eq (T... args) T load_factor cpp/container/unordered_multimap/load_factor (T... args) T max_bucket_count cpp/container/unordered_multimap/max_bucket_count (T... args) T max_load_factor cpp/container/unordered_multimap/max_load_factor (T... args) T max_size cpp/container/unordered_multimap/max_size (T... args) T merge cpp/container/unordered_multimap/merge (T... args) T operator= cpp/container/unordered_multimap/operator= (T... args) T rehash cpp/container/unordered_multimap/rehash (T... args) T reserve cpp/container/unordered_multimap/reserve (T... args) T size cpp/container/unordered_multimap/size (T... args) T swap cpp/container/unordered_multimap/swap (T... args) T unordered_multimap cpp/container/unordered_multimap/unordered_multimap (T... args) T ~unordered_multimap cpp/container/unordered_multimap/~unordered_multimap (T... args) std::unordered_multiset cpp/container/unordered_multiset T begin cpp/container/unordered_multiset/begin (T... args) T begin(int) cpp/container/unordered_multiset/begin2 (T... args) T bucket cpp/container/unordered_multiset/bucket (T... args) T bucket_count cpp/container/unordered_multiset/bucket_count (T... args) T bucket_size cpp/container/unordered_multiset/bucket_size (T... args) T cbegin cpp/container/unordered_multiset/begin (T... args) T cbegin(int) cpp/container/unordered_multiset/begin2 (T... args) T cend cpp/container/unordered_multiset/end (T... args) T cend(int) cpp/container/unordered_multiset/end2 (T... args) T clear cpp/container/unordered_multiset/clear (T... args) T count cpp/container/unordered_multiset/count (T... args) T emplace cpp/container/unordered_multiset/emplace (T... args) T emplace_hint cpp/container/unordered_multiset/emplace_hint (T... args) T empty cpp/container/unordered_multiset/empty (T... args) T end cpp/container/unordered_multiset/end (T... args) T end(int) cpp/container/unordered_multiset/end2 (T... args) T equal_range cpp/container/unordered_multiset/equal_range (T... args) T erase cpp/container/unordered_multiset/erase (T... args) T extract cpp/container/unordered_multiset/extract (T... args) T find cpp/container/unordered_multiset/find (T... args) T get_allocator cpp/container/unordered_multiset/get_allocator (T... args) T hash_function cpp/container/unordered_multiset/hash_function (T... args) T insert cpp/container/unordered_multiset/insert (T... args) T key_eq cpp/container/unordered_multiset/key_eq (T... args) T load_factor cpp/container/unordered_multiset/load_factor (T... args) T max_bucket_count cpp/container/unordered_multiset/max_bucket_count (T... args) T max_load_factor cpp/container/unordered_multiset/max_load_factor (T... args) T max_size cpp/container/unordered_multiset/max_size (T... args) T merge cpp/container/unordered_multiset/merge (T... args) T operator= cpp/container/unordered_multiset/operator= (T... args) T rehash cpp/container/unordered_multiset/rehash (T... args) T reserve cpp/container/unordered_multiset/reserve (T... args) T size cpp/container/unordered_multiset/size (T... args) T swap cpp/container/unordered_multiset/swap (T... args) T unordered_multiset cpp/container/unordered_multiset/unordered_multiset (T... args) T ~unordered_multiset cpp/container/unordered_multiset/~unordered_multiset (T... args) std::unordered_set cpp/container/unordered_set T begin cpp/container/unordered_set/begin (T... args) T begin(int) cpp/container/unordered_set/begin2 (T... args) T bucket cpp/container/unordered_set/bucket (T... args) T bucket_count cpp/container/unordered_set/bucket_count (T... args) T bucket_size cpp/container/unordered_set/bucket_size (T... args) T cbegin cpp/container/unordered_set/begin (T... args) T cbegin(int) cpp/container/unordered_set/begin2 (T... args) T cend cpp/container/unordered_set/end (T... args) T cend(int) cpp/container/unordered_set/end2 (T... args) T clear cpp/container/unordered_set/clear (T... args) T count cpp/container/unordered_set/count (T... args) T emplace cpp/container/unordered_set/emplace (T... args) T emplace_hint cpp/container/unordered_set/emplace_hint (T... args) T empty cpp/container/unordered_set/empty (T... args) T end cpp/container/unordered_set/end (T... args) T end(int) cpp/container/unordered_set/end2 (T... args) T equal_range cpp/container/unordered_set/equal_range (T... args) T erase cpp/container/unordered_set/erase (T... args) T extract cpp/container/unordered_set/extract (T... args) T find cpp/container/unordered_set/find (T... args) T get_allocator cpp/container/unordered_set/get_allocator (T... args) T hash_function cpp/container/unordered_set/hash_function (T... args) T insert cpp/container/unordered_set/insert (T... args) T key_eq cpp/container/unordered_set/key_eq (T... args) T load_factor cpp/container/unordered_set/load_factor (T... args) T max_bucket_count cpp/container/unordered_set/max_bucket_count (T... args) T max_load_factor cpp/container/unordered_set/max_load_factor (T... args) T max_size cpp/container/unordered_set/max_size (T... args) T merge cpp/container/unordered_set/merge (T... args) T operator= cpp/container/unordered_set/operator= (T... args) T rehash cpp/container/unordered_set/rehash (T... args) T reserve cpp/container/unordered_set/reserve (T... args) T size cpp/container/unordered_set/size (T... args) T swap cpp/container/unordered_set/swap (T... args) T unordered_set cpp/container/unordered_set/unordered_set (T... args) T ~unordered_set cpp/container/unordered_set/~unordered_set (T... args) std::uses_allocator cpp/memory/uses_allocator std::valarray cpp/numeric/valarray std::variant cpp/utility/variant T emplace cpp/utility/variant/emplace (T... args) T index cpp/utility/variant/index (T... args) T operator= cpp/utility/variant/operator= (T... args) T swap cpp/utility/variant/swap (T... args) T valueless_by_exception cpp/utility/variant/valueless_by_exception (T... args) T variant cpp/utility/variant/variant (T... args) T ~variant cpp/utility/variant/~variant (T... args) std::variant_alternative cpp/utility/variant/variant_alternative std::variant_alternative_t cpp/utility/variant/variant_alternative std::variant_size cpp/utility/variant/variant_size std::vector cpp/container/vector T assign cpp/container/vector/assign (T... args) T at cpp/container/vector/at (T... args) T back cpp/container/vector/back (T... args) T begin cpp/container/vector/begin (T... args) T capacity cpp/container/vector/capacity (T... args) T cbegin cpp/container/vector/begin (T... args) T cend cpp/container/vector/end (T... args) T clear cpp/container/vector/clear (T... args) T crbegin cpp/container/vector/rbegin (T... args) T crend cpp/container/vector/rend (T... args) T data cpp/container/vector/data (T... args) T emplace cpp/container/vector/emplace (T... args) T emplace_back cpp/container/vector/emplace_back (T... args) T empty cpp/container/vector/empty (T... args) T end cpp/container/vector/end (T... args) T erase cpp/container/vector/erase (T... args) T front cpp/container/vector/front (T... args) T get_allocator cpp/container/vector/get_allocator (T... args) T insert cpp/container/vector/insert (T... args) T max_size cpp/container/vector/max_size (T... args) T operator= cpp/container/vector/operator= (T... args) T operator[] cpp/container/vector/operator_at (T... args) T pop_back cpp/container/vector/pop_back (T... args) T push_back cpp/container/vector/push_back (T... args) T rbegin cpp/container/vector/rbegin (T... args) T rend cpp/container/vector/rend (T... args) T reserve cpp/container/vector/reserve (T... args) T resize cpp/container/vector/resize (T... args) T shrink_to_fit cpp/container/vector/shrink_to_fit (T... args) T size cpp/container/vector/size (T... args) T swap cpp/container/vector/swap (T... args) T vector cpp/container/vector/vector (T... args) T ~vector cpp/container/vector/~vector (T... args) std::void_t cpp/types/void_t std::wbuffer_convert cpp/locale/wbuffer_convert T rdbuf cpp/locale/wbuffer_convert/rdbuf (T... args) T state cpp/locale/wbuffer_convert/state (T... args) T wbuffer_convert cpp/locale/wbuffer_convert/wbuffer_convert (T... args) T ~wbuffer_convert cpp/locale/wbuffer_convert/~wbuffer_convert (T... args) std::wcerr cpp/io/cerr std::wcin cpp/io/cin std::wclog cpp/io/clog std::wcmatch cpp/regex/match_results T begin cpp/regex/match_results/begin (T... args) T cbegin cpp/regex/match_results/begin (T... args) T cend cpp/regex/match_results/end (T... args) T empty cpp/regex/match_results/empty (T... args) T end cpp/regex/match_results/end (T... args) T format cpp/regex/match_results/format (T... args) T get_allocator cpp/regex/match_results/get_allocator (T... args) T length cpp/regex/match_results/length (T... args) T max_size cpp/regex/match_results/max_size (T... args) T operator[] cpp/regex/match_results/operator_at (T... args) T position cpp/regex/match_results/position (T... args) T prefix cpp/regex/match_results/prefix (T... args) T ready cpp/regex/match_results/ready (T... args) T size cpp/regex/match_results/size (T... args) T str cpp/regex/match_results/str (T... args) T suffix cpp/regex/match_results/suffix (T... args) T swap cpp/regex/match_results/swap (T... args) T wcmatch cpp/regex/match_results/match_results (T... args) T ~wcmatch cpp/regex/match_results/~match_results (T... args) std::wcout cpp/io/cout std::wcregex_iterator cpp/regex/regex_iterator T operator!= cpp/regex/regex_iterator/operator_cmp (T... args) T operator* cpp/regex/regex_iterator/operator* (T... args) T operator++ cpp/regex/regex_iterator/operator_arith (T... args) T operator++(int) cpp/regex/regex_iterator/operator_arith (T... args) T operator-> cpp/regex/regex_iterator/operator* (T... args) T operator= cpp/regex/regex_iterator/operator= (T... args) T operator== cpp/regex/regex_iterator/operator_cmp (T... args) T wcregex_iterator cpp/regex/regex_iterator/regex_iterator (T... args) std::wcregex_token_iterator cpp/regex/regex_token_iterator T operator!= cpp/regex/regex_token_iterator/operator_cmp (T... args) T operator* cpp/regex/regex_token_iterator/operator* (T... args) T operator++ cpp/regex/regex_token_iterator/operator_arith (T... args) T operator++(int) cpp/regex/regex_token_iterator/operator_arith (T... args) T operator-> cpp/regex/regex_token_iterator/operator* (T... args) T operator= cpp/regex/regex_token_iterator/operator= (T... args) T operator== cpp/regex/regex_token_iterator/operator_cmp (T... args) T wcregex_token_iterator cpp/regex/regex_token_iterator/regex_token_iterator (T... args) std::wcsub_match cpp/regex/sub_match T compare cpp/regex/sub_match/compare (T... args) T length cpp/regex/sub_match/length (T... args) T operator string_type cpp/regex/sub_match/str (T... args) T str cpp/regex/sub_match/str (T... args) T wcsub_match cpp/regex/sub_match/sub_match (T... args) std::weak_ptr cpp/memory/weak_ptr T expired cpp/memory/weak_ptr/expired (T... args) T lock cpp/memory/weak_ptr/lock (T... args) T operator= cpp/memory/weak_ptr/operator= (T... args) T owner_before cpp/memory/weak_ptr/owner_before (T... args) T reset cpp/memory/weak_ptr/reset (T... args) T swap cpp/memory/weak_ptr/swap (T... args) T use_count cpp/memory/weak_ptr/use_count (T... args) T weak_ptr cpp/memory/weak_ptr/weak_ptr (T... args) T ~weak_ptr cpp/memory/weak_ptr/~weak_ptr (T... args) std::weibull_distribution cpp/numeric/random/weibull_distribution T a cpp/numeric/random/weibull_distribution/params (T... args) T b cpp/numeric/random/weibull_distribution/params (T... args) T max cpp/numeric/random/weibull_distribution/max (T... args) T min cpp/numeric/random/weibull_distribution/min (T... args) T operator() cpp/numeric/random/weibull_distribution/operator() (T... args) T param cpp/numeric/random/weibull_distribution/param (T... args) T reset cpp/numeric/random/weibull_distribution/reset (T... args) T weibull_distribution cpp/numeric/random/weibull_distribution/weibull_distribution (T... args) std::wfilebuf cpp/io/basic_filebuf T close cpp/io/basic_filebuf/close (T... args) T eback cpp/io/basic_streambuf/gptr (T... args) T egptr cpp/io/basic_streambuf/gptr (T... args) T epptr cpp/io/basic_streambuf/pptr (T... args) T gbump cpp/io/basic_streambuf/gbump (T... args) T getloc cpp/io/basic_streambuf/getloc (T... args) T gptr cpp/io/basic_streambuf/gptr (T... args) T imbue cpp/io/basic_streambuf/pubimbue (T... args) T in_avail cpp/io/basic_streambuf/in_avail (T... args) T is_open cpp/io/basic_filebuf/is_open (T... args) T open cpp/io/basic_filebuf/open (T... args) T operator= cpp/io/basic_filebuf/operator= (T... args) T overflow cpp/io/basic_streambuf/overflow (T... args) T pbackfail cpp/io/basic_streambuf/pbackfail (T... args) T pbase cpp/io/basic_streambuf/pptr (T... args) T pbump cpp/io/basic_streambuf/pbump (T... args) T pptr cpp/io/basic_streambuf/pptr (T... args) T pubimbue cpp/io/basic_streambuf/pubimbue (T... args) T pubseekoff cpp/io/basic_streambuf/pubseekoff (T... args) T pubseekpos cpp/io/basic_streambuf/pubseekpos (T... args) T pubsetbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T pubsync cpp/io/basic_streambuf/pubsync (T... args) T sbumpc cpp/io/basic_streambuf/sbumpc (T... args) T seekoff cpp/io/basic_streambuf/pubseekoff (T... args) T seekpos cpp/io/basic_streambuf/pubseekpos (T... args) T setbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T setg cpp/io/basic_streambuf/setg (T... args) T setp cpp/io/basic_streambuf/setp (T... args) T sgetc cpp/io/basic_streambuf/sgetc (T... args) T sgetn cpp/io/basic_streambuf/sgetn (T... args) T showmanyc cpp/io/basic_streambuf/showmanyc (T... args) T snextc cpp/io/basic_streambuf/snextc (T... args) T sputbackc cpp/io/basic_streambuf/sputbackc (T... args) T sputc cpp/io/basic_streambuf/sputc (T... args) T sputn cpp/io/basic_streambuf/sputn (T... args) T sungetc cpp/io/basic_streambuf/sungetc (T... args) T swap cpp/io/basic_streambuf/swap (T... args) T sync cpp/io/basic_streambuf/pubsync (T... args) T uflow cpp/io/basic_streambuf/uflow (T... args) T underflow cpp/io/basic_streambuf/underflow (T... args) T wfilebuf cpp/io/basic_filebuf/basic_filebuf (T... args) T xsgetn cpp/io/basic_streambuf/sgetn (T... args) T xsputn cpp/io/basic_streambuf/sputn (T... args) T ~wfilebuf cpp/io/basic_filebuf/~basic_filebuf (T... args) std::wfstream cpp/io/basic_fstream std::wfstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T close cpp/io/basic_fstream/close (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::wfstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::wfstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T is_open cpp/io/basic_fstream/is_open (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T open cpp/io/basic_fstream/open (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator= cpp/io/basic_fstream/operator= (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::wfstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T wfstream cpp/io/basic_fstream/basic_fstream (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::wfstream::Init cpp/io/ios_base/Init std::wfstream::event_callback cpp/io/ios_base/event_callback std::wfstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::wfstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::wifstream cpp/io/basic_ifstream std::wifstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T close cpp/io/basic_ifstream/close (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::wifstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::wifstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T is_open cpp/io/basic_ifstream/is_open (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T open cpp/io/basic_ifstream/open (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator= cpp/io/basic_ifstream/operator= (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) std::wifstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T wifstream cpp/io/basic_ifstream/basic_ifstream (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::wifstream::Init cpp/io/ios_base/Init std::wifstream::event_callback cpp/io/ios_base/event_callback std::wifstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::wifstream::sentry cpp/io/basic_istream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::wiostream cpp/io/basic_iostream std::wiostream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::wiostream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::wiostream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::wiostream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T wiostream cpp/io/basic_iostream/basic_iostream (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~wiostream cpp/io/basic_iostream/~basic_iostream (T... args) std::wiostream::Init cpp/io/ios_base/Init std::wiostream::event_callback cpp/io/ios_base/event_callback std::wiostream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::wiostream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::wistream cpp/io/basic_istream std::wistream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::wistream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::wistream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) std::wistream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T wistream cpp/io/basic_istream/basic_istream (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~wistream cpp/io/basic_istream/~basic_istream (T... args) std::wistream::Init cpp/io/ios_base/Init std::wistream::event_callback cpp/io/ios_base/event_callback std::wistream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::wistream::sentry cpp/io/basic_istream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::wistringstream cpp/io/basic_istringstream std::wistringstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::wistringstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::wistringstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator= cpp/io/basic_istringstream/operator= (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) std::wistringstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T str cpp/io/basic_istringstream/str (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T wistringstream cpp/io/basic_istringstream/basic_istringstream (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::wistringstream::Init cpp/io/ios_base/Init std::wistringstream::event_callback cpp/io/ios_base/event_callback std::wistringstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::wistringstream::sentry cpp/io/basic_istream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::wofstream cpp/io/basic_ofstream std::wofstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T close cpp/io/basic_ofstream/close (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::wofstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::wofstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T is_open cpp/io/basic_ofstream/is_open (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T open cpp/io/basic_ofstream/open (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator= cpp/io/basic_ofstream/operator= (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::wofstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T wofstream cpp/io/basic_ofstream/basic_ofstream (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::wofstream::Init cpp/io/ios_base/Init std::wofstream::event_callback cpp/io/ios_base/event_callback std::wofstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::wofstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_ostream/sentry (T... args) T sentry cpp/io/basic_ostream/sentry (T... args) T ~sentry cpp/io/basic_ostream/sentry (T... args) std::wostream cpp/io/basic_ostream std::wostream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::wostream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::wostream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::wostream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T wostream cpp/io/basic_ostream/basic_ostream (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) T ~wostream cpp/io/basic_ostream/~basic_ostream (T... args) std::wostream::Init cpp/io/ios_base/Init std::wostream::event_callback cpp/io/ios_base/event_callback std::wostream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::wostream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_ostream/sentry (T... args) T sentry cpp/io/basic_ostream/sentry (T... args) T ~sentry cpp/io/basic_ostream/sentry (T... args) std::wostringstream cpp/io/basic_ostringstream std::wostringstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::wostringstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::wostringstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator= cpp/io/basic_ostringstream/operator= (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::wostringstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T str cpp/io/basic_ostringstream/str (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T wostringstream cpp/io/basic_ostringstream/basic_ostringstream (T... args) T write cpp/io/basic_ostream/write (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::wostringstream::Init cpp/io/ios_base/Init std::wostringstream::event_callback cpp/io/ios_base/event_callback std::wostringstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::wostringstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_ostream/sentry (T... args) T sentry cpp/io/basic_ostream/sentry (T... args) T ~sentry cpp/io/basic_ostream/sentry (T... args) std::wregex cpp/regex/basic_regex T assign cpp/regex/basic_regex/assign (T... args) T flags cpp/regex/basic_regex/flags (T... args) T getloc cpp/regex/basic_regex/getloc (T... args) T imbue cpp/regex/basic_regex/imbue (T... args) T mark_count cpp/regex/basic_regex/mark_count (T... args) T operator= cpp/regex/basic_regex/operator= (T... args) T swap cpp/regex/basic_regex/swap (T... args) T wregex cpp/regex/basic_regex/basic_regex (T... args) T ~wregex cpp/regex/basic_regex/~basic_regex (T... args) std::wsmatch cpp/regex/match_results T begin cpp/regex/match_results/begin (T... args) T cbegin cpp/regex/match_results/begin (T... args) T cend cpp/regex/match_results/end (T... args) T empty cpp/regex/match_results/empty (T... args) T end cpp/regex/match_results/end (T... args) T format cpp/regex/match_results/format (T... args) T get_allocator cpp/regex/match_results/get_allocator (T... args) T length cpp/regex/match_results/length (T... args) T max_size cpp/regex/match_results/max_size (T... args) T operator[] cpp/regex/match_results/operator_at (T... args) T position cpp/regex/match_results/position (T... args) T prefix cpp/regex/match_results/prefix (T... args) T ready cpp/regex/match_results/ready (T... args) T size cpp/regex/match_results/size (T... args) T str cpp/regex/match_results/str (T... args) T suffix cpp/regex/match_results/suffix (T... args) T swap cpp/regex/match_results/swap (T... args) T wsmatch cpp/regex/match_results/match_results (T... args) T ~wsmatch cpp/regex/match_results/~match_results (T... args) std::wsregex_iterator cpp/regex/regex_iterator T operator!= cpp/regex/regex_iterator/operator_cmp (T... args) T operator* cpp/regex/regex_iterator/operator* (T... args) T operator++ cpp/regex/regex_iterator/operator_arith (T... args) T operator++(int) cpp/regex/regex_iterator/operator_arith (T... args) T operator-> cpp/regex/regex_iterator/operator* (T... args) T operator= cpp/regex/regex_iterator/operator= (T... args) T operator== cpp/regex/regex_iterator/operator_cmp (T... args) T wsregex_iterator cpp/regex/regex_iterator/regex_iterator (T... args) std::wsregex_token_iterator cpp/regex/regex_token_iterator T operator!= cpp/regex/regex_token_iterator/operator_cmp (T... args) T operator* cpp/regex/regex_token_iterator/operator* (T... args) T operator++ cpp/regex/regex_token_iterator/operator_arith (T... args) T operator++(int) cpp/regex/regex_token_iterator/operator_arith (T... args) T operator-> cpp/regex/regex_token_iterator/operator* (T... args) T operator= cpp/regex/regex_token_iterator/operator= (T... args) T operator== cpp/regex/regex_token_iterator/operator_cmp (T... args) T wsregex_token_iterator cpp/regex/regex_token_iterator/regex_token_iterator (T... args) std::wssub_match cpp/regex/sub_match T compare cpp/regex/sub_match/compare (T... args) T length cpp/regex/sub_match/length (T... args) T operator string_type cpp/regex/sub_match/str (T... args) T str cpp/regex/sub_match/str (T... args) T wssub_match cpp/regex/sub_match/sub_match (T... args) std::wstreambuf cpp/io/basic_streambuf T eback cpp/io/basic_streambuf/gptr (T... args) T egptr cpp/io/basic_streambuf/gptr (T... args) T epptr cpp/io/basic_streambuf/pptr (T... args) T gbump cpp/io/basic_streambuf/gbump (T... args) T getloc cpp/io/basic_streambuf/getloc (T... args) T gptr cpp/io/basic_streambuf/gptr (T... args) T imbue cpp/io/basic_streambuf/pubimbue (T... args) T in_avail cpp/io/basic_streambuf/in_avail (T... args) T operator= cpp/io/basic_streambuf/operator= (T... args) T overflow cpp/io/basic_streambuf/overflow (T... args) T pbackfail cpp/io/basic_streambuf/pbackfail (T... args) T pbase cpp/io/basic_streambuf/pptr (T... args) T pbump cpp/io/basic_streambuf/pbump (T... args) T pptr cpp/io/basic_streambuf/pptr (T... args) T pubimbue cpp/io/basic_streambuf/pubimbue (T... args) T pubseekoff cpp/io/basic_streambuf/pubseekoff (T... args) T pubseekpos cpp/io/basic_streambuf/pubseekpos (T... args) T pubsetbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T pubsync cpp/io/basic_streambuf/pubsync (T... args) T sbumpc cpp/io/basic_streambuf/sbumpc (T... args) T seekoff cpp/io/basic_streambuf/pubseekoff (T... args) T seekpos cpp/io/basic_streambuf/pubseekpos (T... args) T setbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T setg cpp/io/basic_streambuf/setg (T... args) T setp cpp/io/basic_streambuf/setp (T... args) T sgetc cpp/io/basic_streambuf/sgetc (T... args) T sgetn cpp/io/basic_streambuf/sgetn (T... args) T showmanyc cpp/io/basic_streambuf/showmanyc (T... args) T snextc cpp/io/basic_streambuf/snextc (T... args) T sputbackc cpp/io/basic_streambuf/sputbackc (T... args) T sputc cpp/io/basic_streambuf/sputc (T... args) T sputn cpp/io/basic_streambuf/sputn (T... args) T sungetc cpp/io/basic_streambuf/sungetc (T... args) T swap cpp/io/basic_streambuf/swap (T... args) T sync cpp/io/basic_streambuf/pubsync (T... args) T uflow cpp/io/basic_streambuf/uflow (T... args) T underflow cpp/io/basic_streambuf/underflow (T... args) T wstreambuf cpp/io/basic_streambuf/basic_streambuf (T... args) T xsgetn cpp/io/basic_streambuf/sgetn (T... args) T xsputn cpp/io/basic_streambuf/sputn (T... args) T ~wstreambuf cpp/io/basic_streambuf/~basic_streambuf (T... args) std::wstreampos cpp/io/fpos T state cpp/io/fpos/state (T... args) std::wstring cpp/string/basic_string T append cpp/string/basic_string/append (T... args) T assign cpp/string/basic_string/assign (T... args) T at cpp/string/basic_string/at (T... args) T back cpp/string/basic_string/back (T... args) T begin cpp/string/basic_string/begin (T... args) T c_str cpp/string/basic_string/c_str (T... args) T capacity cpp/string/basic_string/capacity (T... args) T cbegin cpp/string/basic_string/begin (T... args) T cend cpp/string/basic_string/end (T... args) T clear cpp/string/basic_string/clear (T... args) T compare cpp/string/basic_string/compare (T... args) T copy cpp/string/basic_string/copy (T... args) T crbegin cpp/string/basic_string/rbegin (T... args) T crend cpp/string/basic_string/rend (T... args) T data cpp/string/basic_string/data (T... args) T empty cpp/string/basic_string/empty (T... args) T end cpp/string/basic_string/end (T... args) T erase cpp/string/basic_string/erase (T... args) T find cpp/string/basic_string/find (T... args) T find_first_not_of cpp/string/basic_string/find_first_not_of (T... args) T find_first_of cpp/string/basic_string/find_first_of (T... args) T find_last_not_of cpp/string/basic_string/find_last_not_of (T... args) T find_last_of cpp/string/basic_string/find_last_of (T... args) T front cpp/string/basic_string/front (T... args) T get_allocator cpp/string/basic_string/get_allocator (T... args) T insert cpp/string/basic_string/insert (T... args) T length cpp/string/basic_string/size (T... args) T max_size cpp/string/basic_string/max_size (T... args) T operator= cpp/string/basic_string/operator= (T... args) T operator[] cpp/string/basic_string/operator_at (T... args) T pop_back cpp/string/basic_string/pop_back (T... args) T push_back cpp/string/basic_string/push_back (T... args) T rbegin cpp/string/basic_string/rbegin (T... args) T rend cpp/string/basic_string/rend (T... args) T replace cpp/string/basic_string/replace (T... args) T reserve cpp/string/basic_string/reserve (T... args) T resize cpp/string/basic_string/resize (T... args) T rfind cpp/string/basic_string/rfind (T... args) T shrink_to_fit cpp/string/basic_string/shrink_to_fit (T... args) T size cpp/string/basic_string/size (T... args) T substr cpp/string/basic_string/substr (T... args) T swap cpp/string/basic_string/swap (T... args) T wstring cpp/string/basic_string/basic_string (T... args) std::wstring_convert cpp/locale/wstring_convert T converted cpp/locale/wstring_convert/converted (T... args) T from_bytes cpp/locale/wstring_convert/from_bytes (T... args) T state cpp/locale/wstring_convert/state (T... args) T to_bytes cpp/locale/wstring_convert/to_bytes (T... args) T wstring_convert cpp/locale/wstring_convert/wstring_convert (T... args) T ~wstring_convert cpp/locale/wstring_convert/~wstring_convert (T... args) std::wstring_view cpp/string/basic_string_view T at cpp/string/basic_string_view/at (T... args) T back cpp/string/basic_string_view/back (T... args) T begin cpp/string/basic_string_view/begin (T... args) T cbegin cpp/string/basic_string_view/begin (T... args) T cend cpp/string/basic_string_view/end (T... args) T compare cpp/string/basic_string_view/compare (T... args) T copy cpp/string/basic_string_view/copy (T... args) T crbegin cpp/string/basic_string_view/rbegin (T... args) T crend cpp/string/basic_string_view/rend (T... args) T data cpp/string/basic_string_view/data (T... args) T empty cpp/string/basic_string_view/empty (T... args) T end cpp/string/basic_string_view/end (T... args) T find cpp/string/basic_string_view/find (T... args) T find_first_not_of cpp/string/basic_string_view/find_first_not_of (T... args) T find_first_of cpp/string/basic_string_view/find_first_of (T... args) T find_last_not_of cpp/string/basic_string_view/find_last_not_of (T... args) T find_last_of cpp/string/basic_string_view/find_last_of (T... args) T front cpp/string/basic_string_view/front (T... args) T length cpp/string/basic_string_view/size (T... args) T max_size cpp/string/basic_string_view/max_size (T... args) T operator= cpp/string/basic_string_view/operator= (T... args) T operator[] cpp/string/basic_string_view/operator_at (T... args) T rbegin cpp/string/basic_string_view/rbegin (T... args) T remove_prefix cpp/string/basic_string_view/remove_prefix (T... args) T remove_suffix cpp/string/basic_string_view/remove_suffix (T... args) T rend cpp/string/basic_string_view/rend (T... args) T rfind cpp/string/basic_string_view/rfind (T... args) T size cpp/string/basic_string_view/size (T... args) T substr cpp/string/basic_string_view/substr (T... args) T swap cpp/string/basic_string_view/swap (T... args) T wstring_view cpp/string/basic_string_view/basic_string_view (T... args) std::wstringbuf cpp/io/basic_stringbuf T eback cpp/io/basic_streambuf/gptr (T... args) T egptr cpp/io/basic_streambuf/gptr (T... args) T epptr cpp/io/basic_streambuf/pptr (T... args) T gbump cpp/io/basic_streambuf/gbump (T... args) T getloc cpp/io/basic_streambuf/getloc (T... args) T gptr cpp/io/basic_streambuf/gptr (T... args) T imbue cpp/io/basic_streambuf/pubimbue (T... args) T in_avail cpp/io/basic_streambuf/in_avail (T... args) T operator= cpp/io/basic_stringbuf/operator= (T... args) T overflow cpp/io/basic_streambuf/overflow (T... args) T pbackfail cpp/io/basic_streambuf/pbackfail (T... args) T pbase cpp/io/basic_streambuf/pptr (T... args) T pbump cpp/io/basic_streambuf/pbump (T... args) T pptr cpp/io/basic_streambuf/pptr (T... args) T pubimbue cpp/io/basic_streambuf/pubimbue (T... args) T pubseekoff cpp/io/basic_streambuf/pubseekoff (T... args) T pubseekpos cpp/io/basic_streambuf/pubseekpos (T... args) T pubsetbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T pubsync cpp/io/basic_streambuf/pubsync (T... args) T sbumpc cpp/io/basic_streambuf/sbumpc (T... args) T seekoff cpp/io/basic_streambuf/pubseekoff (T... args) T seekpos cpp/io/basic_streambuf/pubseekpos (T... args) T setbuf cpp/io/basic_streambuf/pubsetbuf (T... args) T setg cpp/io/basic_streambuf/setg (T... args) T setp cpp/io/basic_streambuf/setp (T... args) T sgetc cpp/io/basic_streambuf/sgetc (T... args) T sgetn cpp/io/basic_streambuf/sgetn (T... args) T showmanyc cpp/io/basic_streambuf/showmanyc (T... args) T snextc cpp/io/basic_streambuf/snextc (T... args) T sputbackc cpp/io/basic_streambuf/sputbackc (T... args) T sputc cpp/io/basic_streambuf/sputc (T... args) T sputn cpp/io/basic_streambuf/sputn (T... args) T str cpp/io/basic_stringbuf/str (T... args) T sungetc cpp/io/basic_streambuf/sungetc (T... args) T swap cpp/io/basic_streambuf/swap (T... args) T sync cpp/io/basic_streambuf/pubsync (T... args) T uflow cpp/io/basic_streambuf/uflow (T... args) T underflow cpp/io/basic_streambuf/underflow (T... args) T wstringbuf cpp/io/basic_stringbuf/basic_stringbuf (T... args) T xsgetn cpp/io/basic_streambuf/sgetn (T... args) T xsputn cpp/io/basic_streambuf/sputn (T... args) std::wstringstream cpp/io/basic_stringstream std::wstringstream::Init T bad cpp/io/basic_ios/bad (T... args) T clear cpp/io/basic_ios/clear (T... args) T copyfmt cpp/io/basic_ios/copyfmt (T... args) T eof cpp/io/basic_ios/eof (T... args) std::wstringstream::event_callback T exceptions cpp/io/basic_ios/exceptions (T... args) T fail cpp/io/basic_ios/fail (T... args) std::wstringstream::failure T fill cpp/io/basic_ios/fill (T... args) T flags cpp/io/ios_base/flags (T... args) T flush cpp/io/basic_ostream/flush (T... args) T gcount cpp/io/basic_istream/gcount (T... args) T get cpp/io/basic_istream/get (T... args) T getline cpp/io/basic_istream/getline (T... args) T getloc cpp/io/ios_base/getloc (T... args) T good cpp/io/basic_ios/good (T... args) T ignore cpp/io/basic_istream/ignore (T... args) T imbue cpp/io/basic_ios/imbue (T... args) T init cpp/io/basic_ios/init (T... args) T iword cpp/io/ios_base/iword (T... args) T move cpp/io/basic_ios/move (T... args) T narrow cpp/io/basic_ios/narrow (T... args) T operator bool cpp/io/basic_ios/operator_bool (T... args) T operator! cpp/io/basic_ios/operator! (T... args) T operator<< cpp/io/basic_ostream/operator_ltlt (T... args) T operator= cpp/io/basic_stringstream/operator= (T... args) T operator>> cpp/io/basic_istream/operator_gtgt (T... args) T peek cpp/io/basic_istream/peek (T... args) T precision cpp/io/ios_base/precision (T... args) T put cpp/io/basic_ostream/put (T... args) T putback cpp/io/basic_istream/putback (T... args) T pword cpp/io/ios_base/pword (T... args) T rdbuf cpp/io/basic_ios/rdbuf (T... args) T rdstate cpp/io/basic_ios/rdstate (T... args) T read cpp/io/basic_istream/read (T... args) T readsome cpp/io/basic_istream/readsome (T... args) T register_callback cpp/io/ios_base/register_callback (T... args) T seekg cpp/io/basic_istream/seekg (T... args) T seekp cpp/io/basic_ostream/seekp (T... args) std::wstringstream::sentry T set_rdbuf cpp/io/basic_ios/set_rdbuf (T... args) T setf cpp/io/ios_base/setf (T... args) T setstate cpp/io/basic_ios/setstate (T... args) T str cpp/io/basic_stringstream/str (T... args) T swap cpp/io/basic_ios/swap (T... args) T sync cpp/io/basic_istream/sync (T... args) T sync_with_stdio cpp/io/ios_base/sync_with_stdio (T... args) T tellg cpp/io/basic_istream/tellg (T... args) T tellp cpp/io/basic_ostream/tellp (T... args) T tie cpp/io/basic_ios/tie (T... args) T unget cpp/io/basic_istream/unget (T... args) T unsetf cpp/io/ios_base/unsetf (T... args) T widen cpp/io/basic_ios/widen (T... args) T width cpp/io/ios_base/width (T... args) T write cpp/io/basic_ostream/write (T... args) T wstringstream cpp/io/basic_stringstream/basic_stringstream (T... args) T xalloc cpp/io/ios_base/xalloc (T... args) std::wstringstream::Init cpp/io/ios_base/Init std::wstringstream::event_callback cpp/io/ios_base/event_callback std::wstringstream::failure cpp/io/ios_base/failure T failure cpp/io/ios_base/failure (T... args) T what cpp/error/exception/what (T... args) std::wstringstream::sentry cpp/io/basic_ostream/sentry T operator bool cpp/io/basic_istream/sentry (T... args) T sentry cpp/io/basic_istream/sentry (T... args) T ~sentry cpp/io/basic_istream/sentry (T... args) std::yocto cpp/numeric/ratio/ratio std::yotta cpp/numeric/ratio/ratio std::zetta cpp/numeric/ratio/ratio va_list cpp/utility/variadic/va_list ================================================ FILE: docs/config/custom.css ================================================ /** Distributed under the MIT License. See LICENSE.txt for details. */ html { /* This width must correspond to Doxygen's `TREEVIEW_WIDTH` */ --side-nav-fixed-width: 280px; } #nav-sync { display: none; } ================================================ FILE: docs/config/doxygen-awesome-fragment-copy-button.js ================================================ /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css MIT License Copyright (c) 2022 - 2023 jothepro Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ class DoxygenAwesomeFragmentCopyButton extends HTMLElement { constructor() { super(); this.onclick=this.copyContent } static title = "Copy to clipboard" static copyIcon = `` static successIcon = `` static successDuration = 980 static init() { $(function() { $(document).ready(function() { if(navigator.clipboard) { const fragments = document.getElementsByClassName("fragment") for(const fragment of fragments) { const fragmentWrapper = document.createElement("div") fragmentWrapper.className = "doxygen-awesome-fragment-wrapper" const fragmentCopyButton = document.createElement("doxygen-awesome-fragment-copy-button") fragmentCopyButton.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon fragmentCopyButton.title = DoxygenAwesomeFragmentCopyButton.title fragment.parentNode.replaceChild(fragmentWrapper, fragment) fragmentWrapper.appendChild(fragment) fragmentWrapper.appendChild(fragmentCopyButton) } } }) }) } copyContent() { const content = this.previousSibling.cloneNode(true) // filter out line number from file listings content.querySelectorAll(".lineno, .ttc").forEach((node) => { node.remove() }) let textContent = content.textContent // remove trailing newlines that appear in file listings let numberOfTrailingNewlines = 0 while(textContent.charAt(textContent.length - (numberOfTrailingNewlines + 1)) == '\n') { numberOfTrailingNewlines++; } textContent = textContent.substring(0, textContent.length - numberOfTrailingNewlines) navigator.clipboard.writeText(textContent); this.classList.add("success") this.innerHTML = DoxygenAwesomeFragmentCopyButton.successIcon window.setTimeout(() => { this.classList.remove("success") this.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon }, DoxygenAwesomeFragmentCopyButton.successDuration); } } customElements.define("doxygen-awesome-fragment-copy-button", DoxygenAwesomeFragmentCopyButton) ================================================ FILE: docs/config/doxygen-awesome-interactive-toc.js ================================================ /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css MIT License Copyright (c) 2022 - 2023 jothepro Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ class DoxygenAwesomeInteractiveToc { static topOffset = 38 static hideMobileMenu = true static headers = [] static init() { window.addEventListener("load", () => { let toc = document.querySelector(".contents > .toc") if(toc) { toc.classList.add("interactive") if(!DoxygenAwesomeInteractiveToc.hideMobileMenu) { toc.classList.add("open") } document.querySelector(".contents > .toc > h3")?.addEventListener("click", () => { if(toc.classList.contains("open")) { toc.classList.remove("open") } else { toc.classList.add("open") } }) document.querySelectorAll(".contents > .toc > ul a").forEach((node) => { let id = node.getAttribute("href").substring(1) DoxygenAwesomeInteractiveToc.headers.push({ node: node, headerNode: document.getElementById(id) }) document.getElementById("doc-content")?.addEventListener("scroll",this.throttle(DoxygenAwesomeInteractiveToc.update, 100)) }) DoxygenAwesomeInteractiveToc.update() } }) } static update() { let active = DoxygenAwesomeInteractiveToc.headers[0]?.node DoxygenAwesomeInteractiveToc.headers.forEach((header) => { let position = header.headerNode.getBoundingClientRect().top header.node.classList.remove("active") header.node.classList.remove("aboveActive") if(position < DoxygenAwesomeInteractiveToc.topOffset) { active = header.node active?.classList.add("aboveActive") } }) active?.classList.add("active") active?.classList.remove("aboveActive") } static throttle(func, delay) { let lastCall = 0; return function (...args) { const now = new Date().getTime(); if (now - lastCall < delay) { return; } lastCall = now; return setTimeout(() => {func(...args)}, delay); }; } } ================================================ FILE: docs/config/doxygen-awesome-paragraph-link.js ================================================ /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css MIT License Copyright (c) 2022 - 2023 jothepro Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ class DoxygenAwesomeParagraphLink { // Icon from https://fonts.google.com/icons // Licensed under the Apache 2.0 license: // https://www.apache.org/licenses/LICENSE-2.0.html static icon = `` static title = "Permanent Link" static init() { $(function() { $(document).ready(function() { document.querySelectorAll(".contents a.anchor[id], .contents .groupheader > a[id]").forEach((node) => { let anchorlink = document.createElement("a") anchorlink.setAttribute("href", `#${node.getAttribute("id")}`) anchorlink.setAttribute("title", DoxygenAwesomeParagraphLink.title) anchorlink.classList.add("anchorlink") node.classList.add("anchor") anchorlink.innerHTML = DoxygenAwesomeParagraphLink.icon node.parentElement.appendChild(anchorlink) }) }) }) } } ================================================ FILE: docs/config/doxygen-awesome-sidebar-only.css ================================================ /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css MIT License Copyright (c) 2021 - 2023 jothepro Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ html { /* side nav width. MUST be = `TREEVIEW_WIDTH`. * Make sure it is wide enough to contain the page title (logo + title + version) */ --side-nav-fixed-width: 335px; --menu-display: none; --top-height: 120px; --toc-sticky-top: -25px; --toc-max-height: calc(100vh - 2 * var(--spacing-medium) - 25px); } #projectname { white-space: nowrap; } @media screen and (min-width: 768px) { html { --searchbar-background: var(--page-background-color); } #side-nav { min-width: var(--side-nav-fixed-width); max-width: var(--side-nav-fixed-width); top: var(--top-height); overflow: visible; } #nav-tree, #side-nav { height: calc(100vh - var(--top-height)) !important; } #nav-tree { padding: 0; } #top { display: block; border-bottom: none; height: var(--top-height); margin-bottom: calc(0px - var(--top-height)); max-width: var(--side-nav-fixed-width); overflow: hidden; background: var(--side-nav-background); } #main-nav { float: left; padding-right: 0; } .ui-resizable-handle { cursor: default; width: 1px !important; background: var(--separator-color); box-shadow: 0 calc(-2 * var(--top-height)) 0 0 var(--separator-color); } #nav-path { position: fixed; right: 0; left: var(--side-nav-fixed-width); bottom: 0; width: auto; } #doc-content { height: calc(100vh - 31px) !important; padding-bottom: calc(3 * var(--spacing-large)); padding-top: calc(var(--top-height) - 80px); box-sizing: border-box; margin-left: var(--side-nav-fixed-width) !important; } #MSearchBox { width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium))); } #MSearchField { width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - 65px); } #MSearchResultsWindow { left: var(--spacing-medium) !important; right: auto; } } ================================================ FILE: docs/config/doxygen-awesome.css ================================================ /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css MIT License Copyright (c) 2021 - 2023 jothepro Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ html { /* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */ --primary-color: #1779c4; --primary-dark-color: #335c80; --primary-light-color: #70b1e9; /* page base colors */ --page-background-color: #ffffff; --page-foreground-color: #2f4153; --page-secondary-foreground-color: #6f7e8e; /* color for all separators on the website: hr, borders, ... */ --separator-color: #dedede; /* border radius for all rounded components. Will affect many components, like dropdowns, memitems, codeblocks, ... */ --border-radius-large: 8px; --border-radius-small: 4px; --border-radius-medium: 6px; /* default spacings. Most components reference these values for spacing, to provide uniform spacing on the page. */ --spacing-small: 5px; --spacing-medium: 10px; --spacing-large: 16px; /* default box shadow used for raising an element above the normal content. Used in dropdowns, search result, ... */ --box-shadow: 0 2px 8px 0 rgba(0,0,0,.075); --odd-color: rgba(0,0,0,.028); /* font-families. will affect all text on the website * font-family: the normal font for text, headlines, menus * font-family-monospace: used for preformatted text in memtitle, code, fragments */ --font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif; --font-family-monospace: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace; /* font sizes */ --page-font-size: 15.6px; --navigation-font-size: 14.4px; --toc-font-size: 13.4px; --code-font-size: 14px; /* affects code, fragment */ --title-font-size: 22px; /* content text properties. These only affect the page content, not the navigation or any other ui elements */ --content-line-height: 27px; /* The content is centered and constraint in it's width. To make the content fill the whole page, set the variable to auto.*/ --content-maxwidth: 1050px; --table-line-height: 24px; --toc-sticky-top: var(--spacing-medium); --toc-width: 200px; --toc-max-height: calc(100vh - 2 * var(--spacing-medium) - 85px); /* colors for various content boxes: @warning, @note, @deprecated @bug */ --warning-color: #faf3d8; --warning-color-dark: #f3a600; --warning-color-darker: #5f4204; --note-color: #e4f3ff; --note-color-dark: #1879C4; --note-color-darker: #274a5c; --todo-color: #e4dafd; --todo-color-dark: #5b2bdd; --todo-color-darker: #2a0d72; --deprecated-color: #ecf0f3; --deprecated-color-dark: #5b6269; --deprecated-color-darker: #43454a; --bug-color: #f8d1cc; --bug-color-dark: #b61825; --bug-color-darker: #75070f; --invariant-color: #d8f1e3; --invariant-color-dark: #44b86f; --invariant-color-darker: #265532; /* blockquote colors */ --blockquote-background: #f8f9fa; --blockquote-foreground: #636568; /* table colors */ --tablehead-background: #f1f1f1; --tablehead-foreground: var(--page-foreground-color); /* menu-display: block | none * Visibility of the top navigation on screens >= 768px. On smaller screen the menu is always visible. * `GENERATE_TREEVIEW` MUST be enabled! */ --menu-display: block; --menu-focus-foreground: var(--page-background-color); --menu-focus-background: var(--primary-color); --menu-selected-background: rgba(0,0,0,.05); --header-background: var(--page-background-color); --header-foreground: var(--page-foreground-color); /* searchbar colors */ --searchbar-background: var(--side-nav-background); --searchbar-foreground: var(--page-foreground-color); /* searchbar size * (`searchbar-width` is only applied on screens >= 768px. * on smaller screens the searchbar will always fill the entire screen width) */ --searchbar-height: 33px; --searchbar-width: 210px; --searchbar-border-radius: var(--searchbar-height); /* code block colors */ --code-background: #f5f5f5; --code-foreground: var(--page-foreground-color); /* fragment colors */ --fragment-background: #F8F9FA; --fragment-foreground: #37474F; --fragment-keyword: #bb6bb2; --fragment-keywordtype: #8258b3; --fragment-keywordflow: #d67c3b; --fragment-token: #438a59; --fragment-comment: #969696; --fragment-link: #5383d6; --fragment-preprocessor: #46aaa5; --fragment-linenumber-color: #797979; --fragment-linenumber-background: #f4f4f5; --fragment-linenumber-border: #e3e5e7; --fragment-lineheight: 20px; /* sidebar navigation (treeview) colors */ --side-nav-background: #fbfbfb; --side-nav-foreground: var(--page-foreground-color); --side-nav-arrow-opacity: 0; --side-nav-arrow-hover-opacity: 0.9; --toc-background: var(--side-nav-background); --toc-foreground: var(--side-nav-foreground); /* height of an item in any tree / collapsible table */ --tree-item-height: 30px; --memname-font-size: var(--code-font-size); --memtitle-font-size: 18px; --webkit-scrollbar-size: 7px; --webkit-scrollbar-padding: 4px; --webkit-scrollbar-color: var(--separator-color); --animation-duration: .12s } @media screen and (max-width: 767px) { html { --page-font-size: 16px; --navigation-font-size: 16px; --toc-font-size: 15px; --code-font-size: 15px; /* affects code, fragment */ --title-font-size: 22px; } } @media (prefers-color-scheme: dark) { html:not(.light-mode) { color-scheme: dark; --primary-color: #1982d2; --primary-dark-color: #86a9c4; --primary-light-color: #4779ac; --box-shadow: 0 2px 8px 0 rgba(0,0,0,.35); --odd-color: rgba(100,100,100,.06); --menu-selected-background: rgba(0,0,0,.4); --page-background-color: #1C1D1F; --page-foreground-color: #d2dbde; --page-secondary-foreground-color: #859399; --separator-color: #38393b; --side-nav-background: #252628; --code-background: #2a2c2f; --tablehead-background: #2a2c2f; --blockquote-background: #222325; --blockquote-foreground: #7e8c92; --warning-color: #3b2e04; --warning-color-dark: #f1b602; --warning-color-darker: #ceb670; --note-color: #163750; --note-color-dark: #1982D2; --note-color-darker: #dcf0fa; --todo-color: #2a2536; --todo-color-dark: #7661b3; --todo-color-darker: #ae9ed6; --deprecated-color: #2e323b; --deprecated-color-dark: #738396; --deprecated-color-darker: #abb0bd; --bug-color: #2e1917; --bug-color-dark: #ad2617; --bug-color-darker: #f5b1aa; --invariant-color: #303a35; --invariant-color-dark: #76ce96; --invariant-color-darker: #cceed5; --fragment-background: #282c34; --fragment-foreground: #dbe4eb; --fragment-keyword: #cc99cd; --fragment-keywordtype: #ab99cd; --fragment-keywordflow: #e08000; --fragment-token: #7ec699; --fragment-comment: #999999; --fragment-link: #98c0e3; --fragment-preprocessor: #65cabe; --fragment-linenumber-color: #cccccc; --fragment-linenumber-background: #35393c; --fragment-linenumber-border: #1f1f1f; } } /* dark mode variables are defined twice, to support both the dark-mode without and with doxygen-awesome-darkmode-toggle.js */ html.dark-mode { color-scheme: dark; --primary-color: #1982d2; --primary-dark-color: #86a9c4; --primary-light-color: #4779ac; --box-shadow: 0 2px 8px 0 rgba(0,0,0,.30); --odd-color: rgba(100,100,100,.06); --menu-selected-background: rgba(0,0,0,.4); --page-background-color: #1C1D1F; --page-foreground-color: #d2dbde; --page-secondary-foreground-color: #859399; --separator-color: #38393b; --side-nav-background: #252628; --code-background: #2a2c2f; --tablehead-background: #2a2c2f; --blockquote-background: #222325; --blockquote-foreground: #7e8c92; --warning-color: #3b2e04; --warning-color-dark: #f1b602; --warning-color-darker: #ceb670; --note-color: #163750; --note-color-dark: #1982D2; --note-color-darker: #dcf0fa; --todo-color: #2a2536; --todo-color-dark: #7661b3; --todo-color-darker: #ae9ed6; --deprecated-color: #2e323b; --deprecated-color-dark: #738396; --deprecated-color-darker: #abb0bd; --bug-color: #2e1917; --bug-color-dark: #ad2617; --bug-color-darker: #f5b1aa; --invariant-color: #303a35; --invariant-color-dark: #76ce96; --invariant-color-darker: #cceed5; --fragment-background: #282c34; --fragment-foreground: #dbe4eb; --fragment-keyword: #cc99cd; --fragment-keywordtype: #ab99cd; --fragment-keywordflow: #e08000; --fragment-token: #7ec699; --fragment-comment: #999999; --fragment-link: #98c0e3; --fragment-preprocessor: #65cabe; --fragment-linenumber-color: #cccccc; --fragment-linenumber-background: #35393c; --fragment-linenumber-border: #1f1f1f; } body { color: var(--page-foreground-color); background-color: var(--page-background-color); font-size: var(--page-font-size); } body, table, div, p, dl, #nav-tree .label, .title, .sm-dox a, .sm-dox a:hover, .sm-dox a:focus, #projectname, .SelectItem, #MSearchField, .navpath li.navelem a, .navpath li.navelem a:hover, p.reference, p.definition, div.toc li, div.toc h3 { font-family: var(--font-family); } h1, h2, h3, h4, h5 { margin-top: 1em; font-weight: 600; line-height: initial; } p, div, table, dl, p.reference, p.definition { font-size: var(--page-font-size); } p.reference, p.definition { color: var(--page-secondary-foreground-color); } a:link, a:visited, a:hover, a:focus, a:active { color: var(--primary-color) !important; font-weight: 500; background: none; } a.anchor { scroll-margin-top: var(--spacing-large); display: block; } /* Title and top navigation */ #top { background: var(--header-background); border-bottom: 1px solid var(--separator-color); } @media screen and (min-width: 768px) { #top { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; } } #main-nav { flex-grow: 5; padding: var(--spacing-small) var(--spacing-medium); } #titlearea { width: auto; padding: var(--spacing-medium) var(--spacing-large); background: none; color: var(--header-foreground); border-bottom: none; } @media screen and (max-width: 767px) { #titlearea { padding-bottom: var(--spacing-small); } } #titlearea table tbody tr { height: auto !important; } #projectname { font-size: var(--title-font-size); font-weight: 600; } #projectnumber { font-family: inherit; font-size: 60%; } #projectbrief { font-family: inherit; font-size: 80%; } #projectlogo { vertical-align: middle; } #projectlogo img { max-height: calc(var(--title-font-size) * 2); margin-right: var(--spacing-small); } .sm-dox, .tabs, .tabs2, .tabs3 { background: none; padding: 0; } .tabs, .tabs2, .tabs3 { border-bottom: 1px solid var(--separator-color); margin-bottom: -1px; } .main-menu-btn-icon, .main-menu-btn-icon:before, .main-menu-btn-icon:after { background: var(--page-secondary-foreground-color); } @media screen and (max-width: 767px) { .sm-dox a span.sub-arrow { background: var(--code-background); } #main-menu a.has-submenu span.sub-arrow { color: var(--page-secondary-foreground-color); border-radius: var(--border-radius-medium); } #main-menu a.has-submenu:hover span.sub-arrow { color: var(--page-foreground-color); } } @media screen and (min-width: 768px) { .sm-dox li, .tablist li { display: var(--menu-display); } .sm-dox a span.sub-arrow { border-color: var(--header-foreground) transparent transparent transparent; } .sm-dox a:hover span.sub-arrow { border-color: var(--menu-focus-foreground) transparent transparent transparent; } .sm-dox ul a span.sub-arrow { border-color: transparent transparent transparent var(--page-foreground-color); } .sm-dox ul a:hover span.sub-arrow { border-color: transparent transparent transparent var(--menu-focus-foreground); } } .sm-dox ul { background: var(--page-background-color); box-shadow: var(--box-shadow); border: 1px solid var(--separator-color); border-radius: var(--border-radius-medium) !important; padding: var(--spacing-small); animation: ease-out 150ms slideInMenu; } @keyframes slideInMenu { from { opacity: 0; transform: translate(0px, -2px); } to { opacity: 1; transform: translate(0px, 0px); } } .sm-dox ul a { color: var(--page-foreground-color) !important; background: var(--page-background-color); font-size: var(--navigation-font-size); } .sm-dox>li>ul:after { border-bottom-color: var(--page-background-color) !important; } .sm-dox>li>ul:before { border-bottom-color: var(--separator-color) !important; } .sm-dox ul a:hover, .sm-dox ul a:active, .sm-dox ul a:focus { font-size: var(--navigation-font-size) !important; color: var(--menu-focus-foreground) !important; text-shadow: none; background-color: var(--menu-focus-background); border-radius: var(--border-radius-small) !important; } .sm-dox a, .sm-dox a:focus, .tablist li, .tablist li a, .tablist li.current a { text-shadow: none; background: transparent; background-image: none !important; color: var(--header-foreground) !important; font-weight: normal; font-size: var(--navigation-font-size); border-radius: var(--border-radius-small) !important; } .sm-dox a:focus { outline: auto; } .sm-dox a:hover, .sm-dox a:active, .tablist li a:hover { text-shadow: none; font-weight: normal; background: var(--menu-focus-background); color: var(--menu-focus-foreground) !important; border-radius: var(--border-radius-small) !important; font-size: var(--navigation-font-size); } .tablist li.current { border-radius: var(--border-radius-small); background: var(--menu-selected-background); } .tablist li { margin: var(--spacing-small) 0 var(--spacing-small) var(--spacing-small); } .tablist a { padding: 0 var(--spacing-large); } /* Search box */ #MSearchBox { height: var(--searchbar-height); background: var(--searchbar-background); border-radius: var(--searchbar-border-radius); border: 1px solid var(--separator-color); overflow: hidden; width: var(--searchbar-width); position: relative; box-shadow: none; display: block; margin-top: 0; } /* until Doxygen 1.9.4 */ .left img#MSearchSelect { left: 0; user-select: none; padding-left: 8px; } /* Doxygen 1.9.5 */ .left span#MSearchSelect { left: 0; user-select: none; margin-left: 8px; padding: 0; } .left #MSearchSelect[src$=".png"] { padding-left: 0 } .SelectionMark { user-select: none; } .tabs .left #MSearchSelect { padding-left: 0; } .tabs #MSearchBox { position: absolute; right: var(--spacing-medium); } @media screen and (max-width: 767px) { .tabs #MSearchBox { position: relative; right: 0; margin-left: var(--spacing-medium); margin-top: 0; } } #MSearchSelectWindow, #MSearchResultsWindow { z-index: 9999; } #MSearchBox.MSearchBoxActive { border-color: var(--primary-color); box-shadow: inset 0 0 0 1px var(--primary-color); } #main-menu > li:last-child { margin-right: 0; } @media screen and (max-width: 767px) { #main-menu > li:last-child { height: 50px; } } #MSearchField { font-size: var(--navigation-font-size); height: calc(var(--searchbar-height) - 2px); background: transparent; width: calc(var(--searchbar-width) - 64px); } .MSearchBoxActive #MSearchField { color: var(--searchbar-foreground); } #MSearchSelect { top: calc(calc(var(--searchbar-height) / 2) - 11px); } #MSearchBox span.left, #MSearchBox span.right { background: none; background-image: none; } #MSearchBox span.right { padding-top: calc(calc(var(--searchbar-height) / 2) - 12px); position: absolute; right: var(--spacing-small); } .tabs #MSearchBox span.right { top: calc(calc(var(--searchbar-height) / 2) - 12px); } @keyframes slideInSearchResults { from { opacity: 0; transform: translate(0, 15px); } to { opacity: 1; transform: translate(0, 20px); } } #MSearchResultsWindow { left: auto !important; right: var(--spacing-medium); border-radius: var(--border-radius-large); border: 1px solid var(--separator-color); transform: translate(0, 20px); box-shadow: var(--box-shadow); animation: ease-out 280ms slideInSearchResults; background: var(--page-background-color); } iframe#MSearchResults { margin: 4px; } iframe { color-scheme: normal; } @media (prefers-color-scheme: dark) { html:not(.light-mode) iframe#MSearchResults { filter: invert() hue-rotate(180deg); } } html.dark-mode iframe#MSearchResults { filter: invert() hue-rotate(180deg); } #MSearchResults .SRPage { background-color: transparent; } #MSearchResults .SRPage .SREntry { font-size: 10pt; padding: var(--spacing-small) var(--spacing-medium); } #MSearchSelectWindow { border: 1px solid var(--separator-color); border-radius: var(--border-radius-medium); box-shadow: var(--box-shadow); background: var(--page-background-color); padding-top: var(--spacing-small); padding-bottom: var(--spacing-small); } #MSearchSelectWindow a.SelectItem { font-size: var(--navigation-font-size); line-height: var(--content-line-height); margin: 0 var(--spacing-small); border-radius: var(--border-radius-small); color: var(--page-foreground-color) !important; font-weight: normal; } #MSearchSelectWindow a.SelectItem:hover { background: var(--menu-focus-background); color: var(--menu-focus-foreground) !important; } @media screen and (max-width: 767px) { #MSearchBox { margin-top: var(--spacing-medium); margin-bottom: var(--spacing-medium); width: calc(100vw - 30px); } #main-menu > li:last-child { float: none !important; } #MSearchField { width: calc(100vw - 110px); } @keyframes slideInSearchResultsMobile { from { opacity: 0; transform: translate(0, 15px); } to { opacity: 1; transform: translate(0, 20px); } } #MSearchResultsWindow { left: var(--spacing-medium) !important; right: var(--spacing-medium); overflow: auto; transform: translate(0, 20px); animation: ease-out 280ms slideInSearchResultsMobile; width: auto !important; } /* * Overwrites for fixing the searchbox on mobile in doxygen 1.9.2 */ label.main-menu-btn ~ #searchBoxPos1 { top: 3px !important; right: 6px !important; left: 45px; display: flex; } label.main-menu-btn ~ #searchBoxPos1 > #MSearchBox { margin-top: 0; margin-bottom: 0; flex-grow: 2; float: left; } } /* Tree view */ #side-nav { padding: 0 !important; background: var(--side-nav-background); min-width: 8px; max-width: 50vw; } @media screen and (max-width: 767px) { #side-nav { display: none; } #doc-content { margin-left: 0 !important; } } #nav-tree { background: transparent; margin-right: 1px; } #nav-tree .label { font-size: var(--navigation-font-size); } #nav-tree .item { height: var(--tree-item-height); line-height: var(--tree-item-height); overflow: hidden; text-overflow: ellipsis; } #nav-tree .item > a:focus { outline: none; } #nav-sync { bottom: 12px; right: 12px; top: auto !important; user-select: none; } #nav-tree .selected { text-shadow: none; background-image: none; background-color: transparent; position: relative; color: var(--primary-color) !important; font-weight: 500; } #nav-tree .selected::after { content: ""; position: absolute; top: 1px; bottom: 1px; left: 0; width: 4px; border-radius: 0 var(--border-radius-small) var(--border-radius-small) 0; background: var(--primary-color); } #nav-tree a { color: var(--side-nav-foreground) !important; font-weight: normal; } #nav-tree a:focus { outline-style: auto; } #nav-tree .arrow { opacity: var(--side-nav-arrow-opacity); background: none; } .arrow { color: inherit; cursor: pointer; font-size: 45%; vertical-align: middle; margin-right: 2px; font-family: serif; height: auto; text-align: right; } #nav-tree div.item:hover .arrow, #nav-tree a:focus .arrow { opacity: var(--side-nav-arrow-hover-opacity); } #nav-tree .selected a { color: var(--primary-color) !important; font-weight: bolder; font-weight: 600; } .ui-resizable-e { width: 4px; background: transparent; box-shadow: inset -1px 0 0 0 var(--separator-color); } /* Contents */ div.header { border-bottom: 1px solid var(--separator-color); background-color: var(--page-background-color); background-image: none; } @media screen and (min-width: 1000px) { #doc-content > div > div.contents, .PageDoc > div.contents { display: flex; flex-direction: row-reverse; flex-wrap: nowrap; align-items: flex-start; } div.contents .textblock { min-width: 200px; flex-grow: 1; } } div.contents, div.header .title, div.header .summary { max-width: var(--content-maxwidth); } div.contents, div.header .title { line-height: initial; margin: calc(var(--spacing-medium) + .2em) auto var(--spacing-medium) auto; } div.header .summary { margin: var(--spacing-medium) auto 0 auto; } div.headertitle { padding: 0; } div.header .title { font-weight: 600; font-size: 225%; padding: var(--spacing-medium) var(--spacing-large); word-break: break-word; } div.header .summary { width: auto; display: block; float: none; padding: 0 var(--spacing-large); } td.memSeparator { border-color: var(--separator-color); } span.mlabel { background: var(--primary-color); border: none; padding: 4px 9px; border-radius: 12px; margin-right: var(--spacing-medium); } span.mlabel:last-of-type { margin-right: 2px; } div.contents { padding: 0 var(--spacing-large); } div.contents p, div.contents li { line-height: var(--content-line-height); } div.contents div.dyncontent { margin: var(--spacing-medium) 0; } @media (prefers-color-scheme: dark) { html:not(.light-mode) div.contents div.dyncontent img, html:not(.light-mode) div.contents center img, html:not(.light-mode) div.contents > table img, html:not(.light-mode) div.contents div.dyncontent iframe, html:not(.light-mode) div.contents center iframe, html:not(.light-mode) div.contents table iframe, html:not(.light-mode) div.contents .dotgraph iframe { filter: brightness(89%) hue-rotate(180deg) invert(); } } html.dark-mode div.contents div.dyncontent img, html.dark-mode div.contents center img, html.dark-mode div.contents > table img, html.dark-mode div.contents div.dyncontent iframe, html.dark-mode div.contents center iframe, html.dark-mode div.contents table iframe, html.dark-mode div.contents .dotgraph iframe { filter: brightness(89%) hue-rotate(180deg) invert(); } h2.groupheader { border-bottom: 0px; color: var(--page-foreground-color); box-shadow: 100px 0 var(--page-background-color), -100px 0 var(--page-background-color), 100px 0.75px var(--separator-color), -100px 0.75px var(--separator-color), 500px 0 var(--page-background-color), -500px 0 var(--page-background-color), 500px 0.75px var(--separator-color), -500px 0.75px var(--separator-color), 900px 0 var(--page-background-color), -900px 0 var(--page-background-color), 900px 0.75px var(--separator-color), -900px 0.75px var(--separator-color), 1400px 0 var(--page-background-color), -1400px 0 var(--page-background-color), 1400px 0.75px var(--separator-color), -1400px 0.75px var(--separator-color), 1900px 0 var(--page-background-color), -1900px 0 var(--page-background-color), 1900px 0.75px var(--separator-color), -1900px 0.75px var(--separator-color); } blockquote { margin: 0 var(--spacing-medium) 0 var(--spacing-medium); padding: var(--spacing-small) var(--spacing-large); background: var(--blockquote-background); color: var(--blockquote-foreground); border-left: 0; overflow: visible; border-radius: var(--border-radius-medium); overflow: visible; position: relative; } blockquote::before, blockquote::after { font-weight: bold; font-family: serif; font-size: 360%; opacity: .15; position: absolute; } blockquote::before { content: "“"; left: -10px; top: 4px; } blockquote::after { content: "”"; right: -8px; bottom: -25px; } blockquote p { margin: var(--spacing-small) 0 var(--spacing-medium) 0; } .paramname, .paramname em { font-weight: 600; color: var(--primary-dark-color); } .paramname > code { border: 0; } table.params .paramname { font-weight: 600; font-family: var(--font-family-monospace); font-size: var(--code-font-size); padding-right: var(--spacing-small); line-height: var(--table-line-height); } h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { text-shadow: 0 0 15px var(--primary-light-color); } .alphachar a { color: var(--page-foreground-color); } .dotgraph { max-width: 100%; overflow-x: scroll; } .dotgraph .caption { position: sticky; left: 0; } /* Wrap Graphviz graphs with the `interactive_dotgraph` class if `INTERACTIVE_SVG = YES` */ .interactive_dotgraph .dotgraph iframe { max-width: 100%; } /* Table of Contents */ div.contents .toc { max-height: var(--toc-max-height); min-width: var(--toc-width); border: 0; border-left: 1px solid var(--separator-color); border-radius: 0; background-color: var(--page-background-color); box-shadow: none; position: sticky; top: var(--toc-sticky-top); padding: 0 var(--spacing-large); margin: var(--spacing-small) 0 var(--spacing-large) var(--spacing-large); } div.toc h3 { color: var(--toc-foreground); font-size: var(--navigation-font-size); margin: var(--spacing-large) 0 var(--spacing-medium) 0; } div.toc li { padding: 0; background: none; line-height: var(--toc-font-size); margin: var(--toc-font-size) 0 0 0; } div.toc li::before { display: none; } div.toc ul { margin-top: 0 } div.toc li a { font-size: var(--toc-font-size); color: var(--page-foreground-color) !important; text-decoration: none; } div.toc li a:hover, div.toc li a.active { color: var(--primary-color) !important; } div.toc li a.aboveActive { color: var(--page-secondary-foreground-color) !important; } @media screen and (max-width: 999px) { div.contents .toc { max-height: 45vh; float: none; width: auto; margin: 0 0 var(--spacing-medium) 0; position: relative; top: 0; position: relative; border: 1px solid var(--separator-color); border-radius: var(--border-radius-medium); background-color: var(--toc-background); box-shadow: var(--box-shadow); } div.contents .toc.interactive { max-height: calc(var(--navigation-font-size) + 2 * var(--spacing-large)); overflow: hidden; } div.contents .toc > h3 { -webkit-tap-highlight-color: transparent; cursor: pointer; position: sticky; top: 0; background-color: var(--toc-background); margin: 0; padding: var(--spacing-large) 0; display: block; } div.contents .toc.interactive > h3::before { content: ""; width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid var(--primary-color); display: inline-block; margin-right: var(--spacing-small); margin-bottom: calc(var(--navigation-font-size) / 4); transform: rotate(-90deg); transition: transform var(--animation-duration) ease-out; } div.contents .toc.interactive.open > h3::before { transform: rotate(0deg); } div.contents .toc.interactive.open { max-height: 45vh; overflow: auto; transition: max-height 0.2s ease-in-out; } div.contents .toc a, div.contents .toc a.active { color: var(--primary-color) !important; } div.contents .toc a:hover { text-decoration: underline; } } /* Code & Fragments */ code, div.fragment, pre.fragment { border-radius: var(--border-radius-small); border: 1px solid var(--separator-color); overflow: hidden; } code { display: inline; background: var(--code-background); color: var(--code-foreground); padding: 2px 6px; } div.fragment, pre.fragment { margin: var(--spacing-medium) 0; padding: calc(var(--spacing-large) - (var(--spacing-large) / 6)) var(--spacing-large); background: var(--fragment-background); color: var(--fragment-foreground); overflow-x: auto; } @media screen and (max-width: 767px) { div.fragment, pre.fragment { border-top-right-radius: 0; border-bottom-right-radius: 0; border-right: 0; } .contents > div.fragment, .textblock > div.fragment, .textblock > pre.fragment, .textblock > .tabbed > ul > li > div.fragment, .textblock > .tabbed > ul > li > pre.fragment, .contents > .doxygen-awesome-fragment-wrapper > div.fragment, .textblock > .doxygen-awesome-fragment-wrapper > div.fragment, .textblock > .doxygen-awesome-fragment-wrapper > pre.fragment, .textblock > .tabbed > ul > li > .doxygen-awesome-fragment-wrapper > div.fragment, .textblock > .tabbed > ul > li > .doxygen-awesome-fragment-wrapper > pre.fragment { margin: var(--spacing-medium) calc(0px - var(--spacing-large)); border-radius: 0; border-left: 0; } .textblock li > .fragment, .textblock li > .doxygen-awesome-fragment-wrapper > .fragment { margin: var(--spacing-medium) calc(0px - var(--spacing-large)); } .memdoc li > .fragment, .memdoc li > .doxygen-awesome-fragment-wrapper > .fragment { margin: var(--spacing-medium) calc(0px - var(--spacing-medium)); } .textblock ul, .memdoc ul { overflow: initial; } .memdoc > div.fragment, .memdoc > pre.fragment, dl dd > div.fragment, dl dd pre.fragment, .memdoc > .doxygen-awesome-fragment-wrapper > div.fragment, .memdoc > .doxygen-awesome-fragment-wrapper > pre.fragment, dl dd > .doxygen-awesome-fragment-wrapper > div.fragment, dl dd .doxygen-awesome-fragment-wrapper > pre.fragment { margin: var(--spacing-medium) calc(0px - var(--spacing-medium)); border-radius: 0; border-left: 0; } } code, code a, pre.fragment, div.fragment, div.fragment .line, div.fragment span, div.fragment .line a, div.fragment .line span { font-family: var(--font-family-monospace); font-size: var(--code-font-size) !important; } div.line:after { margin-right: var(--spacing-medium); } div.fragment .line, pre.fragment { white-space: pre; word-wrap: initial; line-height: var(--fragment-lineheight); } div.fragment span.keyword { color: var(--fragment-keyword); } div.fragment span.keywordtype { color: var(--fragment-keywordtype); } div.fragment span.keywordflow { color: var(--fragment-keywordflow); } div.fragment span.stringliteral { color: var(--fragment-token) } div.fragment span.comment { color: var(--fragment-comment); } div.fragment a.code { color: var(--fragment-link) !important; } div.fragment span.preprocessor { color: var(--fragment-preprocessor); } div.fragment span.lineno { display: inline-block; width: 27px; border-right: none; background: var(--fragment-linenumber-background); color: var(--fragment-linenumber-color); } div.fragment span.lineno a { background: none; color: var(--fragment-link) !important; } div.fragment > .line:first-child .lineno { box-shadow: -999999px 0px 0 999999px var(--fragment-linenumber-background), -999998px 0px 0 999999px var(--fragment-linenumber-border); background-color: var(--fragment-linenumber-background) !important; } div.line { border-radius: var(--border-radius-small); } div.line.glow { background-color: var(--primary-light-color); box-shadow: none; } /* dl warning, attention, note, deprecated, bug, ... */ dl.bug dt a, dl.deprecated dt a, dl.todo dt a { font-weight: bold !important; } dl.warning, dl.attention, dl.note, dl.deprecated, dl.bug, dl.invariant, dl.pre, dl.post, dl.todo, dl.remark { padding: var(--spacing-medium); margin: var(--spacing-medium) 0; color: var(--page-background-color); overflow: hidden; margin-left: 0; border-radius: var(--border-radius-small); } dl.section dd { margin-bottom: 2px; } dl.warning, dl.attention { background: var(--warning-color); border-left: 8px solid var(--warning-color-dark); color: var(--warning-color-darker); } dl.warning dt, dl.attention dt { color: var(--warning-color-dark); } dl.note, dl.remark { background: var(--note-color); border-left: 8px solid var(--note-color-dark); color: var(--note-color-darker); } dl.note dt, dl.remark dt { color: var(--note-color-dark); } dl.todo { background: var(--todo-color); border-left: 8px solid var(--todo-color-dark); color: var(--todo-color-darker); } dl.todo dt a { color: var(--todo-color-dark) !important; } dl.bug dt a { color: var(--todo-color-dark) !important; } dl.bug { background: var(--bug-color); border-left: 8px solid var(--bug-color-dark); color: var(--bug-color-darker); } dl.bug dt a { color: var(--bug-color-dark) !important; } dl.deprecated { background: var(--deprecated-color); border-left: 8px solid var(--deprecated-color-dark); color: var(--deprecated-color-darker); } dl.deprecated dt a { color: var(--deprecated-color-dark) !important; } dl.section dd, dl.bug dd, dl.deprecated dd, dl.todo dd { margin-inline-start: 0px; } dl.invariant, dl.pre, dl.post { background: var(--invariant-color); border-left: 8px solid var(--invariant-color-dark); color: var(--invariant-color-darker); } dl.invariant dt, dl.pre dt, dl.post dt { color: var(--invariant-color-dark); } /* memitem */ div.memdoc, div.memproto, h2.memtitle { box-shadow: none; background-image: none; border: none; } div.memdoc { padding: 0 var(--spacing-medium); background: var(--page-background-color); } h2.memtitle, div.memitem { border: 1px solid var(--separator-color); box-shadow: var(--box-shadow); } h2.memtitle { box-shadow: 0px var(--spacing-medium) 0 -1px var(--fragment-background), var(--box-shadow); } div.memitem { transition: none; } div.memproto, h2.memtitle { background: var(--fragment-background); } h2.memtitle { font-weight: 500; font-size: var(--memtitle-font-size); font-family: var(--font-family-monospace); border-bottom: none; border-top-left-radius: var(--border-radius-medium); border-top-right-radius: var(--border-radius-medium); word-break: break-all; position: relative; } h2.memtitle:after { content: ""; display: block; background: var(--fragment-background); height: var(--spacing-medium); bottom: calc(0px - var(--spacing-medium)); left: 0; right: -14px; position: absolute; border-top-right-radius: var(--border-radius-medium); } h2.memtitle > span.permalink { font-size: inherit; } h2.memtitle > span.permalink > a { text-decoration: none; padding-left: 3px; margin-right: -4px; user-select: none; display: inline-block; margin-top: -6px; } h2.memtitle > span.permalink > a:hover { color: var(--primary-dark-color) !important; } a:target + h2.memtitle, a:target + h2.memtitle + div.memitem { border-color: var(--primary-light-color); } div.memitem { border-top-right-radius: var(--border-radius-medium); border-bottom-right-radius: var(--border-radius-medium); border-bottom-left-radius: var(--border-radius-medium); overflow: hidden; display: block !important; } div.memdoc { border-radius: 0; } div.memproto { border-radius: 0 var(--border-radius-small) 0 0; overflow: auto; border-bottom: 1px solid var(--separator-color); padding: var(--spacing-medium); margin-bottom: -1px; } div.memtitle { border-top-right-radius: var(--border-radius-medium); border-top-left-radius: var(--border-radius-medium); } div.memproto table.memname { font-family: var(--font-family-monospace); color: var(--page-foreground-color); font-size: var(--memname-font-size); text-shadow: none; } div.memproto div.memtemplate { font-family: var(--font-family-monospace); color: var(--primary-dark-color); font-size: var(--memname-font-size); margin-left: 2px; text-shadow: none; } table.mlabels, table.mlabels > tbody { display: block; } td.mlabels-left { width: auto; } td.mlabels-right { margin-top: 3px; position: sticky; left: 0; } table.mlabels > tbody > tr:first-child { display: flex; justify-content: space-between; flex-wrap: wrap; } .memname, .memitem span.mlabels { margin: 0 } /* reflist */ dl.reflist { box-shadow: var(--box-shadow); border-radius: var(--border-radius-medium); border: 1px solid var(--separator-color); overflow: hidden; padding: 0; } dl.reflist dt, dl.reflist dd { box-shadow: none; text-shadow: none; background-image: none; border: none; padding: 12px; } dl.reflist dt { font-weight: 500; border-radius: 0; background: var(--code-background); border-bottom: 1px solid var(--separator-color); color: var(--page-foreground-color) } dl.reflist dd { background: none; } /* Table */ .contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname), .contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody { display: inline-block; max-width: 100%; } .contents > table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname):not(.classindex) { margin-left: calc(0px - var(--spacing-large)); margin-right: calc(0px - var(--spacing-large)); max-width: calc(100% + 2 * var(--spacing-large)); } table.fieldtable, table.markdownTable tbody, table.doxtable tbody { border: none; margin: var(--spacing-medium) 0; box-shadow: 0 0 0 1px var(--separator-color); border-radius: var(--border-radius-small); } table.markdownTable, table.doxtable, table.fieldtable { padding: 1px; } table.doxtable caption { display: block; } table.fieldtable { border-collapse: collapse; width: 100%; } th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone, table.doxtable th { background: var(--tablehead-background); color: var(--tablehead-foreground); font-weight: 600; font-size: var(--page-font-size); } th.markdownTableHeadLeft:first-child, th.markdownTableHeadRight:first-child, th.markdownTableHeadCenter:first-child, th.markdownTableHeadNone:first-child, table.doxtable tr th:first-child { border-top-left-radius: var(--border-radius-small); } th.markdownTableHeadLeft:last-child, th.markdownTableHeadRight:last-child, th.markdownTableHeadCenter:last-child, th.markdownTableHeadNone:last-child, table.doxtable tr th:last-child { border-top-right-radius: var(--border-radius-small); } table.markdownTable td, table.markdownTable th, table.fieldtable td, table.fieldtable th, table.doxtable td, table.doxtable th { border: 1px solid var(--separator-color); padding: var(--spacing-small) var(--spacing-medium); } table.markdownTable td:last-child, table.markdownTable th:last-child, table.fieldtable td:last-child, table.fieldtable th:last-child, table.doxtable td:last-child, table.doxtable th:last-child { border-right: none; } table.markdownTable td:first-child, table.markdownTable th:first-child, table.fieldtable td:first-child, table.fieldtable th:first-child, table.doxtable td:first-child, table.doxtable th:first-child { border-left: none; } table.markdownTable tr:first-child td, table.markdownTable tr:first-child th, table.fieldtable tr:first-child td, table.fieldtable tr:first-child th, table.doxtable tr:first-child td, table.doxtable tr:first-child th { border-top: none; } table.markdownTable tr:last-child td, table.markdownTable tr:last-child th, table.fieldtable tr:last-child td, table.fieldtable tr:last-child th, table.doxtable tr:last-child td, table.doxtable tr:last-child th { border-bottom: none; } table.markdownTable tr, table.doxtable tr { border-bottom: 1px solid var(--separator-color); } table.markdownTable tr:last-child, table.doxtable tr:last-child { border-bottom: none; } .full_width_table table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) { display: block; } .full_width_table table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody { display: table; width: 100%; } table.fieldtable th { font-size: var(--page-font-size); font-weight: 600; background-image: none; background-color: var(--tablehead-background); color: var(--tablehead-foreground); } table.fieldtable td.fieldtype, .fieldtable td.fieldname, .fieldtable td.fieldinit, .fieldtable td.fielddoc, .fieldtable th { border-bottom: 1px solid var(--separator-color); border-right: 1px solid var(--separator-color); } table.fieldtable tr:last-child td:first-child { border-bottom-left-radius: var(--border-radius-small); } table.fieldtable tr:last-child td:last-child { border-bottom-right-radius: var(--border-radius-small); } .memberdecls td.glow, .fieldtable tr.glow { background-color: var(--primary-light-color); box-shadow: none; } table.memberdecls { display: block; -webkit-tap-highlight-color: transparent; } table.memberdecls tr[class^='memitem'] { font-family: var(--font-family-monospace); font-size: var(--code-font-size); } table.memberdecls tr[class^='memitem'] .memTemplParams { font-family: var(--font-family-monospace); font-size: var(--code-font-size); color: var(--primary-dark-color); white-space: normal; } table.memberdecls .memItemLeft, table.memberdecls .memItemRight, table.memberdecls .memTemplItemLeft, table.memberdecls .memTemplItemRight, table.memberdecls .memTemplParams { transition: none; padding-top: var(--spacing-small); padding-bottom: var(--spacing-small); border-top: 1px solid var(--separator-color); border-bottom: 1px solid var(--separator-color); background-color: var(--fragment-background); } table.memberdecls .memTemplItemLeft, table.memberdecls .memTemplItemRight { padding-top: 2px; } table.memberdecls .memTemplParams { border-bottom: 0; border-left: 1px solid var(--separator-color); border-right: 1px solid var(--separator-color); border-radius: var(--border-radius-small) var(--border-radius-small) 0 0; padding-bottom: var(--spacing-small); } table.memberdecls .memTemplItemLeft { border-radius: 0 0 0 var(--border-radius-small); border-left: 1px solid var(--separator-color); border-top: 0; } table.memberdecls .memTemplItemRight { border-radius: 0 0 var(--border-radius-small) 0; border-right: 1px solid var(--separator-color); padding-left: 0; border-top: 0; } table.memberdecls .memItemLeft { border-radius: var(--border-radius-small) 0 0 var(--border-radius-small); border-left: 1px solid var(--separator-color); padding-left: var(--spacing-medium); padding-right: 0; } table.memberdecls .memItemRight { border-radius: 0 var(--border-radius-small) var(--border-radius-small) 0; border-right: 1px solid var(--separator-color); padding-right: var(--spacing-medium); padding-left: 0; } table.memberdecls .mdescLeft, table.memberdecls .mdescRight { background: none; color: var(--page-foreground-color); padding: var(--spacing-small) 0; } table.memberdecls .memItemLeft, table.memberdecls .memTemplItemLeft { padding-right: var(--spacing-medium); } table.memberdecls .memSeparator { background: var(--page-background-color); height: var(--spacing-large); border: 0; transition: none; } table.memberdecls .groupheader { margin-bottom: var(--spacing-large); } table.memberdecls .inherit_header td { padding: 0 0 var(--spacing-medium) 0; text-indent: -12px; color: var(--page-secondary-foreground-color); } table.memberdecls img[src="closed.png"], table.memberdecls img[src="open.png"], div.dynheader img[src="open.png"], div.dynheader img[src="closed.png"] { width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid var(--primary-color); margin-top: 8px; display: block; float: left; margin-left: -10px; transition: transform var(--animation-duration) ease-out; } table.memberdecls img { margin-right: 10px; } table.memberdecls img[src="closed.png"], div.dynheader img[src="closed.png"] { transform: rotate(-90deg); } .compoundTemplParams { font-family: var(--font-family-monospace); color: var(--primary-dark-color); font-size: var(--code-font-size); } @media screen and (max-width: 767px) { table.memberdecls .memItemLeft, table.memberdecls .memItemRight, table.memberdecls .mdescLeft, table.memberdecls .mdescRight, table.memberdecls .memTemplItemLeft, table.memberdecls .memTemplItemRight, table.memberdecls .memTemplParams { display: block; text-align: left; padding-left: var(--spacing-large); margin: 0 calc(0px - var(--spacing-large)) 0 calc(0px - var(--spacing-large)); border-right: none; border-left: none; border-radius: 0; white-space: normal; } table.memberdecls .memItemLeft, table.memberdecls .mdescLeft, table.memberdecls .memTemplItemLeft { border-bottom: 0; padding-bottom: 0; } table.memberdecls .memTemplItemLeft { padding-top: 0; } table.memberdecls .mdescLeft { margin-bottom: calc(0px - var(--page-font-size)); } table.memberdecls .memItemRight, table.memberdecls .mdescRight, table.memberdecls .memTemplItemRight { border-top: 0; padding-top: 0; padding-right: var(--spacing-large); overflow-x: auto; } table.memberdecls tr[class^='memitem']:not(.inherit) { display: block; width: calc(100vw - 2 * var(--spacing-large)); } table.memberdecls .mdescRight { color: var(--page-foreground-color); } table.memberdecls tr.inherit { visibility: hidden; } table.memberdecls tr[style="display: table-row;"] { display: block !important; visibility: visible; width: calc(100vw - 2 * var(--spacing-large)); animation: fade .5s; } @keyframes fade { 0% { opacity: 0; max-height: 0; } 100% { opacity: 1; max-height: 200px; } } } /* Horizontal Rule */ hr { margin-top: var(--spacing-large); margin-bottom: var(--spacing-large); height: 1px; background-color: var(--separator-color); border: 0; } .contents hr { box-shadow: 100px 0 var(--separator-color), -100px 0 var(--separator-color), 500px 0 var(--separator-color), -500px 0 var(--separator-color), 900px 0 var(--separator-color), -900px 0 var(--separator-color), 1400px 0 var(--separator-color), -1400px 0 var(--separator-color), 1900px 0 var(--separator-color), -1900px 0 var(--separator-color); } .contents img, .contents .center, .contents center, .contents div.image object { max-width: 100%; overflow: auto; } @media screen and (max-width: 767px) { .contents .dyncontent > .center, .contents > center { margin-left: calc(0px - var(--spacing-large)); margin-right: calc(0px - var(--spacing-large)); max-width: calc(100% + 2 * var(--spacing-large)); } } /* Directories */ div.directory { border-top: 1px solid var(--separator-color); border-bottom: 1px solid var(--separator-color); width: auto; } table.directory { font-family: var(--font-family); font-size: var(--page-font-size); font-weight: normal; width: 100%; } table.directory td.entry, table.directory td.desc { padding: calc(var(--spacing-small) / 2) var(--spacing-small); line-height: var(--table-line-height); } table.directory tr.even td:last-child { border-radius: 0 var(--border-radius-small) var(--border-radius-small) 0; } table.directory tr.even td:first-child { border-radius: var(--border-radius-small) 0 0 var(--border-radius-small); } table.directory tr.even:last-child td:last-child { border-radius: 0 var(--border-radius-small) 0 0; } table.directory tr.even:last-child td:first-child { border-radius: var(--border-radius-small) 0 0 0; } table.directory td.desc { min-width: 250px; } table.directory tr.even { background-color: var(--odd-color); } table.directory tr.odd { background-color: transparent; } .icona { width: auto; height: auto; margin: 0 var(--spacing-small); } .icon { background: var(--primary-color); border-radius: var(--border-radius-small); font-size: var(--page-font-size); padding: calc(var(--page-font-size) / 5); line-height: var(--page-font-size); transform: scale(0.8); height: auto; width: var(--page-font-size); user-select: none; } .iconfopen, .icondoc, .iconfclosed { background-position: center; margin-bottom: 0; height: var(--table-line-height); } .icondoc { filter: saturate(0.2); } @media screen and (max-width: 767px) { div.directory { margin-left: calc(0px - var(--spacing-large)); margin-right: calc(0px - var(--spacing-large)); } } @media (prefers-color-scheme: dark) { html:not(.light-mode) .iconfopen, html:not(.light-mode) .iconfclosed { filter: hue-rotate(180deg) invert(); } } html.dark-mode .iconfopen, html.dark-mode .iconfclosed { filter: hue-rotate(180deg) invert(); } /* Class list */ .classindex dl.odd { background: var(--odd-color); border-radius: var(--border-radius-small); } .classindex dl.even { background-color: transparent; } /* Class Index Doxygen 1.8 */ table.classindex { margin-left: 0; margin-right: 0; width: 100%; } table.classindex table div.ah { background-image: none; background-color: initial; border-color: var(--separator-color); color: var(--page-foreground-color); box-shadow: var(--box-shadow); border-radius: var(--border-radius-large); padding: var(--spacing-small); } div.qindex { background-color: var(--odd-color); border-radius: var(--border-radius-small); border: 1px solid var(--separator-color); padding: var(--spacing-small) 0; } /* Footer and nav-path */ #nav-path { width: 100%; } #nav-path ul { background-image: none; background: var(--page-background-color); border: none; border-top: 1px solid var(--separator-color); border-bottom: 1px solid var(--separator-color); border-bottom: 0; box-shadow: 0 0.75px 0 var(--separator-color); font-size: var(--navigation-font-size); } img.footer { width: 60px; } .navpath li.footer { color: var(--page-secondary-foreground-color); } address.footer { color: var(--page-secondary-foreground-color); margin-bottom: var(--spacing-large); } #nav-path li.navelem { background-image: none; display: flex; align-items: center; } .navpath li.navelem a { text-shadow: none; display: inline-block; color: var(--primary-color) !important; } .navpath li.navelem b { color: var(--primary-dark-color); font-weight: 500; } li.navelem { padding: 0; margin-left: -8px; } li.navelem:first-child { margin-left: var(--spacing-large); } li.navelem:first-child:before { display: none; } #nav-path li.navelem:after { content: ''; border: 5px solid var(--page-background-color); border-bottom-color: transparent; border-right-color: transparent; border-top-color: transparent; transform: translateY(-1px) scaleY(4.2); z-index: 10; margin-left: 6px; } #nav-path li.navelem:before { content: ''; border: 5px solid var(--separator-color); border-bottom-color: transparent; border-right-color: transparent; border-top-color: transparent; transform: translateY(-1px) scaleY(3.2); margin-right: var(--spacing-small); } .navpath li.navelem a:hover { color: var(--primary-color); } /* Scrollbars for Webkit */ #nav-tree::-webkit-scrollbar, div.fragment::-webkit-scrollbar, pre.fragment::-webkit-scrollbar, div.memproto::-webkit-scrollbar, .contents center::-webkit-scrollbar, .contents .center::-webkit-scrollbar, .contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody::-webkit-scrollbar, div.contents .toc::-webkit-scrollbar, .contents .dotgraph::-webkit-scrollbar, .contents .tabs-overview-container::-webkit-scrollbar { background: transparent; width: calc(var(--webkit-scrollbar-size) + var(--webkit-scrollbar-padding) + var(--webkit-scrollbar-padding)); height: calc(var(--webkit-scrollbar-size) + var(--webkit-scrollbar-padding) + var(--webkit-scrollbar-padding)); } #nav-tree::-webkit-scrollbar-thumb, div.fragment::-webkit-scrollbar-thumb, pre.fragment::-webkit-scrollbar-thumb, div.memproto::-webkit-scrollbar-thumb, .contents center::-webkit-scrollbar-thumb, .contents .center::-webkit-scrollbar-thumb, .contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody::-webkit-scrollbar-thumb, div.contents .toc::-webkit-scrollbar-thumb, .contents .dotgraph::-webkit-scrollbar-thumb, .contents .tabs-overview-container::-webkit-scrollbar-thumb { background-color: transparent; border: var(--webkit-scrollbar-padding) solid transparent; border-radius: calc(var(--webkit-scrollbar-padding) + var(--webkit-scrollbar-padding)); background-clip: padding-box; } #nav-tree:hover::-webkit-scrollbar-thumb, div.fragment:hover::-webkit-scrollbar-thumb, pre.fragment:hover::-webkit-scrollbar-thumb, div.memproto:hover::-webkit-scrollbar-thumb, .contents center:hover::-webkit-scrollbar-thumb, .contents .center:hover::-webkit-scrollbar-thumb, .contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody:hover::-webkit-scrollbar-thumb, div.contents .toc:hover::-webkit-scrollbar-thumb, .contents .dotgraph:hover::-webkit-scrollbar-thumb, .contents .tabs-overview-container:hover::-webkit-scrollbar-thumb { background-color: var(--webkit-scrollbar-color); } #nav-tree::-webkit-scrollbar-track, div.fragment::-webkit-scrollbar-track, pre.fragment::-webkit-scrollbar-track, div.memproto::-webkit-scrollbar-track, .contents center::-webkit-scrollbar-track, .contents .center::-webkit-scrollbar-track, .contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody::-webkit-scrollbar-track, div.contents .toc::-webkit-scrollbar-track, .contents .dotgraph::-webkit-scrollbar-track, .contents .tabs-overview-container::-webkit-scrollbar-track { background: transparent; } #nav-tree::-webkit-scrollbar-corner { background-color: var(--side-nav-background); } #nav-tree, div.fragment, pre.fragment, div.memproto, .contents center, .contents .center, .contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody, div.contents .toc { overflow-x: auto; overflow-x: overlay; } #nav-tree { overflow-x: auto; overflow-y: auto; overflow-y: overlay; } /* Scrollbars for Firefox */ #nav-tree, div.fragment, pre.fragment, div.memproto, .contents center, .contents .center, .contents table:not(.memberdecls):not(.mlabels):not(.fieldtable):not(.memname) tbody, div.contents .toc, .contents .dotgraph, .contents .tabs-overview-container { scrollbar-width: thin; } /* Optional Dark mode toggle button */ doxygen-awesome-dark-mode-toggle { display: inline-block; margin: 0 0 0 var(--spacing-small); padding: 0; width: var(--searchbar-height); height: var(--searchbar-height); background: none; border: none; border-radius: var(--searchbar-height); vertical-align: middle; text-align: center; line-height: var(--searchbar-height); font-size: 22px; display: flex; align-items: center; justify-content: center; user-select: none; cursor: pointer; } doxygen-awesome-dark-mode-toggle > svg { transition: transform var(--animation-duration) ease-in-out; } doxygen-awesome-dark-mode-toggle:active > svg { transform: scale(.5); } doxygen-awesome-dark-mode-toggle:hover { background-color: rgba(0,0,0,.03); } html.dark-mode doxygen-awesome-dark-mode-toggle:hover { background-color: rgba(0,0,0,.18); } /* Optional fragment copy button */ .doxygen-awesome-fragment-wrapper { position: relative; } doxygen-awesome-fragment-copy-button { opacity: 0; background: var(--fragment-background); width: 28px; height: 28px; position: absolute; right: calc(var(--spacing-large) - (var(--spacing-large) / 2.5)); top: calc(var(--spacing-large) - (var(--spacing-large) / 2.5)); border: 1px solid var(--fragment-foreground); cursor: pointer; border-radius: var(--border-radius-small); display: flex; justify-content: center; align-items: center; } .doxygen-awesome-fragment-wrapper:hover doxygen-awesome-fragment-copy-button, doxygen-awesome-fragment-copy-button.success { opacity: .28; } doxygen-awesome-fragment-copy-button:hover, doxygen-awesome-fragment-copy-button.success { opacity: 1 !important; } doxygen-awesome-fragment-copy-button:active:not([class~=success]) svg { transform: scale(.91); } doxygen-awesome-fragment-copy-button svg { fill: var(--fragment-foreground); width: 18px; height: 18px; } doxygen-awesome-fragment-copy-button.success svg { fill: rgb(14, 168, 14); } doxygen-awesome-fragment-copy-button.success { border-color: rgb(14, 168, 14); } @media screen and (max-width: 767px) { .textblock > .doxygen-awesome-fragment-wrapper > doxygen-awesome-fragment-copy-button, .textblock li > .doxygen-awesome-fragment-wrapper > doxygen-awesome-fragment-copy-button, .memdoc li > .doxygen-awesome-fragment-wrapper > doxygen-awesome-fragment-copy-button, .memdoc > .doxygen-awesome-fragment-wrapper > doxygen-awesome-fragment-copy-button, dl dd > .doxygen-awesome-fragment-wrapper > doxygen-awesome-fragment-copy-button { right: 0; } } /* Optional paragraph link button */ a.anchorlink { font-size: 90%; margin-left: var(--spacing-small); color: var(--page-foreground-color) !important; text-decoration: none; opacity: .15; display: none; transition: opacity var(--animation-duration) ease-in-out, color var(--animation-duration) ease-in-out; } a.anchorlink svg { fill: var(--page-foreground-color); } h3 a.anchorlink svg, h4 a.anchorlink svg { margin-bottom: -3px; margin-top: -4px; } a.anchorlink:hover { opacity: .45; } h2:hover a.anchorlink, h1:hover a.anchorlink, h3:hover a.anchorlink, h4:hover a.anchorlink { display: inline-block; } /* Optional tab feature */ .tabbed > ul { padding-inline-start: 0px; margin: 0; padding: var(--spacing-small) 0; } .tabbed > ul > li { display: none; } .tabbed > ul > li.selected { display: block; } .tabs-overview-container { overflow-x: auto; display: block; overflow-y: visible; } .tabs-overview { border-bottom: 1px solid var(--separator-color); display: flex; flex-direction: row; } @media screen and (max-width: 767px) { .tabs-overview-container { margin: 0 calc(0px - var(--spacing-large)); } .tabs-overview { padding: 0 var(--spacing-large) } } .tabs-overview button.tab-button { color: var(--page-foreground-color); margin: 0; border: none; background: transparent; padding: calc(var(--spacing-large) / 2) 0; display: inline-block; font-size: var(--page-font-size); cursor: pointer; box-shadow: 0 1px 0 0 var(--separator-color); position: relative; -webkit-tap-highlight-color: transparent; } .tabs-overview button.tab-button .tab-title::before { display: block; content: attr(title); font-weight: 600; height: 0; overflow: hidden; visibility: hidden; } .tabs-overview button.tab-button .tab-title { float: left; white-space: nowrap; font-weight: normal; padding: calc(var(--spacing-large) / 2) var(--spacing-large); border-radius: var(--border-radius-medium); transition: background-color var(--animation-duration) ease-in-out, font-weight var(--animation-duration) ease-in-out; } .tabs-overview button.tab-button:not(:last-child) .tab-title { box-shadow: 8px 0 0 -7px var(--separator-color); } .tabs-overview button.tab-button:hover .tab-title { background: var(--separator-color); box-shadow: none; } .tabs-overview button.tab-button.active .tab-title { font-weight: 600; } .tabs-overview button.tab-button::after { content: ''; display: block; position: absolute; left: 0; bottom: 0; right: 0; height: 0; width: 0%; margin: 0 auto; border-radius: var(--border-radius-small) var(--border-radius-small) 0 0; background-color: var(--primary-color); transition: width var(--animation-duration) ease-in-out, height var(--animation-duration) ease-in-out; } .tabs-overview button.tab-button.active::after { width: 100%; box-sizing: border-box; height: 3px; } /* Navigation Buttons */ .section_buttons:not(:empty) { margin-top: calc(var(--spacing-large) * 3); } .section_buttons table.markdownTable { display: block; width: 100%; } .section_buttons table.markdownTable tbody { display: table !important; width: 100%; box-shadow: none; border-spacing: 10px; } .section_buttons table.markdownTable td { padding: 0; } .section_buttons table.markdownTable th { display: none; } .section_buttons table.markdownTable tr.markdownTableHead { border: none; } .section_buttons tr th, .section_buttons tr td { background: none; border: none; padding: var(--spacing-large) 0 var(--spacing-small); } .section_buttons a { display: inline-block; border: 1px solid var(--separator-color); border-radius: var(--border-radius-medium); color: var(--page-secondary-foreground-color) !important; text-decoration: none; transition: color var(--animation-duration) ease-in-out, background-color var(--animation-duration) ease-in-out; } .section_buttons a:hover { color: var(--page-foreground-color) !important; background-color: var(--odd-color); } .section_buttons tr td.markdownTableBodyLeft a { padding: var(--spacing-medium) var(--spacing-large) var(--spacing-medium) calc(var(--spacing-large) / 2); } .section_buttons tr td.markdownTableBodyRight a { padding: var(--spacing-medium) calc(var(--spacing-large) / 2) var(--spacing-medium) var(--spacing-large); } .section_buttons tr td.markdownTableBodyLeft a::before, .section_buttons tr td.markdownTableBodyRight a::after { color: var(--page-secondary-foreground-color) !important; display: inline-block; transition: color .08s ease-in-out, transform .09s ease-in-out; } .section_buttons tr td.markdownTableBodyLeft a::before { content: '〈'; padding-right: var(--spacing-large); } .section_buttons tr td.markdownTableBodyRight a::after { content: '〉'; padding-left: var(--spacing-large); } .section_buttons tr td.markdownTableBodyLeft a:hover::before { color: var(--page-foreground-color) !important; transform: translateX(-3px); } .section_buttons tr td.markdownTableBodyRight a:hover::after { color: var(--page-foreground-color) !important; transform: translateX(3px); } @media screen and (max-width: 450px) { .section_buttons a { width: 100%; box-sizing: border-box; } .section_buttons tr td:nth-of-type(1).markdownTableBodyLeft a { border-radius: var(--border-radius-medium) 0 0 var(--border-radius-medium); border-right: none; } .section_buttons tr td:nth-of-type(2).markdownTableBodyRight a { border-radius: 0 var(--border-radius-medium) var(--border-radius-medium) 0; } } ================================================ FILE: docs/config/footer.html ================================================ ================================================ FILE: docs/config/header.html ================================================ $projectname: $title $title $treeview $search $mathjax $extrastylesheet
$projectname  v$projectnumber
$projectbrief
$projectbrief
$searchbox
================================================ FILE: docs/config/icons/octicons.css ================================================ @font-face { font-family: 'octicons'; src: url('octicons.eot?#iefix') format('embedded-opentype'), url('octicons.woff') format('woff'), url('octicons.ttf') format('truetype'), url('octicons.svg#octicons') format('svg'); font-weight: normal; font-style: normal; } /* .octicon is optimized for 16px. .mega-octicon is optimized for 32px but can be used larger. */ .octicon, .mega-octicon { font: normal normal normal 16px/1 octicons; display: inline-block; text-decoration: none; text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .mega-octicon { font-size: 32px; } .octicon-alert:before { content: '\f02d'} /*  */ .octicon-arrow-down:before { content: '\f03f'} /*  */ .octicon-arrow-left:before { content: '\f040'} /*  */ .octicon-arrow-right:before { content: '\f03e'} /*  */ .octicon-arrow-small-down:before { content: '\f0a0'} /*  */ .octicon-arrow-small-left:before { content: '\f0a1'} /*  */ .octicon-arrow-small-right:before { content: '\f071'} /*  */ .octicon-arrow-small-up:before { content: '\f09f'} /*  */ .octicon-arrow-up:before { content: '\f03d'} /*  */ .octicon-microscope:before, .octicon-beaker:before { content: '\f0dd'} /*  */ .octicon-bell:before { content: '\f0de'} /*  */ .octicon-bold:before { content: '\f0e2'} /*  */ .octicon-book:before { content: '\f007'} /*  */ .octicon-bookmark:before { content: '\f07b'} /*  */ .octicon-briefcase:before { content: '\f0d3'} /*  */ .octicon-broadcast:before { content: '\f048'} /*  */ .octicon-browser:before { content: '\f0c5'} /*  */ .octicon-bug:before { content: '\f091'} /*  */ .octicon-calendar:before { content: '\f068'} /*  */ .octicon-check:before { content: '\f03a'} /*  */ .octicon-checklist:before { content: '\f076'} /*  */ .octicon-chevron-down:before { content: '\f0a3'} /*  */ .octicon-chevron-left:before { content: '\f0a4'} /*  */ .octicon-chevron-right:before { content: '\f078'} /*  */ .octicon-chevron-up:before { content: '\f0a2'} /*  */ .octicon-circle-slash:before { content: '\f084'} /*  */ .octicon-circuit-board:before { content: '\f0d6'} /*  */ .octicon-clippy:before { content: '\f035'} /*  */ .octicon-clock:before { content: '\f046'} /*  */ .octicon-cloud-download:before { content: '\f00b'} /*  */ .octicon-cloud-upload:before { content: '\f00c'} /*  */ .octicon-code:before { content: '\f05f'} /*  */ .octicon-color-mode:before { content: '\f065'} /*  */ .octicon-comment-add:before, .octicon-comment:before { content: '\f02b'} /*  */ .octicon-comment-discussion:before { content: '\f04f'} /*  */ .octicon-credit-card:before { content: '\f045'} /*  */ .octicon-dash:before { content: '\f0ca'} /*  */ .octicon-dashboard:before { content: '\f07d'} /*  */ .octicon-database:before { content: '\f096'} /*  */ .octicon-clone:before, .octicon-desktop-download:before { content: '\f0dc'} /*  */ .octicon-device-camera:before { content: '\f056'} /*  */ .octicon-device-camera-video:before { content: '\f057'} /*  */ .octicon-device-desktop:before { content: '\f27c'} /*  */ .octicon-device-mobile:before { content: '\f038'} /*  */ .octicon-diff:before { content: '\f04d'} /*  */ .octicon-diff-added:before { content: '\f06b'} /*  */ .octicon-diff-ignored:before { content: '\f099'} /*  */ .octicon-diff-modified:before { content: '\f06d'} /*  */ .octicon-diff-removed:before { content: '\f06c'} /*  */ .octicon-diff-renamed:before { content: '\f06e'} /*  */ .octicon-ellipsis:before { content: '\f09a'} /*  */ .octicon-eye-unwatch:before, .octicon-eye-watch:before, .octicon-eye:before { content: '\f04e'} /*  */ .octicon-file-binary:before { content: '\f094'} /*  */ .octicon-file-code:before { content: '\f010'} /*  */ .octicon-file-directory:before { content: '\f016'} /*  */ .octicon-file-media:before { content: '\f012'} /*  */ .octicon-file-pdf:before { content: '\f014'} /*  */ .octicon-file-submodule:before { content: '\f017'} /*  */ .octicon-file-symlink-directory:before { content: '\f0b1'} /*  */ .octicon-file-symlink-file:before { content: '\f0b0'} /*  */ .octicon-file-text:before { content: '\f011'} /*  */ .octicon-file-zip:before { content: '\f013'} /*  */ .octicon-flame:before { content: '\f0d2'} /*  */ .octicon-fold:before { content: '\f0cc'} /*  */ .octicon-gear:before { content: '\f02f'} /*  */ .octicon-gift:before { content: '\f042'} /*  */ .octicon-gist:before { content: '\f00e'} /*  */ .octicon-gist-secret:before { content: '\f08c'} /*  */ .octicon-git-branch-create:before, .octicon-git-branch-delete:before, .octicon-git-branch:before { content: '\f020'} /*  */ .octicon-git-commit:before { content: '\f01f'} /*  */ .octicon-git-compare:before { content: '\f0ac'} /*  */ .octicon-git-merge:before { content: '\f023'} /*  */ .octicon-git-pull-request-abandoned:before, .octicon-git-pull-request:before { content: '\f009'} /*  */ .octicon-globe:before { content: '\f0b6'} /*  */ .octicon-graph:before { content: '\f043'} /*  */ .octicon-heart:before { content: '\2665'} /* ♥ */ .octicon-history:before { content: '\f07e'} /*  */ .octicon-home:before { content: '\f08d'} /*  */ .octicon-horizontal-rule:before { content: '\f070'} /*  */ .octicon-hubot:before { content: '\f09d'} /*  */ .octicon-inbox:before { content: '\f0cf'} /*  */ .octicon-info:before { content: '\f059'} /*  */ .octicon-issue-closed:before { content: '\f028'} /*  */ .octicon-issue-opened:before { content: '\f026'} /*  */ .octicon-issue-reopened:before { content: '\f027'} /*  */ .octicon-italic:before { content: '\f0e4'} /*  */ .octicon-jersey:before { content: '\f019'} /*  */ .octicon-key:before { content: '\f049'} /*  */ .octicon-keyboard:before { content: '\f00d'} /*  */ .octicon-law:before { content: '\f0d8'} /*  */ .octicon-light-bulb:before { content: '\f000'} /*  */ .octicon-link:before { content: '\f05c'} /*  */ .octicon-link-external:before { content: '\f07f'} /*  */ .octicon-list-ordered:before { content: '\f062'} /*  */ .octicon-list-unordered:before { content: '\f061'} /*  */ .octicon-location:before { content: '\f060'} /*  */ .octicon-gist-private:before, .octicon-mirror-private:before, .octicon-git-fork-private:before, .octicon-lock:before { content: '\f06a'} /*  */ .octicon-logo-gist:before { content: '\f0ad'} /*  */ .octicon-logo-github:before { content: '\f092'} /*  */ .octicon-mail:before { content: '\f03b'} /*  */ .octicon-mail-read:before { content: '\f03c'} /*  */ .octicon-mail-reply:before { content: '\f051'} /*  */ .octicon-mark-github:before { content: '\f00a'} /*  */ .octicon-markdown:before { content: '\f0c9'} /*  */ .octicon-megaphone:before { content: '\f077'} /*  */ .octicon-mention:before { content: '\f0be'} /*  */ .octicon-milestone:before { content: '\f075'} /*  */ .octicon-mirror-public:before, .octicon-mirror:before { content: '\f024'} /*  */ .octicon-mortar-board:before { content: '\f0d7'} /*  */ .octicon-mute:before { content: '\f080'} /*  */ .octicon-no-newline:before { content: '\f09c'} /*  */ .octicon-octoface:before { content: '\f008'} /*  */ .octicon-organization:before { content: '\f037'} /*  */ .octicon-package:before { content: '\f0c4'} /*  */ .octicon-paintcan:before { content: '\f0d1'} /*  */ .octicon-pencil:before { content: '\f058'} /*  */ .octicon-person-add:before, .octicon-person-follow:before, .octicon-person:before { content: '\f018'} /*  */ .octicon-pin:before { content: '\f041'} /*  */ .octicon-plug:before { content: '\f0d4'} /*  */ .octicon-repo-create:before, .octicon-gist-new:before, .octicon-file-directory-create:before, .octicon-file-add:before, .octicon-plus:before { content: '\f05d'} /*  */ .octicon-primitive-dot:before { content: '\f052'} /*  */ .octicon-primitive-square:before { content: '\f053'} /*  */ .octicon-pulse:before { content: '\f085'} /*  */ .octicon-question:before { content: '\f02c'} /*  */ .octicon-quote:before { content: '\f063'} /*  */ .octicon-radio-tower:before { content: '\f030'} /*  */ .octicon-repo-delete:before, .octicon-repo:before { content: '\f001'} /*  */ .octicon-repo-clone:before { content: '\f04c'} /*  */ .octicon-repo-force-push:before { content: '\f04a'} /*  */ .octicon-gist-fork:before, .octicon-repo-forked:before { content: '\f002'} /*  */ .octicon-repo-pull:before { content: '\f006'} /*  */ .octicon-repo-push:before { content: '\f005'} /*  */ .octicon-rocket:before { content: '\f033'} /*  */ .octicon-rss:before { content: '\f034'} /*  */ .octicon-ruby:before { content: '\f047'} /*  */ .octicon-search-save:before, .octicon-search:before { content: '\f02e'} /*  */ .octicon-server:before { content: '\f097'} /*  */ .octicon-settings:before { content: '\f07c'} /*  */ .octicon-shield:before { content: '\f0e1'} /*  */ .octicon-log-in:before, .octicon-sign-in:before { content: '\f036'} /*  */ .octicon-log-out:before, .octicon-sign-out:before { content: '\f032'} /*  */ .octicon-squirrel:before { content: '\f0b2'} /*  */ .octicon-star-add:before, .octicon-star-delete:before, .octicon-star:before { content: '\f02a'} /*  */ .octicon-stop:before { content: '\f08f'} /*  */ .octicon-repo-sync:before, .octicon-sync:before { content: '\f087'} /*  */ .octicon-tag-remove:before, .octicon-tag-add:before, .octicon-tag:before { content: '\f015'} /*  */ .octicon-tasklist:before { content: '\f0e5'} /*  */ .octicon-telescope:before { content: '\f088'} /*  */ .octicon-terminal:before { content: '\f0c8'} /*  */ .octicon-text-size:before { content: '\f0e3'} /*  */ .octicon-three-bars:before { content: '\f05e'} /*  */ .octicon-thumbsdown:before { content: '\f0db'} /*  */ .octicon-thumbsup:before { content: '\f0da'} /*  */ .octicon-tools:before { content: '\f031'} /*  */ .octicon-trashcan:before { content: '\f0d0'} /*  */ .octicon-triangle-down:before { content: '\f05b'} /*  */ .octicon-triangle-left:before { content: '\f044'} /*  */ .octicon-triangle-right:before { content: '\f05a'} /*  */ .octicon-triangle-up:before { content: '\f0aa'} /*  */ .octicon-unfold:before { content: '\f039'} /*  */ .octicon-unmute:before { content: '\f0ba'} /*  */ .octicon-versions:before { content: '\f064'} /*  */ .octicon-watch:before { content: '\f0e0'} /*  */ .octicon-remove-close:before, .octicon-x:before { content: '\f081'} /*  */ .octicon-zap:before { content: '\26A1'} /* ⚡ */ ================================================ FILE: docs/config/js/doxygen-navtree-hacks.js ================================================ // Distributed under the MIT License. // See LICENSE.txt for details. // This file is mostly copied from: // https://gitlab.com/libeigen/eigen/-/blob/master/doc/eigen_navtree_hacks.js var global_navtree_object; // Overloaded to remove links to sections/subsections function getNode(o, po) { po.childrenVisited = true; var l = po.childrenData.length - 1; for (var i in po.childrenData) { var nodeData = po.childrenData[i]; if ((!nodeData[1]) || (nodeData[1].indexOf('#') == -1)) // <- we added this line po.children[i] = newNode(o, po, nodeData[0], nodeData[1], nodeData[2], i == l); } } // Overloaded to remove the animation of the sidebar function expandNode(o, node, imm, showRoot) { if (node.childrenData && !node.expanded) { if (typeof (node.childrenData) === 'string') { var varName = node.childrenData; getScript(node.relpath + varName, function () { node.childrenData = getData(varName); expandNode(o, node, imm, showRoot); }, showRoot); } else { if (!node.childrenVisited) { getNode(o, node); } $(node.getChildrenUL()).show(); // <- removed slideDown animation // node.plus_img.innerHTML = arrowDown; // <- removed this node.expanded = true; } } } // Overloaded to save the root node into global_navtree_object function initNavTree(toroot, relpath) { var o = new Object(); global_navtree_object = o; // <- we added this line o.toroot = toroot; o.node = new Object(); o.node.li = document.getElementById("nav-tree-contents"); o.node.childrenData = NAVTREE; o.node.children = new Array(); o.node.childrenUL = document.createElement("ul"); o.node.getChildrenUL = function () { return o.node.childrenUL; }; o.node.li.appendChild(o.node.childrenUL); o.node.depth = 0; o.node.relpath = relpath; o.node.expanded = false; o.node.isLast = true; o.node.plus_img = document.createElement("img"); o.node.plus_img.src = relpath + "ftv2pnode.png"; o.node.plus_img.width = 16; o.node.plus_img.height = 22; if (localStorageSupported()) { var navSync = $('#nav-sync'); if (cachedLink()) { showSyncOff(navSync, relpath); navSync.removeClass('sync'); } else { showSyncOn(navSync, relpath); } navSync.click(function () { toggleSyncButton(relpath); }); } navTo(o, toroot, window.location.hash, relpath); $(window).bind('hashchange', function () { if (window.location.hash && window.location.hash.length > 1) { var a; if ($(location).attr('hash')) { var clslink = stripPath($(location).attr('pathname')) + ':' + $(location).attr('hash').substring(1); a = $('.item a[class$="' + clslink + '"]'); } if (a == null || !$(a).parent().parent().hasClass('selected')) { $('.item').removeClass('selected'); $('.item').removeAttr('id'); } var link = stripPath2($(location).attr('pathname')); navTo(o, link, $(location).attr('hash'), relpath); } else if (!animationInProgress) { $('#doc-content').scrollTop(0); $('.item').removeClass('selected'); $('.item').removeAttr('id'); navTo(o, toroot, window.location.hash, relpath); } }) $(window).on("load", showRoot); } // return false if the the node has no children at all, or has only section/subsection children function checkChildrenData(node) { if (!(typeof (node.childrenData) === 'string')) { for (var i in node.childrenData) { var url = node.childrenData[i][1]; if (url.indexOf("#") == -1) return true; } return false; } return (node.childrenData); } // Modified to: // 1 - remove the root node // 2 - remove the section/subsection children function createIndent(o, domNode, node, level) { var level = -2; // <- we replaced level=-1 by level=-2 var n = node; while (n.parentNode) { level++; n = n.parentNode; } if (checkChildrenData(node)) { // <- we modified this line to use checkChildrenData(node) instead of node.childrenData var imgNode = document.createElement("span"); imgNode.className = 'arrow'; imgNode.style.paddingLeft = (16 * level).toString() + 'px'; imgNode.innerHTML = arrowRight; node.plus_img = imgNode; node.expandToggle = document.createElement("a"); node.expandToggle.href = "javascript:void(0)"; node.expandToggle.onclick = function () { if (node.expanded) { $(node.getChildrenUL()).slideUp("fast"); node.plus_img.innerHTML = arrowRight; node.expanded = false; } else { expandNode(o, node, false, false); } } node.expandToggle.appendChild(imgNode); domNode.appendChild(node.expandToggle); } else { var span = document.createElement("span"); span.className = 'arrow'; span.style.width = 16 * (level + 1) + 'px'; span.innerHTML = ' '; domNode.appendChild(span); } } // Overloaded to automatically expand the selected node function selectAndHighlight(hash, n) { var a; if (hash) { var link = stripPath($(location).attr('pathname')) + ':' + hash.substring(1); a = $('.item a[class$="' + link + '"]'); } if (a && a.length) { a.parent().parent().addClass('selected'); a.parent().parent().attr('id', 'selected'); highlightAnchor(); } else if (n) { $(n.itemDiv).addClass('selected'); $(n.itemDiv).attr('id', 'selected'); } if ($('#nav-tree-contents .item:first').hasClass('selected')) { $('#nav-sync').css('top', '30px'); } else { $('#nav-sync').css('top', '5px'); } expandNode(global_navtree_object, n, true, true); // <- we added this line showRoot(); } $(document).ready(function () { (function () { // wait until the first "selected" element has been created try { // this line will triger an exception if there is no #selected element, i.e., before the tree structure is complete. document.getElementById("selected").className = "item selected"; // ok, the default tree has been created, we can keep going... // expand the "Code reference" node var sidebar_root_items = global_navtree_object.node.children[0].children; expandNode(global_navtree_object, sidebar_root_items[sidebar_root_items.length - 1], true, true); // Hide the root node $(document.getElementsByClassName('index.html')[0]).parent().parent().css({ display: "none" }); } catch (err) { setTimeout(arguments.callee, 10); } })(); }); ================================================ FILE: docs/config/js/spectre.js ================================================ // Distributed under the MIT License. // See LICENSE.txt for details. window.onload = function(){ // Hide type alias RHS that refers to a metafunction result in a (*_)detail namespace $("body").children(). find("td.memItemRight, td.memTemplItemRight, td.memname").each(function () { $(this).html( $(this).html().replace(/( =[ ]+)[typedef ]*typename [A-Za-z0-9]*[_]?detail[s]?::[A-Za-z0-9\-_\.&;<> /;:\"=,#]+::[A-Za-z0-9_]+/g, "$1implementation defined") ); }); // Hide type alias RHS that refers to a type in a (*_)detail namespace // Also remove ... = decltype(something(_detail)::) $("body").children().find("td.memItemRight, td.memTemplItemRight, td.memname").each(function () { $(this).html( $(this).html().replace(/( =[ ]+)[typedef ]*[A-Za-z0-9\(]*[_]?detail[s]?::[A-Za-z0-9\-_\.&;<> /;:\"=,#\(\)]+/g, "$1implementation defined") ); }); // Hide unnamed template parameters: , typename = void // Not applied to div.memitem because that causes problems with rendering // MathJAX $("body").children().find("td.memItemRight, td.memTemplItemRight").each(function () { $(this).html( $(this).html().replace(/(template[< ]+.*)(,[ ]*typename[ ]*=[ ]*void[ ]*)+/g, "$1") ); }); $("body").children().find("td.memItemRight, td.memTemplItemRight, div.title").each(function () { $(this).html( $(this).html().replace(/(<[A-Za-z0-9 ,]+.*)(,[ ]*typename[ ]*>)+/g, "$1>") ); }); // Hide SFINAE in template parameters $("body").children().find("td.memTemplParams, div.memtemplate").each(function () { $(this).html( $(this).html().replace(/(template[A-Za-z0-9&;,\.=\(\) _]+)(,[ ]+typename[ ]+=[ ]+typename[ ]+std::enable_if.*::type)+/g, "$1") ); }); $("body").children().find("td.memTemplParams, div.memtemplate").each(function () { $(this).html( $(this).html().replace(/(template[A-Za-z0-9&;,\.=\(\) _]+)(,[ ]+typename[ ]+std::enable_if.*)+>/g, "$1>") ); }); // Hide enable_if_t for SFINAE $("body").children().find("td.memTemplParams, div.memtemplate").each(function () { $(this).html( $(this).html() .replace(/(template[A-Za-z0-9&;,\.=\(\) _]+)(,[ ]+std::enable_if_t.*)+>/g, "$1>") ); }); // Hide metafunctions that use only the template metaprogramming libraries $("body").children().find("td.memItemRight, td.memTemplItemRight").each(function () { $(this).html( $(this).html().replace(/( =[ ]+).*tmpl::(?!list\b).*/g, "$1implementation defined") ); }); // Italicize "implementation defined" // Not applied to div.memitem because that causes problems with rendering // MathJAX $("body").children().find("td.memItemRight, td.memTemplItemRight").each(function () { $(this).html( $(this).html().replace(/implementation defined/g, "implementation defined".italics()) ); }); // Show popovers for references $("body").children().find('a[href*="citelist.html#CITEREF_"]').each(function () { var tooltip_base = this; // Get the reference id, e.g. `CITEREF_Kopriva`. This is the one used as // anchor on the bibliography page. var ref_id = $(this).attr('href').match(/CITEREF_(.*)/)[0]; // Backslashify colons, which indicate CSS pseudo-selectors ref_id = ref_id.replaceAll(":", "\\:"); // Load the bibliography page to retrieve the reference data as nicely // formatted HTML. // This does not work locally because it is forbidden to access files, // so just spin up a web server in the `html` directory with // `python3 -m http.server` to enable this functionality $.get('citelist.html', function(data) { // Filter the bibliography data for this particular reference var ref_html = $('').append($.parseHTML(data)) .find('#' + ref_id) .parent() .next() .find('p.startdd') .html(); // Show the reference in a tooltip tippy(tooltip_base, { content: ref_html, allowHTML: true, interactive: true, }); }, 'html'); }); }; ================================================ FILE: docs/config/markdown-math-filter.pl ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. # Doxygen filter to format markdown math for Doxygen # # In Doxygen documentation, including markdown files or Jupyter notebooks that # get converted to markdown, you can use standard $...$ syntax for inline math, # and "naked LaTeX" syntax for display-style math: # # \begin{equation} # ... # \end{equation} # # You can also replace `equation` with another supported environment, e.g. # `align`. # # This Doxygen filter formats the math for Doxygen, i.e., uses \f$...\f$ for # inline math and \f{equation}{ ... \f} for display-style math. This is needed # until Doxygen adds support for markdown-style math, see # https://github.com/doxygen/doxygen/issues/8009. # Wrap inline math in \f$...\f$ # - Match code blocks (wrapped in ``` or \code...\endcode) and inline code # (wrapped in ` or ``), and print them directly to the output with no changes. # - Match display math blocks (wrapped in \f[...\f], \f{...\f}, or # \begin...\end), and print them directly to the output with no changes. # - Replace $...$ by \f$...\f$, unless already preceded by '\f$'. # - The '?' makes the pattern match lazily, i.e., match as few characters as # possible. # - Modifiers: # s: Allow '.' to match newlines # g: Replace all occurences # e: Evaluate replacement as perl code, so we can switch between # replacements depending on the matched alternative, using the '//' # (definedness) operator. # x: Ignore spaces for better readability s{ (```.*?```) | (``.*?``) | (`.*?`) | (\\code.*?\\endcode) | (\\f\[.*?\\f\]) | (\\f\{.*?\\f\}) | (\\begin\{(.*?)\}(.*?)\\end\{\6\}) | (? C++ documentation .. toctree:: :maxdepth: 3 :caption: Command-line interface (CLI) cli Python modules -------------- .. autosummary:: :toctree: _autosummary :recursive: :caption: Python modules spectre ================================================ FILE: external/CMakeLists.txt ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. add_subdirectory(brigand) add_subdirectory(EffectiveSource) add_subdirectory(GravitationalEffectiveSource) add_subdirectory(SPHEREPACK) add_subdirectory(slatec) set(LIBRARY Libsharp) set(LIBSHARP_LIBDIR ${CMAKE_CURRENT_BINARY_DIR}/libsharp/auto/lib) set(LIBSHARP_LIB_libsharp ${LIBSHARP_LIBDIR}/libsharp.a) set(LIBSHARP_LIB_libfftpack ${LIBSHARP_LIBDIR}/libfftpack.a) set(LIBSHARP_LIB_libc_utils ${LIBSHARP_LIBDIR}/libc_utils.a) set(LIBSHARP_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/libsharp/auto/include) find_program(MAKE NAMES gmake make REQUIRED) set(LIBSHARP_BUILD ${MAKE}) # When using the Unix Makefile generator, verbosity is inherited from # the main build and works acceptably well. There's no way to # dynamically detect the verbosity with ninja, so silence it # unconditionally because ninja is quieter than make. if (NOT CMAKE_GENERATOR STREQUAL "Unix Makefiles") list(APPEND LIBSHARP_BUILD > /dev/null) endif() set(JOB_SERVER "") if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.28) set(JOB_SERVER BUILD_JOB_SERVER_AWARE TRUE) endif() include(ExternalProject) ExternalProject_Add( Libsharp-external PREFIX ${CMAKE_BINARY_DIR}/external/libsharp SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/libsharp DOWNLOAD_COMMAND cp -r ${CMAKE_CURRENT_SOURCE_DIR}/libsharp ${CMAKE_CURRENT_BINARY_DIR} # libsharp has an autoconf build system, but it doesn't do anything # except set CFLAGS, so we can skip it to avoid depending on # autoconf and set the flags below by manually writing config.auto. CONFIGURE_COMMAND "" # out-of-tree builds don't work BUILD_IN_SOURCE TRUE BUILD_COMMAND "${LIBSHARP_BUILD}" ${JOB_SERVER} BUILD_BYPRODUCTS ${LIBSHARP_LIB_libsharp} ${LIBSHARP_LIB_libfftpack} ${LIBSHARP_LIB_libc_utils} INSTALL_COMMAND "" ) # Always build libsharp with optimization, since there is a big speed # difference and we're not interested in debugging it. file( GENERATE OUTPUT "libsharp/config/config.auto" CONTENT "CC=${CMAKE_C_COMPILER} CL=\$(CC) SPECTRE_FLAGS=\\ \$(subst ;, ,$) CCFLAGS=\$(SPECTRE_FLAGS) -fno-openmp -O3 -c CLFLAGS=-L. -L\$(LIBDIR) \$(SPECTRE_FLAGS) -fno-openmp -O3 -lm ARCREATE=ar cr" CONDITION "$" ) add_library(Libsharp::libsharp STATIC IMPORTED GLOBAL) set_target_properties( Libsharp::libsharp PROPERTIES IMPORTED_LOCATION ${LIBSHARP_LIB_libsharp} ) add_library(Libsharp::libfftpack STATIC IMPORTED GLOBAL) set_target_properties( Libsharp::libfftpack PROPERTIES IMPORTED_LOCATION ${LIBSHARP_LIB_libfftpack} ) add_library(Libsharp::libc_utils STATIC IMPORTED GLOBAL) set_target_properties( Libsharp::libc_utils PROPERTIES IMPORTED_LOCATION ${LIBSHARP_LIB_libc_utils} ) add_library(Libsharp INTERFACE IMPORTED GLOBAL) target_link_libraries( ${LIBRARY} INTERFACE Libsharp::libsharp Libsharp::libfftpack Libsharp::libc_utils ) # cmake issue #15052 file(MAKE_DIRECTORY ${LIBSHARP_INCLUDE}) target_include_directories( ${LIBRARY} SYSTEM INTERFACE ${LIBSHARP_INCLUDE} ) add_dependencies( ${LIBRARY} Libsharp-external ) ================================================ FILE: external/EffectiveSource/CMakeLists.txt ================================================ set(LIBRARY EffectiveSource) add_library(${LIBRARY} kerr-circular.c) target_link_libraries( ${LIBRARY} PRIVATE GSL::gsl ) target_include_directories(${LIBRARY} SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) ================================================ FILE: external/EffectiveSource/LICENSE.md ================================================ MIT License Copyright (c) 2025 Black Hole Perturbation Toolkit Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: external/EffectiveSource/README.md ================================================ This is a modified version of https://github.com/barrywardell/EffectiveSource (revision 07a31cedfcc895fbdaab47de88825234a03f7cec). This code is licensed under MIT. The license can be found in LICENSE.md. Summary of modifications: - Added CMakeLists.txt. - Added C++ compatibility header `effsource.hpp`. ================================================ FILE: external/EffectiveSource/effsource.h ================================================ /******************************************************************************* * Copyright (C) 2011 Barry Wardell ******************************************************************************/ struct coordinate { double r; double theta; double phi; double t; }; void effsource_init(double M, double a); void effsource_set_particle(struct coordinate * x_p, double e, double l, double ur_p); void effsource_PhiS(struct coordinate * x, double * PhiS); void effsource_calc(struct coordinate * x, double * PhiS, double * dPhiS_dx, double * d2PhiS_dx2, double * src); void effsource_PhiS_m(int m, struct coordinate * x, double * PhiS); void effsource_calc_m(int m, struct coordinate * x, double * PhiS, double * dPhiS_dx, double * d2PhiS_dx2, double * src); ================================================ FILE: external/EffectiveSource/effsource.hpp ================================================ #pragma once extern "C" { #include } ================================================ FILE: external/EffectiveSource/kerr-circular.c ================================================ /******************************************************************************* * Copyright (C) 2012 Barry Wardell ******************************************************************************/ #include #include #include "effsource.h" #include #include /* The particle's coordinate location and 4-velocity */ static struct coordinate xp; /* Mass and spin of the Kerr black hole */ static double M, a; /* Static variables used to store the coefficients of the series expansions */ static double A006, A008, A024, A026, A042, A044, A060, A062, A080, A106, A108, A124, A126, A142, A144, A160, A162, A180, A204, A206, A222, A224, A240, A242, A260, A304, A306, A322, A324, A340, A342, A360, A402, A404, A420, A422, A440, A502, A504, A520, A522, A540, A600, A602, A620, A700, A702, A720, A800, A900; static double alpha20, alpha02, beta; /* Numerical coefficients appearing in the elliptic integrals expressions. The indices here correspond to mode m, EllipticK/EllipticE, order in Sin[dphi]/Sin[dphi/2], term in polynomial in alpha/beta. */ static const double ReEI[21][2][5][27] = { {{{0,-0.26666666666666666,-0.5333333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,0.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.4,0.13333333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,1.2666666666666666,0.5333333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-4,-6.933333333333334,-3.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,1.5333333333333334,1.5333333333333334,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,0.4666666666666667,-0.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,-0.4666666666666667,-0.13333333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-1.5333333333333334,-1.5333333333333334,-0.5333333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,6.866666666666666,8.533333333333333,3.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,-0.4,-0.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,-0.6,-0.26666666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-1.6,-2.4,-1.0666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,9.266666666666667,14.4,6.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.3333333333333335,-24.933333333333334,-38.4,-17.066666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,1.2666666666666666,0.6,0.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,0.06666666666666667,0.7333333333333333,0.26666666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,2.6,2.933333333333333,1.0666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-3.533333333333333,-15.266666666666667,-17.6,-6.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.3333333333333333,10.2,40.93333333333333,46.93333333333333,17.066666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,0,1.6,1.0666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,5,9.066666666666666,4.266666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-7.6,-42,-59.733333333333334,-25.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,30.6,128,166.4,68.26666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.466666666666667,-73.6,-275.2,-341.3333333333333,-136.53333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,0.4666666666666667,-0.6,-2.1333333333333333,-1.0666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-1.1333333333333333,-8.733333333333333,-11.2,-4.266666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,19.8,67.06666666666666,72.53333333333333,25.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-4.2,-69.8,-198.4,-200.53333333333333,-68.26666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.06666666666666667,13.266666666666667,160,420.26666666666665,409.6,136.53333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,0.6666666666666666,-16.4,-34.13333333333333,-17.066666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,41,186.4,247.46666666666667,102.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-17.6,-204,-630.4,-716.8,-273.06666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,65.8,536,1427.2,1501.8666666666666,546.1333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4857142857142858,-153.0857142857143,-1073.3714285714286,-2640.457142857143,-2652.647619047619,-936.2285714285714,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-0.8666666666666667,2.7333333333333334,30.266666666666666,42.666666666666664,17.066666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-3.1333333333333333,-97.4,-290.93333333333334,-298.6666666666667,-102.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,53.8,410.4,937.6,853.3333333333334,273.06666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-4.6,-177.4,-1019.2,-2075.733333333333,-1774.9333333333334,-546.1333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.02857142857142857,14.771428571428572,392.62857142857143,1984,3791.2380952380954,3120.7619047619046,936.2285714285714,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,1.6,-198.4,-814.9333333333333,-1024,-409.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,147.4,1179.7333333333333,3012.266666666667,3072,1092.2666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-31.6,-629.2,-3345.0666666666666,-7116.8,-6553.6,-2184.5333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,114.94285714285714,1556.3428571428572,6981.4857142857145,13497.295238095237,11702.857142857143,3744.9142857142856,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.492063492063492,-263.84761904761905,-3017.295238095238,-12327.009523809524,-22469.485714285714,-18724.571428571428,-5825.422222222222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-2.7333333333333334,18.6,452.26666666666665,1250.1333333333334,1228.8,409.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-5.933333333333334,-401.26666666666665,-2212.266666666667,-4343.466666666666,-3618.133333333333,-1092.2666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,106.2,1463.3333333333333,5879.466666666666,9984,7645.866666666667,2184.5333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-4.885714285714286,-344.0857142857143,-3410.5142857142855,-11886.933333333332,-18646.55238095238,-13575.314285714287,-3744.9142857142856,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.015873015873015872,15.806349206349207,753.3714285714286,6407.466666666666,20597.02857142857,30739.504761904762,21637.28253968254,5825.422222222222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,2.8,-970,-6314.666666666667,-14080,-13107.2,-4369.066666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,380.2,4689.866666666667,19157.333333333332,34508.8,28398.933333333334,8738.133333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-49.6,-1514.1714285714286,-12285.104761904762,-41442.74285714285,-66823.31428571428,-51180.49523809524,-14979.657142857142,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,178.05396825396826,3632.0761904761903,24604.95238095238,74800.76190476191,112737.52380952382,82388.11428571428,23301.68888888889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.494949494949495,-405.9919191919192,-6920.145454545454,-42364.121212121216,-120645.81818181818,-173769.69696969696,-122863.45050505051,-33893.36565656566,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-5.133333333333334,58.2,2479.3333333333335,11306.666666666666,19814.4,15291.733333333334,4369.066666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-9.533333333333333,-1129.9333333333334,-9986.933333333332,-31906.133333333335,-47069.86666666667,-32768,-8738.133333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,178.14285714285714,3892.609523809524,24463.390476190478,66662.4,89604.87619047619,58670.32380952381,14979.657142857142,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.1079365079365076,-573.9968253968254,-8815.314285714287,-47328,-117906.28571428571,-149562.51428571428,-94038.95873015873,-23301.68888888889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.010101010101010102,16.6,1251.761616161616,16279.660606060606,79786.66666666667,187671.27272727274,228846.41616161616,139810.13333333333,33893.36565656566,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,4.266666666666667,-3262.4,-30573.866666666665,-103765.33333333333,-163840,-122333.86666666667,-34952.53333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,811.4,14256.685714285713,84442.81904761905,231716.57142857142,322998.85714285716,222198.24761904762,59918.62857142857,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-71.6,-3111.35873015873,-35753.44761904762,-174188.49523809523,-426296.0761904762,-551126.5523809524,-359511.77142857143,-93206.75555555556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,255.14487734487736,7331.7772005772,69909.00086580086,305560.71341991343,696355.4632034632,856110.1021645021,538057.1797979798,135573.46262626263,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4965034965034967,-579.5630147630147,-13824.999533799533,-118555.33053613054,-483592.47365967365,-1.0497981165501166e6,-1.2450923412587412e6,-761297.1362859363,-187717.1020979021,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-8.066666666666666,135.93333333333334,9026.133333333333,61310.933333333334,166024.53333333333,218453.33333333334,139810.13333333333,34952.53333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-13.933333333333334,-2571.1714285714284,-33332.038095238095,-157322.3619047619,-357171.2,-422863.2380952381,-252157.5619047619,-59918.62857142857,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,270.5174603174603,8617.873015873016,78308.57142857143,312652.8,643189.0285714286,713406.1714285715,406115.1492063492,93206.75555555556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.28975468975469,-870.3079365079365,-19227.160750360752,-147887.70909090908,-536312.6857142857,-1.0362348051948051e6,-1.0997186678210679e6,-605843.911111111,-135573.46262626263,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.006993006993006993,17.244910644910647,1895.0315462315461,35180.35244755245,245442.05874125875,836234.2041958042,1.5471995524475526e6,1.5905439527583527e6,855155.6873348873,187717.1020979021,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,6,-8800.4,-111859.80952380953,-531221.9428571429,-1.2414390857142857e6,-1.5322940952380951e6,-958698.0571428571,-239674.51428571428,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,1529,36268.93968253968,292742.09523809527,1.1256783238095238e6,2.3227830857142857e6,2.6401645714285714e6,1.557884342857143e6,372827.02222222224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-97.6,-5729.1255411255415,-88548.89927849927,-586570.2510822511,-2.0080116917748917e6,-3.8364944623376625e6,-4.1284842943722946e6,-2.3386422303030305e6,-542293.8505050505,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,346.2218004218004,13349.73026973027,170513.0474858475,1.0105419870795871e6,3.214343297236097e6,5.829024556243756e6,6.033182035742036e6,3.3163354703962705e6,750868.4083916084,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4974358974358974,-784.5839937839938,-25005.26247086247,-286327.7053613054,-1.5797995114219114e6,-4.77710082983683e6,-8.342656417715617e6,-8.387304409013209e6,-4.50521045034965e6,-1.0011578778554779e6,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-11.533333333333333,269.4,25857.619047619046,244643.3523809524,941524.1142857143,1.8502997333333334e6,1.9667041523809524e6,1.0785353142857142e6,239674.51428571428,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-19.133333333333333,-5094.479365079365,-91148.63492063493,-595972.8761904762,-1.9178837333333334e6,-3.3857145904761907e6,-3.3492016761904764e6,-1.744297853968254e6,-372827.02222222224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,384.0510822510823,16824.368253968252,209062.3953823954,1.1501940363636364e6,3.3420239238095237e6,5.513081239826839e6,5.196125312554113e6,2.6097891555555556e6,542293.8505050505,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.443600843600843,-1235.5986901986903,-37219.1333999334,-389168.827972028,-1.9364873206793207e6,-5.267843912887113e6,-8.294196586702187e6,-7.550561944366745e6,-3.6917696745920745e6,-750868.4083916084,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.005128205128205128,17.78850038850039,2689.031546231546,67733.57202797203,639727.53006993,2.9806964363636365e6,7.743910966899767e6,1.1785440213830614e7,1.0452192532090131e7,5.005789389277389e6,1.0011578778554779e6,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,8,-20454.4,-338221.5111111111,-2.129646933333333e6,-6.821751466666667e6,-1.2233386666666666e7,-1.2443101866666667e7,-6.7108864e6,-1.491308088888889e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,2637,81197.69581529581,855236.9685425685,4.365921080519481e6,1.2354614081385281e7,2.0404108744588744e7,1.9569787234632034e7,1.0100222965656566e7,2.169175402020202e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-127.6,-9731.779553779554,-194743.272016872,-1.6810041968697968e6,-7.631895255677655e6,-1.9979235561238762e7,-3.121355504229104e7,-2.8716805848018646e7,-1.4349929582595183e7,-3.0034736335664336e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,451.2884670884671,22506.019314019315,371138.143989344,2.8608340821844824e6,1.2051529176956376e7,2.991034232967033e7,4.489893256254856e7,4.0046315114219114e7,1.9522578618181817e7,4.0046315114219114e6,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4980392156862745,-1021.0684583390466,-41964.88205128205,-619011.4680926916,-4.434788679994515e6,-1.7736541547237076e7,-4.234410989606472e7,-6.1679177494547285e7,-5.3709175564952694e7,-2.5676754984999314e7,-5.182464308898944e6,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-15.533333333333333,479.4,63067.02222222222,792570.3111111111,4.1009152e6,1.1153681066666666e7,1.7336456533333335e7,1.55189248e7,7.456540444444444e6,1.491308088888889e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-25.133333333333333,-9153.99163059163,-216262.70476190475,-1.870872972005772e6,-8.079372412121212e6,-1.9716661638095237e7,-2.849857074978355e7,-2.421317832958153e7,-1.1184810666666666e7,-2.169175402020202e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,519.3591075591075,29973.258252858253,488692.7529359529,3.5444105846153847e6,1.3786808101764902e7,3.138413195977356e7,4.3162921822710626e7,3.5328619333022535e7,1.58516663993784e7,3.0034736335664336e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.576934176934177,-1672.0434454434455,-65967.23223443223,-901384.234965035,-5.895572075924076e6,-2.1422238766033966e7,-4.646431837318237e7,-6.163704083294483e7,-4.905673601491842e7,-2.1524894373892773e7,-4.0046315114219114e6,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.00392156862745098,18.25848530554413,3638.6809634809633,119650.73401892226,1.4725623786096256e6,8.997631810448375e6,3.1165726124667488e7,6.523953848801134e7,8.420522974629554e7,6.55758409995338e7,2.8267987139448788e7,5.182464308898944e6,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,10.266666666666667,-42656.4,-889373.995959596,-7.149019797979798e6,-2.9865748169696968e7,-7.235293556363636e7,-1.0554394065454546e8,-9.146124722424242e7,-4.3383508040404044e7,-8.676701608080808e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,4255.4,165053.57016317017,2.19670492991453e6,1.4330180624708625e7,5.29140260997669e7,1.1808499516270396e8,1.624359102955711e8,1.346948423011655e8,6.173806913442113e7,1.2013894534265734e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-161.6,-15539.587434787434,-390961.72201132204,-4.259990718614719e6,-2.4699115148318347e7,-8.432809336796537e7,-1.779399951088911e8,-2.3469069971592852e8,-1.8834282577156177e8,-8.409726173986015e7,-1.6018526045687646e7,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,570.3472906178788,35746.582191664544,739622.7686979687,7.187172049660143e6,3.862786977665472e7,1.249378262920452e8,2.5314112267361397e8,3.234930047362311e8,2.531309910877828e8,1.1071628296284108e8,2.0729857235595778e7,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.498452012383901,-1289.0251146857959,-66438.47422257825,-1.227617738434115e6,-1.107397992473244e7,-5.645272137256345e7,-1.7550347663965014e8,-3.4482027794523466e8,-4.29947715579034e8,-3.2974049077368206e8,-1.4183586529618162e8,-2.6185082823910456e7,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-20.066666666666666,789.9333333333333,136892.39191919193,2.2055480888888887e6,1.4743798173737373e7,5.277455204848485e7,1.1157285546666667e8,1.4395359728484848e8,1.115261196929293e8,4.7721858844444446e7,8.676701608080808e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-31.933333333333334,-15290.940326340326,-461269.8076146076,-5.10054407956488e6,-2.841850342937063e7,-9.11948410927739e7,-1.7918446766247088e8,-2.193337460960373e8,-1.6331127164320123e8,-6.7745016401554e7,-1.2013894534265734e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,676.9748695748696,49810.32203352203,1.0321920394272394e6,9.544164072727272e6,4.781388058341658e7,1.4294413774385613e8,2.6698699182559663e8,3.145956128422688e8,2.2738798300792542e8,9.210652476270397e7,1.6018526045687646e7,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.694581235757706,-2181.5221419103773,-109270.05492285492,-1.892202578033731e6,-1.5744906345607335e7,-7.356716086097433e7,-2.0929734465833253e8,-3.7668167367356825e8,-4.312426213404269e8,-3.046022843375291e8,-1.2108121158063897e8,-2.0729857235595778e7,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.0030959752321981426,18.672520393263426,4748.226915980476,197766.84242568578,3.0782871159107145e6,2.3888763615371626e7,1.062565981512135e8,2.914255876520172e8,5.098456950542433e8,5.706785877375826e8,3.9574872039228964e8,1.5492840670813686e8,2.6185082823910456e7,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,12.8,-81880,-2.1007407614607615e6,-2.095521238228438e7,-1.1023046737156177e8,-3.441285888596737e8,-6.709847600932401e8,-8.259552492307693e8,-6.240550771965812e8,-2.6430567975384617e8,-4.805557813706294e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,6520.2,311067.7942501943,5.102019779331779e6,4.133440304335664e7,1.922698987114219e8,5.530782550526806e8,1.0170620137920746e9,1.1980522605003884e9,8.746782659530692e8,3.6041683602797204e8,6.407410418275058e7,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-199.6,-23628.784478266833,-730166.5007724302,-9.797468315151514e6,-7.051502323959962e7,-3.0318843028131086e8,-8.24417740343672e8,-1.4532290842782943e9,-1.6563077409054527e9,-1.1777150141972852e9,-4.749021839427396e8,-8.291942894238311e7,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,703.3999221968262,54143.24552805296,1.3738612902969064e6,1.6423980970872264e7,1.0950013007528281e8,4.457761957446739e8,1.1633972193432798e9,1.9862208061391819e9,2.20653026587352e9,1.5363898975089884e9,6.088031756559181e8,1.0474033129564182e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.49874686716792,-1588.4598780648316,-100391.40281967774,-2.2721153274630425e6,-2.5192147588914696e7,-1.5919834323671788e8,-6.225945846062396e8,-1.5748847121862333e9,-2.622330288934644e9,-2.854181112514796e9,-1.9537500785578425e9,-7.631081280111047e8,-1.2967850541365178e8,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-25.133333333333333,1228.2,271881.5229215229,5.463605097125097e6,4.5788857465734266e7,2.0806943674778554e8,5.705886187710955e8,9.891261404195805e8,1.0929306833255634e9,7.47197496172805e8,2.883334688223776e8,4.805557813706294e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-39.53333333333333,-24135.788500388502,-905518.1986013986,-1.2458983344832946e7,-8.693429073752914e7,-3.539285428811189e8,-9.016469155505828e8,-1.4824022811648796e9,-1.5738201839888113e9,-1.0428727894327894e9,-3.9245388811934733e8,-6.407410418275058e7,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,857.3689565336624,78373.47438182733,2.0127715456099457e6,2.3112727872974087e7,1.448205784474976e8,5.48772786971836e8,1.3280004404618127e9,2.1005893010457883e9,2.16389478497818e9,1.3996187132419581e9,5.163618984139312e8,8.291942894238311e7,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.799844393652443,-2765.6909199503625,-171565.7852751995,-3.67408829080517e6,-3.790738907893345e7,-2.2126713741740116e8,-7.971567635483366e8,-1.8574286571222606e9,-2.852811286882909e9,-2.870394025251496e9,-1.8211526732190146e9,-6.61173341303739e8,-1.0474033129564182e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.002506265664160401,19.04256314720711,6021.407418450143,310071.7180627422,5.959559314048181e6,5.72743914936333e7,3.179286576710175e8,1.1032734622114787e9,2.4971591341437187e9,3.7476056187814e9,3.700130737674165e9,2.310989422798335e9,8.279473807179306e8,1.2967850541365178e8,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,15.6,-147184.4,-4.556378703962704e6,-5.516948408391608e7,-3.559327987468532e8,-1.3849838370013986e9,-3.448738599742657e9,-5.628697306405595e9,-5.996935688354312e9,-4.0186477217118883e9,-1.537778500386014e9,-2.5629641673100233e8,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,9583.4,551597.1562502857,1.092800063183875e7,1.0752849872261073e8,6.136858642814754e8,2.2008252360679007e9,5.169359078663266e9,8.074326015812789e9,8.312849426393528e9,5.419679834310819e9,2.0277569441364596e9,3.3167771576953244e8,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-241.6,-34531.581210533535,-1.2859442616457501e6,-2.0830391072875936e7,-1.8202685521436995e8,-9.600492874957876e8,-3.2540002685571485e9,-7.325356346213779e9,-1.1069155880596071e10,-1.1097453830148788e10,-7.079345431875746e9,-2.6010515605084386e9,-4.189613251825673e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,850.4475412444452,78893.74837670069,2.409665423174555e6,3.474925120193656e7,2.8114098072956973e8,1.403407938144174e9,4.564031654437904e9,9.948487456287066e9,1.4649250696397833e10,1.4378787962114319e10,9.011876808307611e9,3.2619131746357026e9,5.187140216546071e8,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4989648033126293,-1919.3769533617697,-146019.8335099459,-3.9742071741968985e6,-5.311713496745179e7,-4.071180069944188e8,-1.951471853701304e9,-6.149049338477993e9,-1.3068470999123806e10,-1.8848566822377876e10,-1.8183385037681484e10,-1.1230798287201794e10,-4.014395471935655e9,-6.314779394056087e8,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-30.733333333333334,1824.6,503413.80792540795,1.23437348997669e7,1.2666985013706294e8,7.111014843972028e8,2.4453185536e9,5.440886345756643e9,8.003944371617716e9,7.74195386945641e9,4.739481393767832e9,1.6659267087515152e9,2.5629641673100233e8,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-47.93333333333333,-36410.112500571326,-1.6632604871154989e6,-2.7868508792540792e7,-2.3790098953758398e8,-1.1959445584594543e9,-3.819200511326039e9,-8.057472578080973e9,-1.1386686300517574e10,-1.0673579702376745e10,-6.371368734672261e9,-2.193595802021226e9,-3.3167771576953244e8,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,1060.962421067065,117999.39040993406,3.6796141928934497e6,5.137764483644158e7,3.934568326273124e8,1.8396699858694205e9,5.577640943291375e9,1.131629761773835e10,1.5511646734480068e10,1.4188707002727196e10,8.301315963658234e9,2.8105322230997224e9,4.189613251825673e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.895082488890538,-3426.029950579177,-257947.1453013447,-6.696260875827578e6,-8.390810906845228e7,-5.980646799483613e8,-2.656730813122411e9,-7.751269489416868e9,-1.5263016489000265e10,-2.042660824129106e10,-1.832174708555405e10,-1.0545574516565224e10,-3.521270185463006e9,-5.187140216546071e8,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.002070393374741201,19.377095129336347,7461.561160324547,465737.4659903026,1.0838682409513706e7,1.2638856718220124e8,8.560311134982536e8,3.660454950424734e9,1.0368589915334404e10,1.9940417844891014e10,2.6176608626888607e10,2.310528608711372e10,1.3119593909531069e10,4.330134441638459e9,6.314779394056087e8,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,18.666666666666668,-250822.4,-9.21840527146579e6,-1.3309575831290278e8,-1.0317491250125874e9,-4.880582542269025e9,-1.5029793383663677e10,-3.1108875678233482e10,-4.36671203627632e10,-4.102438746924404e10,-2.470622075987824e10,-8.623620610007843e9,-1.3267108630781298e9,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,13613,930252.8430925112,2.189775853092872e7,2.5704415869336855e8,1.7632092507090087e9,7.688769367066271e9,2.233765721776305e10,4.425202515598031e10,6.002764410921827e10,5.486875815318882e10,3.230882151159315e10,1.1067561673572819e10,1.6758453007302692e9,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-287.6,-48836.168107778016,-2.157297016025873e6,-4.150197552329858e7,-4.325356919968865e8,-2.7414740676285434e9,-1.129721454934732e10,-3.1453610225900883e10,-6.027595384543495e10,-7.961419543169162e10,-7.119894052826602e10,-4.116669092530494e10,-1.3885575348907944e10,-2.0748560866184285e9,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,1011.4910195053149,111321.75903879551,4.0295488900919873e6,6.897135012978844e7,6.652503712536638e8,3.9895117085213494e9,1.5770553504337744e10,4.2506951460346924e10,7.936585512341737e10,1.0261545331623116e11,9.014849059168524e10,5.1342279166782936e10,1.7095009931051834e10,2.5259117576224346e9,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4991304347826087,-2281.7794378338194,-205750.77203382071,-6.631606823604064e6,-1.0514449275916624e8,-9.603493437127837e8,-5.528469326922443e9,-2.116888539068655e10,-5.561882541965658e10,-1.0169630183320364e11,-1.2921016311537668e11,-1.1184445811395491e11,-6.289520276479862e10,-2.0712476412503963e10,-3.0310941091469216e9,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-36.86666666666667,2612.733333333333,880586.5429315782,2.58769066508707e7,3.190248779785548e8,2.165737490196956e9,9.103826722266722e9,2.516944859639786e10,4.714484837223376e10,6.028345544481031e10,5.188494812822027e10,2.876927277805501e10,9.286976041546907e9,1.3267108630781298e9,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-57.13333333333333,-52928.28618502241,-2.8930003372693355e6,-5.799649101182244e7,-5.943782676834052e8,-3.6117879045470395e9,-1.4095434050579176e10,-3.694310664816257e10,-6.646474288799973e10,-8.235087355324098e10,-6.910511159213396e10,-3.752838135449264e10,-1.1905484323937954e10,-1.6758453007302692e9,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,1288.1362155560298,171329.4262403575,6.378245421382333e6,1.0642760530321938e8,9.777255230809364e8,5.52282590456045e9,2.045420469861058e10,5.153708389209838e10,8.991146463998302e10,1.0868422825737668e11,8.937325837111873e10,4.772044308351795e10,1.4923003392217157e10,2.0748560866184285e9,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.982039010629669,-4163.8773617253355,-374174.74996878806,-1.1581383324811196e7,-1.7326355869602597e8,-1.4804164912081263e9,-7.940429316689499e9,-2.828693012341041e10,-6.914758135245525e10,-1.1774449383689468e11,-1.395287760054435e11,-1.1285112004028159e11,-5.941617567775465e10,-1.8357965809863052e10,-2.5259117576224346e9,0,0,0,0,0,0,0,0,0},{0,0,0,-0.0017391304347826088,19.68235392850819,9071.70504037235,675142.9984015393,1.87165462532353e7,2.6038147706447074e8,2.1128045296213334e9,1.0902989617985832e10,3.76931192037466e10,8.995871805969456e10,1.5020871457643378e11,1.7511705338495316e11,1.3969263524174225e11,7.268311082558556e10,2.2228023467077423e10,3.0310941091469216e9,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,22,-408912.4,-1.760144321133892e7,-2.9861306666560435e8,-2.735742086051796e9,-1.5429018250372686e10,-5.7365925635849785e10,-1.459396829211136e11,-2.5834540566109332e11,-3.181407036536493e11,-2.6734969563212573e11,-1.462262308496573e11,-4.692366842044753e10,-6.703381202921077e9,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,18793,1.5042532023658487e6,4.1496704494122185e7,5.725677207573206e8,4.642875405124088e9,2.4142609768578815e10,8.469481355425212e10,2.0624416519975134e11,3.5284625417378284e11,4.227746181988333e11,3.4738564819211395e11,1.8647020933259586e11,5.8893991997092316e10,8.299424346473714e9,0,0,0,0,0,0,0,0,0,0},{0,0,0,-337.6,-67186.71908304376,-3.473936806561178e6,-7.829175553408918e7,-9.589299292985568e8,-7.183900332775953e9,-3.529847566422289e10,-1.1866407812293896e11,-2.795105576516615e11,-4.6559435752690393e11,-5.4578034888958093e11,-4.4032629265684235e11,-2.3272130603976505e11,-7.25297518974442e10,-1.0103647030489738e10,0,0,0,0,0,0,0,0,0},{0,0,0,1,1186.5310195053148,152876.8874522256,6.472435445144703e6,1.2971987635205658e8,1.4699377328144228e9,1.0417012853749659e10,4.909095266192736e10,1.5974095702715295e11,3.6655776122906323e11,5.976373260031626e11,6.881257568365696e11,5.468004776147498e11,2.8525211689964355e11,8.790172916526073e10,1.2124376436587687e10,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4992592592592593,-2675.669679379713,-282242.09231669543,-1.0633815228365488e7,-1.9732870645890525e8,-2.1167235434403558e9,-1.4395851669845222e10,-6.570092170701432e10,-2.08363647527213e11,-4.6815844108415533e11,-7.499685194097299e11,-8.507323675829946e11,-6.674090341577878e11,-3.4432387109323157e11,-1.0507792911709328e11,-1.4369631332252073e10,0,0,0,0,0,0,0}},{{0.5333333333333333,-43.53333333333333,3629.4,1.4694724226778382e6,5.0982079751051836e7,7.433658698673364e8,5.9978865667303295e9,3.02094865091216e10,1.0127974704935579e11,2.3405817896550006e11,3.7868392857216315e11,4.284339090756366e11,3.3229306521589435e11,1.6843118108433334e11,5.027535902190807e10,6.703381202921077e9,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-67.13333333333334,-74599.00473169761,-4.808057892384602e6,-1.1363745491663341e8,-1.3765659670421038e9,-9.93853334295837e9,-4.646297120807411e10,-1.476455595126865e11,-3.276911350438754e11,-5.136740259640373e11,-5.665757674791024e11,-4.3035620039143896e11,-2.143610632661782e11,-6.304370417032917e10,-8.299424346473714e9,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,1539.2381660875133,241314.9715176823,1.0573575649746368e7,2.0780309906924197e8,2.255048448318664e9,1.5127647788083984e10,6.709248572068778e10,2.0490559066010007e11,4.4090160795530695e11,6.741577248596049e11,7.285603048003533e11,5.440348341050625e11,2.6709174817027032e11,7.758157541268906e10,1.0103647030489738e10,0,0,0,0,0,0,0,0,0},{0,0,0,-6.062039010629669,-4980.454188585528,-526689.1747977207,-1.9167077767400973e7,-3.374851933365408e8,-3.4042942107257743e9,-2.167534593874192e10,-9.243454922934729e10,-2.738046230308966e11,-5.748972516712766e11,-8.61570663231068e11,-9.156248791038105e11,-6.740816221370153e11,-3.269296609004137e11,-9.396391738355457e10,-1.2124376436587687e10,0,0,0,0,0,0,0,0},{0,0,0,-0.0014814814814814814,19.963062463129766,10854.591016749811,949896.1873083068,3.0939338982764497e7,5.0627985565643203e8,4.84757118825071e9,2.9683411242703876e10,1.2280305832607028e11,3.5504229585249896e11,7.308189481361008e11,1.0772753882648191e12,1.1289483918947014e12,8.212160109323472e11,3.941685297769809e11,1.1226274478321931e11,1.4369631332252073e10,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,25.6,-642174.4,-3.2001493960675444e7,-6.301171929947947e8,-6.730005930120287e9,-4.45489555789727e10,-1.9627249696235114e11,-5.995497443810022e11,-1.2980003517584287e12,-2.0066420365331858e12,-2.2010916432997065e12,-1.6733714338577625e12,-8.384014633082003e11,-2.4898273039421143e11,-3.3197697385894855e10,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,25323.4,2.3470004379713614e6,7.499139768356036e7,1.2012583049576294e9,1.1358261276733395e10,6.933205150119518e10,2.8824587254763275e11,8.428926177352782e11,1.7637070948449934e12,2.6530579083520938e12,2.8455838704309585e12,2.1231780276189883e12,1.0469973628525146e12,3.067178562827242e11,4.0414588121958954e10,0,0,0,0,0,0,0,0,0},{0,0,0,-391.6,-90283.39413633075,-5.402084146905385e6,-1.409712773254586e8,-2.0042036720084534e9,-1.7506077529181057e10,-1.009677881940971e11,-4.0223835666768646e11,-1.1377089895665e12,-2.317805564538369e12,-3.4109110612635464e12,-3.591988921734658e12,-2.6387589471896216e12,-1.2839931153068442e12,-3.718142107220224e11,-4.8497505746350746e10,0,0,0,0,0,0,0,0},{0,0,0,1,1375.5680565423518,205134.69458317457,1.00442903694642e7,2.3300366348778668e8,3.0639399202108026e9,2.531140817273939e10,1.3999475849889786e11,5.397786494220163e11,1.4872042574435613e12,2.9652929630267153e12,4.285977100720373e12,4.445188146394695e12,3.223045360499386e12,1.5505730309458252e12,4.4456046934154846e11,5.747852532900829e10,0,0,0,0,0,0,0},{0,0,0,0,-3.499361430395913,-3101.049500580224,-378382.55774830375,-1.6479398081656067e7,-3.538256790695258e8,-4.4032169385133705e9,-3.490151422566471e10,-1.869146820137703e11,-7.023015906202007e11,-1.8944051915725413e12,-3.7109112830375283e12,-5.283759154390902e12,-5.409848733761012e12,-3.8788481619419673e12,-1.8478757481648335e12,-5.2523480042024817e11,-6.7388615902975235e10,0,0,0,0,0,0}},{{0.5333333333333333,-50.733333333333334,4914.6,2.3567543213508883e6,9.531948442077139e7,1.6222566814226518e9,1.533629951143212e10,9.106927966780995e10,3.6324193033461017e11,1.0115537476095123e12,2.0078489418750176e12,2.859678973879202e12,2.902119927570143e12,2.0490001876928757e12,9.566682602454508e11,2.6558157908715884e11,3.3197697385894855e10,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-77.93333333333334,-102426.67594272287,-7.688375333570598e6,-2.1157272142042986e8,-2.9899660626777706e9,-2.5285472574644356e10,-1.39341099517905e11,-5.2671795525996155e11,-1.4085398898401514e12,-2.708603610196061e12,-3.76067732280449e12,-3.7374252386297983e12,-2.5929559786286685e12,-1.1927785557210093e12,-3.269251503437037e11,-4.0414588121958954e10,0,0,0,0,0,0,0,0,0},{0,0,0.2,1814.5882726615152,331222.3335493492,1.6875662577301286e7,3.858469039048684e8,4.882312146902555e9,3.834964651451061e10,2.0043215049773267e11,7.280122943454908e11,1.8871102433942173e12,3.5392202281469395e12,4.81403000415386e12,4.70284874154185e12,3.215586981496385e12,1.4608069383404146e12,3.9606296359519775e11,4.8497505746350746e10,0,0,0,0,0,0,0,0},{0,0,0,-6.136113084703743,-5876.883265298239,-722621.9636936528,-3.0552356959223974e7,-6.254641839081137e8,-7.35329135286915e9,-5.480054731379718e10,-2.753158133060997e11,-9.696738980136191e11,-2.4522191929156543e12,-4.506888343001096e12,-6.027500191226616e12,-5.804540636175082e12,-3.920365399720353e12,-1.7620760421174104e12,-4.732997320060526e11,-5.747852532900829e10,0,0,0,0,0,0,0},{0,0,0,-0.001277139208173691,20.222883663640623,12812.749057488787,1.302854067321981e6,4.927317433912787e7,9.370025785364087e8,1.045225177549322e10,7.488955072282285e10,3.6490079744731726e11,1.254099223039917e12,3.108551076865836e12,5.618437072552979e12,7.408490300586078e12,7.048384464155902e12,4.710622193686491e12,2.09785778289315e12,5.589291083717358e11,6.7388615902975235e10,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,29.466666666666665,-976730,-5.578954646189742e7,-1.2615869100582263e9,-1.5529302994019297e10,-1.1910193801450629e11,-6.125072742936332e11,-2.206143296031422e12,-5.709225768796877e12,-1.0749971748792695e13,-1.4747065224375662e13,-1.4582852118589701e13,-1.0122591368671906e13,-4.679251530995561e12,-1.2932668199026865e12,-1.6165835248783582e11,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,33420.2,3.550881250122197e6,1.3009442746062008e8,2.3938339984597726e9,2.6090461836376514e10,1.8454580335053577e11,8.956680843174019e11,3.088494496941551e12,7.725403893782204e12,1.415456345665883e13,1.898742633772399e13,1.842784153284401e13,1.2590136522466424e13,5.741108749446352e12,1.5680860191320073e12,1.9399002298540298e11,0,0,0,0,0,0,0,0},{0,0,0,-449.6,-118882.34141578716,-8.1507702655822905e6,-2.4382796059468478e8,-3.981492068669497e9,-4.008401440642937e10,-2.6788273341492886e11,-1.2457916692080254e12,-4.155022019169404e12,-1.011883380132408e13,-1.8137213625744375e13,-2.3887559953693965e13,-2.2825549173918258e13,-1.538763792071379e13,-6.935816898196855e12,-1.8752368888588955e12,-2.2991410131603317e11,0,0,0,0,0,0,0},{0,0,0,1,1578.6025393009725,269796.6997164444,1.5129675524776911e7,4.02205042950141e8,6.073244823885286e9,5.781867124578261e10,3.705046212385272e11,1.6674750698719607e12,5.417057116138862e12,1.2910569366340434e13,2.272747357675429e13,2.947861243273825e13,2.7800233539143176e13,1.8528636980494258e13,8.268499554905844e12,2.2158962523390093e12,2.6955446361190094e11,0,0,0,0,0,0},{0,0,0,0,-3.49944382647386,-3557.9203447280424,-497291.8376827858,-2.479476383769259e7,-6.098901382048699e8,-8.713451379196568e9,-7.957942158518886e10,-4.937089707091298e11,-2.1650359733823113e12,-6.885306538377396e12,-1.6120601827215521e13,-2.7953517732769695e13,-3.579038142482068e13,-3.3375171285503258e13,-2.2026160316691473e13,-9.744096556853e12,-2.5912009727853706e12,-3.1303099000091724e11,0,0,0,0,0}},{{0.5333333333333333,-58.46666666666667,6511.533333333334,3.65374292379483e6,1.7041039042477334e8,3.3474383786596866e9,3.6634576706844986e10,2.5307096312507574e11,1.1825685116914846e12,3.8959211372933706e12,9.271173514538479e12,1.6125338479467012e13,2.0514656081142355e13,1.8879270148820613e13,1.2234885075983668e13,5.295573999855435e12,1.3740959961466045e12,1.6165835248783582e11,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-89.53333333333333,-137512.7002443942,-1.189358210895399e7,-3.7701063823343146e8,-6.146753773932911e9,-6.016166039394057e10,-3.856178138857783e11,-1.7075189529981672e12,-5.401437822018391e12,-1.2451974168004955e13,-2.1111659790717637e13,-2.6300614293483598e13,-2.3782945860158555e13,-1.5184861333257229e13,-6.488778629702592e12,-1.665081030624709e12,-1.9399002298540298e11,0,0,0,0,0,0,0,0},{0,0,0.2,2114.4828315743325,444637.2286422091,2.6068237359630816e7,6.861001365773908e8,1.00114325811189e10,9.098481065241385e10,5.529740045299663e11,2.3523822512552803e12,7.2120144708876045e12,1.621315950309689e13,2.692705307551175e13,3.29716634138851e13,2.938224475952283e13,1.8525493900149555e13,7.830326448629547e12,1.990193939516912e12,2.2991410131603317e11,0,0,0,0,0,0,0},{0,0,0,-6.2050786019451225,-6854.203876665512,-969805.7488195399,-4.71490524203349e7,-1.110535871836198e9,-1.5050298809158161e10,-1.2973475579082533e11,-7.577552802741434e11,-3.1251463627856104e12,-9.3459380263197e12,-2.058641033023447e13,-3.3613123793561336e13,-4.056896085255746e13,-3.57073389951639e13,-2.2272676941597234e13,-9.325906219148117e12,-2.3506734841449595e12,-2.6955446361190094e11,0,0,0,0,0,0},{0,0,0,-0.0011123470522803114,20.46471615241416,14948.520395986918,1.7481414056108568e6,7.598676584469618e7,1.6618757729228277e9,2.1362875654996433e10,1.7699538829298035e11,1.0024052815552432e12,4.0333265266471006e12,1.182051050899169e13,2.5601839654882164e13,4.120957066054989e13,4.913190571704601e13,4.278719239553509e13,2.6441705068033305e13,1.0981003732620514e13,2.747716467785829e12,3.1303099000091724e11,0,0,0,0,0}}}, {{{0,-0.26666666666666666,33.6,-1.4449664e6,-9.378112396360818e7,-2.4134343369641385e9,-3.3903936051757397e10,-2.9801676779554596e11,-1.7669252650270583e12,-7.395409184951448e12,-2.247442917360153e13,-5.039491703618102e13,-8.391129263208694e13,-1.034420381542176e14,-9.311814740541167e13,-5.94700664214626e13,-2.5517770940204883e13,-6.595660781503701e12,-7.759600919416119e11,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,43315.4,5.230291427936181e6,2.1780053830000895e8,4.561721534340654e9,5.6748630670697624e10,4.600956128255938e11,2.574621229746886e12,1.0317263052979926e13,3.0307188769397027e13,6.613140421026188e13,1.0767812330799452e14,1.302827448528449e14,1.1543547237775336e14,7.272605132546514e13,3.083902504292948e13,7.888927601406388e12,9.196564052641327e11,0,0,0,0,0,0,0},{0,0,0,-511.6,-153795.69885244747,-1.1978643183124974e7,-4.072033459630186e8,-7.567600637131104e9,-8.695493057921883e10,-6.660723636188911e11,-3.571363466702473e12,-1.384223532826015e13,-3.9588090502665234e13,-8.450579365558694e13,-1.3509302529267044e14,-1.609267891315999e14,-1.4069221688269344e14,-8.761436750764872e13,-3.677597449159481e13,-9.323413211988104e12,-1.0782178544476038e12,0,0,0,0,0,0},{0,0,0,1,1795.6347973654888,348690.3862286264,2.2204228030820765e7,6.705854777632657e8,1.1522110280379248e10,1.2517973983561208e11,9.19332170318912e11,4.770007373158425e12,1.8007053868363406e13,5.039707192316374e13,1.056513773616503e14,1.663261076501606e14,1.955389474170697e14,1.6900738607205572e14,1.0419707990723603e14,4.335070020676101e13,1.0903912818365283e13,1.252123960003669e12,0,0,0,0,0},{0,0,0,0,-3.4995112414467253,-4046.283374356923,-642320.5204937553,-3.6354442541503884e7,-1.0156406403679376e9,-1.6508254693268639e10,-1.7202985544924103e11,-1.2230324761502656e12,-6.182633991853942e12,-2.2846441388588523e13,-6.281007640234248e13,-1.2969530267124028e14,-2.0154019556485406e14,-2.3427740497541834e14,-2.0049551613303962e14,-1.2253405597896867e14,-5.058454321247145e13,-1.2635069050946113e13,-1.4418397115193762e12,0,0,0,0}},{{0.5333333333333333,-66.73333333333333,8466.6,5.500782327216349e6,2.9307562486459124e8,6.580662628830447e9,8.25198689979895e10,6.557192881581038e11,3.544366348591472e12,1.3610364338969898e13,3.81402493752755e13,7.919889465707464e13,1.2257383139758511e14,1.4091199728388275e14,1.1864488533235611e14,7.106501175365262e13,2.8670108813717684e13,6.983640827474507e12,7.759600919416119e11,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-101.93333333333334,-181056.65587236284,-1.787733779890622e7,-6.467215044849563e8,-1.2047942031497614e10,-1.3508357853771237e11,-9.958337708633071e11,-5.100215968856238e12,-1.8803864759217754e13,-5.1043402609364266e13,-1.0331528027101834e14,-1.565720156503844e14,-1.7685958939722884e14,-1.4670592314888475e14,-8.675260770965969e13,-3.461105326764565e13,-8.348755804038454e12,-9.196564052641327e11,0,0,0,0,0,0,0},{0,0,0.2,2439.19770489493,585468.939241731,3.91400351372385e7,1.1749495789312527e9,1.958269650268004e10,2.0382117002694974e11,1.4244548817255012e12,7.007773329261644e12,2.5037504149523434e13,6.627085088332564e13,1.3138571746780752e14,1.956929732604737e14,2.1782474594777912e14,1.7841953684261428e14,1.0435529770005283e14,4.123551524987994e13,9.862522139211904e12,1.0782178544476038e12,0,0,0,0,0,0},{0,0,0,-6.2695947309773805,-7913.383352642443,-1.2767836155293747e6,-7.073831350388925e7,-1.899554623143067e9,-2.939480935713848e10,-2.901204668878392e11,-1.9481763004141086e12,-9.290239953778574e12,-3.237296296631215e13,-8.39479743534346e13,-1.6360610601542472e14,-2.401716637111394e14,-2.6402193545879147e14,-2.1393204742321744e14,-1.2394533297842339e14,-4.856788337344296e13,-1.1529974798367117e13,-1.252123960003669e12,0,0,0,0,0},{0,0,0,-0.0009775171065493646,20.69089338637782,17264.0838134564,2.3011678842776404e6,1.1394226862290737e8,2.840139762731206e9,4.167633267110191e10,3.95266965553167e11,2.5731613895229917e12,1.1969456812409002e13,4.086863287421054e13,1.0419401598474152e14,2.0016347293020044e14,2.902331341320077e14,3.156571512430503e14,2.533843334077847e14,1.4559242461110694e14,5.6631732792034625e13,1.33559889067058e13,1.4418397115193762e12,0,0,0,0}}}, {{{0,-0.26666666666666666,38,-2.0864644e6,-1.5269386717706367e8,-4.4364839170700865e9,-7.052545524685811e10,-7.039261202593761e11,-4.761725707062858e12,-2.288315999285902e13,-8.050868479032589e13,-2.1126861740115747e14,-4.1760113688084575e14,-6.230137174218235e14,-6.97244682853531e14,-5.760027708229431e14,-3.406464803623676e14,-1.3638576338223748e14,-3.3107630589508773e13,-3.678625621056531e12,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,55257,7.524884401159955e6,3.534212218718977e8,8.358422454073611e9,1.1767720205354315e11,1.0834651446175271e12,6.917863829651936e12,3.183148547582819e13,1.0825791495805245e14,2.7646060697452588e14,5.3439199490061275e14,7.825097493435275e14,8.619879647594399e14,7.024798614322576e14,4.105674340973219e14,1.6268776314620662e14,3.913296565848068e13,4.312871417790415e12,0,0,0,0,0,0},{0,0,0,-577.6,-195891.5954785697,-1.720127764558216e7,-6.593956434546355e8,-1.3836051116645775e10,-1.7991428787352527e11,-1.5649809531653018e12,-9.574263945472568e12,-4.260947812998459e13,-1.4108556267746003e14,-3.5246266137808444e14,-6.68904000078248e14,-9.643324596899239e14,-1.0481525855129518e15,-8.443224624053235e14,-4.884650317232749e14,-1.9181971314970422e14,-4.577208698235634e13,-5.008495840014676e12,0,0,0,0,0},{0,0,0,1,2026.6651003957916,443769.2062382361,3.1848062618839644e7,1.084383682742406e9,2.1033538298344963e10,2.5857382719851614e11,2.1562791411962607e12,1.2764669581045951e13,5.532758658800373e13,1.7926934003434116e14,4.398155867559162e14,8.21954813552544e14,1.1694384435544125e15,1.2565957550652905e15,1.0021077247917248e15,5.746217280770576e14,2.2387644402300447e14,5.304452412379179e13,5.767358846077505e12,0,0,0,0},{0,0,0,0,-3.4995670995670998,-4566.139539696959,-817050.1240826164,-5.210286556396761e7,-1.6407138496930685e9,-3.010064457529331e10,-3.548915820326058e11,-2.864643885149056e12,-1.6520807008205463e13,-7.0090278456826984e13,-2.2307320285268588e14,-5.3903548690406256e14,-9.943274230202304e14,-1.3987464189591615e15,-1.488142833281783e15,-1.1763925899836822e15,-6.693106216369468e14,-2.589498048063432e14,-6.0969222087105055e13,-6.591267252660006e12,0,0,0}},{{0.5333333333333333,-75.53333333333333,10829.4,8.072048354127319e6,4.87250210500034e8,1.2400772896941032e10,1.7659692941512448e11,1.5987019273419814e12,9.889499268944688e12,4.3725671416071375e13,1.4222478427288353e14,3.464460612721393e14,6.378941277981012e14,8.892327870204825e14,9.324932431776439e14,7.236581421029889e14,4.029765524699275e14,1.5224983637304378e14,3.494694340003704e13,3.678625621056531e12,0,0,0,0,0,0,0},{0,0.13333333333333333,-115.13333333333334,-234357.4023199112,-2.6202969245825373e7,-1.0729925112854352e9,-2.264892860478733e10,-2.8833628269220435e11,-2.421334407948635e12,-1.4190732511616314e13,-6.023738501346369e13,-1.897848476488173e14,-4.506023042846216e14,-8.123862868785152e14,-1.1127081259761939e15,-1.1495259687556288e15,-8.80694584160074e14,-4.849782163048779e14,-1.8144558258461128e14,-4.128940136737588e13,-4.312871417790415e12,0,0,0,0,0,0},{0,0,0.2,2788.9909571394373,757954.1832518226,5.731896737696369e7,1.9467522753006718e9,3.6752178916813446e10,4.342367668300395e11,3.456417626472393e12,1.945586960892444e13,8.002395364327356e13,2.45820394128803e14,5.716362792738416e14,1.0128387071687611e15,1.366953901980593e15,1.394401321620245e15,1.0566084586443459e15,5.762621684739365e14,2.1376666367087962e14,4.827633490236368e13,5.008495840014676e12,0,0,0,0,0},{0,0,0,-6.330200791583441,-9055.326402164885,-1.652817817493035e6,-1.0353224612455417e8,-3.1443424489415655e9,-5.5099878956043625e10,-6.172115086692606e11,-4.719665182766741e12,-2.5747979102863504e13,-1.0327781515594061e14,-3.107840698734769e14,-7.103751521762541e14,-1.240428258290523e15,-1.6532690684504498e15,-1.6682200228770388e15,-1.2521020933688375e15,-6.771547917071688e14,-2.4931732630126084e14,-5.592820354683055e13,-5.767358846077505e12,0,0,0,0},{0,0,0,-0.0008658008658008658,20.90332181816109,19761.47677528686,2.9786440888161287e6,1.6669440060546213e8,4.697988868588864e9,7.804846936458011e10,8.399601182809939e11,6.225772187860445e12,3.3126459614313613e13,1.3018123394897244e14,3.8510657020790756e14,8.676089997567239e14,1.4962826923778152e15,1.9729018315606848e15,1.9720423433634065e15,1.4678534354359658e15,7.87971726203723e14,2.8819855324002194e14,6.4264855713435055e13,6.591267252660006e12,0,0,0}}}, {{{0,-0.26666666666666666,42.666666666666664,-2.9489904e6,-2.4170614799515897e8,-7.873218384663625e9,-1.405806642582533e11,-1.580544280937379e12,-1.2090386727568768e13,-6.6042366119374336e13,-2.65868882310363e14,-8.051739775983438e14,-1.857133409027708e15,-3.2801533762918805e15,-4.4314102156757605e15,-4.540487334262183e15,-3.465694635513561e15,-1.9084456023722588e15,-7.161903536719025e14,-1.6388911387603578e14,-1.725148567116166e13,0,0,0,0,0,0},{0,0,-0.06666666666666667,69509,1.060304375629801e7,5.578470160261151e8,1.479270594762511e10,2.3394997790297177e11,2.4264918279035615e12,1.7521030242218191e13,9.164276368056673e13,3.5664655366664625e14,1.05113206044863e15,2.370956512005569e15,4.1103527541472025e15,5.465870295900822e15,5.524844013590857e15,4.167585692773008e15,2.2713467255841065e15,8.446251275105141e14,1.917140907650062e14,2.0033983360058703e13,0,0,0,0,0},{0,0,0,-647.6,-246094.15250627516,-2.4198988932992294e7,-1.038980191421611e9,-2.444203632713007e10,-3.570077983612116e11,-3.498184851505777e12,-2.4202280989027707e13,-1.2243539925589284e14,-4.638933812042697e14,-1.3374968892379465e15,-2.9619773218874905e15,-5.055557384458424e15,-6.63336672836086e15,-6.627413577564161e15,-4.948584988121854e15,-2.672802925395651e15,-9.85971732202283e14,-2.2219508817519653e14,-2.306943538431002e13,0,0,0,0},{0,0,0,1,2271.693671824363,557112.5844066336,4.4760097703188986e7,1.7065933499774168e9,3.710782171508295e10,5.123704928625934e11,4.812792440204033e12,3.2217907329529703e13,1.587313473404659e14,5.885027219728265e14,1.6662726075609255e15,3.6337254670711775e15,6.120647631772677e15,7.939169799895172e15,7.852589702803345e15,5.811463115882084e15,3.1140914617754305e15,1.1406361435129525e15,2.5541160604057522e14,2.6365069010640023e13,0,0,0},{0,0,0,0,-3.4996138996138995,-5117.489627447047,-1.0252931044630904e6,-7.317764631938808e7,-2.5799387735712266e9,-5.305164082877038e10,-7.024571823174719e11,-6.386343641756565e12,-4.1646702455182195e13,-2.0082495548407444e14,-7.313240134063729e14,-2.0393725447628995e15,-4.389582156680698e15,-7.310312322718411e15,-9.388355782488322e15,-9.204613694406318e15,-6.75889981067322e15,-3.596449851906305e15,-1.3090123157014138e15,-2.9144089798248025e14,-2.9927916174240027e13,0,0}},{{0.5333333333333333,-84.86666666666666,13652.733333333334,1.1580743990317933e7,7.862366731187782e8,2.251285321019336e10,3.6126970425140875e11,3.6950296972946763e12,2.591996982109244e13,1.3060390853963811e14,4.872588592243463e14,1.3728326184824732e15,2.955623641337104e15,4.887098724271143e15,6.197174104927707e15,5.97435514747484e15,4.3000613327664335e15,2.2374288971381245e15,7.949002570465775e14,1.725148567116166e14,1.725148567116166e13,0,0,0,0,0,0},{0,0.13333333333333333,-129.13333333333333,-298814.1125960173,-3.756041742575181e7,-1.7285393875937688e9,-4.103692427927973e10,-5.885977025139501e11,-5.58378211235412e12,-3.710691956026596e13,-1.7949438370340738e14,-6.486221072613646e14,-1.7811709048134368e15,-3.7547456752020125e15,-6.099911491230204e15,-7.620161622284745e15,-7.252241847091468e15,-5.161779213919494e15,-2.65959108326093e15,-9.367258010130061e14,-2.0173108244503553e14,-2.0033983360058703e13,0,0,0,0,0},{0,0,0.2,3164.105012550278,966660.7328705739,8.210917088666102e7,3.1326839561683073e9,6.649903112671311e10,8.850518794573038e11,7.957226405896327e12,5.07826266196542e13,2.3800231954847772e14,8.384811979980429e14,2.2550231205737835e15,4.671485049782065e15,7.477796091175499e15,9.223459380199674e15,8.681741711096794e15,6.119697195173343e15,3.1262899720312225e15,1.0927437571553231e15,2.3372980586735153e14,2.306943538431002e13,0,0,0,0},{0,0,0,-6.387343648726298,-10280.88273895997,-2.1078979265578426e6,-1.482407551004836e8,-5.055907877161912e9,-9.959690402930423e10,-1.2564964279090027e12,-1.0850994538243352e13,-6.710880700339022e13,-3.066885058028235e14,-1.0583451011894089e15,-2.7975704791687135e15,-5.711120851896802e15,-9.02764697095337e15,-1.10141153245736e16,-1.0268428227212878e16,-7.177155441784758e15,-3.6389915826190465e15,-1.2633984960937452e15,-2.6859414054589525e14,-2.6365069010640023e13,0,0,0},{0,0,0,-0.0007722007722007722,21.103579218418492,22442.61268540996,3.7985964582853154e6,2.3859794710035256e8,7.549734457672135e9,1.4096953641872162e11,1.7083678819651787e12,1.429842236994991e13,8.623782828471784e13,3.860843010721173e14,1.3096501921718585e15,3.4118527798952095e15,6.87871387556754e15,1.0756091873106256e16,1.2998921089798014e16,1.2017683521567574e16,8.337385441942756e15,4.199116583526632e15,1.4491212804099838e15,3.0640485606960025e14,2.9927916174240027e13,0,0}}}, {{{0,-0.26666666666666666,47.6,-4.0895524e6,-3.731306038384463e8,-1.3541340916361624e10,-2.698066970601489e11,-3.3929623532272686e12,-2.912501505968892e13,-1.792856932147624e14,-8.178001345526671e14,-2.825665552462115e15,-7.50119392296909e15,-1.5421119083184214e16,-2.46069867650868e16,-3.036845308130471e16,-2.8690118845028184e16,-2.035084821245431e16,-1.0484659979090722e16,-3.7026001121730715e15,-8.013593344023481e14,-8.013593344023481e13,0,0,0,0,0},{0,0,-0.06666666666666667,86351.4,1.4665579721461162e7,8.590687659123018e8,2.5382910206863052e10,4.4799089906092065e11,5.197549704634442e12,4.2116936060807555e13,2.4826316584141612e14,1.0947767893988114e15,3.681377038739813e15,9.557508586062312e15,1.928610504650084e16,3.02919821648759e16,3.68806750791929e16,3.4434258261705336e16,2.417434564050942e16,1.2341328990945152e16,4.323002238921354e15,9.288483194209035e14,9.227774153724008e13,0,0,0,0},{0,0,0,-721.6,-305383.484221278,-3.3425150558028962e7,-1.5976051302013426e9,-4.187439493752403e10,-6.825325957092296e11,-7.480870721296626e12,-5.808146779339898e13,-3.311329496999199e14,-1.421626589092943e15,-4.676542004989115e15,-1.1920141073940436e16,-2.3681684177511636e16,-3.670117139829947e16,-4.416718389230369e16,-4.0819063755733816e16,-2.8399638601169932e16,-1.4382537224523932e16,-5.001926254562189e15,-1.067785294930921e15,-1.054602760425601e14,0,0,0},{0,0,0,1,2530.72069885139,690925.9210848194,6.1773305205390684e7,2.6215136024899797e9,6.350186022610584e10,9.783737218417522e11,1.0279134468481693e13,7.721651964503972e13,4.287219179136568e14,1.8010359258476095e15,5.818025681991426e15,1.460298629964141e16,2.8630185446713732e16,4.3862993135598696e16,5.225649481076826e16,4.7866759281312376e16,3.3039905722220736e16,1.6614027170527334e16,5.741105116040728e15,1.218493729951201e15,1.1971166469696011e14,0,0},{0,0,0,0,-3.4996534996535,-5700.334296291716,-1.2710928628651593e6,-1.0093436202872059e8,-3.9601706432110143e9,-9.070909301290082e10,-1.3400853937505337e12,-1.3626158227398803e13,-9.970831360069828e13,-5.418127541007572e14,-2.2355599883931558e15,-7.112384380705038e15,-1.7619359196305414e16,-3.415306825634278e16,-5.180484759888663e16,-6.1176142561382664e16,-5.559884636602166e16,-3.810791930105565e16,-1.904137287813753e16,-6.54222329112722e15,-1.3812884388110782e15,-1.350593140170832e14,0}},{{0.5333333333333333,-94.73333333333333,16992.6,1.6284696076892616e7,1.2354648054405298e9,3.953909107382076e10,7.10090176204812e11,8.145748277303172e12,6.428556882265668e13,3.6590982390426875e14,1.5502704689894388e15,4.993707604738265e15,1.2398036774129854e16,2.3903947362329856e16,3.5861500931598584e16,4.170569864198567e16,3.720611350142881e16,2.496972481358118e16,1.2193217903736838e16,4.0882542918542015e15,8.414273011224655e14,8.013593344023481e13,0,0,0,0,0},{0,0.13333333333333333,-143.93333333333334,-375927.24292232457,-5.278450853716055e7,-2.7125229474487467e9,-7.195565577844536e10,-1.1548552468425483e12,-1.2286437334588822e13,-9.185201223250092e13,-5.0188188887196794e14,-2.0594686450678228e15,-6.465664297334423e15,-1.5717197545820644e16,-2.9773055055612476e16,-4.400198164051586e16,-5.051762663082156e16,-4.456554705592129e16,-2.961652536463062e16,-1.4337322088783526e16,-4.770124322093573e15,-9.749871901895235e14,-9.227774153724008e13,0,0,0,0},{0,0,0.2,3564.768442556024,1.2164908134451648e6,1.1533096610258973e8,4.911578657437878e9,1.1646951484526044e11,1.7342546082017852e12,1.7484020896956271e13,1.2551336178335739e14,6.644159134672428e14,2.6578960250785765e15,8.171790366631361e15,1.9520413309070224e16,3.643312168795762e16,5.316310532259258e16,6.036333626184364e16,5.273684513072426e16,3.4747435047530596e16,1.6693177509884468e16,5.516045100269669e15,1.120515432952201e15,1.054602760425601e14,0,0,0},{0,0,0,-6.441397702780352,-11590.853392628731,-2.6527484863642906e6,-2.081436499095543e8,-7.921865093783669e9,-1.742928669332534e11,-2.459659492823631e12,-2.3815795421580676e13,-1.6566332438371656e14,-8.550505095885778e14,-3.35024333679381e15,-1.0123366574848608e16,-2.382922456508392e16,-4.391688037572645e16,-6.338437811869518e16,-7.128043872024897e16,-6.174789017813265e16,-4.037820760670786e16,-1.9267335122747188e16,-6.327906043885648e15,-1.2783495622996812e15,-1.1971166469696011e14,0,0},{0,0,0,-0.000693000693000693,21.292986207825482,25309.29515631317,4.780381324186655e6,3.3492374593636465e8,1.1823731636670485e10,2.4653622561126352e11,3.3416154029679727e12,3.135410116283323e13,2.126729757114602e14,1.0752440457778672e15,4.1409771925451395e15,1.233117595422076e16,2.8664288229529544e16,5.225580879389953e16,7.470388245200797e16,8.330526615716496e16,7.162566653980231e16,4.652411455487196e16,2.2066154752113164e16,7.207543889154556e15,1.4488180958196198e15,1.350593140170832e14,0}}}, {{{0,-0.26666666666666666,52.8,-5575520,-5.632173785675783e8,-2.264573851170883e10,-5.005643706894967e11,-6.997344021760841e12,-6.694984221034684e13,-4.609967645533807e14,-2.3627840501606355e15,-9.225264284921132e15,-2.7870762591869724e16,-6.579211913432579e16,-1.219269835005012e17,-1.7736434748785085e17,-2.014372433713144e17,-1.7653028386935773e17,-1.1695051216654723e17,-5.660662707425071e16,-1.887747613881895e16,-3.8756651445640835e15,-3.691109661489603e14,0,0,0,0},{0,0,-0.06666666666666667,106080.2,1.9949649623509426e7,1.2939911180306041e9,4.2363534986906364e10,8.295293999689657e11,1.0698737964202242e13,9.66363247645834e13,6.372094391758614e14,3.1574388239306565e15,1.1998128373402768e16,3.545022868007551e16,8.214242163461622e16,1.498448307438975e17,2.1504119173799283e17,2.413696663998524e17,2.0935359957837e17,1.3743658725905952e17,6.598443928517343e16,2.1845367673730504e16,4.455696662798164e15,4.218411041702404e14,0,0,0},{0,0,0,-799.6,-374795.69873168645,-4.541501586740491e7,-2.4033232898026366e9,-6.979280795787791e10,-1.2620648339616711e12,-1.5377051478454482e13,-1.3307719247169702e14,-8.486965787241058e14,-4.0942474686362435e15,-1.521973082413072e16,-4.415040755395909e16,-1.0071975616913048e17,-1.8128971785509302e17,-2.5715892674943798e17,-2.8571552176641878e17,-2.4559351140219373e17,-1.5993872560572854e17,-7.623776610305851e16,-2.5076921618640444e16,-5.084895471889925e15,-4.7884665878784044e14,0,0},{0,0,0,1,2803.746339877031,847540.594948172,8.387088415905303e7,3.940171303117425e9,1.057365813099728e11,1.8072133228725144e12,2.1105818071761484e13,1.7671976487014494e14,1.0975457428896409e15,5.180820146125421e15,1.8912018709994548e16,5.402178465503179e16,1.2161716004687645e17,2.1639908949667334e17,3.038797903142797e17,3.3462662569227334e17,2.853611054467527e17,1.845190954017643e17,8.739229013859099e16,2.857951555540064e16,5.764577084638233e15,5.402372560683328e14,0},{0,0,0,0,-3.499687304565353,-6314.674103265669,-1.5587237516807944e6,-1.3697283658064875e8,-5.948433133232432e9,-1.5092828425611444e11,-2.4733417883407153e12,-2.7953736163984633e13,-2.2798507703929834e14,-1.3857335293027922e15,-6.424397479638844e15,-2.30959575834661e16,-6.511275177576189e16,-1.4492407203283318e17,-2.5530540726016147e17,-3.553604828117912e17,-3.882498975703751e17,-3.287640702824053e17,-2.1123805647598467e17,-9.947298157155096e16,-3.2360331425024412e16,-6.496023591260685e15,-6.06119848271788e14}},{{0.5333333333333333,-105.13333333333334,20908.2,2.2492357135156598e7,1.8958309719109235e9,6.741542072724315e10,1.3467332712719966e12,1.721588784468186e13,1.517969171625762e14,9.68623788198903e14,4.620809634242403e15,1.6852457171265348e16,4.7703107096260296e16,1.0578958618367114e17,1.8461804798071936e17,2.5344496869855994e17,2.7218267219337744e17,2.2596420895370938e17,1.4205763700894958e17,6.535328208213089e16,2.074610040494806e16,4.0602206276385635e15,3.691109661489603e14,0,0,0,0},{0,0.13333333333333333,-159.53333333333333,-467299.4470188559,-7.287456290234995e7,-4.157830371714083e9,-1.2252070190736252e11,-2.186990850552188e12,-2.5926110989630664e13,-2.1653318849256094e14,-1.326322841173958e15,-6.127978836743251e15,-2.1781741790169716e16,-6.036681088296472e16,-1.3152785185627565e17,-2.2611628841057744e17,-3.06435432704922e17,-3.2542265994529766e17,-2.6752084016889734e17,-1.667276585666764e17,-7.611122760127998e16,-2.3994120798097664e16,-4.666617214883284e15,-4.218411041702404e14,0,0,0},{0,0,0.2,3991.1974633728914,1.5126843075902709e6,1.591637552639756e8,7.523047958345665e9,1.981274589389424e11,3.28062880467928e12,3.684945335931074e13,2.9550727863338325e14,1.753482804920874e15,7.897512890513422e15,2.748953095986418e16,7.486280786775282e16,1.6070534554507542e17,2.7277027276789126e17,3.6558244328737126e17,3.8447574794727104e17,3.133601408355606e17,1.9380644168944502e17,8.786770088566074e16,2.7529585606062684e16,5.324318801283845e15,4.7884665878784044e14,0,0},{0,0,0,-6.4926797540624035,-12985.995991128793,-3.298836226795991e6,-2.871680700153716e8,-1.2127517294150885e10,-2.9628375638388446e11,-4.648967460183313e12,-5.014705791678989e13,-3.896342464153759e14,-2.254104416220173e15,-9.943117755509682e15,-3.401307144070906e16,-9.127203209515408e16,-1.934632666986177e17,-3.247778760884149e17,-4.311079790213169e17,-4.495396895431404e17,-3.636200897900059e17,-2.2336772996888845e17,-1.0065183695567805e17,-3.1360509612206944e16,-6.034695712672399e15,-5.402372560683328e14,0},{0,0,0,-0.0006253908692933083,21.472659314327856,28363.229946619325,5.944698143021086e6,4.619832444694353e8,1.809376056308954e10,4.1886637559539825e11,6.31178461726564e12,6.596977935869714e13,4.997768062476191e14,2.8319808910505985e15,1.2277848441468622e16,4.138797722399096e16,1.0967212084846331e17,2.299374395484744e17,3.823298988047106e17,5.032265327743345e17,5.208059242745585e17,4.1843448110868006e17,2.5548313610900355e17,1.1449196659647726e17,3.5494695749103796e16,6.799083515396579e15,6.06119848271788e14}}} }; static const double ImEI[21][2][5][27] = { {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.03333333333333333,-0.06666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.3,-0.26666666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.5,2.1333333333333333,1.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-1.8333333333333333,-6.133333333333334,-4.266666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.03333333333333333,4.2,12.8,8.533333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.06666666666666667,0.06666666666666667,0.06666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.1,0.43333333333333335,0.26666666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-1.2666666666666666,-2.933333333333333,-1.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.16666666666666666,4.1,8.266666666666667,4.266666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.06666666666666667,-0.4666666666666667,-9,-17.066666666666666,-8.533333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.06666666666666667,1.0666666666666667,1.0666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-2.6,-9.066666666666666,-6.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,1,11.6,27.733333333333334,17.066666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-3.533333333333333,-29.066666666666666,-59.733333333333334,-34.13333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.009523809523809525,8,56.68571428571428,107.27619047619048,58.51428571428571,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.13333333333333333,-0.26666666666666666,-1.6,-1.0666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.2,5.933333333333334,12.266666666666667,6.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-3.2,-22.266666666666666,-36.266666666666666,-17.066666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.06666666666666667,10.066666666666666,52.53333333333333,76.8,34.13333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.01904761904761905,-0.26666666666666666,-21.714285714285715,-99.35238095238095,-136.53333333333333,-58.51428571428571,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.1,12.6,38.4,25.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-8.9,-64.26666666666667,-123.73333333333333,-68.26666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,1.5,35.2,170.13333333333333,273.06666666666666,136.53333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.271428571428571,-84,-341.9428571428571,-497.37142857142857,-234.05714285714285,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.0015873015873015873,11.88888888888889,159.4920634920635,589.6126984126984,806.1968253968254,364.0888888888889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.2,-1.4,-27,-51.2,-25.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.3,24.233333333333334,113.33333333333333,157.86666666666667,68.26666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-5.4,-81.86666666666666,-281.06666666666666,-341.3333333333333,-136.53333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.04285714285714286,17.1,183.65714285714284,546.7428571428571,614.4,234.05714285714285,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.0031746031746031746,-0.15555555555555556,-36.93015873015873,-337.26984126984127,-924.4444444444445,-988.2412698412699,-364.0888888888889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.13333333333333333,59.733333333333334,332.8,546.1333333333333,273.06666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-21.2,-260.26666666666665,-921.6,-1228.8,-546.1333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,2,79.88571428571429,648.5333333333333,1896.8380952380953,2262.552380952381,936.2285714285714,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-7.015873015873016,-186.48888888888888,-1262.120634920635,-3319.0603174603175,-3692.9015873015874,-1456.3555555555556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.0005772005772005772,15.806060606060607,349.617316017316,2133.1116883116883,5241.461471861472,5560.630303030303,2118.3353535353535,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.26666666666666666,-3.7333333333333334,-149.33333333333334,-554.6666666666666,-682.6666666666666,-273.06666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.4,64.13333333333334,541.8666666666667,1433.6,1501.8666666666666,546.1333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-7.771428571428571,-209.86666666666667,-1260.4952380952382,-2852.5714285714284,-2730.6666666666665,-936.2285714285714,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.031746031746031744,24.755555555555556,462.5015873015873,2365.765079365079,4892.444444444444,4421.079365079365,1456.3555555555556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.0011544011544011544,-0.11313131313131314,-53.58268398268398,-839.8961038961039,-3909.818181818182,-7624.588744588745,-6619.79797979798,-2118.3353535353535,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.16666666666666666,191.66666666666666,1668.2666666666667,4753.066666666667,5461.333333333333,2184.5333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-41.5,-775.8095238095239,-4313.6,-9976.685714285713,-10142.47619047619,-3744.9142857142856,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,2.5,152.63492063492063,1872.888888888889,8569.092063492064,17664.812698412698,16644.06349206349,5825.422222222222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-8.762626262626263,-352.2020202020202,-3580.7676767676767,-14673.19595959596,-28117.59191919192,-25155.23232323232,-8473.341414141414,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.0002775002775002775,19.731934731934732,655.7495837495837,5983.52047952048,22836.666267066266,41605.430303030305,35848.75213675214,11732.318881118881,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.3333333333333333,-7.666666666666667,-528.2,-3225.6,-7074.133333333333,-6553.6,-2184.5333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.5,135.11904761904762,1809.8666666666666,7751.314285714286,14345.752380952381,12014.933333333332,3744.9142857142856,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-10.26984126984127,-436.8888888888889,-4089.930158730159,-14826.869841269841,-24894.577777777777,-19556.774603174603,-5825.422222222222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.025252525252525252,32.86363636363637,955.6767676767677,7544.371717171717,24809.761616161617,39106.45656565657,29391.90303030303,8473.341414141414,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.000555000555000555,-0.08935508935508936,-71.26440226440226,-1727.040959040959,-12325.773426573427,-38017.645288045285,-57329.99658119658,-41714.91157731158,-11732.318881118881,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.2,489.6,6106.971428571429,26214.4,50556.34285714286,44938.97142857143,14979.657142857142,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-71.8,-1901.8920634920635,-15197.155555555555,-53000.93968253968,-90398.06984126984,-74066.08253968254,-23301.68888888889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,3,260.43463203463205,4506.052525252525,29564.416738816737,91759.85685425685,144822.26608946608,112271.77373737373,33893.36565656566,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-10.51048951048951,-596.8428904428904,-8522.413053613054,-49961.41351981352,-143888.94731934732,-215275.8303030303,-160341.69137529138,-46929.275524475524,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.0001554001554001554,23.661849261849262,1106.6579642579643,14141.066045066045,77056.03978243978,210652.15602175603,303084.9044289044,219003.28578088578,62572.367365967366,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.4,-13.6,-1447.5428571428572,-13136,-44470.857142857145,-70217.14285714286,-52428.8,-14979.657142857142,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.6,247.18412698412698,4825.422222222222,30428.749206349206,86497.11746031746,123062.04444444444,85716.92698412699,23301.68888888889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-12.86926406926407,-795.3656565656565,-10742.07215007215,-56978.655122655124,-146297.53535353535,-194603.1468975469,-129218.45656565657,-33893.36565656566,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.02097902097902098,41.329137529137526,1733.909557109557,19631.14219114219,94030.1724941725,225862.41491841493,286647.4368298368,183806.32913752913,46929.275524475524,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.0003108003108003108,-0.07397047397047397,-89.75540015540015,-3126.114063714064,-31870.1898989899,-142693.88282828283,-326997.6515928516,-400854.2284382284,-250289.46946386946,-62572.367365967366,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.23333333333333334,1074.7333333333333,18153.244444444445,108464.35555555555,307655.1111111111,449285.68888888886,326223.64444444445,93206.75555555556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-114.1,-4069.7131313131313,-44104.92121212121,-214282.8606060606,-537693.0909090909,-723676.3151515152,-495690.4727272727,-135573.46262626263,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,3.5,410.27630147630146,9526.587723387724,84649.39362859362,365700.5550893551,848556.257964258,1.0798214464646464e6,709153.4968142968,187717.1020979021,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-12.25897435897436,-936.1311577311577,-17890.690287490288,-141813.89526029525,-567884.4618492619,-1.2480050523698523e6,-1.524549659052059e6,-969871.6941724942,-250289.46946386946,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.0000959824489236254,27.593994241053064,1731.1486631016044,29547.359934183463,217402.40296174414,825519.0614561909,1.7431695357191828e6,2.0641979866721514e6,1.280893167256273e6,323904.019306184,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.4666666666666667,-21.933333333333334,-3355.6222222222223,-42348.08888888889,-203582.57777777777,-479869.15555555554,-594921.2444444444,-372827.02222222224,-93206.75555555556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.7,410.7262626262626,11022.440404040404,96074.47272727273,386563.103030303,819299.296969697,946101.5272727272,563477.2040404041,135573.46262626263,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-15.552602952602953,-1319.1589743589743,-24329.85236985237,-177655.00916860916,-643821.182905983,-1.273099178865579e6,-1.3992012382284382e6,-803012.0478632479,-187717.1020979021,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.017948717948717947,50.09052059052059,2871.1639471639473,44222.36891996892,290731.34296814294,983393.9045843045,1.851893577000777e6,1.9625562306138305e6,1.0950164289044288e6,250289.46946386946,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.0001919648978472508,-0.06315645139174551,-108.91493212669683,-5170.4839160839165,-71524.53607568901,-438562.81431509665,-1.4125950964486494e6,-2.565467062004662e6,-2.6439125666803783e6,-1.4428451769093652e6,-323904.019306184,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,2116.266666666667,46478.36998556999,367133.99595959595,1.4218853217893217e6,3.00440476998557e6,3.5321728923520925e6,2.169175402020202e6,542293.8505050505,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-170.4,-7878.639405039405,-111119.03776223776,-714162.356043956,-2.447790332334332e6,-4.76751157962038e6,-5.287365042424242e6,-3.1077609125097124e6,-750868.4083916084,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,4,609.1538683538683,18291.647552447554,211297.13166833165,1.2068968343656345e6,3.8238280972360973e6,7.039391328671329e6,7.482612264180264e6,4.254920980885781e6,1.0011578778554779e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-14.007843137254902,-1385.7954019836372,-34183.56217377394,-351855.81673751085,-1.8614895882261528e6,-5.582810520261438e6,-9.861435769605558e6,-1.0149606059509119e7,-5.624151607952831e6,-1.295616077224736e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.0000635071842502183,31.527506549178376,2558.0482279330577,56272.57883911754,537113.6969927904,2.6926125869276235e6,7.7549386769432835e6,1.3272122169070559e7,1.3318034401472213e7,7.228173904516948e6,1.6365676764944035e6,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-33.06666666666667,-6906.606637806638,-115649.93939393939,-746992.1893217893,-2.4357735803751806e6,-4.414610876767676e6,-4.515080496392496e6,-2.440322327272727e6,-542293.8505050505,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.8,636.47881007881,22496.094483294484,259039.60572760573,1.3972491252747253e6,4.090821281118881e6,6.898882843023643e6,6.700457672105672e6,3.483195116705517e6,750868.4083916084,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-18.30773670773671,-2043.3143745143745,-49402.28837828838,-475220.8388944389,-2.3042702023310023e6,-6.28517082917083e6,-1.0076758327894328e7,-9.422355652525252e6,-4.75549991981352e6,-1.0011578778554779e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.01568627450980392,59.10452945747063,4444.078065725124,89495.53131313132,773530.6577448695,3.495176651510581e6,9.067520102966314e6,1.400317438010878e7,1.2718753849005897e7,6.2719596465652e6,1.295616077224736e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.0001270143685004366,-0.05512423592918949,-128.64458637337896,-7998.43481348373,-144411.5393015653,-1.162342659386434e6,-4.9947002896331735e6,-1.2482808925253488e7,-1.8729284982381087e7,-1.6625264914387986e7,-8.04645774276415e6,-1.6365676764944035e6,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.3,3839.4,106318.05314685314,1.0702797874125873e6,5.392764956643357e6,1.5350685180419581e7,2.580816845874126e7,2.539460421818182e7,1.3515631351048952e7,3.0034736335664336e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-242.7,-14124.181152181152,-251299.74452214452,-2.0592303781551782e6,-9.185474911222111e6,-2.4106659233033635e7,-3.8236604926806524e7,-3.601039741911422e7,-1.852142074032634e7,-4.0046315114219114e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,4.5,864.0628077804548,32599.88898944193,474679.1184031655,3.455516380591957e6,1.4245058289412549e7,3.533020329192376e7,5.370181410996846e7,4.892054909771013e7,2.449892218752228e7,5.182464308898944e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-15.756965944272446,-1961.5696724328304,-60708.62697178982,-786988.0535711966,-5.303549502574206e6,-2.0688066335863516e7,-4.921807658793219e7,-7.241782910112797e7,-6.427015135233064e7,-3.1503927772517268e7,-6.546270705977614e6,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.00004422821760283061,35.461919504643966,3616.1956285200868,99702.79558212686,1.1976321362253844e6,7.643730469367165e6,2.8621924200018764e7,6.595342171821161e7,9.458539786739412e7,8.219612447821817e7,3.9589351412340805e7,8.104906588353236e6,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.6,-47.4,-13003.506293706294,-278936.1678321678,-2.3265602237762236e6,-9.980674506293707e6,-2.4597585633566435e7,-3.625286534265734e7,-3.158926858741259e7,-1.5017368167832168e7,-3.0034736335664336e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.9,935.4623043623044,42143.00606060606,619613.8922410923,4.308818503096903e6,1.6579424074592074e7,3.799234747545788e7,5.314447145174825e7,4.452023938088578e7,2.0523736496037297e7,4.0046315114219114e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-21.12561556090968,-3003.887892499657,-92251.03664962489,-1.130768793872794e6,-7.0588418527355e6,-2.5277949085518405e7,-5.502439582942548e7,-7.405439677762237e7,-6.019829813355272e7,-2.7090154341971755e7,-5.182464308898944e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.01393188854489164,68.33903526813744,6531.570529779818,166762.43296022862,1.8339761297278572e6,1.0656330035982594e7,3.6261947787464544e7,7.597502823061767e7,9.92596311986317e7,7.879468948121847e7,3.477706312550607e7,6.546270705977614e6,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.00008845643520566122,-0.04891640866873065,-148.871487026905,-11752.440015711842,-268684.86844919785,-2.74861261174986e6,-1.5174070609897017e7,-4.97030496228197e7,-1.0110656940201923e8,-1.2902029170934741e8,-1.0047113019907235e8,-4.364180470651743e7,-8.104906588353236e6,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.3333333333333333,6533.333333333333,222654.46091686093,2.778624556954157e6,1.7600566104118105e7,6.443886523574203e7,1.4451080095726496e8,2.0156645274156955e8,1.7053055852804974e8,8.009263022843823e7,1.6018526045687646e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-333,-23825.97413044472,-521880.007239819,-5.303014873879062e6,-2.974522501247772e7,-1.0042604004409708e8,-2.1250665797888386e8,-2.837202903655926e8,-2.319741694631016e8,-1.0600495177293295e8,-2.0729857235595778e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,5,1181.999610984131,54754.40911616763,980895.6130251585,8.852088141103067e6,4.5880486491885826e7,1.4637328059863028e8,2.967933223074854e8,3.832574936190464e8,3.0507729190651166e8,1.3638063970786697e8,2.6185082823910456e7,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-17.506265664160402,-2679.1916209005994,-101698.47428388605,-1.6209314727333898e6,-1.3536137961823797e7,-6.6368244028934255e7,-2.0306241420633388e8,-3.984997390155933e8,-5.012577425662849e8,-3.9049673738068247e8,-1.7144994706131846e8,-3.2419626353412945e7,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.000032049433045529426,39.39695786781532,4934.437997592661,166727.4017375813,2.460969788432378e6,1.945561056293358e7,9.154241300341979e7,2.712219032798776e8,5.1868580194167066e8,6.387408437835916e8,4.888559794904897e8,2.114323457831279e8,3.946737121285054e7,0,0,0,0,0,0,0,0,0,0,0}},{{0.6666666666666666,-65.33333333333333,-22842.255167055166,-610794.4205128205,-6.384583827195027e6,-3.4760849444599845e7,-1.1109825668873349e8,-2.199600400907537e8,-2.733161006545454e8,-2.075734000087024e8,-8.810189325128205e7,-1.6018526045687646e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1,1318.9482608894373,73805.46920791626,1.3491923253530783e6,1.1743463056410257e7,5.730339427900727e7,1.7019760844996572e8,3.196860685490927e8,3.8177487075555557e8,2.810897971178939e8,1.1636988039073084e8,2.0729857235595778e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-23.999221968262216,-4237.817551557489,-161226.06704008067,-2.4533664806920635e6,-1.9149318022051428e7,-8.689604748579635e7,-2.450198244808148e8,-4.4258655082519025e8,-5.1267962114181876e8,-3.683579087309619e8,-1.4947318111982217e8,-2.6185082823910456e7,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.012531328320802004,77.76920671347916,9214.54894194213,291039.0946701733,3.9691610755076366e6,2.8811933867454045e7,1.2415265791155085e8,3.367590805724054e8,5.902267861563345e8,6.673985861532614e8,4.701430309700768e8,1.8765976023802492e8,3.2419626353412945e7,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.00006409886609105885,-0.04397182213846637,-169.53941844936594,-16578.624554339185,-468446.0812958478,-5.9377916416310035e6,-4.0923115567559e7,-1.696412196057358e8,-4.465302941617743e8,-7.640784094103152e8,-8.472253347457047e8,-5.871720202796443e8,-2.3116603138955316e8,-3.946737121285054e7,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.36666666666666664,10559.266666666666,434294.7652086476,6.574489355455003e6,5.10204267471091e7,2.3250794534097537e8,6.64917593632177e8,1.2277649331804926e9,1.4624266471674209e9,1.0850784646757164e9,4.560568591831071e8,8.291942894238311e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-443.3,-38255.76555264481,-1.0114779064221641e6,-1.2470381821703581e7,-8.571332767814559e7,-3.6026736682270384e8,-9.722698334254823e8,-1.7186034725420127e9,-1.9784568926620624e9,-1.4283144396604905e9,-5.869822733026594e8,-1.0474033129564182e8,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,5.5,1569.961476844449,87625.69572649573,1.8939060047826958e6,2.0732385792547733e7,1.3166046654165429e8,5.228893340210738e8,1.352134487330338e9,2.311593394202756e9,2.5906866318906407e9,1.8295657646295648e9,7.381699538930948e8,1.2967850541365178e8,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-19.255693581780537,-3554.4014008396293,-162426.07358635293,-3.1217844988459083e6,-3.16126055748029e7,-1.8987086397373933e8,-7.230764038384147e8,-1.809469262049569e9,-3.0129885415469217e9,-3.304452922123214e9,-2.2917775413786182e9,-9.105686358393375e8,-1.5786948485140216e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.00002397297591805601,43.33244851258581,6541.62812737135,265926.5903814425,4.731094982759278e6,4.5340842546994835e7,2.612763288477679e8,9.633487135585018e8,2.348932232111619e9,3.828700312931434e9,4.124825501869743e9,2.8177588722517457e9,1.105086393959815e9,1.894433818216826e8,0,0,0,0,0,0,0,0,0,0}},{{0.7333333333333333,-87.26666666666667,-37956.79708396179,-1.2378745500251383e6,-1.5839376732026143e7,-1.06514876608547e8,-4.268125048599296e8,-1.084457648638713e9,-1.7937872069180493e9,-1.927228914871795e9,-1.297559501340573e9,-4.9751657365429866e8,-8.291942894238311e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1.1,1798.4311052896192,122419.20256145643,2.723675026625387e6,2.8991573532491863e7,1.7462463657162815e8,6.49987059367659e8,1.5663069635696964e9,2.4893757054309864e9,2.5923743423070254e9,1.7021667641938875e9,6.393524389504802e8,1.0474033129564182e8,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-26.922953688897962,-5782.824037469239,-267059.29319830495,-4.940120546192026e6,-4.71164384933979e7,-2.6376188135589048e8,-9.316258847784076e8,-2.1581550271623797e9,-3.3260680887754226e9,-3.3792200077329974e9,-2.1743360218110523e9,-8.030092065999206e8,-1.2967850541365178e8,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.011387163561076604,87.37526544737474,12575.685027901907,481630.25459747476,7.978130346470807e6,7.071870426544951e7,3.7573583030587316e8,1.2761080113371363e9,2.867315117761134e9,4.312316120466565e9,4.2944103377974663e9,2.717461330888649e9,9.895033782650386e8,1.5786948485140216e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.00004794595183611202,-0.039938977879481315,-190.60366239225843,-22626.351358782555,-774685.3323404123,-1.1919507515836926e7,-1.0026023448105781e8,-5.122220252548393e8,-1.6875254790953407e9,-3.7006690484617324e9,-5.456117441460743e9,-5.344261556173933e9,-3.3347814351400876e9,-1.1998080848706565e9,-1.894433818216826e8,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.4,16358.4,798958.1317110135,1.4416265779644504e7,1.3432181467691442e8,7.434303361587911e8,2.626393853597904e9,6.143042747321345e9,9.628736625974842e9,1.0003891869771244e10,6.609352950962489e9,2.5137679510954037e9,4.189613251825673e8,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-575.6,-58965.4028822227,-1.851578588510492e6,-2.721337278865888e7,-2.246109735140044e8,-1.1467505597679276e9,-3.823590344956376e9,-8.562024604039784e9,-1.2971313192672047e10,-1.3113370455110611e10,-8.471497747887982e9,-3.1621604781636624e9,-5.187140216546071e8,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,6,2034.9461170318891,134714.58794018233,3.456620690885645e6,4.5099821439376034e7,3.4389086889063436e8,1.6588888433384745e9,5.299781267706849e9,1.1477806342984741e10,1.6928250138062456e10,1.6740562578044119e10,1.0617264990476751e10,3.9016315541846533e9,6.314779394056087e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-21.00521739130435,-4602.940974829003,-249320.1853983052,-5.686343886484196e6,-6.861345311881912e7,-4.947368541065237e8,-2.288195708861567e9,-7.073833639317552e9,-1.4920448268974035e10,-2.1533210358591484e10,-2.091140714317489e10,-1.3059753134332243e10,-4.736084545542065e9,-7.577735272867304e8,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.00001840349666436623,47.2682769726248,8466.622898449223,407758.88048708765,8.605464337728756e6,9.82448816901423e7,6.795288568188525e8,3.042463166214668e9,9.163485366790909e9,1.8918381774570183e10,2.681818912368284e10,2.565065895730421e10,1.5811505960561546e10,5.669268611552575e9,8.981019582657546e8,0,0,0,0,0,0,0,0,0}},{{0.8,-113.6,-60265.06342202689,-2.354631489783282e6,-3.6188869743358806e7,-2.9423519790246165e8,-1.4410252993176384e9,-4.548903494657308e9,-9.579486167460339e9,-1.3604387251458832e10,-1.2876514478657967e10,-7.78768167803846e9,-2.7232486136866875e9,-4.189613251825673e8,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1.2,2385.605764445393,194164.23206487356,5.166394900690916e6,6.6000166193341576e7,4.804116328378407e8,2.1848240357089143e9,6.539431397703931e9,1.3229596648755936e10,1.8207931242597847e10,1.6804843678929035e10,9.955319107909575e9,3.4215174889909663e9,5.187140216546071e8,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-29.892234063778012,-7677.3315851704865,-423195.2594681369,-9.353395630081888e6,-1.069960803506276e8,-7.235025322877827e8,-3.121175266299493e9,-8.978155548848114e9,-1.7608717027453564e10,-2.363934658860129e10,-2.1376840213692146e10,-1.2449678653930527e10,-4.217370523887458e9,-6.314779394056087e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.010434782608695653,97.14108009278826,16699.23576343072,762726.8199599064,1.5085840946795626e7,1.603035047267927e8,1.0283599406244267e9,4.2643450431212244e9,1.1894505365747297e10,2.2759909848626797e10,2.9943147410467827e10,2.6624309126235004e10,1.5285712870737015e10,5.114971309185431e9,7.577735272867304e8,0,0,0,0,0,0,0,0,0,0},{0,0,-0.00003680699332873246,-0.03658615136876006,-212.02777987521023,-30047.89230250005,-1.2262431435256745e6,-2.251696238611375e7,-2.2695429228591478e8,-1.3994804759815316e9,-5.627673799689461e9,-1.5316193575786037e10,-2.8723952643539726e10,-3.7161678742566864e10,-3.257762113150629e10,-1.8477746149163006e10,-6.118319590685452e9,-8.981019582657546e8,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.43333333333333335,24459.933333333334,1.39948310974227e6,2.9664356557875972e7,3.264766937613553e8,2.1527966210326242e9,9.174872352635342e9,2.63526819412877e10,5.20431450209414e10,7.080795804555496e10,6.521613086318431e10,3.8830607464800354e10,1.3486564563019785e10,2.0748560866184285e9,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-731.9,-87814.82467992813,-3.230537622359549e6,-5.578284651915676e7,-5.439079051073674e8,-3.308797228275689e9,-1.3310466229841167e10,-3.660457080636495e10,-6.987539486462099e10,-9.251142702281056e10,-8.331826353464978e10,-4.868864058693869e10,-1.6643954260047829e10,-2.5259117576224346e9,0,0,0,0,0,0,0,0,0,0,0},{0,0,6.5,2583.9516267845465,200215.24405318496,6.016616118581815e6,9.221263263214113e7,8.305750837148908e8,4.77383576908197e9,1.840021088352963e10,4.8939353849036934e10,9.094760672013042e10,1.177844008258246e11,1.0414198859975996e11,5.991259714028463e10,2.0207294060979477e10,3.0310941091469216e9,0,0,0,0,0,0,0,0,0,0},{0,0,0,-22.754814814814814,-5840.553656708876,-370080.7888040544,-9.881938796070835e6,-1.4003615801375034e8,-1.1925823709998772e9,-6.57143044116013e9,-2.4508050681444206e10,-6.348184946356478e10,-1.1543549489334048e11,-1.468037932397025e11,-1.27811573462042e11,-7.256032344847891e10,-2.4192621500783764e10,-3.5924078330630183e9,0,0,0,0,0,0,0,0,0},{0,0,0,0.00001443722583152868,51.20436448442445,10738.282242670764,604748.6713855794,1.493782547301189e7,2.0024139920202476e8,1.6355739069693673e9,8.723538381973366e9,3.1694134443060642e10,8.035017116564796e10,1.435061488294865e11,1.797385196878227e11,1.544460759994406e11,8.668740434615086e10,2.861538653232956e10,4.211788493935952e9,0,0,0,0,0,0,0,0}},{{0.8666666666666667,-144.73333333333332,-92115.75281787357,-4.24804535780092e6,-7.720394235745513e7,-7.459561839697425e8,-4.37688462512671e9,-1.675264548351156e10,-4.352291071881835e10,-7.819993218306961e10,-9.728719442636674e10,-8.229722149813876e10,-4.518485423006929e10,-1.4523992606328999e10,-2.0748560866184285e9,0,0,0,0,0,0,0,0,0,0,0,0},{0,1.3,3092.3493598562786,296618.58790897264,9.301895812628992e6,1.4042234137451884e8,1.2141829505065637e9,6.6136711412013e9,2.3997256897036137e10,5.988243978747334e10,1.0425835625270293e11,1.2646490694806935e11,1.0477864663163727e11,5.65370092624084e10,1.7906910138859047e10,2.5259117576224346e9,0,0,0,0,0,0,0,0,0,0,0},{0,0,-32.90325356909285,-9960.403453242889,-646128.1687916917,-1.6817577993811376e7,-2.272190859950398e8,-1.8244572021268456e9,-9.424164410318285e9,-3.2855536243018745e10,-7.94693874291209e10,-1.3493911256397678e11,-1.6035193404744455e11,-1.3059358460620116e11,-6.944791402530933e10,-2.1722841115552937e10,-3.0310941091469216e9,0,0,0,0,0,0,0,0,0,0},{0,0,0.00962962962962963,107.05323934367682,21670.89761846037,1.1640149545323383e6,2.7098524121223144e7,3.3995615473259085e8,2.5888012200866394e9,1.2850503978831438e10,4.34323908124913e10,1.0247227787993118e11,1.704876950572971e11,1.9917787189184882e11,1.5989240688923416e11,8.398305773017148e10,2.5988825417315273e10,3.5924078330630183e9,0,0,0,0,0,0,0,0,0},{0,0,-0.00002887445166305736,-0.033754233994114057,-233.78149683578326,-38998.16031069183,-1.8707910950575937e6,-4.041802774693853e7,-4.8079742512005436e8,-3.518362643932259e9,-1.6932117246290905e10,-5.582666431497299e10,-1.2906973332811464e11,-2.1113776786988696e11,-2.4316208621413403e11,-1.9281924836901074e11,-1.0020538726970265e11,-3.0721280779297535e10,-4.211788493935952e9,0,0,0,0,0,0,0,0}}}, {{{0,-0.4666666666666667,35489.066666666666,2.3512673864932396e6,5.783459782554564e7,7.417629589224231e8,5.737794526335927e9,2.8958539764775536e10,9.980418605461873e10,2.4087583664136777e11,4.1111360367982263e11,4.938686168666484e11,4.0842050111710443e11,2.2130873014861176e11,7.072552921342816e10,1.0103647030489738e10,0,0,0,0,0,0,0,0,0,0,0},{0,0,-914.2,-127000.05298477177,-5.410357632421346e6,-1.084187847239819e8,-1.2320553672292948e9,-8.793144231643013e9,-4.189268519105384e10,-1.3824796054280862e11,-3.2253689193271765e11,-5.3569991047103217e11,-6.2930263262471e11,-5.107830750947536e11,-2.7241958305957956e11,-8.588099975916278e10,-1.2124376436587687e10,0,0,0,0,0,0,0,0,0,0},{0,0,7,3223.9763957964633,289078.1147930231,1.0056934701494202e7,1.7885319900918955e8,1.8774039305941489e9,1.2659112178824976e10,5.778636226399293e10,1.8443310408086594e11,4.188943611564575e11,6.80570218646967e11,7.848818851678533e11,6.271698565745526e11,3.30024403976469e11,1.028326742214289e11,1.4369631332252073e10,0,0,0,0,0,0,0,0,0},{0,0,0,-24.504469987228607,-7282.983796526446,-533794.5211804865,-1.6496528391199792e7,-2.7121016480072916e8,-2.69139348470133e9,-1.7396960801336163e10,-7.683642125146432e10,-2.388197884303981e11,-5.3073846409068134e11,-8.467207746541761e11,-9.615174725410426e11,-7.581688663491782e11,-3.943770868588842e11,-1.2164636179544427e11,-1.6847153975743809e10,0,0,0,0,0,0,0,0},{0,0,0,0.000011535450912536563,55.140655048819674,13385.468430331828,871673.8196526119,2.4913415664470177e7,3.873820740702931e8,3.686591045638684e9,2.3063912016993534e10,9.92281083489501e10,3.018436477318775e11,6.588209340059844e11,1.0351031513181844e12,1.160082623098246e12,9.043453403023804e11,4.6572230892101843e11,1.4238562392402832e11,1.9564436875057327e10,0,0,0,0,0,0,0}},{{0.9333333333333333,-181.06666666666666,-136335.83965314535,-7.327933577454448e6,-1.5542659822206742e8,-1.7593665355350988e9,-1.2169475752962036e10,-5.541107203717101e10,-1.734553628583209e11,-3.823252362645737e11,-5.987312993848872e11,-6.626663891105165e11,-5.067610463730009e11,-2.5477706093710904e11,-7.577735272867303e10,-1.0103647030489738e10,0,0,0,0,0,0,0,0,0,0,0},{0,1.4,3930.705969543536,438914.5575660432,1.6021909399733834e7,2.821148285309416e8,2.8568306121554456e9,1.834034705520107e10,7.915174003764148e10,2.3795742789826575e11,5.0818633097929156e11,7.758814204731168e11,8.410097103451432e11,6.320268394606305e11,3.130867623573008e11,9.194318797745662e10,1.2124376436587687e10,0,0,0,0,0,0,0,0,0,0},{0,0,-35.952791592926204,-12671.688278689997,-955744.668589088,-2.8937820175670214e7,-4.558361881243446e8,-4.2852364908962717e9,-2.6082358434683636e10,-1.0813493285251514e11,-3.150596210807534e11,-6.56127990059077e11,-9.812778081103854e11,-1.045448978125867e12,-7.742480850836678e11,-3.7874643521238617e11,-1.1001748988755493e11,-1.4369631332252073e10,0,0,0,0,0,0,0,0,0},{0,0,0.008939974457215836,117.10041553054182,27577.685460833156,1.7212957303475374e6,4.6594371675881036e7,6.812809157261431e8,6.07243220002907e9,3.551011349027069e10,1.4269874524439893e11,4.054913031711275e11,8.273111760165848e11,1.2162825061370105e12,1.2771474457642676e12,9.341281376272004e11,4.520414263861544e11,1.3006993878331618e11,1.6847153975743809e10,0,0,0,0,0,0,0,0},{0,0,-0.000023070901825073126,-0.031330284678449304,-255.83925591764077,-49634.48688799174,-2.765829691982738e6,-6.945891513716699e7,-9.627476140344408e8,-8.244250951607839e9,-4.673088800021546e10,-1.8316187642444714e11,-5.0994384612902716e11,-1.022841420534557e12,-1.4821974712563923e12,-1.5372206353757112e12,-1.112343356234171e12,-5.3324678896895935e11,-1.5216784236155698e11,-1.9564436875057327e10,0,0,0,0,0,0,0}}}, {{{0,-0.5,50175,3.8110518751832955e6,1.076462696229007e8,1.5907243629794188e9,1.4251013900556408e10,8.39147841034878e10,3.408264309321651e11,9.827003704330287e11,2.041566817044961e12,3.065320744754241e12,3.2952209252682485e12,2.4722631961132183e12,1.2290545345785562e12,3.6373129309763055e11,4.8497505746350746e10,0,0,0,0,0,0,0,0,0,0},{0,0,-1124.5,-179081.18687280125,-8.746490101655236e6,-2.0128246173478386e8,-2.6356156253879805e9,-2.1787106957386932e10,-1.2111135286756642e11,-4.7103679933522406e11,-1.312930805324278e12,-2.654465838545084e12,-3.897567876302638e12,-4.1124050502739814e12,-3.036874638157322e12,-1.489333703666579e12,-4.355794497588909e11,-5.747852532900829e10,0,0,0,0,0,0,0,0,0},{0,0,7.5,3962.019044757294,407072.920718967,1.6232431369128535e7,3.3147987895103717e8,4.0090734366763234e9,3.13099625273733e10,1.6676035684980087e11,6.272725393185522e11,1.702120269314377e12,3.366309892830835e12,4.852504880352651e12,5.040497006172991e12,3.6725169792886714e12,1.7801426017692478e12,5.153247098462812e11,6.7388615902975235e10,0,0,0,0,0,0,0,0},{0,0,0,-26.25417130144605,-8945.976556539295,-751050.1272782461,-2.6597813264939196e7,-5.0203783424558866e8,-5.739732894683955e9,-4.2968855344066925e10,-2.214204398894586e11,-8.110701607930319e11,-2.1534160242155322e12,-4.1819214920925874e12,-5.935635976892781e12,-6.084107901642862e12,-4.381942913426506e12,-2.1025895514418992e12,-6.03236803647601e11,-7.825774750022931e10,0,0,0,0,0,0,0},{0,0,0,9.363190675760198e-6,59.07710774785302,16437.045563842872,1.2257532331766458e6,4.013768184797409e7,7.164271778242302e8,7.854094148649289e9,5.6903267984881676e10,2.856175070922272e11,1.0238847552212717e12,2.6698130647352876e12,5.105908405067799e12,7.152238271875518e12,7.247671528966757e12,5.167805995087918e12,2.457745328571359e12,6.99576833714171e11,9.011498196996101e10,0,0,0,0,0,0}},{{1,-223,-196278.75036659127,-1.2163480027372148e7,-2.9773689168561506e8,-3.901236201224221e9,-3.1389389329419144e10,-1.6743088681163474e11,-6.199947751483894e11,-1.6382802519391409e12,-3.132920728260574e12,-4.3465612386153613e12,-4.3323760798965054e12,-3.0231374871104106e12,-1.4018268987999307e12,-3.8798004597080597e11,-4.8497505746350746e10,0,0,0,0,0,0,0,0,0,0},{0,1.5,4912.873745602497,631897.2803378738,2.656490166119503e7,5.395585963900452e8,6.322823026301706e9,4.720796893278593e10,2.3863565691698135e11,8.485721474191187e11,2.172352790028894e12,4.049809894234472e12,5.50235200650019e12,5.38931258216232e12,3.7052589549104136e12,1.6963462050468354e12,4.643187124233951e11,5.747852532900829e10,0,0,0,0,0,0,0,0,0},{0,0,-39.038089514588414,-15851.374766259272,-1.3756719102298168e6,-4.7943245278919205e7,-8.708307769571735e8,-9.47113944257027e9,-6.703028125916526e10,-3.254547834230943e11,-1.1214448357099817e12,-2.7992820802386875e12,-5.111448386239666e12,-6.825434396193574e12,-6.587638039199097e12,-4.472282579818021e12,-2.0251695912105806e12,-5.4901901779776886e11,-6.7388615902975235e10,0,0,0,0,0,0,0,0},{0,0,0.008342602892102336,127.27291285612064,34507.8303268765,2.4771144537147037e6,7.715353799846987e7,1.3004413372683635e9,1.3407053636109262e10,9.11467268081413e10,4.288886516771684e11,1.4411578341601123e12,3.5239100414919814e12,6.3247528225204e12,8.32319236966487e12,7.933155759027074e12,5.327467452291677e12,2.3895346256094067e12,6.423656773977156e11,7.825774750022931e10,0,0,0,0,0,0,0},{0,0,-0.000018726381351520396,-0.029231881289723337,-278.179190366686,-62116.434369362025,-3.979701958366857e6,-1.1496637205380797e8,-1.8365386839217353e9,-1.8187049742974773e10,-1.198292372617549e11,-5.49880612073813e11,-1.810124500260231e12,-4.3508491817515527e12,-7.696337232599344e12,-1.000270962164139e13,-9.431448443943848e12,-6.273956282611874e12,-2.7906371863090767e12,-7.446343246991516e11,-9.011498196996101e10,0,0,0,0,0,0}}}, {{{0,-0.5333333333333333,69358.93333333333,5.9871611113645565e6,1.924439018268767e8,3.2448156139755497e9,3.330669577632881e10,2.2601945627174777e11,1.0662940872799772e12,3.608672101565586e12,8.923743251707213e12,1.6254636226822168e13,2.1772292854629945e13,2.117283786317375e13,1.453488209257297e13,6.674693753831088e12,1.8393128105282654e12,2.2991410131603317e11,0,0,0,0,0,0,0,0,0},{0,0,-1364.8,-247010.3969398599,-1.3710914253764993e7,-3.5907586422209996e8,-5.365095399350815e9,-5.081736342983615e10,-3.255698706535722e11,-1.470867065526843e12,-4.812414875990048e12,-1.1581712843876643e13,-2.0631072691303906e13,-2.7124046546863812e13,-2.5963317717947027e13,-1.758285432472868e13,-7.979604930158186e12,-2.1762558900431414e12,-2.6955446361190094e11,0,0,0,0,0,0,0,0},{0,0,8,4805.078378923909,560851.6328710681,2.5412128545875855e7,5.904978119526415e8,8.148894279740852e9,7.291974445465744e10,4.476097728118765e11,1.955793734114073e12,6.229626820644424e12,1.4665713663876832e13,2.56478138439078e13,3.319636806334255e13,3.135144116117232e13,2.098522418302309e13,9.426637994127908e12,2.547724446396354e12,3.1303099000091724e11,0,0,0,0,0,0,0},{0,0,0,-28.003910068426197,-10845.277747543556,-1.0340539156313771e6,-4.160211107138518e7,-8.934162310823445e8,-1.1653781015963501e10,-9.995712648139485e10,-5.936175304669795e11,-2.525790561524574e12,-7.87163260522547e12,-1.819637446847215e13,-3.1333388101515715e13,-4.001900002443862e13,-3.736019485586116e13,-2.4754756721440023e13,-1.1020607767604893e13,-2.954822829857143e12,-3.6045992787984406e11,0,0,0,0,0,0},{0,0,0,7.704568327482677e-6,63.01369198098898,19921.879208008424,1.6868344786841804e6,6.273964748932823e7,1.273959927266718e9,1.593305010069684e10,1.3225038205179854e11,7.649853076246484e11,3.185325437278451e12,9.749212126813445e12,2.219341094639236e13,3.771515415332075e13,4.76205488262829e13,4.401174323403532e13,2.890378760514151e13,1.2766176186368576e13,3.3986221771528154e12,4.1195420329125037e11,0,0,0,0,0}},{{1.0666666666666667,-270.93333333333334,-275873.1560624472,-1.9526615598641343e7,-5.463067917939428e8,-8.201340252473525e9,-7.590059501108307e10,-4.682825773172421e11,-2.0210768151063833e12,-6.288523857290183e12,-1.4356521317251836e13,-2.4229695665058094e13,-3.016739913942077e13,-2.7348748241932996e13,-1.7548912264512844e13,-7.551241265098464e12,-1.9542698611862817e12,-2.2991410131603317e11,0,0,0,0,0,0,0,0,0},{0,1.6,6051.193879719814,888285.5021747415,4.261058156357549e7,9.887753453648256e8,1.327213854827666e10,1.1396014858065186e11,6.662406988329823e11,2.7610060006323486e12,8.322298591918423e12,1.852086668895058e13,3.0609487847613902e13,3.744833590963831e13,3.344798330425991e13,2.11898795413883e13,9.017191413252525e12,2.311033121849092e12,2.6955446361190094e11,0,0,0,0,0,0,0,0},{0,0,-42.156757847819044,-19540.15290525303,-1.9336304731780519e6,-7.685712819702701e7,-1.594439517783882e9,-1.9858807743317722e10,-1.6160641862808392e11,-9.073615412262385e11,-3.643384657047884e12,-1.0707067507058748e13,-2.333725913033687e13,-3.790443110434288e13,-4.569379747197401e13,-4.029844176053195e13,-2.5250191501700312e13,-1.0641806906700912e13,-2.7042399413968125e12,-3.1303099000091724e11,0,0,0,0,0,0,0},{0,0,0.007820136852394917,137.56233770685833,42550.691954386595,3.4813989145593178e6,1.2363151215452614e8,2.3794672470258155e9,2.8087829807876396e10,2.19531539097911e11,1.1943955071569575e12,4.67634681344435e12,1.34610069080083e13,2.883661986591e13,4.615458622396285e13,5.4943021866992516e13,4.792868725397259e13,2.9744824442882992e13,1.2430432946055994e13,3.135052793797065e12,3.6045992787984406e11,0,0,0,0,0,0},{0,0,-0.000015409136654965353,-0.027397444972528398,-300.78237626127407,-76605.63532406824,-5.592621537223804e6,-1.841644469419035e8,-3.3586851599070764e9,-3.807661046434377e10,-2.883838211797314e11,-1.5299369967994255e12,-5.867608218199371e12,-1.6601437441364713e13,-3.5048526877146164e13,-5.5398397289151914e13,-6.523376765866994e13,-5.636627223479088e13,-3.46882547466682e13,-1.4388245861827873e13,-3.604599278798441e12,-4.1195420329125037e11,0,0,0,0,0}}}, {{{0,-0.5666666666666667,94002.06666666667,9.151311935305258e6,3.320851910459127e8,6.33521032186008e9,7.382275924950447e10,5.713935821593523e11,3.094041226242078e12,1.2118112094805514e13,3.5055579190329652e13,7.577080308439667e13,1.2277365554920727e14,1.4836959871768953e14,1.316939805223555e14,8.331707351347927e13,3.554854783594292e13,9.164851762804633e12,1.0782178544476038e12,0,0,0,0,0,0,0,0},{0,0,-1637.1,-334159.9205226142,-2.0918744937359024e7,-6.185177808929194e8,-1.0456566421124214e10,-1.1244319702124878e11,-8.217073662582078e11,-4.261136422965968e12,-1.613507388311211e13,-4.54274671317859e13,-9.60274321618125e13,-1.5272694341908484e14,-1.8167523305110694e14,-1.5908213959048006e14,-9.946452714264984e13,-4.200158523126891e13,-1.0730006712809219e13,-1.252123960003669e12,0,0,0,0,0,0,0},{0,0,8.5,5760.15335336423,758011.4560133434,3.872804138514868e7,1.0159241892397866e9,1.586238004713476e10,1.611446504457956e11,1.1282876946995315e12,5.658785050777512e12,2.0860295618072766e13,5.745164785582471e13,1.1922862068135155e14,1.8668579152657497e14,2.1910636544081044e14,1.8963108518772156e14,1.1735697816416962e14,4.9110491347309305e13,1.2445353299430406e13,1.4418397115193762e12,0,0,0,0,0,0},{0,0,0,-29.753679653679654,-12996.633706471774,-1.396745220816542e6,-6.3353746792567894e7,-1.5357532178764133e9,-2.2663668846309917e10,-2.2067759802151013e11,-1.4948161492516946e12,-7.300452192754711e12,-2.633115093534921e13,-7.12076759521055e13,-1.4550478401170806e14,-2.2481450876051734e14,-2.608206421034274e14,-2.2345389682757944e14,-1.3705312915212823e14,-5.689609265768836e13,-1.4315408564370951e13,-1.6478168131650015e12,0,0,0,0,0},{0,0,0,6.416135448393513e-6,66.95038440199731,23868.836113681442,2.2775814000040796e6,9.549105192520149e7,2.1884705815436573e9,3.0963237347720776e10,2.91743710502673e11,1.9247605684553428e12,9.198896562512525e12,3.258322450023937e13,8.677160313048934e13,1.749810194392509e14,2.6727116291968612e14,3.0697010372751906e14,2.6065987367419022e14,1.5860983054210656e14,6.537859338635338e13,1.6344561363015016e13,1.8704947608900017e12,0,0,0,0}},{{1.1333333333333333,-325.26666666666665,-379672.3372771824,-3.044289317860951e7,-9.653190181565726e8,-1.645654568518213e10,-1.7350035488585364e11,-1.224974862145457e12,-6.087121650396307e12,-2.198279146517062e13,-5.886931627391679e13,-1.1819629684730314e14,-1.7844037358940066e14,-2.014677026353088e14,-1.674879308472654e14,-9.947402064977933e13,-3.992880786963631e13,-9.703960690028434e12,-1.0782178544476038e12,0,0,0,0,0,0,0,0},{0,1.7,7358.141045228405,1.2228343356326213e6,6.639078335866816e7,1.7454206071277142e9,2.6599212141387142e10,2.601475592017887e11,1.740271415261319e12,8.302886018750533e12,2.904578302199949e13,7.582019351190167e13,1.490656602100751e14,2.211250836544858e14,2.4596589754150544e14,2.018771799198576e14,1.185708301208829e14,4.713181534517283e13,1.1356068692811053e13,1.252123960003669e12,0,0,0,0,0,0,0},{0,0,-45.30670672845925,-23779.18039507422,-2.661791803943833e6,-1.1969660677337208e8,-2.812574307228695e9,-3.9764345032168434e10,-3.685338752285082e11,-2.367394455421027e12,-1.0942906507013615e13,-3.73202401876562e13,-9.540709750646728e13,-1.843299072761322e14,-2.694183018006003e14,-2.9589668840921594e14,-2.401899624280804e14,-1.3971389256713602e14,-5.5062823051114625e13,-1.3166273155190094e13,-1.4418397115193762e12,0,0,0,0,0,0},{0,0,0.00735930735930736,147.96135233748615,51796.68308694178,4.792105916700205e6,1.9247997245947763e8,4.195150944550882e9,5.6203346619271835e10,5.002227932450558e11,3.113437647355672e12,1.403128377992629e13,4.686853664732211e13,1.1775423667475845e14,2.241800875868455e14,3.235464771315656e14,3.5146497769033325e14,2.825652031993201e14,1.6297151920138706e14,6.37448312874054e13,1.5139316970953451e13,1.6478168131650015e12,0,0,0,0,0},{0,0,-0.000012832270896787026,-0.025780032231645135,-323.6322744648659,-93265.65360101484,-7.69771425123931e6,-2.866519541825688e8,-5.919173280043663e9,-7.614963399570706e10,-6.566791772809753e11,-3.985094039738327e12,-1.7590885222630846e13,-5.775012578906397e13,-1.429804558962491e14,-2.6879959044347166e14,-3.8372757967297875e14,-4.1286846760141056e14,-3.291372259583687e14,-1.8840988086355138e14,-7.320015630019402e13,-1.7279808743460016e13,-1.8704947608900017e12,0,0,0,0}}}, {{{0,-0.6,125193.6,1.3652102441336416e7,5.554014600143847e8,1.1899676153316288e10,1.56165088407177e11,1.366540496131952e12,8.40861783023701e12,3.767209777990931e13,1.2572771066140053e14,3.1699683846911475e14,6.078847468910346e14,8.864741332485448e14,9.755540111565658e14,7.962880116350478e14,4.6711589143195694e14,1.8610613034936884e14,4.507646256013208e13,5.008495840014676e12,0,0,0,0,0,0,0},{0,0,-1943.4,-444350.0575188254,-3.1158621445006426e7,-1.0328718631043336e9,-1.9611734199856762e10,-2.3751855080120044e11,-1.9624234636460256e12,-1.1564556559203219e13,-5.009287309334422e13,-1.6271440389198622e14,-4.0123038305561994e14,-7.55244323016712e14,-1.0841303144905668e15,-1.1770068866194732e15,-9.494737901060278e14,-5.512548272291732e14,-2.1763242435124375e14,-5.228566111772896e13,-5.767358846077505e12,0,0,0,0,0,0},{0,0,9,6834.2430464192685,1.0071578139815058e6,5.7630935107687674e7,1.6947655536972034e9,2.971887868603432e10,3.400242318221734e11,2.691676008673227e12,1.5341040964447729e13,6.469277318651995e13,2.0556218578916944e14,4.9764013132721725e14,9.221943510366396e14,1.306119324762518e15,1.4015595146061295e15,1.1191029056445291e15,6.438857748567351e14,2.5216204623961334e14,6.0145313680522555e13,6.591267252660006e12,0,0,0,0,0},{0,0,0,-31.503474903474903,-15415.791203007979,-1.8549118704564322e6,-9.421570811376691e7,-2.5600544123712883e9,-4.242743900283097e10,-4.6525101895250854e11,-3.5629896100471016e12,-1.977415609780622e13,-8.158625551552306e13,-2.545518754366963e14,-6.067625924438578e14,-1.1095340952535998e15,-1.553365741029738e15,-1.650033451843795e15,-1.3057251452334125e15,-7.452766846539458e14,-2.8978473074627556e14,-6.867387907839006e13,-7.481979043560007e12,0,0,0,0},{0,0,0,5.4000054000054e-6,70.88716688716688,28306.784007021753,3.0236617450400395e6,1.4194238784983155e8,3.6460856395006375e9,5.792852759286986e10,6.146661187977393e11,4.584553043233062e12,2.4898101684512574e13,1.008823224117668e14,3.099519834507942e14,7.291125023795298e14,1.3180326124569462e15,1.826761435393357e15,1.9232229378190795e15,1.5098730462049652e15,8.556875473106161e14,3.305876811925353e14,7.788932029962469e13,8.4412071260677e12,0,0,0}},{{1.2,-386.4,-512904.0826728312,-4.6250508101108156e7,-1.6498943779538748e9,-3.1693433546401592e10,-3.774969633261728e11,-3.0222573837808267e12,-1.7114252146731506e13,-7.088860314805319e13,-2.195652433185797e14,-5.154436720771549e14,-9.229759888796809e14,-1.260086991646628e15,-1.3012905395960398e15,-9.989055197138905e14,-5.52186666361618e14,-2.0770526865943212e14,-4.758071048013942e13,-5.008495840014676e12,0,0,0,0,0,0,0},{0,1.8,8846.315037650835,1.652499890670798e6,1.0081815236953616e8,2.980852295984091e9,5.117658296341241e10,5.653923499515992e11,4.2884376326036885e12,2.3314343858552824e13,9.354089348013502e13,2.8240048108547756e14,6.491502225984054e14,1.142121460503862e15,1.5361570189811522e15,1.5661512339351905e15,1.188884318540835e15,6.508081678370406e14,2.4269387512646872e14,5.516934054076771e13,5.767358846077505e12,0,0,0,0,0,0},{0,0,-48.486092838536685,-28610.053294245357,-3.5971398670573817e6,-1.8170450901651797e8,-4.800628986511418e9,-7.645048609922267e10,-8.002747183060198e11,-5.828318542596038e12,-3.0696178946402035e13,-1.2005854798795881e14,-3.549510824718861e14,-8.017723301469554e14,-1.3898631564766085e15,-1.8456808435841622e15,-1.8609896441157935e15,-1.3990467910248515e15,-7.593074829663808e14,-2.8099884047000084e14,-6.3440947306852555e13,-6.591267252660006e12,0,0,0,0,0},{0,0,0.0069498069498069494,158.46348709704054,62337.20331735644,6.475875533245151e6,2.921192897693864e8,7.157442458806223e9,1.0799555655084192e11,1.0855125833750288e12,7.659196496678287e12,3.932659690536154e13,1.5063960727715928e14,4.376723566398628e14,9.741274125347245e14,1.6673482941700252e15,2.189911586818609e15,2.1868594523613995e15,1.630061509290193e15,8.779941332352192e14,3.227187992148031e14,7.241486860017006e13,7.481979043560007e12,0,0,0,0},{0,0,-0.0000108000108000108,-0.024343224343224345,-346.71430558980086,-112261.86290506809,-1.0402072220276337e7,-4.349568507848248e8,-1.009552791463289e10,-1.4625792737830328e11,-1.4242626335574956e12,-9.797394622514166e12,-4.9269031116791766e13,-1.8547288277928522e14,-5.3100005187471706e14,-1.167000294197266e15,-1.9756813909489115e15,-2.5700586158413735e15,-2.544779679266689e15,-1.882576246583223e15,-1.007168503518773e15,-3.6794961500620994e14,-8.210992386265853e13,-8.4412071260677e12,0,0,0}}}, {{{0,-0.6333333333333333,164158.73333333334,1.9930293177442875e7,9.033522147628825e8,2.159562943718983e10,3.1695435436427655e11,3.1117616133093535e12,2.1572888288816043e13,1.09484309701826e14,4.1677133450584825e14,1.2090804894217778e15,2.6979173704553415e15,4.645555959846248e15,6.155935299753043e15,6.217286496234509e15,4.696578395452082e15,2.568066717852626e15,9.596044046707916e14,2.191596361509452e14,2.306943538431002e13,0,0,0,0,0,0},{0,0,-2285.7,-581877.1667007137,-4.542712920857985e7,-1.6777496857464986e9,-3.554596419337812e10,-4.8146941932528937e11,-4.463236488322537e12,-2.963468073013338e13,-1.4541483616136725e14,-5.387724333982664e14,-1.528682077106105e15,-3.3483222279232085e15,-5.675362800076585e15,-7.419408932698538e15,-7.405721111493924e15,-5.536919691805194e15,-3.000077941416619e15,-1.1119673832339076e15,-2.5211597241424522e14,-2.6365069010640023e13,0,0,0,0,0},{0,0,9.5,8034.346639088207,1.3179673367617e6,8.39534763120524e7,2.750469750609688e9,5.381559497441904e10,6.886135692098751e11,6.116068398456957e12,3.927525531830635e13,1.87621875146192e14,6.800177457846064e14,1.8942591437198682e15,4.0847532803221355e15,6.831268665098625e15,8.82695090814349e15,8.720982640500069e15,6.461561639299811e15,3.4729854777955795e15,1.277987710634628e15,2.8787805081888025e14,2.9927916174240027e13,0,0,0,0},{0,0,0,-33.253291753291755,-18118.497367092852,-2.4263056561244098e6,-1.371723164151261e8,-4.1521251582654886e9,-7.677555171735455e10,-9.415385502549863e11,-8.089827546033466e12,-5.058607217578998e13,-2.364337668337472e14,-8.414253645683544e14,-2.307828334679184e15,-4.910703691264801e15,-8.118041289783834e15,-1.0383658748433438e16,-1.0167288912591014e16,-7.473149461470064e15,-3.9880042421706445e15,-1.4580506661137562e15,-3.2652123928561875e14,-3.37648285042708e13,0,0,0},{0,0,0,4.587809465858246e-6,74.82402515085442,33264.59142595566,3.9539347999028377e6,2.0657696267892247e8,5.910713251530081e9,1.0476957462492262e11,1.2431924580143315e12,1.0402955953492928e13,6.365382991017692e13,2.9216326172935256e14,1.0238733031895974e15,2.7713247980029775e15,5.829535183879195e15,9.540280533475378e15,1.209446128636118e16,1.1748726073620186e16,8.574250203286003e15,4.5463150567317e15,1.6525312353663298e15,3.6811898393680606e14,3.788249051698675e13,0,0}},{{1.2666666666666666,-454.73333333333335,-681521.0882190833,-6.866812258629e7,-2.7377423472293215e9,-5.885373059155742e10,-7.861999036201415e11,-7.081109305222594e12,-4.529513317348146e13,-2.1305179026514706e14,-7.544247442837826e14,-2.042292971648917e15,-4.264112494563583e15,-6.887192122673396e15,-8.579721224269423e15,-8.162941954518764e15,-5.819981799016939e15,-3.0089392479769985e15,-1.064858703611706e15,-2.3069435384310022e14,-2.306943538431002e13,0,0,0,0,0,0},{0,1.9,10528.43340142741,2.1966056588859563e6,1.496340808486337e8,4.94310202090654e9,9.495646973148334e10,1.1764390850983005e12,1.0037702723170137e13,6.163907586873927e13,2.808207197238787e14,9.692149606108888e14,2.56903911487428e15,5.27020715794106e15,8.385800766327233e15,1.0313148662287174e16,9.703156383423962e15,6.850671684428315e15,3.5112616134256495e15,1.2330819190015352e15,2.6529850691956525e14,2.6365069010640023e13,0,0,0,0,0},{0,0,-51.693278176413344,-34074.78014180465,-4.781836743440356e6,-2.6961591339264446e8,-7.957160824871687e9,-1.417663970015018e11,-1.6639977875868992e12,-1.3631292963271166e13,-8.108623737250361e13,-3.6010324340970756e14,-1.2170534965459422e15,-3.1699041795772295e15,-6.406817661291515e15,-1.006485817543921e16,-1.2241435673077942e16,-1.1405817498928164e16,-7.983798180042419e15,-4.0608079407256885e15,-1.4163152517613982e15,-3.0284200890600025e14,-2.9927916174240027e13,0,0,0,0},{0,0,0.006583506583506584,169.06299475396784,74264.58077013028,8.60869260141037e6,4.3336689596040046e8,1.1859561376200863e10,2.0016987814094357e11,2.255834083018215e12,1.7902005880230887e13,1.0381148852085344e14,4.5148680237416356e14,1.499482007722108e15,3.8480749449814715e15,7.679151287997549e15,1.1931083759742532e16,1.4371388164888972e16,1.3276270216445754e16,9.222548421515924e15,4.658972295533745e15,1.614980380412015e15,3.434036535377542e14,3.37648285042708e13,0,0,0},{0,0,-9.175618931716493e-6,-0.023058330375403547,-370.01552049520996,-133761.33977549043,-1.3827819745792182e7,-6.451738118427956e8,-1.6723378636699493e10,-2.709901673195793e11,-2.9584696444771226e12,-2.288771647820421e13,-1.2998082039545089e14,-5.555315701855969e14,-1.8179762075703875e15,-4.606611728235598e15,-9.092222501474912e15,-1.3990963605707124e16,-1.6709589472590812e16,-1.5319694204447672e16,-1.0570016078374418e16,-5.307109848412682e15,-1.8294877603627978e15,-3.8706022919529944e14,-3.788249051698675e13,0,0}}}, {{{0,-0.6666666666666666,212266.66666666666,2.853599258035219e7,1.4330114863456995e9,3.800258146404937e10,6.199274770948887e11,6.782860407787912e12,5.259010470068523e13,2.998352445442762e14,1.289474302995765e15,4.256253873967506e15,1.0902678302444068e16,2.1797926698136784e16,3.403776778865586e16,4.131592071162812e16,3.85489253454479e16,2.709770607257666e16,1.3874444112447926e16,4.881180309397506e15,1.054602760425601e15,1.054602760425601e14,0,0,0,0,0},{0,0,-2666,-751541.6624389548,-6.496750631920008e7,-2.6584414136368732e9,-6.248207318933823e10,-9.406826677470544e11,-9.718503789838549e12,-7.216907849489138e13,-3.978378205026157e14,-1.6653179634893145e15,-5.376204754295016e15,-1.3518436707709178e16,-2.6605608406951144e16,-4.0986885639172104e16,-4.9169772065455784e16,-4.540651511838149e16,-3.162877001568124e16,-1.6063591016532404e16,-5.610415428520925e15,-1.204242341296801e15,-1.1971166469696011e14,0,0,0,0},{0,0,10,9367.463398770313,1.701250849010266e6,1.1998124014091475e8,4.354863213182676e9,9.45208118958657e10,1.344305113466995e12,1.3306614989260633e13,9.556877985629884e13,5.12895265809024e14,2.1002083731150322e15,6.656579614385937e15,1.6478625548324368e16,3.1999232770493936e16,4.8724507460816184e16,5.785749736908936e16,5.294839315410694e16,3.65864067552318e16,1.844784707627131e16,6.401367498840126e15,1.365940789490955e15,1.350593140170832e14,0,0,0},{0,0,0,-35.00312695434646,-21120.499631781146,-3.13075780749621e6,-1.9594466391609663e8,-6.57050375487538e9,-1.3476651743799847e11,-1.8369043800571548e12,-1.7589435314077154e13,-1.2300981206774544e14,-6.45896597792679e14,-2.5969519006174225e15,-8.1043872896729e15,-1.979717247928791e16,-3.800085757405471e16,-5.727840617892459e16,-6.7406697825393336e16,-6.119592653276693e16,-4.198322456673902e16,-2.1032687680075924e16,-7.255685440992997e15,-1.5400055927557658e15,-1.51529962067947e14,0,0},{0,0,0,3.930803703917714e-6,78.76094777966587,38771.1275913068,5.100639029001081e6,2.949841095687273e8,9.349478097378347e9,1.8381938202018082e11,2.42419630975418e12,2.2606778024802125e13,1.547013295439825e14,7.976887641336864e14,3.1582328358075825e15,9.726354425919532e15,2.3487483127377148e16,4.463176708335417e16,6.667543951844797e16,7.784411667165024e16,7.0169853688251656e16,4.78314795584771e16,2.3823442630743476e16,8.174976337050191e15,1.7267367770533495e15,1.6914972509910362e14,0}},{{1.3333333333333333,-530.6666666666666,-892251.827371045,-9.987215970701566e7,-4.424126639899304e9,-1.0578643572033942e11,-1.5747287228400437e12,-1.5845717567057562e13,-1.1362682509291195e14,-6.01771280857198e14,-2.4125671241445005e15,-7.446002113664234e15,-1.7881405459744606e16,-3.35951258854644e16,-4.9401354974251736e16,-5.657957303847233e16,-4.9900402465368104e16,-3.3212859965007824e16,-1.612718315044587e16,-5.388707887852326e15,-1.107332898446881e15,-1.054602760425601e14,0,0,0,0,0},{0,2,12417.32487790964,2.877010547668333e6,2.1757735630149266e8,7.983815399399566e9,1.7056499979904105e11,2.354551408251009e12,2.244295896408418e13,1.5448897973201038e14,7.924454954576368e14,3.09644241377513e15,9.357141993333924e15,2.2077909573687176e16,4.086271515883938e16,5.931957879239599e16,6.7183171140618856e16,5.867380519673225e16,3.8715022071894504e16,1.8654226260365056e16,6.190090662038646e15,1.2640981736452812e15,1.1971166469696011e14,0,0,0,0},{0,0,-54.92679754062404,-40215.75896837982,-6.263591942903851e6,-3.919620881744125e8,-1.2847160247073557e10,-2.5452055340858438e11,-3.3284003694315527e12,-3.045760371601915e13,-2.0308431931952872e14,-1.0153938929148701e15,-3.8851031201166525e15,-1.1535964059895936e16,-2.6816071946032308e16,-4.9000640659284456e16,-7.0346216741010216e16,-7.889814086638738e16,-6.831336974290147e16,-4.473081072704507e16,-2.1405078738350924e16,-7.0590142722074e15,-1.4334704464994968e15,-1.350593140170832e14,0,0,0},{0,0,0.006253908692933083,179.75473573239677,87672.02030488498,1.127655502867755e7,6.299257811345832e8,1.9142375540966686e10,3.592377142778432e11,4.510116251939719e12,3.997869384169198e13,2.598472460491622e14,1.2722572790529712e15,4.783417939546741e15,1.3993927307709768e16,3.2117401194767464e16,5.8041145938566104e16,8.251977130024504e16,9.176083681396456e16,7.884587952758733e16,5.127529010535035e16,2.4385985285874588e16,7.99727636948314e15,1.6157705737897392e15,1.51529962067947e14,0,0},{0,0,-7.861607407835427e-6,-0.021902438238229502,-393.52434085950074,-157932.76854200763,-1.8113190266049244e7,-9.376913624338514e8,-2.698711715217962e10,-4.86188476940676e11,-5.912673590075985e12,-5.109028982891983e13,-3.251901708214681e14,-1.5646005583864498e15,-5.796048104691107e15,-1.6742037879323554e16,-3.800261305735843e16,-6.801536029880263e16,-9.587749223709138e16,-1.0580649570083427e17,-9.029733700258528e16,-5.8363106600548536e16,-2.7603025440299108e16,-9.006629152120784e15,-1.8113116396029015e15,-1.6914972509910362e14,0}}} }; /* Compute the singular field at the point x for the particle at xp */ void effsource_PhiS(struct coordinate * x, double * PhiS) { double A, alpha, rho2; double r = x->r; double theta = x->theta; double phi = x->phi; double rp = xp.r; double thetap = xp.theta; double phip = xp.phi; double dr = r - rp; double dtheta = theta - thetap; double dphi = phi - phip; double dr2 = dr*dr; double dr3 = dr2*dr; double dr4 = dr2*dr2; double dr6 = dr3*dr3; double dr8 = dr4*dr4; double dtheta2 = dtheta*dtheta; double dtheta4 = dtheta2*dtheta2; double dtheta8 = dtheta4*dtheta4; double sindphi = sin(0.5*dphi); double sindphi2 = sindphi*sindphi; double sindphi4 = sindphi2*sindphi2; double sindphi8 = sindphi4*sindphi4; A = dr6*(A600 + A700*dr) + dr8*(A800 + A900*dr) + dr4*(A420 + A520*dr + dr2*(A620 + A720*dr))*dtheta2 + (A080 + A180*dr)*dtheta8 + dtheta4*(dr2*(A240 + A340*dr) + dr4*(A440 + A540*dr) + (A060 + A160*dr + dr2*(A260 + A360*dr))*dtheta2) + (dr4*(A402 + A502*dr + dr2*(A602 + A702*dr)) + (dr2*(A222 + A322*dr) + dr4*(A422 + A522*dr))*dtheta2 + dtheta4*(A042 + A142*dr + dr2*(A242 + A342*dr) + (A062 + A162*dr)*dtheta2))*sindphi2 + (A008 + A108*dr)*sindphi8 + sindphi4*(dr2*(A204 + A304*dr) + dr4*(A404 + A504*dr) + (A024 + A124*dr + dr2*(A224 + A324*dr))*dtheta2 + (A044 + A144*dr)*dtheta4 + (A006 + A106*dr + dr2*(A206 + A306*dr) + (A026 + A126*dr)*dtheta2)*sindphi2); alpha = alpha20*dr2 + alpha02*dtheta2; rho2 = alpha + beta*sindphi2; *PhiS = A/pow(rho2, 3.5); } /* Compute the singular field at the point x for the particle at xp */ void effsource_PhiS_m(int m, struct coordinate * x, double * PhiS) { double A[5], num, alpha, ellE, ellK; double r = x->r; const double theta = x->theta; const double rp = xp.r; const double thetap = xp.theta; const double dr = r - rp; const double dtheta = theta - thetap; const double dr2 = dr*dr; const double dr3 = dr2*dr; const double dr4 = dr2*dr2; const double dr6 = dr3*dr3; const double dr8 = dr4*dr4; const double dtheta2 = dtheta*dtheta; const double dtheta4 = dtheta2*dtheta2; const double dtheta8 = dtheta4*dtheta4; A[0] = dr6*(A600 + A700*dr) + dr8*(A800 + A900*dr) + dr4*(A420 + A520*dr + dr2*(A620 + A720*dr))*dtheta2 + (A080 + A180*dr)*dtheta8 + dtheta4*(dr2*(A240 + A340*dr) + dr4*(A440 + A540*dr) + (A060 + A160*dr + dr2*(A260 + A360*dr))*dtheta2); A[1] = dr4*(A402 + A502*dr + dr2*(A602 + A702*dr)) + (dr2*(A222 + A322*dr) + dr4*(A422 + A522*dr))*dtheta2 + dtheta4*(A042 + A142*dr + dr2*(A242 + A342*dr) + (A062 + A162*dr)*dtheta2); A[2] = dr2*(A204 + A304*dr) + dr4*(A404 + A504*dr) + (A024 + A124*dr + dr2*(A224 + A324*dr))*dtheta2 + (A044 + A144*dr)*dtheta4; A[3] = A006 + A106*dr + dr2*(A206 + A306*dr) + (A026 + A126*dr)*dtheta2; A[4] = A008 + A108*dr; alpha = alpha20*dr2 + alpha02*dtheta2; const double C1 = alpha / beta; double C[27]; C[0] = 1; C[1] = C1; C[2] = C[1]*C[1]; C[3] = C[2]*C[1]; C[4] = C[2]*C[2]; C[5] = C[3]*C[2]; C[6] = C[3]*C[3]; C[7] = C[4]*C[3]; C[8] = C[4]*C[4]; C[9] = C[5]*C[4]; C[10] = C[5]*C[5]; C[11] = C[6]*C[5]; C[12] = C[6]*C[6]; C[13] = C[7]*C[6]; C[14] = C[7]*C[7]; C[15] = C[8]*C[7]; C[16] = C[8]*C[8]; C[17] = C[9]*C[8]; C[18] = C[9]*C[9]; C[19] = C[10]*C[9]; C[20] = C[10]*C[10]; C[21] = C[11]*C[10]; C[22] = C[11]*C[11]; C[23] = C[12]*C[11]; C[24] = C[12]*C[12]; C[25] = C[13]*C[12]; C[26] = C[13]*C[13]; ellE = gsl_sf_ellint_Ecomp(sqrt(1.0/(1.0+C1)), GSL_PREC_DOUBLE); ellK = gsl_sf_ellint_Kcomp(sqrt(1.0/(1.0+C1)), GSL_PREC_DOUBLE); const double ellip[2] = {ellK, ellE}; if(m>20) { printf("Support for computing mode %d has not yet been added.\n", m); return; } num = 0; for(int i=0; i<2; i++) for(int j=0; j<5; j++) for(int k=0; k<27; k++) num += ReEI[m][i][j][k]*ellip[i]*A[j]*C[k]; double RePhiS = 4.0*num/(beta*C[3]*pow(alpha+beta, 2.5)); /* Store calculated quantities into the arrays provided by the caller, including the phase factor exp(-i*m*phi_p) */ double cosmph = cos(m*xp.phi); double sinmph = sin(m*xp.phi); PhiS[0] = RePhiS*cosmph; PhiS[1] = - RePhiS*sinmph; } /* Compute the singular field, its derivatives and its d'Alembertian */ void effsource_calc(struct coordinate * x, double *PhiS, double *dPhiS_dx, double *d2PhiS_dx2, double *src) { double A, dA_dr, d2A_dr2, dA_dth, d2A_dth2, dA_dR, dA_dph, d2A_dR2, d2A_dph2, dA_dt, d2A_dt2, d2A_dphdt; double s2, sqrts2, s2_15, s2_25, s2_35, s2_45, s2_55, ds2_dr, d2s2_dr2, ds2_dth, d2s2_dth2, ds2_dR, ds2_dph, d2s2_dR2, d2s2_dph2, ds2_dt, d2s2_dt2, d2s2_dphdt; double dPhiS_dt, dPhiS_dr, dPhiS_dth, dPhiS_dph, d2PhiS_dt2, d2PhiS_dtr, d2PhiS_dtth; double d2PhiS_dtph, d2PhiS_dr2, d2PhiS_drth, d2PhiS_drph, d2PhiS_dth2, d2PhiS_dthph, d2PhiS_dph2; double r = x->r; double theta = x->theta; double phi = x->phi; double rp = xp.r; double thetap = xp.theta; double phip = xp.phi; double dr = r - rp; double dtheta = theta - thetap; double dphi = phi - phip; double dr2 = dr*dr; double dr3 = dr2*dr; double dr4 = dr2*dr2; double dr5 = dr3*dr2; double dr6 = dr3*dr3; double dr7 = dr4*dr3; double dr8 = dr4*dr4; double dtheta2 = dtheta*dtheta; double dtheta3 = dtheta2*dtheta; double dtheta4 = dtheta2*dtheta2; double dtheta5 = dtheta3*dtheta2; double dtheta6 = dtheta3*dtheta3; double dtheta7 = dtheta4*dtheta3; double dtheta8 = dtheta4*dtheta4; double R = sin(0.5*dphi); double R2 = R*R; double R3 = R2*R; double R4 = R2*R2; double R5 = R3*R2; double R6 = R3*R3; double R7 = R4*R3; double R8 = R4*R4; double dR = 0.5*cos(0.5*dphi); double om = M / (a*M + sqrt(M*pow(rp,3))); /* A, dA/dx, d^2A/dx^2 */ A = dr6*(A600 + A700*dr) + dr8*(A800 + A900*dr) + dr4*(A420 + A520*dr + dr2*(A620 + A720*dr))*dtheta2 + (A080 + A180*dr)*dtheta8 + dtheta4*(dr2*(A240 + A340*dr) + dr4*(A440 + A540*dr) + (A060 + A160*dr + dr2*(A260 + A360*dr))*dtheta2) + (dr4*(A402 + A502*dr + dr2*(A602 + A702*dr)) + (dr2*(A222 + A322*dr) + dr4*(A422 + A522*dr))*dtheta2 + dtheta4*(A042 + A142*dr + dr2*(A242 + A342*dr) + (A062 + A162*dr)*dtheta2))*R2 + (A008 + A108*dr)*R8 + R4*(dr2*(A204 + A304*dr) + dr4*(A404 + A504*dr) + (A024 + A124*dr + dr2*(A224 + A324*dr))*dtheta2 + (A044 + A144*dr)*dtheta4 + (A006 + A106*dr + dr2*(A206 + A306*dr) + (A026 + A126*dr)*dtheta2)*R2);; dA_dr = 6*(A600 + A700*dr)*dr5 + A700*dr6 + 8*(A800 + A900*dr)*dr7 + A900*dr8 + 4*(A420 + A520*dr + (A620 + A720*dr)*dr2)*dr3*dtheta2 + (A520 + 2*dr*(A620 + A720*dr) + A720*dr2)*dr4*dtheta2 + (2*dr*(A240 + A340*dr) + A340*dr2 + 4*(A440 + A540*dr)*dr3 + A540*dr4 + (A160 + 2*dr*(A260 + A360*dr) + A360*dr2)*dtheta2)*dtheta4 + A180*dtheta8 + (4*(A402 + A502*dr + (A602 + A702*dr)*dr2)*dr3 + (A502 + 2*dr*(A602 + A702*dr) + A702*dr2)*dr4 + (2*dr*(A222 + A322*dr) + A322*dr2 + 4*(A422 + A522*dr)*dr3 + A522*dr4)* dtheta2 + (A142 + 2*dr*(A242 + A342*dr) + A342*dr2 + A162*dtheta2)* dtheta4)*R2 + (2*dr*(A204 + A304*dr) + A304*dr2 + 4*(A404 + A504*dr)*dr3 + A504*dr4 + (A124 + 2*dr*(A224 + A324*dr) + A324*dr2)*dtheta2 + A144*dtheta4 + (A106 + 2*dr*(A206 + A306*dr) + A306*dr2 + A126*dtheta2)*R2)* R4 + A108*R8; dA_dth = 2*(A420 + A520*dr + (A620 + A720*dr)*dr2)*dr4*dtheta + 4*((A240 + A340*dr)*dr2 + (A440 + A540*dr)*dr4 + (A060 + A160*dr + (A260 + A360*dr)*dr2)*dtheta2)*dtheta3 + 2*(A060 + A160*dr + (A260 + A360*dr)*dr2)*dtheta5 + 8*(A080 + A180*dr)*dtheta7 + (2*((A222 + A322*dr)*dr2 + (A422 + A522*dr)*dr4)*dtheta + 4*(A042 + A142*dr + (A242 + A342*dr)*dr2 + (A062 + A162*dr)*dtheta2)* dtheta3 + 2*(A062 + A162*dr)*dtheta5)*R2 + (2*(A024 + A124*dr + (A224 + A324*dr)*dr2)*dtheta + 4*(A044 + A144*dr)*dtheta3 + 2*(A026 + A126*dr)*dtheta*R2)* R4; dA_dR = 2*((A402 + A502*dr + (A602 + A702*dr)*dr2)*dr4 + ((A222 + A322*dr)*dr2 + (A422 + A522*dr)*dr4)*dtheta2 + (A042 + A142*dr + (A242 + A342*dr)*dr2 + (A062 + A162*dr)*dtheta2)* dtheta4)*R + 4*((A204 + A304*dr)*dr2 + (A404 + A504*dr)*dr4 + (A024 + A124*dr + (A224 + A324*dr)*dr2)*dtheta2 + (A044 + A144*dr)*dtheta4 + (A006 + A106*dr + (A206 + A306*dr)*dr2 + (A026 + A126*dr)*dtheta2)* R2)*R3 + 2*(A006 + A106*dr + (A206 + A306*dr)*dr2 + (A026 + A126*dr)*dtheta2)*R5 + 8*(A008 + A108*dr)*R7; dA_dph = dA_dR*dR; dA_dt = -om*dA_dph; d2A_dr2 = 30*(A600 + A700*dr)*dr4 + 12*A700*dr5 + 56*(A800 + A900*dr)*dr6 + 16*A900*dr7 + 12*dr2*(A420 + A520*dr + (A620 + A720*dr)*dr2)*dtheta2 + 8*(A520 + 2*dr*(A620 + A720*dr) + A720*dr2)*dr3*dtheta2 + (4*A720*dr + 2*(A620 + A720*dr))*dr4*dtheta2 + (4*A340*dr + 2*(A240 + A340*dr) + 12*(A440 + A540*dr)*dr2 + 8*A540*dr3 + (4*A360*dr + 2*(A260 + A360*dr))*dtheta2)*dtheta4 + (12*dr2*(A402 + A502*dr + (A602 + A702*dr)*dr2) + 8*(A502 + 2*dr*(A602 + A702*dr) + A702*dr2)*dr3 + (4*A702*dr + 2*(A602 + A702*dr))*dr4 + (4*A322*dr + 2*(A222 + A322*dr) + 12*(A422 + A522*dr)*dr2 + 8*A522*dr3)*dtheta2 + (4*A342*dr + 2*(A242 + A342*dr))*dtheta4)* R2 + (4*A304*dr + 2*(A204 + A304*dr) + 12*(A404 + A504*dr)*dr2 + 8*A504*dr3 + (4*A324*dr + 2*(A224 + A324*dr))*dtheta2 + (4*A306*dr + 2*(A206 + A306*dr))*R2)*R4; d2A_dth2 = 2*(A420 + A520*dr + (A620 + A720*dr)*dr2)*dr4 + 12*dtheta2*((A240 + A340*dr)*dr2 + (A440 + A540*dr)*dr4 + (A060 + A160*dr + (A260 + A360*dr)*dr2)*dtheta2) + 18*(A060 + A160*dr + (A260 + A360*dr)*dr2)*dtheta4 + 56*(A080 + A180*dr)*dtheta6 + (2*((A222 + A322*dr)*dr2 + (A422 + A522*dr)*dr4) + 12*dtheta2*(A042 + A142*dr + (A242 + A342*dr)*dr2 + (A062 + A162*dr)*dtheta2) + 18*(A062 + A162*dr)*dtheta4)*R2 + (2*(A024 + A124*dr + (A224 + A324*dr)*dr2) + 12*(A044 + A144*dr)*dtheta2 + 2*(A026 + A126*dr)*R2)*R4; d2A_dR2 = 2*((A402 + A502*dr + (A602 + A702*dr)*dr2)*dr4 + ((A222 + A322*dr)*dr2 + (A422 + A522*dr)*dr4)*dtheta2 + (A042 + A142*dr + (A242 + A342*dr)*dr2 + (A062 + A162*dr)*dtheta2)* dtheta4) + 12*R2*((A204 + A304*dr)*dr2 + (A404 + A504*dr)*dr4 + (A024 + A124*dr + (A224 + A324*dr)*dr2)*dtheta2 + (A044 + A144*dr)*dtheta4 + (A006 + A106*dr + (A206 + A306*dr)*dr2 + (A026 + A126*dr)*dtheta2)* R2) + 18*(A006 + A106*dr + (A206 + A306*dr)*dr2 + (A026 + A126*dr)*dtheta2)*R4 + 56*(A008 + A108*dr)*R6; d2A_dph2 = - 0.25*R*dA_dR + dR*dR*d2A_dR2; d2A_dt2 = om*om*d2A_dph2; d2A_dphdt = -om*d2A_dph2; /* s, ds/dr, d^2s/dr^2 */ s2 = alpha20*dr2 + alpha02*dtheta2 + beta*R2; ds2_dr = 2*alpha20*dr; ds2_dth = 2*alpha02*dtheta; ds2_dR = 2*beta*R; ds2_dph = ds2_dR*dR; ds2_dt = -om*ds2_dph; d2s2_dr2 = 2*alpha20; d2s2_dth2 = 2*alpha02; d2s2_dR2 = 2*beta; d2s2_dph2 = - 0.25*R*ds2_dR + dR*dR*d2s2_dR2; d2s2_dt2 = om*om*d2s2_dph2; d2s2_dphdt = -om*d2s2_dph2; sqrts2 = sqrt(s2); s2_15 = s2*sqrts2; s2_25 = s2*s2_15; s2_35 = s2*s2_25; s2_45 = s2*s2_35; s2_55 = s2*s2_45; /* PhiS */ *PhiS = A/s2_35; /* First derivatives of PhiS */ dPhiS_dt = (-7*ds2_dt*A + 2*dA_dt*s2)/(2.*s2_45); dPhiS_dr = (-7*ds2_dr*A + 2*dA_dr*s2) /(2.*s2_45); dPhiS_dth = (-7*ds2_dth*A + 2*dA_dth*s2)/(2.*s2_45); dPhiS_dph = (-7*ds2_dph*A + 2*dA_dph*s2)/(2.*s2_45); /* Second derivatives of PhiS */ d2PhiS_dr2 = (63*ds2_dr*ds2_dr*A - 14*s2*(2*dA_dr*ds2_dr + d2s2_dr2*A) + 4*d2A_dr2*s2*s2)/(4.*s2_55); d2PhiS_dth2 = (63*ds2_dth*ds2_dth*A - 14*s2*(2*dA_dth*ds2_dth + d2s2_dth2*A) + 4*d2A_dth2*s2*s2)/(4.*s2_55); d2PhiS_dph2 = (63*ds2_dph*ds2_dph*A - 14*s2*(2*dA_dph*ds2_dph + d2s2_dph2*A) + 4*d2A_dph2*s2*s2)/(4.*s2_55); d2PhiS_dt2 = (63*ds2_dt*ds2_dt*A - 14*s2*(2*dA_dt*ds2_dt + d2s2_dt2*A) + 4*d2A_dt2*s2*s2)/(4.*s2_55); d2PhiS_dtph = (63*ds2_dph*ds2_dt*A - 14*s2*(dA_dt*ds2_dph + dA_dph*ds2_dt + d2s2_dphdt*A) + 4*d2A_dphdt*s2*s2)/(4.*s2_55); d2PhiS_dtr = NAN; d2PhiS_dtth = NAN; d2PhiS_drth = NAN; d2PhiS_drph = NAN; d2PhiS_dthph = NAN; /* Box[PhiS] */ double sinth = sin(theta); double sinth2 = sinth*sinth; double sin2th = sin(2*theta); double cos2th = cos(2*theta); double r2 = r*r; double r3 = r2*r; double r4 = r2*r2; double a2 = a*a; double a4 = a2*a2; *src = -((2*a2*dPhiS_dr - a2*d2PhiS_dph2 - a4*d2PhiS_dr2 - a2*d2PhiS_dth2 - 4*dPhiS_dr*r - 2*a2*dPhiS_dr*r + 4*d2PhiS_dph2*r + 2*a*d2PhiS_dtph*r + 4*a2*d2PhiS_dr2*r + 2*d2PhiS_dth2*r + 6*dPhiS_dr*r2 - 2*d2PhiS_dph2*r2 - 4*d2PhiS_dr2*r2 - 2*a2*d2PhiS_dr2*r2 - d2PhiS_dth2*r2 - 2*dPhiS_dr*r3 + 4*d2PhiS_dr2*r3 - d2PhiS_dr2*r4 + (a4*d2PhiS_dt2 + 4*a*d2PhiS_dtph*r + 2*d2PhiS_dt2*r4 + a2*d2PhiS_dt2*r*(2 + 3*r))*sinth2 + cos2th*(a4*d2PhiS_dr2 - 2*a*d2PhiS_dtph*r + (-2 + r)*r*(d2PhiS_dth2 + 2*dPhiS_dr*(-1 + r) + d2PhiS_dr2*(-2 + r)*r) + a2*(-d2PhiS_dph2 + d2PhiS_dth2 + 2*dPhiS_dr*(-1 + r) - 4*d2PhiS_dr2*r + 2*d2PhiS_dr2*r2) + a2*d2PhiS_dt2*(a2 + (-2 + r)*r)*sinth2) - a2*dPhiS_dth*sin2th + 2*dPhiS_dth*r*sin2th - dPhiS_dth*r2*sin2th))/((sinth2*(a2 + (-2 + r)*r)*(a2 + 2*r2 + a2*cos2th))); dPhiS_dx[0] = dPhiS_dt; dPhiS_dx[1] = dPhiS_dr; dPhiS_dx[2] = dPhiS_dth; dPhiS_dx[3] = dPhiS_dph; d2PhiS_dx2[0] = d2PhiS_dt2; d2PhiS_dx2[1] = d2PhiS_dtr; d2PhiS_dx2[2] = d2PhiS_dtth; d2PhiS_dx2[3] = d2PhiS_dtph; d2PhiS_dx2[4] = d2PhiS_dr2; d2PhiS_dx2[5] = d2PhiS_drth; d2PhiS_dx2[6] = d2PhiS_drph; d2PhiS_dx2[7] = d2PhiS_dth2; d2PhiS_dx2[8] = d2PhiS_dthph; d2PhiS_dx2[9] = d2PhiS_dph2; } /* Compute the 2D singular field, its derivatives and its d'Alembertian */ void effsource_calc_m(int m, struct coordinate * x, double *PhiS, double *dPhiS_dx, double *d2PhiS_dx2, double *src) { double A[5], alpha, ellE, ellK; double dA_dr[5], dalpha_dr, dC1_dr, dellE_dC, dellK_dC, d2ellE_dC2, d2ellK_dC2, dellE_dr, dellK_dr; double d2A_dr2[5], d2alpha_dr2, d2C1_dr2, d2ellE_dr2, d2ellK_dr2; double dA_dtheta[5], dalpha_dtheta, dC1_dtheta, dellE_dtheta, dellK_dtheta; double d2A_dtheta2[5], d2alpha_dtheta2, d2C1_dtheta2, d2ellE_dtheta2, d2ellK_dtheta2; double s, ds_dr, d2s_dr2, ds_dtheta, d2s_dtheta2; double dPhiS_dt, dPhiS_dr, dPhiS_dth, dPhiS_dph, d2PhiS_dt2, d2PhiS_dtr, d2PhiS_dtth; double d2PhiS_dtph, d2PhiS_dr2, d2PhiS_drth, d2PhiS_drph, d2PhiS_dth2, d2PhiS_dthph, d2PhiS_dph2; const double r = x->r; const double theta = x->theta; const double rp = xp.r; const double thetap = xp.theta; const double om = M / (a*M + sqrt(M*pow(rp,3))); const double dr = r - rp; const double dtheta = theta - thetap; const double dr2 = dr*dr; const double dr3 = dr2*dr; const double dr4 = dr2*dr2; const double dr5 = dr3*dr2; const double dr6 = dr3*dr3; const double dr7 = dr4*dr3; const double dr8 = dr4*dr4; const double dtheta2 = dtheta*dtheta; const double dtheta3 = dtheta2*dtheta; const double dtheta4 = dtheta2*dtheta2; const double dtheta5 = dtheta3*dtheta2; const double dtheta6 = dtheta3*dtheta3; const double dtheta7 = dtheta4*dtheta3; const double dtheta8 = dtheta4*dtheta4; /* Coefficients of sin(dphi) in the numerator */ A[0] = dr6*(A600 + A700*dr) + dr8*(A800 + A900*dr) + dr4*(A420 + A520*dr + dr2*(A620 + A720*dr))*dtheta2 + (A080 + A180*dr)*dtheta8 + dtheta4*(dr2*(A240 + A340*dr) + dr4*(A440 + A540*dr) + (A060 + A160*dr + dr2*(A260 + A360*dr))*dtheta2); A[1] = dr4*(A402 + A502*dr + dr2*(A602 + A702*dr)) + (dr2*(A222 + A322*dr) + dr4*(A422 + A522*dr))*dtheta2 + dtheta4*(A042 + A142*dr + dr2*(A242 + A342*dr) + (A062 + A162*dr)*dtheta2); A[2] = dr2*(A204 + A304*dr) + dr4*(A404 + A504*dr) + (A024 + A124*dr + dr2*(A224 + A324*dr))*dtheta2 + (A044 + A144*dr)*dtheta4; A[3] = A006 + A106*dr + dr2*(A206 + A306*dr) + (A026 + A126*dr)*dtheta2; A[4] = A008 + A108*dr; /* r derivatives of coefficients */ dA_dr[0] = 6*A600*dr5 + 7*A700*dr6 + 8*A800*dr7 + 9*A900*dr8 + 4*A420*dr3*dtheta2 + 5*A520*dr4*dtheta2 + 6*A620*dr5*dtheta2 + 7*A720*dr6*dtheta2 + 2*A240*dr*dtheta4 + 3*A340*dr2*dtheta4 + 4*A440*dr3*dtheta4 + 5*A540*dr4*dtheta4 + A160*dtheta6 + 2*A260*dr*dtheta6 + 3*A360*dr2*dtheta6 + A180*dtheta8; dA_dr[1] = 4*A402*dr3 + 5*A502*dr4 + 6*A602*dr5 + 7*A702*dr6 + 2*A222*dr*dtheta2 + 3*A322*dr2*dtheta2 + 4*A422*dr3*dtheta2 + 5*A522*dr4*dtheta2 + A142*dtheta4 + 2*A242*dr*dtheta4 + 3*A342*dr2*dtheta4 + A162*dtheta6; dA_dr[2] = 2*A204*dr + 3*A304*dr2 + 4*A404*dr3 + 5*A504*dr4 + A124*dtheta2 + 2*A224*dr*dtheta2 + 3*A324*dr2*dtheta2 + A144*dtheta4; dA_dr[3] = A106 + 2*A206*dr + 3*A306*dr2 + A126*dtheta2; dA_dr[4] = A108; /* r,r derivatives of coefficients */ d2A_dr2[0] = 2*(15*A600*dr4 + 21*A700*dr5 + 28*A800*dr6 + 36*A900*dr7 + 6*A420*dr2*dtheta2 + 10*A520*dr3*dtheta2 + 15*A620*dr4*dtheta2 + 21*A720*dr5*dtheta2 + A240*dtheta4 + 3*A340*dr*dtheta4 + 6*A440*dr2*dtheta4 + 10*A540*dr3*dtheta4 + A260*dtheta6 + 3*A360*dr*dtheta6); d2A_dr2[1] = 2*(6*A402*dr2 + 10*A502*dr3 + 15*A602*dr4 + 21*A702*dr5 + A222*dtheta2 + 3*A322*dr*dtheta2 + 6*A422*dr2*dtheta2 + 10*A522*dr3*dtheta2 + A242*dtheta4 + 3*A342*dr*dtheta4); d2A_dr2[2] = 2*(A204 + 3*A304*dr + 6*A404*dr2 + 10*A504*dr3 + A224*dtheta2 + 3*A324*dr*dtheta2); d2A_dr2[3] = 2*(A206 + 3*A306*dr); d2A_dr2[4] = 0; /* theta derivatives of coefficients */ dA_dtheta[0] = 2*(A420 + dr*(A520 + dr*(A620 + A720*dr)))*dr4*dtheta + 4*((A240 + A340*dr)*dr2 + (A440 + A540*dr)*dr4 + (A060 + dr*(A160 + dr*(A260 + A360*dr)))*dtheta2)*dtheta3 + 2*(A060 + dr*(A160 + dr*(A260 + A360*dr)))*dtheta5 + 8*(A080 + A180*dr)*dtheta7; dA_dtheta[1] = 2*dtheta*((A222 + A322*dr)*dr2 + (A422 + A522*dr)*dr4 + 2*dtheta2*(A042 + A142*dr + (A242 + A342*dr)*dr2 + (A062 + A162*dr)*dtheta2) + (A062 + A162*dr)*dtheta4); dA_dtheta[2] = 2*dtheta*(A024 + A124*dr + (A224 + A324*dr)*dr2 + 2*(A044 + A144*dr)*dtheta2); dA_dtheta[3] = 2*(A026 + A126*dr)*dtheta; dA_dtheta[4] = 0; /* theta,theta derivatives of coefficients */ d2A_dtheta2[0] = 2*((A420 + dr*(A520 + dr*(A620 + A720*dr)))*dr4 + 6*dtheta2*((A240 + A340*dr)*dr2 + (A440 + A540*dr)*dr4 + (A060 + dr*(A160 + dr*(A260 + A360*dr)))*dtheta2) + 9*(A060 + dr*(A160 + dr*(A260 + A360*dr)))*dtheta4 + 28*(A080 + A180*dr)*dtheta6); d2A_dtheta2[1] = 2*((A222 + A322*dr)*dr2 + (A422 + A522*dr)*dr4 + 6*dtheta2*(A042 + A142*dr + (A242 + A342*dr)*dr2 + (A062 + A162*dr)*dtheta2) + 9*(A062 + A162*dr)*dtheta4); d2A_dtheta2[2] = 2*(A024 + A124*dr + (A224 + A324*dr)*dr2 + 6*(A044 + A144*dr)*dtheta2); d2A_dtheta2[3] = 2*(A026 + A126*dr); d2A_dtheta2[4] = 0; /* alpha term appearing in the denominator */ alpha = alpha20*dr2 + alpha02*dtheta2; /* Derivatives of alpha */ dalpha_dr = 2*alpha20*dr; d2alpha_dr2 = 2*alpha20; dalpha_dtheta = 2*alpha02*dtheta; d2alpha_dtheta2 = 2*alpha02; /* C term appearing in Elliptic integrals and related power series in numerator */ const double C1 = alpha / beta; double C[27]; C[0] = 1; C[1] = C1; C[2] = C1*C1; C[3] = C[2]*C[1]; C[4] = C[2]*C[2]; C[5] = C[3]*C[2]; C[6] = C[3]*C[3]; C[7] = C[4]*C[3]; C[8] = C[4]*C[4]; C[9] = C[5]*C[4]; C[10] = C[5]*C[5]; C[11] = C[6]*C[5]; C[12] = C[6]*C[6]; C[13] = C[7]*C[6]; C[14] = C[7]*C[7]; C[15] = C[8]*C[7]; C[16] = C[8]*C[8]; C[17] = C[9]*C[8]; C[18] = C[9]*C[9]; C[19] = C[10]*C[9]; C[20] = C[10]*C[10]; C[21] = C[11]*C[10]; C[22] = C[11]*C[11]; C[23] = C[12]*C[11]; C[24] = C[12]*C[12]; C[25] = C[13]*C[12]; C[26] = C[13]*C[13]; dC1_dr = dalpha_dr / beta; d2C1_dr2 = d2alpha_dr2 / beta; dC1_dtheta = dalpha_dtheta / beta; d2C1_dtheta2 = d2alpha_dtheta2 / beta; double dC_dr[27]; dC_dr[0] = 0; dC_dr[1] = 1*C[0]*dC1_dr; dC_dr[2] = 2*C[1]*dC1_dr; dC_dr[3] = 3*C[2]*dC1_dr; dC_dr[4] = 4*C[3]*dC1_dr; dC_dr[5] = 5*C[4]*dC1_dr; dC_dr[6] = 6*C[5]*dC1_dr; dC_dr[7] = 7*C[6]*dC1_dr; dC_dr[8] = 8*C[7]*dC1_dr; dC_dr[9] = 9*C[8]*dC1_dr; dC_dr[10] = 10*C[9]*dC1_dr; dC_dr[11] = 11*C[10]*dC1_dr; dC_dr[12] = 12*C[11]*dC1_dr; dC_dr[13] = 13*C[12]*dC1_dr; dC_dr[14] = 14*C[13]*dC1_dr; dC_dr[15] = 15*C[14]*dC1_dr; dC_dr[16] = 16*C[15]*dC1_dr; dC_dr[17] = 17*C[16]*dC1_dr; dC_dr[18] = 18*C[17]*dC1_dr; dC_dr[19] = 19*C[18]*dC1_dr; dC_dr[20] = 20*C[19]*dC1_dr; dC_dr[21] = 21*C[20]*dC1_dr; dC_dr[22] = 22*C[21]*dC1_dr; dC_dr[23] = 23*C[22]*dC1_dr; dC_dr[24] = 24*C[23]*dC1_dr; dC_dr[25] = 25*C[24]*dC1_dr; dC_dr[26] = 26*C[25]*dC1_dr; double d2C_dr2[27]; d2C_dr2[0] = 0; d2C_dr2[1] = d2C1_dr2; d2C_dr2[2] = 2*1*C[0]*dC1_dr*dC1_dr + 2*C[1]*d2C1_dr2; d2C_dr2[3] = 3*2*C[1]*dC1_dr*dC1_dr + 3*C[2]*d2C1_dr2; d2C_dr2[4] = 4*3*C[2]*dC1_dr*dC1_dr + 4*C[3]*d2C1_dr2; d2C_dr2[5] = 5*4*C[3]*dC1_dr*dC1_dr + 5*C[4]*d2C1_dr2; d2C_dr2[6] = 6*5*C[4]*dC1_dr*dC1_dr + 6*C[5]*d2C1_dr2; d2C_dr2[7] = 7*6*C[5]*dC1_dr*dC1_dr + 7*C[6]*d2C1_dr2; d2C_dr2[8] = 8*7*C[6]*dC1_dr*dC1_dr + 8*C[7]*d2C1_dr2; d2C_dr2[9] = 9*8*C[7]*dC1_dr*dC1_dr + 9*C[8]*d2C1_dr2; d2C_dr2[10] = 10*9*C[8]*dC1_dr*dC1_dr + 10*C[9]*d2C1_dr2; d2C_dr2[11] = 11*10*C[9]*dC1_dr*dC1_dr + 11*C[10]*d2C1_dr2; d2C_dr2[12] = 12*11*C[10]*dC1_dr*dC1_dr + 12*C[11]*d2C1_dr2; d2C_dr2[13] = 13*12*C[11]*dC1_dr*dC1_dr + 13*C[12]*d2C1_dr2; d2C_dr2[14] = 14*13*C[12]*dC1_dr*dC1_dr + 14*C[13]*d2C1_dr2; d2C_dr2[15] = 15*14*C[13]*dC1_dr*dC1_dr + 15*C[14]*d2C1_dr2; d2C_dr2[16] = 16*15*C[14]*dC1_dr*dC1_dr + 16*C[15]*d2C1_dr2; d2C_dr2[17] = 17*16*C[15]*dC1_dr*dC1_dr + 17*C[16]*d2C1_dr2; d2C_dr2[18] = 18*17*C[16]*dC1_dr*dC1_dr + 18*C[17]*d2C1_dr2; d2C_dr2[19] = 19*18*C[17]*dC1_dr*dC1_dr + 19*C[18]*d2C1_dr2; d2C_dr2[20] = 20*19*C[18]*dC1_dr*dC1_dr + 20*C[19]*d2C1_dr2; d2C_dr2[21] = 21*20*C[19]*dC1_dr*dC1_dr + 21*C[20]*d2C1_dr2; d2C_dr2[22] = 22*21*C[20]*dC1_dr*dC1_dr + 22*C[21]*d2C1_dr2; d2C_dr2[23] = 23*22*C[21]*dC1_dr*dC1_dr + 23*C[22]*d2C1_dr2; d2C_dr2[24] = 24*23*C[22]*dC1_dr*dC1_dr + 24*C[23]*d2C1_dr2; d2C_dr2[25] = 25*24*C[23]*dC1_dr*dC1_dr + 25*C[24]*d2C1_dr2; d2C_dr2[26] = 26*25*C[24]*dC1_dr*dC1_dr + 26*C[25]*d2C1_dr2; double dC_dtheta[27]; dC_dtheta[0] = 0; dC_dtheta[1] = 1*C[0]*dC1_dtheta; dC_dtheta[2] = 2*C[1]*dC1_dtheta; dC_dtheta[3] = 3*C[2]*dC1_dtheta; dC_dtheta[4] = 4*C[3]*dC1_dtheta; dC_dtheta[5] = 5*C[4]*dC1_dtheta; dC_dtheta[6] = 6*C[5]*dC1_dtheta; dC_dtheta[7] = 7*C[6]*dC1_dtheta; dC_dtheta[8] = 8*C[7]*dC1_dtheta; dC_dtheta[9] = 9*C[8]*dC1_dtheta; dC_dtheta[10] = 10*C[9]*dC1_dtheta; dC_dtheta[11] = 11*C[10]*dC1_dtheta; dC_dtheta[12] = 12*C[11]*dC1_dtheta; dC_dtheta[13] = 13*C[12]*dC1_dtheta; dC_dtheta[14] = 14*C[13]*dC1_dtheta; dC_dtheta[15] = 15*C[14]*dC1_dtheta; dC_dtheta[16] = 16*C[15]*dC1_dtheta; dC_dtheta[17] = 17*C[16]*dC1_dtheta; dC_dtheta[18] = 18*C[17]*dC1_dtheta; dC_dtheta[19] = 19*C[18]*dC1_dtheta; dC_dtheta[20] = 20*C[19]*dC1_dtheta; dC_dtheta[21] = 21*C[20]*dC1_dtheta; dC_dtheta[22] = 22*C[21]*dC1_dtheta; dC_dtheta[23] = 23*C[22]*dC1_dtheta; dC_dtheta[24] = 24*C[23]*dC1_dtheta; dC_dtheta[25] = 25*C[24]*dC1_dtheta; dC_dtheta[26] = 26*C[25]*dC1_dtheta; double d2C_dtheta2[27]; d2C_dtheta2[0] = 0; d2C_dtheta2[1] = d2C1_dtheta2; d2C_dtheta2[2] = 2*1*C[0]*dC1_dtheta*dC1_dtheta + 2*C[1]*d2C1_dtheta2; d2C_dtheta2[3] = 3*2*C[1]*dC1_dtheta*dC1_dtheta + 3*C[2]*d2C1_dtheta2; d2C_dtheta2[4] = 4*3*C[2]*dC1_dtheta*dC1_dtheta + 4*C[3]*d2C1_dtheta2; d2C_dtheta2[5] = 5*4*C[3]*dC1_dtheta*dC1_dtheta + 5*C[4]*d2C1_dtheta2; d2C_dtheta2[6] = 6*5*C[4]*dC1_dtheta*dC1_dtheta + 6*C[5]*d2C1_dtheta2; d2C_dtheta2[7] = 7*6*C[5]*dC1_dtheta*dC1_dtheta + 7*C[6]*d2C1_dtheta2; d2C_dtheta2[8] = 8*7*C[6]*dC1_dtheta*dC1_dtheta + 8*C[7]*d2C1_dtheta2; d2C_dtheta2[9] = 9*8*C[7]*dC1_dtheta*dC1_dtheta + 9*C[8]*d2C1_dtheta2; d2C_dtheta2[10] = 10*9*C[8]*dC1_dtheta*dC1_dtheta + 10*C[9]*d2C1_dtheta2; d2C_dtheta2[11] = 11*10*C[9]*dC1_dtheta*dC1_dtheta + 11*C[10]*d2C1_dtheta2; d2C_dtheta2[12] = 12*11*C[10]*dC1_dtheta*dC1_dtheta + 12*C[11]*d2C1_dtheta2; d2C_dtheta2[13] = 13*12*C[11]*dC1_dtheta*dC1_dtheta + 13*C[12]*d2C1_dtheta2; d2C_dtheta2[14] = 14*13*C[12]*dC1_dtheta*dC1_dtheta + 14*C[13]*d2C1_dtheta2; d2C_dtheta2[15] = 15*14*C[13]*dC1_dtheta*dC1_dtheta + 15*C[14]*d2C1_dtheta2; d2C_dtheta2[16] = 16*15*C[14]*dC1_dtheta*dC1_dtheta + 16*C[15]*d2C1_dtheta2; d2C_dtheta2[17] = 17*16*C[15]*dC1_dtheta*dC1_dtheta + 17*C[16]*d2C1_dtheta2; d2C_dtheta2[18] = 18*17*C[16]*dC1_dtheta*dC1_dtheta + 18*C[17]*d2C1_dtheta2; d2C_dtheta2[19] = 19*18*C[17]*dC1_dtheta*dC1_dtheta + 19*C[18]*d2C1_dtheta2; d2C_dtheta2[20] = 20*19*C[18]*dC1_dtheta*dC1_dtheta + 20*C[19]*d2C1_dtheta2; d2C_dtheta2[21] = 21*20*C[19]*dC1_dtheta*dC1_dtheta + 21*C[20]*d2C1_dtheta2; d2C_dtheta2[22] = 22*21*C[20]*dC1_dtheta*dC1_dtheta + 22*C[21]*d2C1_dtheta2; d2C_dtheta2[23] = 23*22*C[21]*dC1_dtheta*dC1_dtheta + 23*C[22]*d2C1_dtheta2; d2C_dtheta2[24] = 24*23*C[22]*dC1_dtheta*dC1_dtheta + 24*C[23]*d2C1_dtheta2; d2C_dtheta2[25] = 25*24*C[23]*dC1_dtheta*dC1_dtheta + 25*C[24]*d2C1_dtheta2; d2C_dtheta2[26] = 26*25*C[24]*dC1_dtheta*dC1_dtheta + 26*C[25]*d2C1_dtheta2; /* Elliptic integrals */ ellE = gsl_sf_ellint_Ecomp(sqrt(1.0/(1.0+C1)), GSL_PREC_DOUBLE); ellK = gsl_sf_ellint_Kcomp(sqrt(1.0/(1.0+C1)), GSL_PREC_DOUBLE); const double ellip[2] = {ellK, ellE}; /* Derivatives of elliptic integrals */ dellE_dC = (ellK - ellE)/(2.*(1+C1)); dellK_dC = (C1*ellK - (1+C1)*ellE)/(2.*C1*(1+C1)); d2ellE_dC2 = -(2*C1*ellK - (2*C1-1)*ellE)/(4.*C1*(1+C1)*(1+C1)); d2ellK_dC2 = -(C1*(1+2*C1)*ellK - 2*(1+C1)*(1+C1)*ellE)/(4.*C1*C1*(1+C1)*(1+C1)); dellE_dr = dellE_dC * dC1_dr; dellE_dtheta = dellE_dC * dC1_dtheta; d2ellE_dr2 = d2ellE_dC2 * dC1_dr * dC1_dr + dellE_dC * d2C1_dr2; d2ellE_dtheta2 = d2ellE_dC2 * dC1_dtheta * dC1_dtheta + dellE_dC * d2C1_dtheta2; dellK_dr = dellK_dC * dC1_dr; dellK_dtheta = dellK_dC * dC1_dtheta; d2ellK_dr2 = d2ellK_dC2 * dC1_dr * dC1_dr + dellK_dC * d2C1_dr2; d2ellK_dtheta2 = d2ellK_dC2 * dC1_dtheta * dC1_dtheta + dellK_dC * d2C1_dtheta2; const double dellip_dr[2] = {dellK_dr, dellE_dr}; const double dellip_dtheta[2] = {dellK_dtheta, dellE_dtheta}; const double d2ellip_dr2[2] = {d2ellK_dr2, d2ellE_dr2}; const double d2ellip_dtheta2[2] = {d2ellK_dtheta2, d2ellE_dtheta2}; if(m>20) { printf("Support for computing mode %d has not yet been added.\n", m); return; } /* Numerator */ double num = 0; for(int i=0; i<2; i++) for(int j=0; j<5; j++) for(int k=0; k<27; k++) num += ReEI[m][i][j][k]*ellip[i]*A[j]*C[k]; double dnum_dr = 0; for(int i=0; i<2; i++) for(int j=0; j<5; j++) for(int k=0; k<27; k++) dnum_dr += ReEI[m][i][j][k]* (dellip_dr[i]*A[j]*C[k] + ellip[i]*dA_dr[j]*C[k] + ellip[i]*A[j]*dC_dr[k]); double d2num_dr2 = 0; for(int i=0; i<2; i++) for(int j=0; j<5; j++) for(int k=0; k<27; k++) d2num_dr2 += ReEI[m][i][j][k]* (d2ellip_dr2[i]*A[j]*C[k] + dellip_dr[i]*dA_dr[j]*C[k] + dellip_dr[i]*A[j]*dC_dr[k] + dellip_dr[i]*dA_dr[j]*C[k] + ellip[i]*d2A_dr2[j]*C[k] + ellip[i]*dA_dr[j]*dC_dr[k] + dellip_dr[i]*A[j]*dC_dr[k] + ellip[i]*dA_dr[j]*dC_dr[k] + ellip[i]*A[j]*d2C_dr2[k]); double dnum_dtheta = 0; for(int i=0; i<2; i++) for(int j=0; j<5; j++) for(int k=0; k<27; k++) dnum_dtheta += ReEI[m][i][j][k]* (dellip_dtheta[i]*A[j]*C[k] + ellip[i]*dA_dtheta[j]*C[k] + ellip[i]*A[j]*dC_dtheta[k]); double d2num_dtheta2 = 0; for(int i=0; i<2; i++) for(int j=0; j<5; j++) for(int k=0; k<27; k++) d2num_dtheta2 += ReEI[m][i][j][k]* (d2ellip_dtheta2[i]*A[j]*C[k] + dellip_dtheta[i]*dA_dtheta[j]*C[k] + dellip_dtheta[i]*A[j]*dC_dtheta[k] + dellip_dtheta[i]*dA_dtheta[j]*C[k] + ellip[i]*d2A_dtheta2[j]*C[k] + ellip[i]*dA_dtheta[j]*dC_dtheta[k] + dellip_dtheta[i]*A[j]*dC_dtheta[k] + ellip[i]*dA_dtheta[j]*dC_dtheta[k] + ellip[i]*A[j]*d2C_dtheta2[k]); /* Denominator */ s = beta*C[3]*pow(alpha+beta, 2.5); ds_dr = beta*(3*C[2]*pow(alpha+beta, 2.5)*dC1_dr + C[3]*2.5*pow(alpha+beta, 1.5)*dalpha_dr); ds_dtheta = beta*(3*C[2]*pow(alpha+beta, 2.5)*dC1_dtheta + C[3]*2.5*pow(alpha+beta, 1.5)*dalpha_dtheta); d2s_dr2 = beta*(6*C1*pow(alpha+beta, 2.5)*dC1_dr*dC1_dr + 3*C[2]*2.5*pow(alpha+beta, 1.5)*dalpha_dr*dC1_dr + 3*C[2]*pow(alpha+beta, 2.5)*d2C1_dr2 + 3*C[2]*dC1_dr*2.5*pow(alpha+beta, 1.5)*dalpha_dr + C[3]*2.5*1.5*pow(alpha+beta, 0.5)*dalpha_dr*dalpha_dr + C[3]*2.5*pow(alpha+beta, 1.5)*d2alpha_dr2); d2s_dtheta2 = beta*(6*C1*pow(alpha+beta, 2.5)*dC1_dtheta*dC1_dtheta + 3*C[2]*2.5*pow(alpha+beta, 1.5)*dalpha_dtheta*dC1_dtheta + 3*C[2]*pow(alpha+beta, 2.5)*d2C1_dtheta2 + 3*C[2]*dC1_dtheta*2.5*pow(alpha+beta, 1.5)*dalpha_dtheta + C[3]*2.5*1.5*pow(alpha+beta, 0.5)*dalpha_dtheta*dalpha_dtheta + C[3]*2.5*pow(alpha+beta, 1.5)*d2alpha_dtheta2); /* Singular field */ double RePhiS = 4.0*num/s; /* First derivatives of PhiS */ dPhiS_dt = - m * om * (RePhiS); // This should be interpreted as pure-imaginary dPhiS_dr = 4.0*(-ds_dr*num + dnum_dr*s) /(s*s); dPhiS_dth = 4.0*(-ds_dtheta*num + dnum_dtheta*s)/(s*s); dPhiS_dph = m * (RePhiS); // This should be interpreted as pure-imaginary /* Second derivatives of PhiS */ d2PhiS_dr2 = 4.0*(2.0*ds_dr*ds_dr*num - s*(2*dnum_dr*ds_dr + d2s_dr2*num) + d2num_dr2*s*s)/(s*s*s); d2PhiS_dth2 = 4.0*(2.0*ds_dtheta*ds_dtheta*num - s*(2*dnum_dtheta*ds_dtheta + d2s_dtheta2*num) + d2num_dtheta2*s*s)/(s*s*s); d2PhiS_dph2 = - m*m*(RePhiS); d2PhiS_dt2 = - m*m*om*om*(RePhiS); d2PhiS_dtph = m*m*om*(RePhiS); d2PhiS_dtr = NAN; d2PhiS_dtth = NAN; d2PhiS_drth = NAN; d2PhiS_drph = NAN; d2PhiS_dthph = NAN; /* Box[PhiS] */ double sinth = sin(theta); double sinth2 = sinth*sinth; double sin2th = sin(2*theta); double cos2th = cos(2*theta); double r2 = r*r; double r3 = r2*r; double r4 = r2*r2; double a2 = a*a; double a4 = a2*a2; double effsrc = -((2*a2*dPhiS_dr - a2*d2PhiS_dph2 - a4*d2PhiS_dr2 - a2*d2PhiS_dth2 - 4*dPhiS_dr*r - 2*a2*dPhiS_dr*r + 4*d2PhiS_dph2*r + 2*a*d2PhiS_dtph*r + 4*a2*d2PhiS_dr2*r + 2*d2PhiS_dth2*r + 6*dPhiS_dr*r2 - 2*d2PhiS_dph2*r2 - 4*d2PhiS_dr2*r2 - 2*a2*d2PhiS_dr2*r2 - d2PhiS_dth2*r2 - 2*dPhiS_dr*r3 + 4*d2PhiS_dr2*r3 - d2PhiS_dr2*r4 + (a4*d2PhiS_dt2 + 4*a*d2PhiS_dtph*r + 2*d2PhiS_dt2*r4 + a2*d2PhiS_dt2*r*(2 + 3*r))*sinth2 + cos2th*(a4*d2PhiS_dr2 - 2*a*d2PhiS_dtph*r + (-2 + r)*r*(d2PhiS_dth2 + 2*dPhiS_dr*(-1 + r) + d2PhiS_dr2*(-2 + r)*r) + a2*(-d2PhiS_dph2 + d2PhiS_dth2 + 2*dPhiS_dr*(-1 + r) - 4*d2PhiS_dr2*r + 2*d2PhiS_dr2*r2) + a2*d2PhiS_dt2*(a2 + (-2 + r)*r)*sinth2) - a2*dPhiS_dth*sin2th + 2*dPhiS_dth*r*sin2th - dPhiS_dth*r2*sin2th))/((sinth2*(a2 + (-2 + r)*r)*(a2 + 2*r2 + a2*cos2th))); /* Store calculated quantities into the arrays provided by the caller, including the phase factor exp(-i*m*phi_p) */ double cosmph = cos(m*xp.phi); double sinmph = sin(m*xp.phi); PhiS[0] = RePhiS*cosmph; PhiS[1] = - RePhiS*sinmph; dPhiS_dx[0] = dPhiS_dt*sinmph; dPhiS_dx[1] = dPhiS_dt*cosmph; dPhiS_dx[2] = dPhiS_dr*cosmph; dPhiS_dx[3] = - dPhiS_dr*sinmph; dPhiS_dx[4] = dPhiS_dth*cosmph; dPhiS_dx[5] = - dPhiS_dth*sinmph; dPhiS_dx[6] = dPhiS_dph*sinmph; dPhiS_dx[7] = dPhiS_dph*cosmph; d2PhiS_dx2[0] = d2PhiS_dt2*cosmph; d2PhiS_dx2[1] = - d2PhiS_dt2*sinmph; d2PhiS_dx2[2] = d2PhiS_dtr*cosmph; d2PhiS_dx2[3] = - d2PhiS_dtr*sinmph; d2PhiS_dx2[4] = d2PhiS_dtth*cosmph; d2PhiS_dx2[5] = - d2PhiS_dtth*sinmph; d2PhiS_dx2[6] = d2PhiS_dtph*cosmph; d2PhiS_dx2[7] = - d2PhiS_dtph*sinmph; d2PhiS_dx2[8] = d2PhiS_dr2*cosmph; d2PhiS_dx2[9] = - d2PhiS_dr2*sinmph; d2PhiS_dx2[10] = d2PhiS_drth*cosmph; d2PhiS_dx2[11] = - d2PhiS_drth*sinmph; d2PhiS_dx2[12] = d2PhiS_drph*cosmph; d2PhiS_dx2[13] = - d2PhiS_drph*sinmph; d2PhiS_dx2[14] = d2PhiS_dth2*cosmph; d2PhiS_dx2[15] = - d2PhiS_dth2*sinmph; d2PhiS_dx2[16] = d2PhiS_dthph*cosmph; d2PhiS_dx2[17] = - d2PhiS_dthph*sinmph; d2PhiS_dx2[18] = d2PhiS_dph2*cosmph; d2PhiS_dx2[19] = - d2PhiS_dph2*sinmph; src[0] = effsrc*cosmph; src[1] = - effsrc*sinmph; } /* Initialize array of coefficients of pows of dr, dtheta and dphi. */ void effsource_init(double mass, double spin) { M = mass; a = spin; } /* Initialize array of coefficients of pows of dr, dtheta and dphi. */ void effsource_set_particle(struct coordinate * x_p, double E, double L, double ur_p) { xp = *x_p; double r = xp.r; /* Compute A coefficients */ { A006 = 64*pow(pow(L,2) + pow(r,2) + (pow(a,2)*(2*M + r))/r,3); A008 = (-32*pow(pow(a,2)*(2*M + r) + r*(pow(L,2) + pow(r,2)),2)*(-(pow(a,8)*pow(M,2)) + 4*pow(a,7)*E*L*pow(M,2) + 4*a*E*L*M*(2*M - 3*r)*pow(r,6) - 4*pow(a,3)*E*L*M*pow(r,3)*(22*pow(M,2) + 3*M*r + 4*pow(r,2)) - 4*pow(a,5)*E*L*M*(16*pow(M,3) + 18*pow(M,2)*r + pow(r,3)) + pow(r,6)*(2*M*pow(r,2)*(-2*M + r + 2*pow(E,2)*r) + pow(L,2)*(-16*pow(M,2) + 14*M*r - 3*pow(r,2))) + 2*pow(a,6)*M*(-2*pow(L,2)*M + 2*pow(E,2)*pow(2*M + r,3) + r*(2*pow(M,2) - M*r + pow(r,2))) + pow(a,2)*pow(r,3)*(2*M*pow(r,2)*(4*pow(M,2) + 6*(-1 + 2*pow(E,2))*M*r + 3*(1 + 2*pow(E,2))*pow(r,2)) + pow(L,2)*(32*pow(M,3) - 24*pow(M,2)*r + 16*M*pow(r,2) - 3*pow(r,3))) + pow(a,4)*M*(4*pow(L,2)*(8*pow(M,3) + 6*pow(M,2)*r - 3*M*pow(r,2) + 2*pow(r,3)) + pow(r,2)*(-4*pow(M,3) + 3*(-3 + 16*pow(E,2))*M*pow(r,2) + 6*(1 + 2*pow(E,2))*pow(r,3) + 4*pow(M,2)*(r + 12*pow(E,2)*r)))))/(3.*pow(r,8)*(pow(a,2) + r*(-2*M + r))); A024 = 48*pow(pow(a,2)*(2*M + r) + r*(pow(L,2) + pow(r,2)),2); A026 = (-16*(pow(a,2)*(2*M + r) + r*(pow(L,2) + pow(r,2)))*(-2*pow(a,7)*E*L*M*(24*pow(M,2) + 16*M*r + 3*pow(r,2)) + 2*a*E*L*M*pow(r,5)*(pow(L,2)*(10*M - 9*r) + (14*M - 15*r)*pow(r,2)) - 2*pow(a,5)*E*L*M*r*(16*pow(M,3) + 56*pow(M,2)*r + 50*M*pow(r,2) + 17*pow(r,3) + 3*pow(L,2)*(4*M + r)) + pow(a,8)*M*(6*pow(E,2)*pow(2*M + r,2) - r*(7*M + 3*r)) + pow(r,5)*(2*pow(L,2)*pow(r,2)*(-18*pow(M,2) + (21 + 2*pow(E,2))*M*r - 6*pow(r,2)) + pow(r,4)*(-8*pow(M,2) + 2*(5 + 4*pow(E,2))*M*r - 3*pow(r,2)) - 2*pow(L,4)*(8*pow(M,2) - 10*M*r + 3*pow(r,2))) + 2*pow(a,3)*E*L*M*pow(r,2)*(2*pow(L,2)*(4*pow(M,2) - 7*M*r - 6*pow(r,2)) - pow(r,2)*(16*pow(M,2) + 28*M*r + 29*pow(r,2))) + pow(a,4)*r*(12*pow(L,4)*pow(M,2) + pow(L,2)*(16*pow(M,4) - 8*(-5 + pow(E,2))*pow(M,3)*r + 16*(2 + pow(E,2))*pow(M,2)*pow(r,2) + 2*(-3 + 8*pow(E,2))*M*pow(r,3) - 9*pow(r,4)) + pow(r,2)*(4*pow(M,4) + 16*(2 + 3*pow(E,2))*pow(M,3)*r + 3*(3 + 32*pow(E,2))*pow(M,2)*pow(r,2) + 3*(-5 + 14*pow(E,2))*M*pow(r,3) - 9*pow(r,4))) + pow(a,2)*pow(r,2)*(pow(L,2)*pow(r,2)*(-4*pow(M,3) + 4*(6 + pow(E,2))*pow(M,2)*r + (33 + 14*pow(E,2))*M*pow(r,2) - 21*pow(r,3)) + pow(L,4)*(-8*pow(M,3) + 12*pow(M,2)*r + 8*M*pow(r,2) - 6*pow(r,3)) + pow(r,4)*(4*pow(M,3) + 3*(3 + 10*pow(E,2))*M*pow(r,2) - 9*pow(r,3) + 12*pow(M,2)*(r + 3*pow(E,2)*r))) + pow(a,6)*(pow(L,2)*M*(24*pow(M,2) + 4*(2 + 3*pow(E,2))*M*r + 3*(-1 + 2*pow(E,2))*pow(r,2)) + r*(-(r*(-12*pow(M,3) + 18*pow(M,2)*r + 17*M*pow(r,2) + 3*pow(r,3))) + 2*pow(E,2)*M*(8*pow(M,3) + 36*pow(M,2)*r + 42*M*pow(r,2) + 13*pow(r,3))))))/(3.*pow(r,6)*(pow(a,2) + r*(-2*M + r))); A042 = 12*pow(r,3)*(pow(a,2)*(2*M + r) + r*(pow(L,2) + pow(r,2))); A044 = (-2*(-4*pow(a,7)*E*L*M*(72*pow(M,2) + 59*M*r + 12*pow(r,2)) + 4*a*E*L*M*pow(r,3)*(pow(L,4)*(8*M - 6*r) + 6*pow(L,2)*(6*M - 5*r)*pow(r,2) + 3*(10*M - 9*r)*pow(r,4)) + pow(a,8)*(-13*pow(M,2)*r + 3*pow(r,3) + 36*pow(E,2)*M*pow(2*M + r,2)) - 4*pow(a,5)*E*L*M*r*(-48*pow(M,3) + 50*pow(M,2)*r + 140*M*pow(r,2) + 49*pow(r,3) + 6*pow(L,2)*(8*M + 3*r)) + pow(r,3)*(8*pow(L,6)*M*(-2*M + r) + pow(L,2)*pow(r,4)*(-120*pow(M,2) + 2*(71 + 12*pow(E,2))*M*r - 41*pow(r,2)) + pow(L,4)*pow(r,2)*(-100*pow(M,2) + 4*(25 + pow(E,2))*M*r - 25*pow(r,2)) + pow(r,6)*(-24*pow(M,2) + 2*(19 + 12*pow(E,2))*M*r - 13*pow(r,2))) - 4*pow(a,3)*E*L*M*pow(r,2)*(6*pow(L,4) + pow(L,2)*(-48*pow(M,2) + 36*M*r + 48*pow(r,2)) + pow(r,2)*(-66*pow(M,2) + 55*M*r + 64*pow(r,2))) + pow(a,2)*pow(r,2)*(12*pow(L,6)*M + pow(L,2)*pow(r,2)*(-192*pow(M,3) + 176*pow(M,2)*r + 12*(9 + 8*pow(E,2))*M*pow(r,2) - 73*pow(r,3)) + 2*pow(r,4)*(-12*pow(M,3) + 2*(23 + 18*pow(E,2))*pow(M,2)*r + 9*(1 + 6*pow(E,2))*M*pow(r,2) - 18*pow(r,3)) - 2*pow(L,4)*(48*pow(M,3) + 8*(-3 + pow(E,2))*pow(M,2)*r - 2*(17 + 4*pow(E,2))*M*pow(r,2) + 11*pow(r,3))) + pow(a,4)*r*(3*pow(L,4)*(32*pow(M,2) + 4*(2 + pow(E,2))*M*r + pow(r,2)) + pow(r,2)*(12*pow(M,4) + 116*pow(M,3)*r + (55 + 288*pow(E,2))*pow(M,2)*pow(r,2) + 6*(-13 + 30*pow(E,2))*M*pow(r,3) - 30*pow(r,4)) - 2*pow(L,2)*(48*pow(M,4) + 4*(-7 + 12*pow(E,2))*pow(M,3)*r - 2*(53 + 24*pow(E,2))*pow(M,2)*pow(r,2) + 4*(2 - 15*pow(E,2))*M*pow(r,3) + 13*pow(r,4))) + 2*pow(a,6)*(pow(L,2)*(72*pow(M,3) + 2*(23 + 24*pow(E,2))*pow(M,2)*r + 6*(1 + 4*pow(E,2))*M*pow(r,2) + 3*pow(r,3)) + r*(-(r*(-10*pow(M,3) + 37*pow(M,2)*r + 29*M*pow(r,2) + 2*pow(r,3))) + 6*pow(E,2)*M*(-8*pow(M,3) + 12*pow(M,2)*r + 30*M*pow(r,2) + 11*pow(r,3))))))/(3.*pow(r,3)*(pow(a,2) + r*(-2*M + r))); A060 = pow(r,6); A062 = (6*pow(a,5)*E*L*M*(12*M + 5*r) + 4*pow(a,3)*E*L*M*r*(6*pow(L,2) - 20*pow(M,2) + 11*M*r + 18*pow(r,2)) - 3*pow(a,6)*(r*(M + r) + 6*pow(E,2)*M*(2*M + r)) + 2*a*E*L*M*pow(r,2)*(-4*pow(L,2)*(4*M - 3*r) + pow(r,2)*(-26*M + 21*r)) + pow(r,2)*(8*pow(L,4)*M*(2*M - r) + 4*pow(r,4)*(2*pow(M,2) - (3 + 2*pow(E,2))*M*r + pow(r,2)) + pow(L,2)*pow(r,2)*(36*pow(M,2) - 4*(8 + pow(E,2))*M*r + 7*pow(r,2))) + pow(a,2)*r*(-12*pow(L,4)*M + 4*pow(L,2)*(10*pow(M,3) + (-3 + 4*pow(E,2))*pow(M,2)*r - 2*(3 + 2*pow(E,2))*M*pow(r,2) + pow(r,3)) + pow(r,2)*(4*pow(M,3) + 4*(-4 + pow(E,2))*pow(M,2)*r + (1 - 34*pow(E,2))*M*pow(r,2) + 5*pow(r,3))) - pow(a,4)*(3*pow(L,2)*(12*pow(M,2) + 4*(1 + pow(E,2))*M*r + pow(r,2)) + 2*r*(r*(-2*pow(M,2) - 5*M*r + pow(r,2)) + 2*pow(E,2)*M*(-10*pow(M,2) + 8*M*r + 11*pow(r,2)))))/(3.*(pow(a,2) + r*(-2*M + r))); A080 = (pow(r,3)*(r*(-3*pow(a,2) + r*(-2*M + r)) + (4*M*(-3*pow(a,4)*pow(E,2) + 6*pow(a,3)*E*L + 2*a*E*L*r*(-4*M + 3*r) + pow(a,2)*(-3*pow(L,2) + 4*pow(E,2)*(M - r)*r) - r*(pow(E,2)*pow(r,3) + pow(L,2)*(-4*M + 2*r))))/(pow(a,2) + r*(-2*M + r))))/24.; A106 = (-16*pow(pow(L,2) + pow(r,2) + (pow(a,2)*(2*M + r))/r,2)*(-2*pow(a,2)*M + 2*pow(r,3) + (4*L*(pow(a,3)*E*M - pow(a,2)*L*M + 3*a*E*M*pow(r,2) + L*pow(r,2)*(-2*M + r)))/(pow(a,2) + r*(-2*M + r))))/pow(r,2); A108 = (-16*(pow(a,2)*(2*M + r) + r*(pow(L,2) + pow(r,2)))*(2*pow(a,11)*E*L*pow(M,2)*(80*pow(M,2) + 73*M*r + 12*pow(r,2)) + 2*pow(a,9)*E*L*M*r*(32*(-1 + 6*pow(E,2))*pow(M,4) + 12*(23 + 24*pow(E,2))*pow(M,3)*r + (353 + 144*pow(E,2))*pow(M,2)*pow(r,2) + 2*(11 + 12*pow(E,2))*M*pow(r,3) - 12*pow(r,4) + 4*pow(L,2)*M*(16*M + 3*r)) + pow(a,12)*pow(M,2)*(3*r*(3*M + 2*r) - 8*pow(E,2)*(10*pow(M,2) + 11*M*r + 3*pow(r,2))) + 2*a*E*L*M*pow(r,5)*(6*pow(L,4)*pow(r,2)*(20*pow(M,2) + 4*pow(E,2)*M*r - 5*pow(r,2)) + 12*pow(L,6)*(4*pow(M,2) - pow(r,2)) + pow(L,2)*pow(r,4)*(136*pow(M,2) + 2*(-37 + 30*pow(E,2))*M*r + 3*pow(r,2)) - 2*pow(r,6)*(34*pow(M,2) - 41*M*r + 12*pow(r,2))) + 4*pow(a,3)*E*L*M*pow(r,3)*(6*pow(L,6)*(12*pow(M,2) - 2*M*r - pow(r,2)) + pow(L,2)*pow(r,3)*(-340*pow(M,3) + 6*(61 + 20*pow(E,2))*pow(M,2)*r + (-83 + 90*pow(E,2))*M*pow(r,2) - 23*pow(r,3)) + 2*pow(r,5)*(-192*pow(M,3) + 81*pow(M,2)*r + 6*(7 + pow(E,2))*M*pow(r,2) - 19*pow(r,3)) + 6*pow(L,4)*r*(20*pow(M,3) + 4*(10 + pow(E,2))*pow(M,2)*r + 2*(-5 + 2*pow(E,2))*M*pow(r,2) - 5*pow(r,3))) + 2*pow(a,5)*E*L*M*pow(r,2)*(6*pow(L,4)*(2*M + r)*(60*pow(M,2) + 2*(-5 + 2*pow(E,2))*M*r - 5*pow(r,2)) + pow(r,3)*(-420*pow(M,4) - 876*pow(M,3)*r + (907 + 144*pow(E,2))*pow(M,2)*pow(r,2) + 24*(5 + 3*pow(E,2))*M*pow(r,3) - 92*pow(r,4)) + pow(L,2)*r*(-608*pow(M,4) + 8*(13 + 30*pow(E,2))*pow(M,3)*r + 48*(17 + 10*pow(E,2))*pow(M,2)*pow(r,2) + 36*(-7 + 5*pow(E,2))*M*pow(r,3) - 79*pow(r,4))) + pow(a,2)*pow(r,3)*(48*pow(L,8)*pow(M,2)*(-2*M + r) - 24*pow(L,6)*M*pow(r,2)*(2*(5 + 4*pow(E,2))*pow(M,2) + (-5 + 4*pow(E,2))*M*r - 2*pow(E,2)*pow(r,2)) + 2*M*pow(r,7)*(60*pow(M,3) + 4*(-22 + 25*pow(E,2))*pow(M,2)*r + (51 - 86*pow(E,2))*M*pow(r,2) + (-11 + 23*pow(E,2))*pow(r,3)) + pow(L,2)*pow(r,5)*(752*pow(M,4) - 4*(197 + 66*pow(E,2))*pow(M,3)*r + 8*(28 - 11*pow(E,2))*pow(M,2)*pow(r,2) + 3*(1 + 48*pow(E,2))*M*pow(r,3) - 6*pow(r,4)) + 2*pow(L,4)*pow(r,3)*(232*pow(M,4) - 36*(9 + 10*pow(E,2))*pow(M,3)*r - 2*(-71 + 60*pow(E,2))*pow(M,2)*pow(r,2) + 5*(-5 + 18*pow(E,2))*M*pow(r,3) + 3*pow(r,4))) + 2*pow(a,7)*E*L*M*r*(2*pow(L,2)*(288*pow(M,4) + 8*(29 + 15*pow(E,2))*pow(M,3)*r + 2*(71 + 60*pow(E,2))*pow(M,2)*pow(r,2) + 2*(-26 + 15*pow(E,2))*M*pow(r,3) - 15*pow(r,4)) + r*(-256*pow(M,5) - 556*pow(M,4)*r + 8*(-7 + 36*pow(E,2))*pow(M,3)*pow(r,2) + (827 + 288*pow(E,2))*pow(M,2)*pow(r,3) + 4*(11 + 18*pow(E,2))*M*pow(r,4) - 52*pow(r,5))) - pow(a,4)*pow(r,2)*(24*pow(L,6)*M*(20*pow(M,3) + 12*pow(E,2)*pow(M,2)*r + (-5 + 2*pow(E,2))*M*pow(r,2) - pow(E,2)*pow(r,3)) + 2*pow(L,4)*M*r*(-304*pow(M,4) + 8*(11 + 60*pow(E,2))*pow(M,3)*r + 60*(5 + 14*pow(E,2))*pow(M,2)*pow(r,2) + 60*(-3 + pow(E,2))*M*pow(r,3) + (11 - 90*pow(E,2))*pow(r,4)) + M*pow(r,5)*(48*pow(M,4) - 4*(31 + 168*pow(E,2))*pow(M,3)*r - 8*(-34 + 21*pow(E,2))*pow(M,2)*pow(r,2) + (-199 + 448*pow(E,2))*M*pow(r,3) + 12*(4 - 7*pow(E,2))*pow(r,4)) + pow(L,2)*pow(r,3)*(-296*pow(M,5) - 16*(50 + 57*pow(E,2))*pow(M,4)*r + 2*(627 + 452*pow(E,2))*pow(M,3)*pow(r,2) + 2*(-215 + 12*pow(E,2))*pow(M,2)*pow(r,3) - 6*(-3 + 38*pow(E,2))*M*pow(r,4) + 3*pow(r,5))) + pow(a,6)*M*r*(-4*pow(L,4)*(96*pow(M,4) + 4*(11 + 90*pow(E,2))*pow(M,3)*r + 16*(2 + 15*pow(E,2))*pow(M,2)*pow(r,2) - 38*M*pow(r,3) - 15*pow(E,2)*pow(r,4)) + pow(r,3)*(-56*pow(M,5) + 4*(9 + 128*pow(E,2))*pow(M,4)*r + 2*(41 + 520*pow(E,2))*pow(M,3)*pow(r,2) - (157 + 464*pow(E,2))*pow(M,2)*pow(r,3) + (163 - 568*pow(E,2))*M*pow(r,4) + 4*(-13 + 19*pow(E,2))*pow(r,5)) + pow(L,2)*r*(256*pow(M,5) + 8*(47 + 76*pow(E,2))*pow(M,4)*r - 8*(-3 + 76*pow(E,2))*pow(M,3)*pow(r,2) - 2*(415 + 716*pow(E,2))*pow(M,2)*pow(r,3) + 2*(143 - 8*pow(E,2))*M*pow(r,4) + (-17 + 160*pow(E,2))*pow(r,5))) - (2*M - r)*pow(r,8)*(2*pow(E,2)*M*(12*pow(L,6) + 30*pow(L,4)*pow(r,2) + 17*pow(L,2)*pow(r,4) + 5*pow(r,6)) + (2*M - r)*r*(2*pow(L,4)*(8*M - 3*r) + 4*M*pow(r,4) + pow(L,2)*pow(r,2)*(2*M + 3*r))) - pow(a,10)*M*(2*pow(L,2)*M*(40*pow(M,2) + (29 + 32*pow(E,2))*M*r + 3*(-1 + 4*pow(E,2))*pow(r,2)) + r*(r*(50*pow(M,3) + 11*pow(M,2)*r - 19*M*pow(r,2) + 6*pow(r,3)) + pow(E,2)*(-32*pow(M,4) + 336*pow(M,3)*r + 504*pow(M,2)*pow(r,2) + 156*M*pow(r,3) - 6*pow(r,4)))) - pow(a,8)*M*r*(64*pow(L,4)*pow(M,2) + 2*pow(L,2)*(16*(-1 + 36*pow(E,2))*pow(M,4) + 4*(27 + 166*pow(E,2))*pow(M,3)*r + (141 + 364*pow(E,2))*pow(M,2)*pow(r,2) + 3*(-13 + 6*pow(E,2))*M*pow(r,3) + 3*(1 - 7*pow(E,2))*pow(r,4)) + r*(r*(-92*pow(M,4) + 20*pow(M,3)*r + 65*pow(M,2)*pow(r,2) - 63*M*pow(r,3) + 28*pow(r,4)) - 2*pow(E,2)*(128*pow(M,5) + 368*pow(M,4)*r + 120*pow(M,3)*pow(r,2) - 424*pow(M,2)*pow(r,3) - 202*M*pow(r,4) + 17*pow(r,5))))))/(3.*pow(r,10)*pow(pow(a,2) + r*(-2*M + r),2)); A124 = 8*(pow(L,2) + pow(r,2) + (pow(a,2)*(2*M + r))/r)*(-(pow(a,2)*r) - pow(L,2)*r - 3*pow(r,3) - (4*L*(pow(a,3)*E*M - pow(a,2)*L*M + 3*a*E*M*pow(r,2) + L*pow(r,2)*(-2*M + r)))/(pow(a,2) + r*(-2*M + r))); A126 = (-4*(2*pow(a,11)*E*L*pow(M,2)*(-16*(-16 + 9*pow(E,2))*pow(M,2) + (293 - 144*pow(E,2))*M*r + 6*(13 - 6*pow(E,2))*pow(r,2)) + 2*a*E*L*M*pow(r,5)*(2*pow(L,4)*pow(r,2)*(328*pow(M,2) + 2*(-79 + 21*pow(E,2))*M*r - 3*pow(r,2)) + 42*pow(L,6)*(4*pow(M,2) - pow(r,2)) + 3*pow(L,2)*pow(r,4)*(128*pow(M,2) + 2*(-37 + 20*pow(E,2))*M*r + 5*pow(r,2)) - 2*pow(r,6)*(118*pow(M,2) - 125*M*r + 33*pow(r,2))) - (2*M - r)*pow(r,7)*(2*pow(r,6)*(16*pow(M,2) + 2*(-7 + 10*pow(E,2))*M*r + 3*pow(r,2)) + 4*pow(L,6)*(16*pow(M,2) + (-20 + 21*pow(E,2))*M*r + 6*pow(r,2)) + 2*pow(L,2)*pow(r,4)*(10*pow(M,2) + (-17 + 66*pow(E,2))*M*r + 6*pow(r,2)) + pow(L,4)*pow(r,2)*(88*pow(M,2) + 2*(-61 + 94*pow(E,2))*M*r + 39*pow(r,2))) + pow(a,12)*M*(3*r*(21*pow(M,2) + 23*M*r + 6*pow(r,2)) - 2*pow(E,2)*(128*pow(M,3) + 172*pow(M,2)*r + 72*M*pow(r,2) + 9*pow(r,3))) + 4*pow(a,3)*E*L*M*pow(r,3)*(21*pow(L,6)*(12*pow(M,2) - 2*M*r - pow(r,2)) + pow(r,5)*(-1104*pow(M,3) + 4*(82 + 27*pow(E,2))*pow(M,2)*r + (311 - 18*pow(E,2))*M*pow(r,2) - 103*pow(r,3)) + 2*pow(L,4)*r*(256*pow(M,3) + 2*(127 + 21*pow(E,2))*pow(M,2)*r + 6*(-24 + 7*pow(E,2))*M*pow(r,2) - 21*pow(r,3)) - 2*pow(L,2)*pow(r,3)*(102*pow(M,3) - 2*(92 + 87*pow(E,2))*pow(M,2)*r + 5*(17 - 15*pow(E,2))*M*pow(r,2) + 11*pow(r,3))) + 2*pow(a,5)*E*L*M*pow(r,2)*(2*pow(L,4)*(1224*pow(M,3) + 28*(-1 + 3*pow(E,2))*pow(M,2)*r + 2*(-95 + 21*pow(E,2))*M*pow(r,2) - 39*pow(r,3)) + pow(r,3)*(-3300*pow(M,4) + 4*(-517 + 216*pow(E,2))*pow(M,3)*r + (2435 + 504*pow(E,2))*pow(M,2)*pow(r,2) + 12*(59 - 12*pow(E,2))*M*pow(r,3) - 250*pow(r,4)) + pow(L,2)*r*(-192*pow(M,4) + 8*(169 + 114*pow(E,2))*pow(M,3)*r + 72*(4 + 17*pow(E,2))*pow(M,2)*pow(r,2) + 2*(-131 + 102*pow(E,2))*M*pow(r,3) - 131*pow(r,4))) - 2*pow(a,9)*E*L*M*(2*pow(L,2)*M*(216*pow(M,2) + 4*(2 + 9*pow(E,2))*M*r + 3*(-17 + 6*pow(E,2))*pow(r,2)) + r*(-288*(1 + 3*pow(E,2))*pow(M,4) - 4*(275 + 144*pow(E,2))*pow(M,3)*r + 3*(-403 + 72*pow(E,2))*pow(M,2)*pow(r,2) + 6*(-43 + 24*pow(E,2))*M*pow(r,3) + 36*pow(r,4))) + pow(a,2)*pow(r,3)*(-168*pow(L,8)*pow(M,2)*(2*M - r) - 2*pow(L,6)*r*(56*pow(M,4) + 12*(23 + 28*pow(E,2))*pow(M,3)*r + 14*(-13 + 12*pow(E,2))*pow(M,2)*pow(r,2) + 3*(13 - 28*pow(E,2))*M*pow(r,3) - 12*pow(r,4)) + 2*pow(r,7)*(132*pow(M,4) + 4*(-39 + 64*pow(E,2))*pow(M,3)*r + (113 - 246*pow(E,2))*pow(M,2)*pow(r,2) + (-58 + 79*pow(E,2))*M*pow(r,3) + 12*pow(r,4)) + 2*pow(L,4)*pow(r,3)*(592*pow(M,4) - 4*(139 + 329*pow(E,2))*pow(M,3)*r + 2*(91 - 22*pow(E,2))*pow(M,2)*pow(r,2) + 5*(-22 + 53*pow(E,2))*M*pow(r,3) + 42*pow(r,4)) + pow(L,2)*pow(r,5)*(2112*pow(M,4) - 4*(419 + 324*pow(E,2))*pow(M,3)*r - 4*(-73 + 4*pow(E,2))*pow(M,2)*pow(r,2) + (-93 + 464*pow(E,2))*M*pow(r,3) + 51*pow(r,4))) + 2*pow(a,7)*E*L*M*r*(-24*pow(L,4)*M*(9*M - r) + 2*pow(L,2)*(1296*pow(M,4) + 8*(35 + 51*pow(E,2))*pow(M,3)*r + 4*(-52 + 57*pow(E,2))*pow(M,2)*pow(r,2) - (19 + 6*pow(E,2))*M*pow(r,3) - 36*pow(r,4)) + r*(-1600*pow(M,5) + 4*(-515 + 216*pow(E,2))*pow(M,4)*r + 72*(13 + 22*pow(E,2))*pow(M,3)*pow(r,2) + 3*(857 + 72*pow(E,2))*pow(M,2)*pow(r,3) + 12*(43 - 18*pow(E,2))*M*pow(r,4) - 146*pow(r,5))) + pow(a,4)*pow(r,2)*(-4*pow(L,6)*M*(408*pow(M,3) + 4*(-32 + 63*pow(E,2))*pow(M,2)*r + 2*(-26 + 21*pow(E,2))*M*pow(r,2) - (5 + 21*pow(E,2))*pow(r,3)) + 2*pow(r,5)*(192*pow(M,5) + 24*(-1 + 53*pow(E,2))*pow(M,4)*r + 12*(-18 + 11*pow(E,2))*pow(M,3)*pow(r,2) + 4*(27 - 152*pow(E,2))*pow(M,2)*pow(r,3) + (-47 + 107*pow(E,2))*M*pow(r,4) + 18*pow(r,5)) + pow(L,4)*r*(1056*pow(M,5) - 80*(12 + 47*pow(E,2))*pow(M,4)*r - 8*(60 + 491*pow(E,2))*pow(M,3)*pow(r,2) + 12*(12 + 65*pow(E,2))*pow(M,2)*pow(r,3) + 2*(38 + 239*pow(E,2))*M*pow(r,4) + 45*pow(r,5)) + pow(L,2)*pow(r,3)*(3096*pow(M,5) + 12*(55 - 192*pow(E,2))*pow(M,4)*r - 2*(1367 + 788*pow(E,2))*pow(M,3)*pow(r,2) + (275 + 1116*pow(E,2))*pow(M,2)*pow(r,3) + 6*(21 + 94*pow(E,2))*M*pow(r,4) + 66*pow(r,5))) + pow(a,6)*r*(6*pow(L,6)*M*(24*pow(M,2) - 10*M*r + 3*pow(r,2)) - 2*pow(L,4)*M*(864*pow(M,4) + 8*(-1 + 306*pow(E,2))*pow(M,3)*r + 4*(-29 + 164*pow(E,2))*pow(M,2)*pow(r,2) - 32*(-2 + 9*pow(E,2))*M*pow(r,3) - (69 + 59*pow(E,2))*pow(r,4)) + pow(r,3)*(-152*pow(M,6) + 4*(23 + 800*pow(E,2))*pow(M,5)*r + 2*(-31 + 1672*pow(E,2))*pow(M,4)*pow(r,2) - (331 + 1792*pow(E,2))*pow(M,3)*pow(r,3) + (109 - 1704*pow(E,2))*pow(M,2)*pow(r,4) + 4*(8 + 19*pow(E,2))*M*pow(r,5) + 24*pow(r,6)) + pow(L,2)*r*(1600*pow(M,6) - 8*(-167 + 300*pow(E,2))*pow(M,5)*r - 4*(243 + 1228*pow(E,2))*pow(M,4)*pow(r,2) + 6*(-333 + 40*pow(E,2))*pow(M,3)*pow(r,3) + (59 + 1196*pow(E,2))*pow(M,2)*pow(r,4) + (293 + 228*pow(E,2))*M*pow(r,5) + 27*pow(r,6))) - pow(a,10)*M*(pow(L,2)*(-32*(-8 + 27*pow(E,2))*pow(M,3) + (242 - 448*pow(E,2))*pow(M,2)*r + 3*(-19 + 20*pow(E,2))*M*pow(r,2) + 18*(-3 + 2*pow(E,2))*pow(r,3)) + r*(r*(290*pow(M,3) + 165*pow(M,2)*r - 141*M*pow(r,2) - 68*pow(r,3)) + 2*pow(E,2)*(144*pow(M,4) + 680*pow(M,3)*r + 864*pow(M,2)*pow(r,2) + 358*M*pow(r,3) + 37*pow(r,4)))) + pow(a,8)*(2*pow(L,4)*M*(144*pow(M,3) + 8*(-8 + 27*pow(E,2))*pow(M,2)*r + 6*(-6 + 7*pow(E,2))*M*pow(r,2) - 9*(-3 + pow(E,2))*pow(r,3)) - pow(L,2)*M*r*(288*(1 + 18*pow(E,2))*pow(M,4) + 8*(105 + 286*pow(E,2))*pow(M,3)*r - 2*(-589 + 516*pow(E,2))*pow(M,2)*pow(r,2) + (15 - 268*pow(E,2))*M*pow(r,3) + 2*(-93 + 20*pow(E,2))*pow(r,4)) + pow(r,2)*(4*pow(E,2)*M*(400*pow(M,5) + 696*pow(M,4)*r - 12*pow(M,3)*pow(r,2) - 732*pow(M,2)*pow(r,3) - 368*M*pow(r,4) - 19*pow(r,5)) + r*(404*pow(M,5) + 8*pow(M,4)*r - 375*pow(M,3)*pow(r,2) + 103*pow(M,2)*pow(r,3) + 100*M*pow(r,4) + 6*pow(r,5))))))/(3.*pow(r,7)*pow(pow(a,2) + r*(-2*M + r),2)); A142 = pow(r,2)*(2*pow(a,2)*M - 2*pow(r,3) - (4*L*(pow(a,3)*E*M - pow(a,2)*L*M + 3*a*E*M*pow(r,2) + L*pow(r,2)*(-2*M + r)))/(pow(a,2) + r*(-2*M + r)) - 4*(pow(a,2)*(2*M + r) + r*(pow(L,2) + pow(r,2)))); A144 = (2*pow(a,9)*E*L*M*(16*(-16 + 9*pow(E,2))*pow(M,2) + 12*(-13 + 6*pow(E,2))*M*r - 3*pow(r,2)) + (2*M - r)*pow(r,4)*(16*pow(L,6)*M*(2*M - r) + 2*pow(L,2)*pow(r,4)*(-6*pow(M,2) + (-5 + 66*pow(E,2))*M*r + 4*pow(r,2)) + 2*pow(L,4)*pow(r,2)*(34*pow(M,2) + (-33 + 47*pow(E,2))*M*r + 8*pow(r,2)) + pow(r,6)*(48*pow(M,2) + 10*(-5 + 6*pow(E,2))*M*r + 13*pow(r,2))) - 2*a*E*L*M*pow(r,4)*(2*pow(L,4)*(200*pow(M,2) - 94*M*r - 3*pow(r,2)) + 3*pow(L,2)*pow(r,2)*(188*pow(M,2) + 4*(-27 + 5*pow(E,2))*M*r + 7*pow(r,2)) - 3*pow(r,4)*(100*pow(M,2) - 116*M*r + 33*pow(r,2))) + pow(a,10)*M*(-9*r*(13*M + 7*r) + pow(E,2)*(256*pow(M,2) + 264*M*r + 66*pow(r,2))) - 2*pow(a,3)*E*L*M*pow(r,2)*(4*pow(L,4)*(180*pow(M,2) - 92*M*r - 3*pow(r,2)) + pow(L,2)*r*(768*pow(M,3) + 4*(67 + 84*pow(E,2))*pow(M,2)*r + 4*(-149 + 9*pow(E,2))*M*pow(r,2) + 15*pow(r,3)) - 4*pow(r,3)*(426*pow(M,3) - (85 + 108*pow(E,2))*pow(M,2)*r + 12*(-13 + 3*pow(E,2))*M*pow(r,2) + 52*pow(r,3))) - 2*pow(a,5)*E*L*M*r*(-6*pow(L,4)*(18*M + r) + pow(L,2)*(1728*pow(M,3) + 24*(-33 + 10*pow(E,2))*pow(M,2)*r - 4*(83 + 15*pow(E,2))*M*pow(r,2) - 9*pow(r,3)) + 4*r*(-336*pow(M,4) + 2*(-107 + 108*pow(E,2))*pow(M,3)*r + 3*(79 + 36*pow(E,2))*pow(M,2)*pow(r,2) + (161 - 90*pow(E,2))*M*pow(r,3) - 34*pow(r,4))) - pow(a,2)*pow(r,2)*(-2*pow(L,6)*M*(240*pow(M,2) - 154*M*r + 17*pow(r,2)) + 2*pow(L,4)*r*(48*pow(M,4) - 4*(35 + 176*pow(E,2))*pow(M,3)*r + 8*(8 + 15*pow(E,2))*pow(M,2)*pow(r,2) + (-35 + 73*pow(E,2))*M*pow(r,3) + 16*pow(r,4)) + pow(r,5)*(264*pow(M,4) + 4*(-11 + 144*pow(E,2))*pow(M,3)*r + 2*(11 - 222*pow(E,2))*pow(M,2)*pow(r,2) + (-125 + 138*pow(E,2))*M*pow(r,3) + 46*pow(r,4)) + pow(L,2)*pow(r,3)*(1656*pow(M,4) - 12*(65 + 166*pow(E,2))*pow(M,3)*r + 2*(-161 + 374*pow(E,2))*pow(M,2)*pow(r,2) + (47 + 256*pow(E,2))*M*pow(r,3) + 51*pow(r,4))) - pow(a,4)*r*(6*pow(L,6)*M*(12*M + r) + 2*pow(L,4)*(-576*pow(M,4) - 36*(-9 + 20*pow(E,2))*pow(M,3)*r + 2*(-19 + 137*pow(E,2))*pow(M,2)*pow(r,2) + (47 + 29*pow(E,2))*M*pow(r,3) + 8*pow(r,4)) + pow(r,3)*(192*pow(M,5) + 4*(85 + 468*pow(E,2))*pow(M,4)*r + 228*(-1 + 2*pow(E,2))*pow(M,3)*pow(r,2) - 3*(149 + 268*pow(E,2))*pow(M,2)*pow(r,3) - 12*(-9 + pow(E,2))*M*pow(r,4) + 60*pow(r,5)) + pow(L,2)*r*(1344*pow(M,5) + 32*(13 - 105*pow(E,2))*pow(M,4)*r - 4*(243 + 280*pow(E,2))*pow(M,3)*pow(r,2) + 28*(-29 + 75*pow(E,2))*pow(M,2)*pow(r,3) + (391 + 56*pow(E,2))*M*pow(r,4) + 66*pow(r,5))) + 2*pow(a,7)*E*L*M*(4*r*(-8*(5 + 18*pow(E,2))*pow(M,3) + 3*(-59 + 12*pow(E,2))*pow(M,2)*r + (-121 + 72*pow(E,2))*M*pow(r,2) + 6*pow(r,3)) + 3*pow(L,2)*(144*pow(M,2) + pow(r,2) + 4*M*(r + 3*pow(E,2)*r))) + pow(a,8)*(pow(L,2)*M*(-32*(-8 + 27*pow(E,2))*pow(M,2) + 12*(4 - 19*pow(E,2))*M*r + 3*(-41 + 20*pow(E,2))*pow(r,2)) + r*(-(r*(-420*pow(M,3) + 115*pow(M,2)*r + 256*M*pow(r,2) + 7*pow(r,3))) + 4*pow(E,2)*M*(40*pow(M,3) + 178*pow(M,2)*r + 209*M*pow(r,2) + 60*pow(r,3)))) - pow(a,6)*(6*pow(L,4)*M*(48*pow(M,2) + 2*(-5 + 18*pow(E,2))*M*r + (11 + pow(E,2))*pow(r,2)) + pow(L,2)*r*(-32*(5 + 108*pow(E,2))*pow(M,4) + 8*(-88 + 153*pow(E,2))*pow(M,3)*r + 2*(-247 + 658*pow(E,2))*pow(M,2)*pow(r,2) + (417 - 128*pow(E,2))*M*pow(r,3) + 23*pow(r,4)) + pow(r,2)*(4*pow(E,2)*M*(336*pow(M,4) + 324*pow(M,3)*r - 128*pow(M,2)*pow(r,2) - 263*M*pow(r,3) - 66*pow(r,4)) + r*(276*pow(M,4) - 652*pow(M,3)*r - 323*pow(M,2)*pow(r,2) + 350*M*pow(r,3) + 34*pow(r,4)))))/(3.*pow(r,4)*pow(pow(a,2) + r*(-2*M + r),2)); A160 = -pow(r,5)/2.; A162 = (6*pow(a,7)*E*L*M*(12*(-4 + pow(E,2))*M - 11*r) + 3*pow(a,8)*(3*r*(-3*M + r) + 2*pow(E,2)*M*(24*M + 13*r)) + 2*a*E*L*M*(2*M - r)*pow(r,3)*((82*M - 51*r)*pow(r,2) + pow(L,2)*(-124*M + 30*r)) + (2*M - r)*pow(r,3)*(8*pow(L,4)*M*(2*M - r) + pow(L,2)*pow(r,2)*(-36*pow(M,2) + 4*(8 + 11*pow(E,2))*M*r - 7*pow(r,2)) + 8*pow(r,4)*(4*pow(M,2) + (-4 + 5*pow(E,2))*M*r + pow(r,2))) - 2*pow(a,5)*E*L*M*(-12*pow(L,2)*(9*M - 2*r) + r*(8*(-11 + 15*pow(E,2))*pow(M,2) - 24*(-9 + 5*pow(E,2))*M*r + 63*pow(r,2))) - 2*pow(a,3)*E*L*M*r*(pow(L,2)*(360*pow(M,2) - 352*M*r + 54*pow(r,2)) - r*(400*pow(M,3) + 4*(19 - 54*pow(E,2))*pow(M,2)*r + 4*(-40 + 21*pow(E,2))*M*pow(r,2) + 21*pow(r,3))) - pow(a,2)*r*(-8*pow(L,4)*M*(30*pow(M,2) - 29*M*r + 7*pow(r,2)) + pow(r,3)*(88*pow(M,4) + 4*(27 + 64*pow(E,2))*pow(M,3)*r - 2*(57 + 50*pow(E,2))*pow(M,2)*pow(r,2) + (-11 + 26*pow(E,2))*M*pow(r,3) + 15*pow(r,4)) + pow(L,2)*r*(400*pow(M,4) + 8*(-26 + 63*pow(E,2))*pow(M,2)*pow(r,2) + 4*(17 + 4*pow(E,2))*M*pow(r,3) + pow(r,4) - 64*pow(M,3)*(r + 14*pow(E,2)*r))) + pow(a,6)*(-3*pow(L,2)*(24*(-2 + 3*pow(E,2))*pow(M,2) + (4 - 8*pow(E,2))*M*r - 3*pow(r,2)) + r*(r*(86*pow(M,2) - 139*M*r + 19*pow(r,2)) + 2*pow(E,2)*M*(-44*pow(M,2) + 98*M*r + 105*pow(r,2)))) + pow(a,4)*(24*pow(L,4)*M*(-3*M + r) + pow(L,2)*r*(8*(-11 + 90*pow(E,2))*pow(M,3) + 4*(59 - 178*pow(E,2))*pow(M,2)*r + 2*(-41 + 26*pow(E,2))*M*pow(r,2) + pow(r,3)) + pow(r,2)*(r*(-20*pow(M,3) + 296*pow(M,2)*r - 149*M*pow(r,2) + 3*pow(r,3)) + 2*pow(E,2)*M*(-200*pow(M,3) - 108*pow(M,2)*r + 36*M*pow(r,2) + 73*pow(r,3)))))/(12.*r*pow(pow(a,2) + r*(-2*M + r),2)); A180 = -(pow(r,2)*(60*pow(a,3)*E*L*M + 4*a*E*L*M*r*(8*M + 3*r) - 3*pow(a,4)*(10*pow(E,2)*M + 3*r) + r*(8*pow(L,2)*M*(-2*M + r) + pow(r,2)*(8*pow(M,2) + 2*(-3 + 5*pow(E,2))*M*r + pow(r,2))) - 2*pow(a,2)*(15*pow(L,2)*M + r*(r*(-7*M + 4*r) + 2*pow(E,2)*M*(4*M + 5*r)))))/(48.*(pow(a,2) + r*(-2*M + r))); A204 = (48*pow(pow(a,2)*(2*M + r) + r*(pow(L,2) + pow(r,2)),2))/(pow(a,2) + r*(-2*M + r)); A206 = (8*(pow(a,2)*(2*M + r) + r*(pow(L,2) + pow(r,2)))*(-4*pow(a,7)*E*L*M*(12*pow(M,2) + 23*M*r + 3*pow(r,2)) - 4*a*E*L*M*pow(r,5)*(pow(L,2)*(67*M - 36*r) + (17*M - 15*r)*pow(r,2)) - 4*pow(a,5)*E*L*M*r*(-64*pow(M,3) - 104*pow(M,2)*r + 55*M*pow(r,2) + 7*pow(r,3) + 3*pow(L,2)*(8*M + r)) + pow(a,8)*M*(-(r*(M + 6*r)) + 12*pow(E,2)*(2*pow(M,2) + 3*M*r + pow(r,2))) + 4*pow(a,3)*E*L*M*pow(r,2)*(pow(L,2)*(16*pow(M,2) - 73*M*r + 3*pow(r,2)) + pow(r,2)*(196*pow(M,2) - 17*M*r + 11*pow(r,2))) + pow(r,5)*(8*pow(L,4)*(10*pow(M,2) - 11*M*r + 3*pow(r,2)) + pow(r,4)*(40*pow(M,2) - 2*(19 + 2*pow(E,2))*M*r + 9*pow(r,2)) + 2*pow(L,2)*pow(r,2)*(54*pow(M,2) + (-57 + 2*pow(E,2))*M*r + 15*pow(r,2))) - 2*pow(a,2)*pow(r,2)*(pow(r,4)*(58*pow(M,3) + 3*(-23 + 26*pow(E,2))*pow(M,2)*r + 33*M*pow(r,2) - 6*pow(r,3)) + 2*pow(L,4)*(8*pow(M,3) - 33*pow(M,2)*r + 10*M*pow(r,2) + 3*pow(r,3)) - pow(L,2)*pow(r,2)*(-194*pow(M,3) + (171 + 104*pow(E,2))*pow(M,2)*r + (-57 + 10*pow(E,2))*M*pow(r,2) + 6*pow(r,3))) + pow(a,4)*r*(48*pow(L,4)*pow(M,2) + pow(r,2)*(4*pow(M,4) + 20*(1 - 18*pow(E,2))*pow(M,3)*r - 3*(-53 + 76*pow(E,2))*pow(M,2)*pow(r,2) + 12*(-7 + 2*pow(E,2))*M*pow(r,3) - 3*pow(r,4)) - 2*pow(L,2)*(64*pow(M,4) + 8*(11 + 2*pow(E,2))*pow(M,3)*r - (109 + 80*pow(E,2))*pow(M,2)*pow(r,2) + (51 - 14*pow(E,2))*M*pow(r,3) + 9*pow(r,4))) + 2*pow(a,6)*(pow(L,2)*M*(12*pow(M,2) + 4*(7 + 6*pow(E,2))*M*r + 3*(-1 + 2*pow(E,2))*pow(r,2)) - r*(pow(r,3)*(31*M + 3*r) + 2*pow(E,2)*M*(32*pow(M,3) + 60*pow(M,2)*r + 9*M*pow(r,2) - 8*pow(r,3))))))/(3.*pow(r,6)*pow(pow(a,2) + r*(-2*M + r),2)); A222 = (24*pow(r,3)*(pow(a,2)*(2*M + r) + r*(pow(L,2) + pow(r,2))))/(pow(a,2) + r*(-2*M + r)); A224 = (2*(4*pow(a,7)*E*L*M*(24*pow(M,2) + 19*M*r + 9*pow(r,2)) - 4*a*E*L*M*pow(r,3)*(4*pow(L,4)*M + 9*pow(L,2)*(12*M - 7*r)*pow(r,2) + 6*(9*M - 7*r)*pow(r,4)) + 4*pow(a,5)*E*L*M*r*(48*pow(M,3) + 142*pow(M,2)*r + 76*M*pow(r,2) + 50*pow(r,3) + pow(L,2)*(-6*M + 9*r)) - pow(a,8)*(24*pow(E,2)*pow(M,2)*(2*M + r) + r*(49*pow(M,2) + 42*M*r + 6*pow(r,2))) + pow(r,3)*(4*pow(L,6)*M*(2*M - r) + 12*pow(L,2)*pow(r,4)*(28*pow(M,2) - 32*M*r + 9*pow(r,2)) + 3*pow(r,6)*(40*pow(M,2) - 2*(23 + 2*pow(E,2))*M*r + 13*pow(r,2)) + 2*pow(L,4)*pow(r,2)*(118*pow(M,2) + (-131 + 2*pow(E,2))*M*r + 36*pow(r,2))) + 4*pow(a,3)*E*L*M*pow(r,3)*(-6*pow(L,2)*(9*M - 8*r) + r*(114*pow(M,2) + 23*M*r + 83*pow(r,2))) + 2*pow(a,2)*pow(r,3)*(pow(L,4)*(4*(18 + pow(E,2))*pow(M,2) + (-71 + 2*pow(E,2))*M*r + 15*pow(r,2)) - 3*pow(r,3)*(12*pow(M,3) + 2*(-7 + 24*pow(E,2))*pow(M,2)*r + (31 + 6*pow(E,2))*M*pow(r,2) - 15*pow(r,3)) + 3*pow(L,2)*r*(-32*pow(M,3) + 2*(19 + 9*pow(E,2))*pow(M,2)*r - 61*M*pow(r,2) + 25*pow(r,3))) + pow(a,4)*r*(6*pow(L,4)*(2*pow(M,2) - 6*M*r - pow(r,2)) - 3*pow(r,2)*(76*pow(M,4) + 12*(-1 + 16*pow(E,2))*pow(M,3)*r + 3*(-19 + 56*pow(E,2))*pow(M,2)*pow(r,2) + 4*(7 + 3*pow(E,2))*M*pow(r,3) - 19*pow(r,4)) - 2*pow(L,2)*(48*pow(M,4) + 68*pow(M,3)*r - 4*(13 + 9*pow(E,2))*pow(M,2)*pow(r,2) + 84*M*pow(r,3) - 15*pow(r,4))) - 2*pow(a,6)*(pow(L,2)*(24*pow(M,3) + (26 - 6*pow(E,2))*pow(M,2)*r + 39*M*pow(r,2) + 6*pow(r,3)) + M*r*(r*(-106*pow(M,2) - 37*M*r + 39*pow(r,2)) + 6*pow(E,2)*(8*pow(M,3) + 36*pow(M,2)*r + 20*M*pow(r,2) + pow(r,3))))))/(3.*pow(r,3)*pow(pow(a,2) + r*(-2*M + r),2)); A240 = (3*pow(r,6))/(pow(a,2) + r*(-2*M + r)); A242 = (24*pow(a,5)*E*L*M*(7*M + 4*r) + 12*pow(a,3)*E*L*M*r*(4*pow(L,2) - 16*pow(M,2) + 9*M*r + 23*pow(r,2)) - 12*a*E*L*M*pow(r,2)*(pow(L,2)*(8*M - 4*r) + (19*M - 13*r)*pow(r,2)) - 3*pow(a,6)*(4*pow(E,2)*M*(7*M + 3*r) + r*(10*M + 3*r)) + pow(r,2)*(24*pow(L,4)*M*(2*M - r) + pow(r,4)*(120*pow(M,2) - 2*(71 + 6*pow(E,2))*M*r + 41*pow(r,2)) + pow(L,2)*pow(r,2)*(228*pow(M,2) - 232*M*r + 59*pow(r,2))) + pow(a,2)*r*(-24*pow(L,4)*M + pow(r,2)*(-36*pow(M,3) + (22 - 84*pow(E,2))*pow(M,2)*r - 6*(19 + 10*pow(E,2))*M*pow(r,2) + 67*pow(r,3)) + 2*pow(L,2)*(48*pow(M,3) - 6*(13 + 2*pow(E,2))*M*pow(r,2) + 25*pow(r,3) + 6*pow(M,2)*(r + 4*pow(E,2)*r))) - pow(a,4)*(3*pow(L,2)*(28*pow(M,2) + 4*(5 + 2*pow(E,2))*M*r + 3*pow(r,2)) + r*(r*(-78*pow(M,2) + 14*M*r - 17*pow(r,2)) + 12*pow(E,2)*M*(-8*pow(M,2) + 10*M*r + 7*pow(r,2)))))/(6.*pow(pow(a,2) + r*(-2*M + r),2)); A260 = (pow(r,3)*(48*pow(a,3)*E*L*M - 3*pow(a,4)*(8*pow(E,2)*M + r) + 16*a*E*L*M*r*(-5*M + 3*r) + r*(20*pow(L,2)*M*(2*M - r) + pow(r,2)*(40*pow(M,2) - 2*(21 + 2*pow(E,2))*M*r + 11*pow(r,2))) - 2*pow(a,2)*(12*pow(L,2)*M + r*((7*M - 4*r)*r + 2*pow(E,2)*M*(-10*M + 7*r)))))/(24.*pow(pow(a,2) + r*(-2*M + r),2)); A304 = (-8*(pow(a,2)*(2*M + r) + r*(pow(L,2) + pow(r,2)))*(4*pow(a,3)*E*L*M + pow(a,4)*r + 12*a*E*L*M*pow(r,2) + pow(r,2)*(pow(r,2)*(-5*M + 2*r) + pow(L,2)*(-9*M + 4*r)) + pow(a,2)*(pow(L,2)*(-4*M + r) + r*(2*pow(M,2) - 3*M*r + 3*pow(r,2)))))/(r*pow(pow(a,2) + r*(-2*M + r),2)); A306 = (4*(-4*pow(a,11)*E*L*pow(M,2)*(4*(35 + 9*pow(E,2))*pow(M,2) + (127 + 54*pow(E,2))*M*r + 3*(5 + 6*pow(E,2))*pow(r,2)) - 2*a*E*L*M*pow(r,5)*(pow(r,6)*(-184*pow(M,2) + 12*(17 + 9*pow(E,2))*M*r - 57*pow(r,2)) + pow(L,2)*pow(r,4)*(212*pow(M,2) + 4*(-23 + 57*pow(E,2))*M*r - 3*pow(r,2)) + 42*pow(L,6)*(4*pow(M,2) - pow(r,2)) + 2*pow(L,4)*pow(r,2)*(486*pow(M,2) + 2*(-170 + 21*pow(E,2))*M*r + 51*pow(r,2))) - 2*pow(a,3)*E*L*M*pow(r,3)*(4*pow(L,4)*pow(r,2)*((829 + 42*pow(E,2))*pow(M,2) + 2*(-107 + 21*pow(E,2))*M*r - 84*pow(r,2)) + 42*pow(L,6)*(12*pow(M,2) - 2*M*r - pow(r,2)) + pow(r,5)*(-3444*pow(M,3) + 2*(961 - 270*pow(E,2))*pow(M,2)*r + 4*(106 + 135*pow(E,2))*M*pow(r,2) - 257*pow(r,3)) + 2*pow(L,2)*pow(r,3)*(-3230*pow(M,3) + 3*(895 + 224*pow(E,2))*pow(M,2)*r + (-109 + 384*pow(E,2))*M*pow(r,2) - 214*pow(r,3))) + pow(r,7)*(2*pow(L,6)*(2*M - r)*(54*pow(M,2) + (-71 + 42*pow(E,2))*M*r + 24*pow(r,2)) + pow(L,4)*pow(r,2)*(272*pow(M,3) + 2*(-247 + 222*pow(E,2))*pow(M,2)*r + (311 - 226*pow(E,2))*M*pow(r,2) - 66*pow(r,3)) + pow(L,2)*pow(r,4)*(220*pow(M,3) + 340*(-1 + pow(E,2))*pow(M,2)*r + (193 - 184*pow(E,2))*M*pow(r,2) - 39*pow(r,3)) + pow(r,6)*(116*pow(M,3) + 2*(-83 + 44*pow(E,2))*pow(M,2)*r + 6*(14 - 9*pow(E,2))*M*pow(r,2) - 15*pow(r,3))) + pow(a,12)*M*(3*r*(-8*pow(M,2) - 3*M*r + 2*pow(r,2)) + pow(E,2)*(280*pow(M,3) + 308*pow(M,2)*r + 72*M*pow(r,2) - 6*pow(r,3))) - 4*pow(a,9)*E*L*M*(pow(L,2)*M*(108*pow(M,2) + 2*(137 + 24*pow(E,2))*M*r + 3*(13 + 6*pow(E,2))*pow(r,2)) + r*(24*(-1 + 12*pow(E,2))*pow(M,4) + 2*(215 + 234*pow(E,2))*pow(M,3)*r + 12*(49 + 39*pow(E,2))*pow(M,2)*pow(r,2) + 9*(-5 + 18*pow(E,2))*M*pow(r,3) - 30*pow(r,4))) - pow(a,2)*pow(r,3)*(-168*pow(L,8)*pow(M,2)*(2*M - r) + pow(L,4)*pow(r,3)*(4168*pow(M,4) - 4*(1441 + 1086*pow(E,2))*pow(M,3)*r + 4*(583 + 6*pow(E,2))*pow(M,2)*pow(r,2) + (-85 + 732*pow(E,2))*M*pow(r,3) - 81*pow(r,4)) + 2*pow(L,6)*r*(240*pow(M,4) - 4*(233 + 84*pow(E,2))*pow(M,3)*r - 6*(-83 + 28*pow(E,2))*pow(M,2)*pow(r,2) + (23 + 84*pow(E,2))*M*pow(r,3) - 36*pow(r,4)) + pow(L,2)*pow(r,5)*(3640*pow(M,4) + 12*(-413 + 58*pow(E,2))*pow(M,3)*r + 2*(1091 - 1004*pow(E,2))*pow(M,2)*pow(r,2) + (-243 + 800*pow(E,2))*M*pow(r,3) - 27*pow(r,4)) + pow(r,7)*(696*pow(M,4) + 4*(-315 + 274*pow(E,2))*pow(M,3)*r + 4*(204 - 241*pow(E,2))*pow(M,2)*pow(r,2) + (-205 + 268*pow(E,2))*M*pow(r,3) + 15*pow(r,4))) - 2*pow(a,5)*E*L*M*pow(r,2)*(2*pow(L,4)*(1008*pow(M,3) + 4*(257 + 21*pow(E,2))*pow(M,2)*r + 2*(-104 + 21*pow(E,2))*M*pow(r,2) - 87*pow(r,3)) + pow(L,2)*r*(-1888*pow(M,4) + 20*(-161 + 24*pow(E,2))*pow(M,3)*r + 288*(21 + 8*pow(E,2))*pow(M,2)*pow(r,2) + 12*(-89 + 74*pow(E,2))*M*pow(r,3) - 617*pow(r,4)) - pow(r,3)*(768*pow(M,4) + 4*(823 + 378*pow(E,2))*pow(M,3)*r + 4*(-1091 + 18*pow(E,2))*pow(M,2)*pow(r,2) - 18*(-1 + 56*pow(E,2))*M*pow(r,3) + 403*pow(r,4))) + pow(a,4)*pow(r,2)*(2*pow(L,6)*M*(672*pow(M,3) + 4*(101 + 126*pow(E,2))*pow(M,2)*r + 28*(-11 + 3*pow(E,2))*M*pow(r,2) - (31 + 42*pow(E,2))*pow(r,3)) + pow(r,5)*(180*pow(M,5) + 12*(1 - 238*pow(E,2))*pow(M,4)*r - 9*(-161 + 60*pow(E,2))*pow(M,3)*pow(r,2) + 8*(-219 + 287*pow(E,2))*pow(M,2)*pow(r,3) + (421 - 538*pow(E,2))*M*pow(r,4) + 45*pow(r,5)) + pow(L,4)*r*(-1888*pow(M,5) + 8*(-239 + 180*pow(E,2))*pow(M,4)*r + 32*(163 + 293*pow(E,2))*pow(M,3)*pow(r,2) + 12*(-223 + 58*pow(E,2))*pow(M,2)*pow(r,3) + 2*(79 - 396*pow(E,2))*M*pow(r,4) + 147*pow(r,5)) + pow(L,2)*pow(r,3)*(-364*pow(M,5) - 4*(763 + 2976*pow(E,2))*pow(M,4)*r + (6129 + 4072*pow(E,2))*pow(M,3)*pow(r,2) + 4*(-965 + 831*pow(E,2))*pow(M,2)*pow(r,3) + 3*(181 - 436*pow(E,2))*M*pow(r,4) + 171*pow(r,5))) - 2*pow(a,7)*E*L*M*r*(48*pow(L,4)*M*(6*M + r) + 2*pow(L,2)*(864*pow(M,4) + 4*(163 + 84*pow(E,2))*pow(M,3)*r + (1271 + 624*pow(E,2))*pow(M,2)*pow(r,2) + 2*(-101 + 96*pow(E,2))*M*pow(r,3) - 96*pow(r,4)) - r*(896*pow(M,5) + 1840*pow(M,4)*r + 36*(17 + 2*pow(E,2))*pow(M,3)*pow(r,2) - 4*(769 + 324*pow(E,2))*pow(M,2)*pow(r,3) + 2*(179 - 432*pow(E,2))*M*pow(r,4) + 263*pow(r,5))) + pow(a,6)*r*(6*pow(L,6)*M*(32*pow(M,2) + 2*M*r + pow(r,2)) + 4*pow(L,4)*M*(288*pow(M,4) + 4*(23 + 252*pow(E,2))*pow(M,3)*r + (389 + 1450*pow(E,2))*pow(M,2)*pow(r,2) + 2*(-125 + 69*pow(E,2))*M*pow(r,3) - (6 + 73*pow(E,2))*pow(r,4)) + pow(r,3)*(184*pow(M,6) - 4*(11 + 268*pow(E,2))*pow(M,5)*r - 6*(37 + 632*pow(E,2))*pow(M,4)*pow(r,2) + (77 + 2080*pow(E,2))*pow(M,3)*pow(r,3) + (-1231 + 2360*pow(E,2))*pow(M,2)*pow(r,4) + 3*(203 - 184*pow(E,2))*M*pow(r,5) + 75*pow(r,6)) + pow(L,2)*r*(-896*pow(M,6) - 32*(38 + 59*pow(E,2))*pow(M,5)*r - 16*(21 + 292*pow(E,2))*pow(M,4)*pow(r,2) + 2*(1643 + 4488*pow(E,2))*pow(M,3)*pow(r,3) + (-1991 + 2372*pow(E,2))*pow(M,2)*pow(r,4) + (571 - 964*pow(E,2))*M*pow(r,5) + 105*pow(r,6))) + pow(a,10)*M*(pow(L,2)*(8*(35 + 54*pow(E,2))*pow(M,3) + 8*(25 + 109*pow(E,2))*pow(M,2)*r + 3*(-7 + 76*pow(E,2))*M*pow(r,2) + 6*(3 - 2*pow(E,2))*pow(r,3)) + r*(r*(134*pow(M,3) - 21*pow(M,2)*r - 69*M*pow(r,2) + 58*pow(r,3)) + pow(E,2)*(-48*pow(M,4) + 1072*pow(M,3)*r + 1704*pow(M,2)*pow(r,2) + 452*M*pow(r,3) - 76*pow(r,4)))) + pow(a,8)*(2*pow(L,4)*M*(72*pow(M,3) + 4*(55 + 72*pow(E,2))*pow(M,2)*r + 78*pow(E,2)*M*pow(r,2) - 3*(-3 + pow(E,2))*pow(r,3)) + pow(L,2)*M*r*(48*(-1 + 72*pow(E,2))*pow(M,4) + 8*(81 + 514*pow(E,2))*pow(M,3)*r + (869 + 5400*pow(E,2))*pow(M,2)*pow(r,2) + 2*(-285 + 472*pow(E,2))*M*pow(r,3) + 4*(24 - 71*pow(E,2))*pow(r,4)) + pow(r,2)*(r*(-264*pow(M,5) + 92*pow(M,4)*r + 135*pow(M,3)*pow(r,2) - 189*pow(M,2)*pow(r,3) + 361*M*pow(r,4) + 30*pow(r,5)) - 2*pow(E,2)*M*(448*pow(M,5) + 1232*pow(M,4)*r + 680*pow(M,3)*pow(r,2) - 1460*pow(M,2)*pow(r,3) - 660*M*pow(r,4) + 149*pow(r,5))))))/(3.*pow(r,7)*pow(pow(a,2) + r*(-2*M + r),3)); A322 = (-4*pow(r,2)*(2*pow(a,3)*E*L*M + 6*a*E*L*M*pow(r,2) + pow(a,4)*(3*M + 2*r) + pow(r,2)*(pow(r,2)*(-5*M + 2*r) + pow(L,2)*(-7*M + 3*r)) - 2*pow(a,2)*(pow(L,2)*(M - r) + r*(2*pow(M,2) + M*r - 2*pow(r,2)))))/pow(pow(a,2) + r*(-2*M + r),2); A324 = (4*pow(a,9)*E*L*M*(2*(-113 + 9*pow(E,2))*pow(M,2) - 57*M*r + 3*pow(r,2)) - 4*a*E*L*M*pow(r,4)*(pow(L,4)*(240*pow(M,2) - 22*M*r - 51*pow(r,2)) + pow(L,2)*pow(r,2)*(314*pow(M,2) + (-83 + 114*pow(E,2))*M*r - 42*pow(r,2)) + 3*pow(r,4)*(-84*pow(M,2) + 4*(26 + 9*pow(E,2))*M*r - 33*pow(r,2))) + pow(a,10)*M*(-21*r*(7*M + 2*r) + 4*pow(E,2)*(113*pow(M,2) + 81*M*r + 9*pow(r,2))) - 4*pow(a,7)*E*L*M*(3*pow(L,2)*(-18*pow(M,2) + 8*M*r + pow(r,2)) + r*(4*(31 + 108*pow(E,2))*pow(M,3) + 9*(109 + 30*pow(E,2))*pow(M,2)*r + (37 + 108*pow(E,2))*M*pow(r,2) - 69*pow(r,3))) - 4*pow(a,3)*E*L*M*pow(r,2)*(pow(L,4)*(612*pow(M,2) - 92*M*r - 45*pow(r,2)) + pow(r,3)*(-2250*pow(M,3) + (955 - 54*pow(E,2))*pow(M,2)*r + 9*(49 + 36*pow(E,2))*M*pow(r,2) - 211*pow(r,3)) + pow(L,2)*r*(16*pow(M,3) + 2*(409 + 114*pow(E,2))*pow(M,2)*r + 2*(-185 + 108*pow(E,2))*M*pow(r,2) - 45*pow(r,3))) + pow(r,4)*(2*pow(L,6)*M*(12*pow(M,2) - 16*M*r + 5*pow(r,2)) + pow(L,2)*pow(r,4)*(304*pow(M,3) + 2*(-243 + 340*pow(E,2))*pow(M,2)*r + (257 - 368*pow(E,2))*M*pow(r,2) - 45*pow(r,3)) + 2*pow(L,4)*pow(r,2)*(128*pow(M,3) + 2*(-113 + 111*pow(E,2))*pow(M,2)*r + (129 - 113*pow(E,2))*M*pow(r,2) - 24*pow(r,3)) + 3*pow(r,6)*(116*pow(M,3) + 2*(-85 + 44*pow(E,2))*pow(M,2)*r + 2*(41 - 27*pow(E,2))*M*pow(r,2) - 13*pow(r,3))) - 4*pow(a,5)*E*L*M*r*(6*pow(L,4)*r + pow(L,2)*(1296*pow(M,3) + 6*(47 + 34*pow(E,2))*pow(M,2)*r + (-371 + 102*pow(E,2))*M*pow(r,2) - 60*pow(r,3)) + r*(-1008*pow(M,4) + 2*(-641 + 216*pow(E,2))*pow(M,3)*r + 6*(335 + 63*pow(E,2))*pow(M,2)*pow(r,2) + (209 + 324*pow(E,2))*M*pow(r,3) - 178*pow(r,4))) + pow(a,2)*pow(r,2)*(2*pow(L,6)*M*(408*pow(M,2) - 194*M*r - 5*pow(r,2)) - 8*pow(L,4)*M*r*(104*pow(M,3) - 3*(73 + 77*pow(E,2))*pow(M,2)*r + (115 - 101*pow(E,2))*M*pow(r,2) + 17*(-1 + 3*pow(E,2))*pow(r,3)) - 3*pow(r,5)*(464*pow(M,4) + 4*(-187 + 194*pow(E,2))*pow(M,3)*r - 8*(-66 + 83*pow(E,2))*pow(M,2)*pow(r,2) + 2*(-83 + 98*pow(E,2))*M*pow(r,3) + 15*pow(r,4)) + pow(L,2)*pow(r,3)*(-4696*pow(M,4) + 8*(672 + 127*pow(E,2))*pow(M,3)*r + 6*(-347 + 324*pow(E,2))*pow(M,2)*pow(r,2) - 3*(-87 + 352*pow(E,2))*M*pow(r,3) + 15*pow(r,4))) + pow(a,4)*r*(12*pow(L,6)*M*r + 3*pow(r,3)*(60*pow(M,5) - 4*(23 + 326*pow(E,2))*pow(M,4)*r + (751 - 436*pow(E,2))*pow(M,3)*pow(r,2) + 2*(-387 + 586*pow(E,2))*pow(M,2)*pow(r,3) - 4*(-50 + 63*pow(E,2))*M*pow(r,4) + 19*pow(r,5)) + 2*pow(L,2)*r*(-1008*pow(M,5) + 4*(-227 + 328*pow(E,2))*pow(M,4)*r + 2*(1325 + 758*pow(E,2))*pow(M,3)*pow(r,2) + 14*(-95 + 6*pow(E,2))*pow(M,2)*pow(r,3) + 3*(39 - 160*pow(E,2))*M*pow(r,4) + 69*pow(r,5)) + 2*pow(L,4)*(864*pow(M,4) + 2*(-193 + 107*pow(E,2))*pow(M,2)*pow(r,2) + 17*(1 - 5*pow(E,2))*M*pow(r,3) + 24*pow(r,4) + 12*pow(M,3)*(r + 102*pow(E,2)*r))) + pow(a,8)*(2*pow(L,2)*M*((226 - 108*pow(E,2))*pow(M,2) + 24*(-2 + pow(E,2))*M*r + 3*(-15 + 8*pow(E,2))*pow(r,2)) + r*(2*pow(E,2)*M*(124*pow(M,3) + 982*pow(M,2)*r + 686*M*pow(r,2) + 3*pow(r,3)) + 3*r*(179*pow(M,3) - 70*pow(M,2)*r + 30*M*pow(r,2) + 10*pow(r,3)))) + pow(a,6)*(-12*pow(L,4)*M*(6*pow(M,2) - 4*M*r - (-3 + pow(E,2))*pow(r,2)) + 2*pow(L,2)*r*(4*(31 + 648*pow(E,2))*pow(M,4) + 28*(35 + 39*pow(E,2))*pow(M,3)*r - (361 + 140*pow(E,2))*pow(M,2)*pow(r,2) + (43 - 112*pow(E,2))*M*pow(r,3) + 39*pow(r,4)) + pow(r,2)*(3*r*(-192*pow(M,4) + 210*pow(M,3)*r - 381*pow(M,2)*pow(r,2) + 160*M*pow(r,3) + 31*pow(r,4)) - 4*pow(E,2)*M*(504*pow(M,4) + 828*pow(M,3)*r - 433*pow(M,2)*pow(r,2) - 709*M*pow(r,3) + 90*pow(r,4)))))/(3.*pow(r,4)*pow(pow(a,2) + r*(-2*M + r),3)); A340 = -(pow(r,5)*(3*pow(a,2) + r*(-5*M + 2*r)))/(2.*pow(pow(a,2) + r*(-2*M + r),2)); A342 = (24*pow(a,7)*E*L*M*((-25 + 3*pow(E,2))*M - 7*r) + 3*pow(a,8)*(r*(8*M + 9*r) + 2*pow(E,2)*M*(50*M + 19*r)) - 4*a*E*L*M*pow(r,3)*(3*pow(r,2)*(-76*pow(M,2) + (103 + 18*pow(E,2))*M*r - 36*pow(r,2)) + pow(L,2)*(208*pow(M,2) - 64*M*r - 27*pow(r,2))) - 12*pow(a,5)*E*L*M*(pow(L,2)*(-18*M + 8*r) + r*((4 + 48*pow(E,2))*pow(M,2) + (71 - 6*pow(E,2))*M*r + 20*pow(r,2))) - 12*pow(a,3)*E*L*M*r*(pow(L,2)*(144*pow(M,2) - 64*M*r - pow(r,2)) + 2*r*(-88*pow(M,3) + 2*(-5 + 18*pow(E,2))*pow(M,2)*r + 9*(4 + pow(E,2))*M*pow(r,2) - 13*pow(r,3))) + pow(r,3)*(-8*pow(L,4)*M*(2*pow(M,2) - 3*M*r + pow(r,2)) + pow(r,4)*(348*pow(M,3) + 8*(-64 + 33*pow(E,2))*pow(M,2)*r + (245 - 162*pow(E,2))*M*pow(r,2) - 38*pow(r,3)) + pow(L,2)*pow(r,2)*(-52*pow(M,3) + 4*(19 + 85*pow(E,2))*pow(M,2)*r - (33 + 184*pow(E,2))*M*pow(r,2) + 4*pow(r,3))) - pow(a,2)*r*(-12*pow(L,4)*M*(48*pow(M,2) - 29*M*r + pow(r,2)) + pow(L,2)*r*(1056*pow(M,4) - 16*(33 + 107*pow(E,2))*pow(M,3)*r + 4*(-35 + 16*pow(E,2))*pow(M,2)*pow(r,2) + 4*(9 + 64*pow(E,2))*M*pow(r,3) + 25*pow(r,4)) + pow(r,3)*(696*pow(M,4) + 8*(-103 + 171*pow(E,2))*pow(M,3)*r + 4*(166 - 273*pow(E,2))*pow(M,2)*pow(r,2) + 3*(-111 + 124*pow(E,2))*M*pow(r,3) + 57*pow(r,4))) + pow(a,6)*(pow(L,2)*((300 - 216*pow(E,2))*pow(M,2) + 6*(9 + 8*pow(E,2))*M*r + 27*pow(r,2)) + r*(12*pow(E,2)*M*(2*pow(M,2) + 61*M*r + 15*pow(r,2)) + r*(-312*pow(M,2) - 25*M*r + 61*pow(r,2)))) + pow(a,4)*(24*pow(L,4)*M*(-3*M + 2*r) + pow(L,2)*r*(24*(1 + 72*pow(E,2))*pow(M,3) + 12*(10 - 41*pow(E,2))*pow(M,2)*r - 3*(23 + 8*pow(E,2))*M*pow(r,2) - 2*pow(r,3)) + pow(r,2)*(-12*pow(E,2)*M*(88*pow(M,3) + 64*pow(M,2)*r - 97*M*pow(r,2) + 12*pow(r,3)) + r*(876*pow(M,3) - 512*pow(M,2)*r + 63*M*pow(r,2) + 15*pow(r,3)))))/(12.*r*pow(pow(a,2) + r*(-2*M + r),3)); A360 = (pow(r,2)*(-144*pow(a,5)*E*L*M + 28*pow(a,3)*E*L*M*(4*M - 3*r)*r + 3*pow(a,6)*(24*pow(E,2)*M + 7*r) + 4*a*E*L*M*pow(r,2)*(68*pow(M,2) - 54*M*r + 15*pow(r,2)) + pow(r,2)*(-2*pow(L,2)*M*(68*pow(M,2) - 76*M*r + 21*pow(r,2)) + pow(r,2)*(116*pow(M,3) + 8*(-21 + 11*pow(E,2))*pow(M,2)*r + (83 - 54*pow(E,2))*M*pow(r,2) - 14*pow(r,3))) + pow(a,4)*(72*pow(L,2)*M + r*(r*(-53*M + 28*r) + pow(E,2)*(-56*pow(M,2) + 74*M*r))) - pow(a,2)*r*(2*pow(L,2)*M*(28*M - 5*r) + r*(r*(36*pow(M,2) - 30*M*r + 7*pow(r,2)) + 4*pow(E,2)*M*(34*pow(M,2) - 16*M*r + 13*pow(r,2))))))/(48.*pow(pow(a,2) + r*(-2*M + r),3)); A402 = (12*pow(r,3)*(pow(a,2)*(2*M + r) + r*(pow(L,2) + pow(r,2))))/pow(pow(a,2) + r*(-2*M + r),2); A404 = (2*(-4*pow(a,7)*E*L*M*(48*pow(M,2) + 40*M*r + 3*pow(r,2)) - 4*pow(a,5)*E*L*M*r*(-96*pow(M,3) - 110*pow(M,2)*r + 73*M*pow(r,2) + 8*pow(r,3) + 9*pow(L,2)*(6*M + r)) + pow(a,8)*(12*pow(E,2)*M*(8*pow(M,2) + 10*M*r + 3*pow(r,2)) - r*(62*pow(M,2) + 42*M*r + 3*pow(r,2))) + pow(r,3)*(4*pow(L,6)*M*(-2*M + r) + 3*pow(r,6)*(23*pow(M,2) + 4*(-5 + pow(E,2))*M*r + 3*pow(r,2)) + 3*pow(L,2)*pow(r,4)*(42*pow(M,2) + 4*(-9 + 2*pow(E,2))*M*r + 5*pow(r,2)) + pow(L,4)*pow(r,2)*(73*pow(M,2) + 4*(-17 + 2*pow(E,2))*M*r + 12*pow(r,2))) - 4*pow(a,3)*E*L*M*pow(r,2)*(6*pow(L,4) + pow(L,2)*(-48*pow(M,2) + 81*M*r + 9*pow(r,2)) + pow(r,2)*(-234*pow(M,2) + 50*M*r + 17*pow(r,2))) + 4*a*E*L*M*pow(r,3)*(pow(L,4)*(4*M - 6*r) + 3*(M - 4*r)*pow(r,4) + pow(L,2)*(-45*M*pow(r,2) + 6*pow(r,3))) + pow(a,2)*pow(r,2)*(12*pow(L,6)*M + 6*pow(r,4)*(-16*pow(M,3) + (26 - 36*pow(E,2))*pow(M,2)*r + (-25 + 12*pow(E,2))*M*pow(r,2) + 6*pow(r,3)) + 3*pow(L,2)*pow(r,2)*(-152*pow(M,3) + 4*(35 + 9*pow(E,2))*pow(M,2)*r + 2*(-33 + 16*pow(E,2))*M*pow(r,2) + 19*pow(r,3)) + pow(L,4)*(-96*pow(M,3) + 4*(39 - 2*pow(E,2))*pow(M,2)*r + 10*(-5 + 2*pow(E,2))*M*pow(r,2) + 24*pow(r,3))) + pow(a,4)*r*(3*pow(L,4)*(36*pow(M,2) + 4*(-1 + pow(E,2))*M*r - pow(r,2)) - 2*pow(L,2)*(96*pow(M,4) + 4*(19 + 12*pow(E,2))*pow(M,3)*r - (143 + 84*pow(E,2))*pow(M,2)*pow(r,2) + 15*(3 - 4*pow(E,2))*M*pow(r,3) - 18*pow(r,4)) - 3*pow(r,2)*(36*pow(M,4) + 4*(-5 + 48*pow(E,2))*pow(M,3)*r + 9*(-5 + 8*pow(E,2))*pow(M,2)*pow(r,2) + 2*(19 - 24*pow(E,2))*M*pow(r,3) - 14*pow(r,4))) + 2*pow(a,6)*(pow(L,2)*(48*pow(M,3) + 2*(10 + 27*pow(E,2))*pow(M,2)*r + 3*(-11 + 8*pow(E,2))*M*pow(r,2) - 3*pow(r,3)) + r*(-12*pow(E,2)*M*(8*pow(M,3) + 12*pow(M,2)*r - 5*M*pow(r,2) - 5*pow(r,3)) + r*(74*pow(M,3) + 17*pow(M,2)*r - 33*M*pow(r,2) + 6*pow(r,3))))))/(3.*pow(r,3)*pow(pow(a,2) + r*(-2*M + r),3)); A420 = (3*pow(r,6))/pow(pow(a,2) + r*(-2*M + r),2); A422 = (2*pow(a,5)*E*L*M*(-8*M + r) - 2*pow(a,3)*E*L*M*r*(4*pow(L,2) - 8*pow(M,2) + M*r - 7*pow(r,2)) - 2*a*E*L*M*pow(r,3)*(4*pow(L,2) + r*(3*M + 4*r)) + pow(a,6)*M*(-7*r + pow(E,2)*(8*M + 6*r)) + pow(r,4)*(pow(r,2)*(23*pow(M,2) + 2*(-11 + 2*pow(E,2))*M*r + 4*pow(r,2)) + pow(L,2)*(25*pow(M,2) + (-23 + 4*pow(E,2))*M*r + 4*pow(r,2))) + pow(a,2)*r*(4*pow(L,4)*M + pow(r,2)*(-16*pow(M,3) - 4*(-5 + 8*pow(E,2))*pow(M,2)*r + 7*(-5 + 2*pow(E,2))*M*pow(r,2) + 14*pow(r,3)) + pow(L,2)*(-8*pow(M,3) + 10*pow(M,2)*r + (-23 + 8*pow(E,2))*M*pow(r,2) + 15*pow(r,3))) + pow(a,4)*(4*pow(L,2)*M*(2*M + (-2 + pow(E,2))*r) + r*(-8*pow(E,2)*M*(pow(M,2) + M*r - 2*pow(r,2)) + r*(17*pow(M,2) - 8*M*r + 10*pow(r,2)))))/pow(pow(a,2) + r*(-2*M + r),3); A440 = (pow(r,4)*(9*pow(a,4) - 48*a*E*L*pow(M,2) + 12*pow(L,2)*M*(2*M - r) + pow(r,2)*(69*pow(M,2) + 2*(-31 + 6*pow(E,2))*M*r + 10*pow(r,2)) + 2*pow(a,2)*(6*pow(E,2)*M*(2*M + r) + r*(-30*M + 17*r))))/(24.*pow(pow(a,2) + r*(-2*M + r),3)); A502 = (-2*pow(r,2)*(2*pow(a,3)*E*L*M + 6*a*E*L*M*pow(r,2) + pow(a,4)*(3*M + 2*r) + pow(r,2)*(pow(r,2)*(-4*M + r) + pow(L,2)*(-6*M + 2*r)) + pow(a,2)*(-2*pow(L,2)*(M - r) + r*(-2*pow(M,2) - 3*M*r + 3*pow(r,2)))))/pow(pow(a,2) + r*(-2*M + r),3); A504 = (-2*pow(a,9)*E*L*M*(4*(49 + 27*pow(E,2))*pow(M,2) + 6*(-7 + 12*pow(E,2))*M*r - 9*pow(r,2)) + pow(a,10)*M*(3*r*(-10*M + 7*r) + 2*pow(E,2)*(98*pow(M,2) + 30*M*r - 15*pow(r,2))) - 2*a*E*L*M*pow(r,4)*(pow(L,2)*pow(r,2)*(-725*pow(M,2) + 8*(172 + 21*pow(E,2))*M*r - 570*pow(r,2)) + 3*pow(r,4)*(-135*pow(M,2) + 4*(49 + 18*pow(E,2))*M*r - 82*pow(r,2)) + 16*pow(L,4)*(2*pow(M,2) + 15*M*r - 9*pow(r,2))) - 2*pow(a,7)*E*L*M*(pow(L,2)*(324*pow(M,2) + 12*(5 + 3*pow(E,2))*M*r + 9*pow(r,2)) + 2*r*(16*(2 + 9*pow(E,2))*pow(M,3) + 6*(94 + 57*pow(E,2))*pow(M,2)*r + 2*(-65 + 126*pow(E,2))*M*pow(r,2) - 39*pow(r,3))) + pow(r,4)*(-2*pow(L,6)*M*(44*pow(M,2) - 52*M*r + 15*pow(r,2)) + 3*M*pow(r,6)*(52*pow(M,2) + (-65 + 44*pow(E,2))*M*r + (23 - 30*pow(E,2))*pow(r,2)) + 2*pow(L,4)*pow(r,2)*(-153*pow(M,3) + (271 + 140*pow(E,2))*pow(M,2)*r - 2*(82 + 39*pow(E,2))*M*pow(r,2) + 36*pow(r,3)) + pow(L,2)*pow(r,4)*(34*pow(M,3) + (51 + 428*pow(E,2))*pow(M,2)*r - (109 + 248*pow(E,2))*M*pow(r,2) + 48*pow(r,3))) - 2*pow(a,3)*E*L*M*pow(r,2)*(2*pow(L,4)*(252*pow(M,2) + 116*M*r - 63*pow(r,2)) + pow(L,2)*r*(-784*pow(M,3) + 3*(219 + 40*pow(E,2))*pow(M,2)*r + 18*(39 + 22*pow(E,2))*M*pow(r,2) - 168*pow(r,3)) - 2*pow(r,3)*(765*pow(M,3) + 2*(8 + 135*pow(E,2))*pow(M,2)*r - 3*(89 + 132*pow(E,2))*M*pow(r,2) + 119*pow(r,3))) - 2*pow(a,5)*E*L*M*r*(18*pow(L,4)*(6*M + r) + pow(L,2)*(864*pow(M,3) + 84*(15 + 2*pow(E,2))*pow(M,2)*r + 2*(-145 + 132*pow(E,2))*M*pow(r,2) - 123*pow(r,3)) + r*(-576*pow(M,4) - 1390*pow(M,3)*r + 3*(667 + 108*pow(E,2))*pow(M,2)*pow(r,2) + 4*(89 + 252*pow(E,2))*M*pow(r,3) - 61*pow(r,4))) - pow(a,2)*pow(r,2)*(4*pow(L,6)*M*(-84*pow(M,2) + 8*M*r + 23*pow(r,2)) + 3*pow(r,5)*(210*pow(M,4) + (-355 + 484*pow(E,2))*pow(M,3)*r + 12*(23 - 33*pow(E,2))*pow(M,2)*pow(r,2) + 2*(-62 + 65*pow(E,2))*M*pow(r,3) + 21*pow(r,4)) + 2*pow(L,4)*r*(392*pow(M,4) - (409 + 196*pow(E,2))*pow(M,3)*r - (39 + 584*pow(E,2))*pow(M,2)*pow(r,2) + (-41 + 167*pow(E,2))*M*pow(r,3) + 84*pow(r,4)) + pow(L,2)*pow(r,3)*(1618*pow(M,4) + (-1559 + 2272*pow(E,2))*pow(M,3)*r + (683 - 4036*pow(E,2))*pow(M,2)*pow(r,2) + (-413 + 848*pow(E,2))*M*pow(r,3) + 165*pow(r,4))) + pow(a,4)*r*(18*pow(L,6)*M*(4*M + r) + 8*pow(L,4)*(72*pow(M,4) + 18*(4 + 7*pow(E,2))*pow(M,3)*r + (-91 + 128*pow(E,2))*pow(M,2)*pow(r,2) - 4*(-4 + 5*pow(E,2))*M*pow(r,3) + 9*pow(r,4)) + 3*pow(r,3)*(44*pow(M,5) - 56*(-1 + 8*pow(E,2))*pow(M,4)*r + 2*(233 - 192*pow(E,2))*pow(M,3)*pow(r,2) + (-499 + 736*pow(E,2))*pow(M,2)*pow(r,3) + (151 - 220*pow(E,2))*M*pow(r,4) - 27*pow(r,5)) - pow(L,2)*r*(576*pow(M,5) + 4*(263 + 196*pow(E,2))*pow(M,4)*r - 13*(215 + 88*pow(E,2))*pow(M,3)*pow(r,2) - 6*(-313 + 524*pow(E,2))*pow(M,2)*pow(r,3) + 4*(-82 + 241*pow(E,2))*M*pow(r,4) + 96*pow(r,5))) + pow(a,8)*(pow(L,2)*M*(4*(49 + 162*pow(E,2))*pow(M,2) + 12*(-12 + 23*pow(E,2))*M*r + 3*(11 - 4*pow(E,2))*pow(r,2)) + r*(2*pow(E,2)*M*(32*pow(M,3) + 608*pow(M,2)*r + 286*M*pow(r,2) - 105*pow(r,3)) + 3*r*(24*pow(M,3) + 2*pow(M,2)*r + 130*M*pow(r,2) + 15*pow(r,3)))) + pow(a,6)*(6*pow(L,4)*M*(36*pow(M,2) + 2*(-1 + 18*pow(E,2))*M*r + (5 + 3*pow(E,2))*pow(r,2)) + pow(L,2)*r*(64*(1 + 27*pow(E,2))*pow(M,4) + 16*(65 + 207*pow(E,2))*pow(M,3)*r + 68*(-14 + 17*pow(E,2))*pow(M,2)*pow(r,2) + (595 - 376*pow(E,2))*M*pow(r,3) + 117*pow(r,4)) + pow(r,2)*(3*r*(-58*pow(M,4) - 45*pow(M,3)*r - 420*pow(M,2)*pow(r,2) + 173*M*pow(r,3) + 9*pow(r,4)) - 4*pow(E,2)*M*(144*pow(M,4) + 432*pow(M,3)*r - 218*pow(M,2)*pow(r,2) - 416*M*pow(r,3) + 135*pow(r,4)))))/(3.*pow(r,4)*pow(pow(a,2) + r*(-2*M + r),4)); A520 = -(pow(r,5)*(3*pow(a,2) + r*(-4*M + r)))/(2.*pow(pow(a,2) + r*(-2*M + r),3)); A522 = (-6*pow(a,7)*E*L*M*(4*(14 + 3*pow(E,2))*M + 23*r) + 3*pow(a,8)*(2*pow(E,2)*M*(28*M - r) + r*(43*M + 9*r)) - 2*a*E*L*M*pow(r,3)*(pow(L,2)*(64*pow(M,2) + 344*M*r - 222*pow(r,2)) + 3*pow(r,2)*(-199*pow(M,2) + 4*(79 + 18*pow(E,2))*M*r - 134*pow(r,2))) - 6*pow(a,5)*E*L*M*(4*pow(L,2)*(9*M + 2*r) + r*(12*(7 + 6*pow(E,2))*pow(M,2) + 6*(17 + 16*pow(E,2))*M*r + 7*pow(r,2))) - 6*pow(a,3)*E*L*M*r*(2*pow(L,2)*(108*pow(M,2) + 52*M*r - 33*pow(r,2)) + r*(-272*pow(M,3) + (-73 + 72*pow(E,2))*pow(M,2)*r + 2*(103 + 78*pow(E,2))*M*pow(r,2) - 116*pow(r,3))) + pow(r,3)*(-4*pow(L,4)*M*(38*pow(M,2) - 45*M*r + 13*pow(r,2)) + 6*pow(r,4)*(52*pow(M,3) + (-63 + 44*pow(E,2))*pow(M,2)*r - 6*(-3 + 5*pow(E,2))*M*pow(r,2) + 2*pow(r,3)) + pow(L,2)*pow(r,2)*(-158*pow(M,3) + (369 + 428*pow(E,2))*pow(M,2)*r - 4*(73 + 62*pow(E,2))*M*pow(r,2) + 84*pow(r,3))) + pow(a,2)*r*(24*pow(L,4)*M*(18*pow(M,2) + M*r - 7*pow(r,2)) + pow(L,2)*r*(-816*pow(M,4) + 2*(213 + 356*pow(E,2))*pow(M,3)*r + (103 + 1444*pow(E,2))*pow(M,2)*pow(r,2) + 4*(32 - 125*pow(E,2))*M*pow(r,3) - 156*pow(r,4)) - 3*pow(r,3)*(210*pow(M,4) + (-295 + 548*pow(E,2))*pow(M,3)*r + (313 - 488*pow(E,2))*pow(M,2)*pow(r,2) + 2*(-97 + 95*pow(E,2))*M*pow(r,3) + 40*pow(r,4))) + 3*pow(a,6)*(pow(L,2)*(8*(7 + 9*pow(E,2))*pow(M,2) + 8*(6 + pow(E,2))*M*r + 9*pow(r,2)) + r*(2*pow(E,2)*M*(42*pow(M,2) + 148*M*r - 37*pow(r,2)) + r*(-240*pow(M,2) + 87*M*r + 11*pow(r,2)))) + 3*pow(a,4)*(8*pow(L,4)*M*(3*M + r) + pow(L,2)*r*(12*(7 + 36*pow(E,2))*pow(M,3) + 4*(-23 + 98*pow(E,2))*pow(M,2)*r + 4*(3 - 19*pow(E,2))*M*pow(r,2) - 13*pow(r,3)) - pow(r,2)*(r*(-385*pow(M,3) + 317*pow(M,2)*r - 120*M*pow(r,2) + 42*pow(r,3)) + 2*pow(E,2)*M*(136*pow(M,3) + 144*pow(M,2)*r - 312*M*pow(r,2) + 101*pow(r,3)))))/(12.*r*pow(pow(a,2) + r*(-2*M + r),4)); A540 = (pow(r,2)*(-72*pow(a,5)*E*L*M + 9*pow(a,6)*(4*pow(E,2)*M + r) + 12*pow(a,3)*E*L*M*r*(-12*M + 11*r) + 12*a*E*L*M*pow(r,2)*(32*pow(M,2) - 42*M*r + 17*pow(r,2)) + pow(a,4)*(36*pow(L,2)*M + r*(18*pow(E,2)*M*(4*M - 3*r) + (24*M - 13*r)*r)) + pow(r,2)*(-6*pow(L,2)*M*(32*pow(M,2) - 38*M*r + 11*pow(r,2)) + pow(r,2)*(156*pow(M,3) + (-193 + 132*pow(E,2))*pow(M,2)*r + 2*(32 - 45*pow(E,2))*M*pow(r,2) + 2*pow(r,3))) - pow(a,2)*r*(pow(L,2)*(-72*pow(M,2) + 78*M*r) + r*(12*pow(E,2)*M*(16*pow(M,2) - 23*M*r + 15*pow(r,2)) + r*(183*pow(M,2) - 196*M*r + 62*pow(r,2))))))/(48.*pow(pow(a,2) + r*(-2*M + r),4)); A600 = pow(r,6)/pow(pow(a,2) + r*(-2*M + r),3); A602 = (-24*pow(a,5)*E*L*M*(5*M + r) - 16*pow(a,3)*E*L*M*r*(3*pow(L,2) - 8*pow(M,2) + 2*M*r + 3*pow(r,2)) + 8*a*E*L*M*pow(r,2)*(pow(L,2)*(4*M - 6*r) + (11*M - 15*r)*pow(r,2)) + 3*pow(a,6)*(r*(-6*M + r) + 4*pow(E,2)*M*(5*M + 3*r)) + pow(r,2)*(8*pow(L,4)*M*(-2*M + r) + M*pow(r,4)*(43*M + 4*(-8 + 5*pow(E,2))*r) + pow(L,2)*pow(r,2)*(3*pow(M,2) + 4*(3 + 4*pow(E,2))*M*r - 12*pow(r,2))) + pow(a,2)*r*(24*pow(L,4)*M + pow(r,2)*(-34*pow(M,3) + (39 - 100*pow(E,2))*pow(M,2)*r + 2*(-47 + 38*pow(E,2))*M*pow(r,2) + 36*pow(r,3)) + pow(L,2)*(-64*pow(M,3) - 8*(-3 + 2*pow(E,2))*pow(M,2)*r + 10*(-3 + 4*pow(E,2))*M*pow(r,2) + 48*pow(r,3))) + pow(a,4)*(3*pow(L,2)*(20*pow(M,2) + 4*(-1 + 2*pow(E,2))*M*r + pow(r,2)) + r*(r*(32*pow(M,2) - 14*M*r + 39*pow(r,2)) + pow(E,2)*(-64*pow(M,3) + 8*pow(M,2)*r + 92*M*pow(r,2)))))/(6.*pow(pow(a,2) + r*(-2*M + r),4)); A620 = (pow(r,3)*(-48*pow(a,3)*E*L*M + 16*a*E*L*M*(M - 3*r)*r + 3*pow(a,4)*(8*pow(E,2)*M + 5*r) + M*r*(pow(L,2)*(-8*M + 4*r) + pow(r,2)*(43*M + 4*(-8 + 5*pow(E,2))*r)) + pow(a,2)*(24*pow(L,2)*M + 2*r*(r*(-31*M + 18*r) + pow(E,2)*(-4*pow(M,2) + 22*M*r)))))/(24.*pow(pow(a,2) + r*(-2*M + r),4)); A700 = (pow(r,5)*(-pow(a,2) + M*r))/(2.*pow(pow(a,2) + r*(-2*M + r),4)); A702 = (-12*pow(a,7)*E*L*M*((2 + 6*pow(E,2))*M + 3*r) + 3*pow(a,8)*(2*pow(E,2)*M*(2*M - 7*r) + r*(26*M + 3*r)) - 4*a*E*L*M*pow(r,3)*(pow(L,2)*(-52*pow(M,2) + 144*M*r - 69*pow(r,2)) + pow(r,2)*(-85*pow(M,2) + 2*(61 + 27*pow(E,2))*M*r - 51*pow(r,2))) - 8*pow(a,5)*E*L*M*(27*pow(L,2)*M + r*((35 + 12*pow(E,2))*pow(M,2) + 3*(8 + 17*pow(E,2))*M*r - 9*pow(r,2))) + M*pow(r,3)*(-4*pow(L,4)*(26*pow(M,2) - 31*M*r + 9*pow(r,2)) + pow(L,2)*pow(r,2)*(-25*pow(M,2) + 4*(3 + 44*pow(E,2))*M*r + 2*(5 - 54*pow(E,2))*pow(r,2)) + pow(r,4)*(91*pow(M,2) + 2*(-59 + 40*pow(E,2))*M*r + 2*(23 - 29*pow(E,2))*pow(r,2))) - 4*pow(a,3)*E*L*M*r*(pow(L,2)*(72*pow(M,2) + 172*M*r - 69*pow(r,2)) + r*(-80*pow(M,3) - 65*pow(M,2)*r + 2*(64 + 69*pow(E,2))*M*pow(r,2) - 84*pow(r,3))) + pow(a,2)*r*(4*pow(L,4)*M*(24*pow(M,2) + 35*M*r - 31*pow(r,2)) + pow(L,2)*r*(-160*pow(M,4) - 52*(-1 + 2*pow(E,2))*pow(M,3)*r + (27 + 1004*pow(E,2))*pow(M,2)*pow(r,2) + 2*(51 - 130*pow(E,2))*M*pow(r,3) - 84*pow(r,4)) - pow(r,3)*(166*pow(M,4) + (-289 + 532*pow(E,2))*pow(M,3)*r + (371 - 472*pow(E,2))*pow(M,2)*pow(r,2) + 16*(-17 + 14*pow(E,2))*M*pow(r,3) + 72*pow(r,4))) + pow(a,6)*(3*pow(L,2)*((4 + 72*pow(E,2))*pow(M,2) + 26*M*r + 3*pow(r,2)) + r*(4*pow(E,2)*M*(35*pow(M,2) + 88*M*r - 48*pow(r,2)) + r*(-322*pow(M,2) + 147*M*r - 9*pow(r,2)))) + pow(a,4)*(72*pow(L,4)*pow(M,2) + pow(L,2)*r*(4*(35 + 72*pow(E,2))*pow(M,3) + 4*(-40 + 239*pow(E,2))*pow(M,2)*r + (23 - 152*pow(E,2))*M*pow(r,2) - 36*pow(r,3)) - pow(r,2)*(4*pow(E,2)*M*(40*pow(M,3) + 78*pow(M,2)*r - 195*M*pow(r,2) + 79*pow(r,3)) + r*(-376*pow(M,3) + 365*pow(M,2)*r - 205*M*pow(r,2) + 90*pow(r,3)))))/(12.*r*pow(pow(a,2) + r*(-2*M + r),5)); A720 = -(pow(r,2)*(-48*pow(a,5)*E*L*M + 4*pow(a,3)*E*L*M*(68*M - 57*r)*r + 3*pow(a,6)*(8*pow(E,2)*M + 3*r) - 4*a*E*L*M*pow(r,2)*(52*pow(M,2) - 98*M*r + 45*pow(r,2)) + M*pow(r,2)*(2*pow(L,2)*(52*pow(M,2) - 64*M*r + 19*pow(r,2)) + pow(r,2)*(-91*pow(M,2) + 2*(59 - 40*pow(E,2))*M*r + 2*(-23 + 29*pow(E,2))*pow(r,2))) + pow(a,4)*(24*pow(L,2)*M + r*(-2*pow(E,2)*M*(68*M - 65*r) + r*(-79*M + 42*r))) + pow(a,2)*r*(2*pow(L,2)*M*(-68*M + 49*r) + r*(4*pow(E,2)*M*(26*pow(M,2) - 66*M*r + 41*pow(r,2)) + r*(187*pow(M,2) - 212*M*r + 72*pow(r,2))))))/(48.*pow(pow(a,2) + r*(-2*M + r),5)); A800 = (pow(r,3)*(-12*pow(a,3)*E*L*M + 4*a*E*L*M*(2*M - 3*r)*r + 3*pow(a,4)*(2*pow(E,2)*M + r) + M*r*(pow(L,2)*(-4*M + 2*r) + pow(r,2)*(5*M + 4*(-1 + pow(E,2))*r)) + 2*pow(a,2)*(3*pow(L,2)*M + r*(r*(-5*M + 3*r) + pow(E,2)*M*(-2*M + 5*r)))))/(12.*pow(pow(a,2) + r*(-2*M + r),5)); A900 = -(pow(r,2)*(-18*pow(a,5)*E*L*M + 2*pow(a,3)*E*L*M*(26*M - 21*r)*r + 3*pow(a,6)*(3*pow(E,2)*M + r) - 8*a*E*L*M*pow(r,2)*(2*pow(M,2) - 6*M*r + 3*pow(r,2)) + M*pow(r,2)*(pow(L,2)*(8*pow(M,2) - 10*M*r + 3*pow(r,2)) + 2*pow(r,2)*(-5*pow(M,2) + (7 - 4*pow(E,2))*M*r + 3*(-1 + pow(E,2))*pow(r,2))) + pow(a,4)*(9*pow(L,2)*M + r*(-26*pow(E,2)*M*(M - r) + r*(-17*M + 9*r))) + pow(a,2)*r*(2*pow(L,2)*M*(-13*M + 8*r) + r*(r*(30*pow(M,2) - 35*M*r + 12*pow(r,2)) + pow(E,2)*M*(8*pow(M,2) - 38*M*r + 23*pow(r,2))))))/(24.*pow(pow(a,2) + r*(-2*M + r),6)); } /* Compute aLpha, beta coefficients */ alpha20 = r*r/(a*a+r*(r-2*M)); alpha02 = r*r; beta = 4.0*(L*L + r*r + a*a*(r+2*M)/r); } ================================================ FILE: external/GravitationalEffectiveSource/CMakeLists.txt ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. set(LIBRARY GravitationalEffectiveSource) add_library(${LIBRARY} kerr-circular.c) target_link_libraries( ${LIBRARY} PRIVATE GSL::gsl ) target_include_directories(${LIBRARY} SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) ================================================ FILE: external/GravitationalEffectiveSource/LICENSE.md ================================================ MIT License Copyright (c) 2025 Black Hole Perturbation Toolkit Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: external/GravitationalEffectiveSource/README.md ================================================ This is a modified version of https://github.com/barrywardell/GravitationalEffectiveSource (revision 4c73ea39b23bdf17bcc17dc28f980dabdd97dfec). This repository is currently private (as of Jun 2025) and can be made available upon request by the developers of the Black Hole Perturbation Toolkit (https://bhptoolkit.org). A similar public repository but for the scalar (not gravitational) effective source with more information is available at: https://github.com/barrywardell/EffectiveSource. This code is licensed under MIT. The license can be found in LICENSE.md. Summary of modifications: - Added CMakeLists.txt. - Renamed `effsource.h` to `effsource_gr.h`. - Added C++ compatibility header `effsource_gr.hpp`. ================================================ FILE: external/GravitationalEffectiveSource/effsource_gr.h ================================================ /******************************************************************************* * Copyright (C) 2011 Barry Wardell ******************************************************************************/ struct coordinate { double t; double r; double theta; double phi; }; void effsource_init(double M, double a); void effsource_set_particle(struct coordinate * x, double E, double L, double ur); void effsource_hS(struct coordinate * x, double * hS); void effsource_hS_m(int m, struct coordinate * x, double * hS_re, double * hS_im); void effsource_calc(struct coordinate * x, double *hS, double *dhS_dr, double *dhS_dth, double *dhS_dph, double *dhS_dt, double *src); void effsource_calc_m(int m, struct coordinate * x, double *hS_re, double *hS_im, double *dhS_dr_re, double *dhS_dr_im, double *dhS_dth_re, double *dhS_dth_im, double *dhS_dph_re, double *dhS_dph_im, double *dhS_dt_re, double *dhS_dt_im, double *src_re, double *src_im); ================================================ FILE: external/GravitationalEffectiveSource/effsource_gr.hpp ================================================ #pragma once extern "C" { #include } ================================================ FILE: external/GravitationalEffectiveSource/kerr-circular.c ================================================ /******************************************************************************* * Copyright (C) 2012-2013 Barry Wardell *******************************************************************************/ #include #include "effsource_gr.h" #include #include /* The particle's coordinate location and 4-velocity */ static struct coordinate xp; /* Mass of the black hole */ static double M, a; /* Static variables used to store the coefficients of the series expansions */ static double A00060, A00080, A00240, A00260, A00420, A00440, A00600, A00620, A00800, A01060, A01080, A01240, A01260, A01420, A01440, A01600, A01620, A01800, A02040, A02060, A02220, A02240, A02400, A02420, A02600, A03040, A03060, A03220, A03240, A03400, A03420, A03600, A04020, A04040, A04200, A04220, A04400, A05020, A05040, A05200, A05220, A05400, A06000, A06020, A06200, A07000, A07020, A07200, A08000, A09000; static double A10061, A10081, A10241, A10261, A10421, A10441, A10601, A10621, A10801, A11061, A11241, A11421, A11601, A12041, A12061, A12221, A12241, A12401, A12421, A12601, A13041, A13221, A13401, A14021, A14041, A14201, A14221, A14401, A15021, A15201, A16001, A16021, A16201, A17001, A18001; static double A20161, A20341, A20521, A20701, A21161, A21341, A21521, A21701, A22141, A22321, A22501, A23141, A23321, A23501, A24121, A24301, A25121, A25301, A26101, A27101; static double A30060, A30080, A30240, A30260, A30420, A30440, A30600, A30620, A30800, A31060, A31080, A31240, A31260, A31420, A31440, A31600, A31620, A31800, A32040, A32060, A32220, A32240, A32400, A32420, A32600, A33040, A33060, A33220, A33240, A33400, A33420, A33600, A34020, A34040, A34200, A34220, A34400, A35020, A35040, A35200, A35220, A35400, A36000, A36020, A36200, A37000, A37020, A37200, A38000, A39000; static double A40080, A40260, A40440, A40620, A40800, A41080, A41260, A41440, A41620, A41800, A42060, A42240, A42420, A42600, A43060, A43240, A43420, A43600, A44040, A44220, A44400, A45040, A45220, A45400, A46020, A46200, A47020, A47200, A48000, A49000; static double A50180, A50360, A50540, A50720, A50900, A52160, A52340, A52520, A52700, A54140, A54320, A54500, A56120, A56300, A58100; static double A60061, A60081, A60241, A60261, A60421, A60441, A60601, A60621, A60801, A61061, A61241, A61421, A61601, A62041, A62061, A62221, A62241, A62401, A62421, A62601, A63041, A63221, A63401, A64021, A64041, A64201, A64221, A64401, A65021, A65201, A66001, A66021, A66201, A67001, A68001; static double A70080, A70260, A70440, A70620, A70800, A71080, A71260, A71440, A71620, A71800, A72060, A72240, A72420, A72600, A73060, A73240, A73420, A73600, A74040, A74220, A74400, A75040, A75220, A75400, A76020, A76200, A77020, A77200, A78000, A79000; static double A80161, A80341, A80521, A80701, A81161, A81341, A81521, A81701, A82141, A82321, A82501, A83141, A83321, A83501, A84121, A84301, A85121, A85301, A86101, A87101; static double A90060, A90080, A90240, A90260, A90420, A90440, A90600, A90620, A90800, A91060, A91080, A91240, A91260, A91420, A91440, A91600, A91620, A91800, A92040, A92060, A92220, A92240, A92400, A92420, A92600, A93040, A93060, A93220, A93240, A93400, A93420, A93600, A94020, A94040, A94200, A94220, A94400, A95020, A95040, A95200, A95220, A95400, A96000, A96020, A96200, A97000, A97020, A97200, A98000, A99000; static double alpha20, alpha02, beta; /* Numerical coefficients appearing in the elliptic integrals expressions. The indices here correspond to mode m, EllipticK/EllipticE, order in Sin[dphi], term in polynomial in alpha/beta. */ static const double ReEI[21][2][5][27] = { {{{0,-0.26666666666666666,-0.5333333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,0.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.4,0.13333333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,1.2666666666666666,0.5333333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-4,-6.933333333333334,-3.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,1.5333333333333334,1.5333333333333334,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,0.4666666666666667,-0.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,-0.4666666666666667,-0.13333333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-1.5333333333333334,-1.5333333333333334,-0.5333333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,6.866666666666666,8.533333333333333,3.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,-0.4,-0.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,-0.6,-0.26666666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-1.6,-2.4,-1.0666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,9.266666666666667,14.4,6.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.3333333333333335,-24.933333333333334,-38.4,-17.066666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,1.2666666666666666,0.6,0.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,0.06666666666666667,0.7333333333333333,0.26666666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,2.6,2.933333333333333,1.0666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-3.533333333333333,-15.266666666666667,-17.6,-6.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.3333333333333333,10.2,40.93333333333333,46.93333333333333,17.066666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,0,1.6,1.0666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,5,9.066666666666666,4.266666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-7.6,-42,-59.733333333333334,-25.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,30.6,128,166.4,68.26666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.466666666666667,-73.6,-275.2,-341.3333333333333,-136.53333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,0.4666666666666667,-0.6,-2.1333333333333333,-1.0666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-1.1333333333333333,-8.733333333333333,-11.2,-4.266666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,19.8,67.06666666666666,72.53333333333333,25.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-4.2,-69.8,-198.4,-200.53333333333333,-68.26666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.06666666666666667,13.266666666666667,160,420.26666666666665,409.6,136.53333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,0.6666666666666666,-16.4,-34.13333333333333,-17.066666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,41,186.4,247.46666666666667,102.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-17.6,-204,-630.4,-716.8,-273.06666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,65.8,536,1427.2,1501.8666666666666,546.1333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4857142857142858,-153.0857142857143,-1073.3714285714286,-2640.457142857143,-2652.647619047619,-936.2285714285714,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-0.8666666666666667,2.7333333333333334,30.266666666666666,42.666666666666664,17.066666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-3.1333333333333333,-97.4,-290.93333333333334,-298.6666666666667,-102.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,53.8,410.4,937.6,853.3333333333334,273.06666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-4.6,-177.4,-1019.2,-2075.733333333333,-1774.9333333333334,-546.1333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.02857142857142857,14.771428571428572,392.62857142857143,1984,3791.2380952380954,3120.7619047619046,936.2285714285714,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,1.6,-198.4,-814.9333333333333,-1024,-409.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,147.4,1179.7333333333333,3012.266666666667,3072,1092.2666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-31.6,-629.2,-3345.0666666666666,-7116.8,-6553.6,-2184.5333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,114.94285714285714,1556.3428571428572,6981.4857142857145,13497.295238095237,11702.857142857143,3744.9142857142856,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.492063492063492,-263.84761904761905,-3017.295238095238,-12327.009523809524,-22469.485714285714,-18724.571428571428,-5825.422222222222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-2.7333333333333334,18.6,452.26666666666665,1250.1333333333334,1228.8,409.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-5.933333333333334,-401.26666666666665,-2212.266666666667,-4343.466666666666,-3618.133333333333,-1092.2666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,106.2,1463.3333333333333,5879.466666666666,9984,7645.866666666667,2184.5333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-4.885714285714286,-344.0857142857143,-3410.5142857142855,-11886.933333333332,-18646.55238095238,-13575.314285714287,-3744.9142857142856,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.015873015873015872,15.806349206349207,753.3714285714286,6407.466666666666,20597.02857142857,30739.504761904762,21637.28253968254,5825.422222222222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,2.8,-970,-6314.666666666667,-14080,-13107.2,-4369.066666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,380.2,4689.866666666667,19157.333333333332,34508.8,28398.933333333334,8738.133333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-49.6,-1514.1714285714286,-12285.104761904762,-41442.74285714285,-66823.31428571428,-51180.49523809524,-14979.657142857142,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,178.05396825396826,3632.0761904761903,24604.95238095238,74800.76190476191,112737.52380952382,82388.11428571428,23301.68888888889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.494949494949495,-405.9919191919192,-6920.145454545454,-42364.121212121216,-120645.81818181818,-173769.69696969696,-122863.45050505051,-33893.36565656566,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-5.133333333333334,58.2,2479.3333333333335,11306.666666666666,19814.4,15291.733333333334,4369.066666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-9.533333333333333,-1129.9333333333334,-9986.933333333332,-31906.133333333335,-47069.86666666667,-32768,-8738.133333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,178.14285714285714,3892.609523809524,24463.390476190478,66662.4,89604.87619047619,58670.32380952381,14979.657142857142,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.1079365079365076,-573.9968253968254,-8815.314285714287,-47328,-117906.28571428571,-149562.51428571428,-94038.95873015873,-23301.68888888889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.010101010101010102,16.6,1251.761616161616,16279.660606060606,79786.66666666667,187671.27272727274,228846.41616161616,139810.13333333333,33893.36565656566,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,4.266666666666667,-3262.4,-30573.866666666665,-103765.33333333333,-163840,-122333.86666666667,-34952.53333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,811.4,14256.685714285713,84442.81904761905,231716.57142857142,322998.85714285716,222198.24761904762,59918.62857142857,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-71.6,-3111.35873015873,-35753.44761904762,-174188.49523809523,-426296.0761904762,-551126.5523809524,-359511.77142857143,-93206.75555555556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,255.14487734487736,7331.7772005772,69909.00086580086,305560.71341991343,696355.4632034632,856110.1021645021,538057.1797979798,135573.46262626263,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4965034965034967,-579.5630147630147,-13824.999533799533,-118555.33053613054,-483592.47365967365,-1.0497981165501166e6,-1.2450923412587412e6,-761297.1362859363,-187717.1020979021,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-8.066666666666666,135.93333333333334,9026.133333333333,61310.933333333334,166024.53333333333,218453.33333333334,139810.13333333333,34952.53333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-13.933333333333334,-2571.1714285714284,-33332.038095238095,-157322.3619047619,-357171.2,-422863.2380952381,-252157.5619047619,-59918.62857142857,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,270.5174603174603,8617.873015873016,78308.57142857143,312652.8,643189.0285714286,713406.1714285715,406115.1492063492,93206.75555555556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.28975468975469,-870.3079365079365,-19227.160750360752,-147887.70909090908,-536312.6857142857,-1.0362348051948051e6,-1.0997186678210679e6,-605843.911111111,-135573.46262626263,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.006993006993006993,17.244910644910647,1895.0315462315461,35180.35244755245,245442.05874125875,836234.2041958042,1.5471995524475526e6,1.5905439527583527e6,855155.6873348873,187717.1020979021,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,6,-8800.4,-111859.80952380953,-531221.9428571429,-1.2414390857142857e6,-1.5322940952380951e6,-958698.0571428571,-239674.51428571428,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,1529,36268.93968253968,292742.09523809527,1.1256783238095238e6,2.3227830857142857e6,2.6401645714285714e6,1.557884342857143e6,372827.02222222224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-97.6,-5729.1255411255415,-88548.89927849927,-586570.2510822511,-2.0080116917748917e6,-3.8364944623376625e6,-4.1284842943722946e6,-2.3386422303030305e6,-542293.8505050505,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,346.2218004218004,13349.73026973027,170513.0474858475,1.0105419870795871e6,3.214343297236097e6,5.829024556243756e6,6.033182035742036e6,3.3163354703962705e6,750868.4083916084,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4974358974358974,-784.5839937839938,-25005.26247086247,-286327.7053613054,-1.5797995114219114e6,-4.77710082983683e6,-8.342656417715617e6,-8.387304409013209e6,-4.50521045034965e6,-1.0011578778554779e6,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-11.533333333333333,269.4,25857.619047619046,244643.3523809524,941524.1142857143,1.8502997333333334e6,1.9667041523809524e6,1.0785353142857142e6,239674.51428571428,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-19.133333333333333,-5094.479365079365,-91148.63492063493,-595972.8761904762,-1.9178837333333334e6,-3.3857145904761907e6,-3.3492016761904764e6,-1.744297853968254e6,-372827.02222222224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,384.0510822510823,16824.368253968252,209062.3953823954,1.1501940363636364e6,3.3420239238095237e6,5.513081239826839e6,5.196125312554113e6,2.6097891555555556e6,542293.8505050505,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.443600843600843,-1235.5986901986903,-37219.1333999334,-389168.827972028,-1.9364873206793207e6,-5.267843912887113e6,-8.294196586702187e6,-7.550561944366745e6,-3.6917696745920745e6,-750868.4083916084,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.005128205128205128,17.78850038850039,2689.031546231546,67733.57202797203,639727.53006993,2.9806964363636365e6,7.743910966899767e6,1.1785440213830614e7,1.0452192532090131e7,5.005789389277389e6,1.0011578778554779e6,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,8,-20454.4,-338221.5111111111,-2.129646933333333e6,-6.821751466666667e6,-1.2233386666666666e7,-1.2443101866666667e7,-6.7108864e6,-1.491308088888889e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,2637,81197.69581529581,855236.9685425685,4.365921080519481e6,1.2354614081385281e7,2.0404108744588744e7,1.9569787234632034e7,1.0100222965656566e7,2.169175402020202e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-127.6,-9731.779553779554,-194743.272016872,-1.6810041968697968e6,-7.631895255677655e6,-1.9979235561238762e7,-3.121355504229104e7,-2.8716805848018646e7,-1.4349929582595183e7,-3.0034736335664336e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,451.2884670884671,22506.019314019315,371138.143989344,2.8608340821844824e6,1.2051529176956376e7,2.991034232967033e7,4.489893256254856e7,4.0046315114219114e7,1.9522578618181817e7,4.0046315114219114e6,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4980392156862745,-1021.0684583390466,-41964.88205128205,-619011.4680926916,-4.434788679994515e6,-1.7736541547237076e7,-4.234410989606472e7,-6.1679177494547285e7,-5.3709175564952694e7,-2.5676754984999314e7,-5.182464308898944e6,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-15.533333333333333,479.4,63067.02222222222,792570.3111111111,4.1009152e6,1.1153681066666666e7,1.7336456533333335e7,1.55189248e7,7.456540444444444e6,1.491308088888889e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-25.133333333333333,-9153.99163059163,-216262.70476190475,-1.870872972005772e6,-8.079372412121212e6,-1.9716661638095237e7,-2.849857074978355e7,-2.421317832958153e7,-1.1184810666666666e7,-2.169175402020202e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,519.3591075591075,29973.258252858253,488692.7529359529,3.5444105846153847e6,1.3786808101764902e7,3.138413195977356e7,4.3162921822710626e7,3.5328619333022535e7,1.58516663993784e7,3.0034736335664336e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.576934176934177,-1672.0434454434455,-65967.23223443223,-901384.234965035,-5.895572075924076e6,-2.1422238766033966e7,-4.646431837318237e7,-6.163704083294483e7,-4.905673601491842e7,-2.1524894373892773e7,-4.0046315114219114e6,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.00392156862745098,18.25848530554413,3638.6809634809633,119650.73401892226,1.4725623786096256e6,8.997631810448375e6,3.1165726124667488e7,6.523953848801134e7,8.420522974629554e7,6.55758409995338e7,2.8267987139448788e7,5.182464308898944e6,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,10.266666666666667,-42656.4,-889373.995959596,-7.149019797979798e6,-2.9865748169696968e7,-7.235293556363636e7,-1.0554394065454546e8,-9.146124722424242e7,-4.3383508040404044e7,-8.676701608080808e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,4255.4,165053.57016317017,2.19670492991453e6,1.4330180624708625e7,5.29140260997669e7,1.1808499516270396e8,1.624359102955711e8,1.346948423011655e8,6.173806913442113e7,1.2013894534265734e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-161.6,-15539.587434787434,-390961.72201132204,-4.259990718614719e6,-2.4699115148318347e7,-8.432809336796537e7,-1.779399951088911e8,-2.3469069971592852e8,-1.8834282577156177e8,-8.409726173986015e7,-1.6018526045687646e7,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,570.3472906178788,35746.582191664544,739622.7686979687,7.187172049660143e6,3.862786977665472e7,1.249378262920452e8,2.5314112267361397e8,3.234930047362311e8,2.531309910877828e8,1.1071628296284108e8,2.0729857235595778e7,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.498452012383901,-1289.0251146857959,-66438.47422257825,-1.227617738434115e6,-1.107397992473244e7,-5.645272137256345e7,-1.7550347663965014e8,-3.4482027794523466e8,-4.29947715579034e8,-3.2974049077368206e8,-1.4183586529618162e8,-2.6185082823910456e7,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-20.066666666666666,789.9333333333333,136892.39191919193,2.2055480888888887e6,1.4743798173737373e7,5.277455204848485e7,1.1157285546666667e8,1.4395359728484848e8,1.115261196929293e8,4.7721858844444446e7,8.676701608080808e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-31.933333333333334,-15290.940326340326,-461269.8076146076,-5.10054407956488e6,-2.841850342937063e7,-9.11948410927739e7,-1.7918446766247088e8,-2.193337460960373e8,-1.6331127164320123e8,-6.7745016401554e7,-1.2013894534265734e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,676.9748695748696,49810.32203352203,1.0321920394272394e6,9.544164072727272e6,4.781388058341658e7,1.4294413774385613e8,2.6698699182559663e8,3.145956128422688e8,2.2738798300792542e8,9.210652476270397e7,1.6018526045687646e7,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.694581235757706,-2181.5221419103773,-109270.05492285492,-1.892202578033731e6,-1.5744906345607335e7,-7.356716086097433e7,-2.0929734465833253e8,-3.7668167367356825e8,-4.312426213404269e8,-3.046022843375291e8,-1.2108121158063897e8,-2.0729857235595778e7,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.0030959752321981426,18.672520393263426,4748.226915980476,197766.84242568578,3.0782871159107145e6,2.3888763615371626e7,1.062565981512135e8,2.914255876520172e8,5.098456950542433e8,5.706785877375826e8,3.9574872039228964e8,1.5492840670813686e8,2.6185082823910456e7,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,12.8,-81880,-2.1007407614607615e6,-2.095521238228438e7,-1.1023046737156177e8,-3.441285888596737e8,-6.709847600932401e8,-8.259552492307693e8,-6.240550771965812e8,-2.6430567975384617e8,-4.805557813706294e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,6520.2,311067.7942501943,5.102019779331779e6,4.133440304335664e7,1.922698987114219e8,5.530782550526806e8,1.0170620137920746e9,1.1980522605003884e9,8.746782659530692e8,3.6041683602797204e8,6.407410418275058e7,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-199.6,-23628.784478266833,-730166.5007724302,-9.797468315151514e6,-7.051502323959962e7,-3.0318843028131086e8,-8.24417740343672e8,-1.4532290842782943e9,-1.6563077409054527e9,-1.1777150141972852e9,-4.749021839427396e8,-8.291942894238311e7,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,703.3999221968262,54143.24552805296,1.3738612902969064e6,1.6423980970872264e7,1.0950013007528281e8,4.457761957446739e8,1.1633972193432798e9,1.9862208061391819e9,2.20653026587352e9,1.5363898975089884e9,6.088031756559181e8,1.0474033129564182e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.49874686716792,-1588.4598780648316,-100391.40281967774,-2.2721153274630425e6,-2.5192147588914696e7,-1.5919834323671788e8,-6.225945846062396e8,-1.5748847121862333e9,-2.622330288934644e9,-2.854181112514796e9,-1.9537500785578425e9,-7.631081280111047e8,-1.2967850541365178e8,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-25.133333333333333,1228.2,271881.5229215229,5.463605097125097e6,4.5788857465734266e7,2.0806943674778554e8,5.705886187710955e8,9.891261404195805e8,1.0929306833255634e9,7.47197496172805e8,2.883334688223776e8,4.805557813706294e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-39.53333333333333,-24135.788500388502,-905518.1986013986,-1.2458983344832946e7,-8.693429073752914e7,-3.539285428811189e8,-9.016469155505828e8,-1.4824022811648796e9,-1.5738201839888113e9,-1.0428727894327894e9,-3.9245388811934733e8,-6.407410418275058e7,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,857.3689565336624,78373.47438182733,2.0127715456099457e6,2.3112727872974087e7,1.448205784474976e8,5.48772786971836e8,1.3280004404618127e9,2.1005893010457883e9,2.16389478497818e9,1.3996187132419581e9,5.163618984139312e8,8.291942894238311e7,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.799844393652443,-2765.6909199503625,-171565.7852751995,-3.67408829080517e6,-3.790738907893345e7,-2.2126713741740116e8,-7.971567635483366e8,-1.8574286571222606e9,-2.852811286882909e9,-2.870394025251496e9,-1.8211526732190146e9,-6.61173341303739e8,-1.0474033129564182e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.002506265664160401,19.04256314720711,6021.407418450143,310071.7180627422,5.959559314048181e6,5.72743914936333e7,3.179286576710175e8,1.1032734622114787e9,2.4971591341437187e9,3.7476056187814e9,3.700130737674165e9,2.310989422798335e9,8.279473807179306e8,1.2967850541365178e8,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,15.6,-147184.4,-4.556378703962704e6,-5.516948408391608e7,-3.559327987468532e8,-1.3849838370013986e9,-3.448738599742657e9,-5.628697306405595e9,-5.996935688354312e9,-4.0186477217118883e9,-1.537778500386014e9,-2.5629641673100233e8,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,9583.4,551597.1562502857,1.092800063183875e7,1.0752849872261073e8,6.136858642814754e8,2.2008252360679007e9,5.169359078663266e9,8.074326015812789e9,8.312849426393528e9,5.419679834310819e9,2.0277569441364596e9,3.3167771576953244e8,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-241.6,-34531.581210533535,-1.2859442616457501e6,-2.0830391072875936e7,-1.8202685521436995e8,-9.600492874957876e8,-3.2540002685571485e9,-7.325356346213779e9,-1.1069155880596071e10,-1.1097453830148788e10,-7.079345431875746e9,-2.6010515605084386e9,-4.189613251825673e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,850.4475412444452,78893.74837670069,2.409665423174555e6,3.474925120193656e7,2.8114098072956973e8,1.403407938144174e9,4.564031654437904e9,9.948487456287066e9,1.4649250696397833e10,1.4378787962114319e10,9.011876808307611e9,3.2619131746357026e9,5.187140216546071e8,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4989648033126293,-1919.3769533617697,-146019.8335099459,-3.9742071741968985e6,-5.311713496745179e7,-4.071180069944188e8,-1.951471853701304e9,-6.149049338477993e9,-1.3068470999123806e10,-1.8848566822377876e10,-1.8183385037681484e10,-1.1230798287201794e10,-4.014395471935655e9,-6.314779394056087e8,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-30.733333333333334,1824.6,503413.80792540795,1.23437348997669e7,1.2666985013706294e8,7.111014843972028e8,2.4453185536e9,5.440886345756643e9,8.003944371617716e9,7.74195386945641e9,4.739481393767832e9,1.6659267087515152e9,2.5629641673100233e8,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-47.93333333333333,-36410.112500571326,-1.6632604871154989e6,-2.7868508792540792e7,-2.3790098953758398e8,-1.1959445584594543e9,-3.819200511326039e9,-8.057472578080973e9,-1.1386686300517574e10,-1.0673579702376745e10,-6.371368734672261e9,-2.193595802021226e9,-3.3167771576953244e8,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,1060.962421067065,117999.39040993406,3.6796141928934497e6,5.137764483644158e7,3.934568326273124e8,1.8396699858694205e9,5.577640943291375e9,1.131629761773835e10,1.5511646734480068e10,1.4188707002727196e10,8.301315963658234e9,2.8105322230997224e9,4.189613251825673e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.895082488890538,-3426.029950579177,-257947.1453013447,-6.696260875827578e6,-8.390810906845228e7,-5.980646799483613e8,-2.656730813122411e9,-7.751269489416868e9,-1.5263016489000265e10,-2.042660824129106e10,-1.832174708555405e10,-1.0545574516565224e10,-3.521270185463006e9,-5.187140216546071e8,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.002070393374741201,19.377095129336347,7461.561160324547,465737.4659903026,1.0838682409513706e7,1.2638856718220124e8,8.560311134982536e8,3.660454950424734e9,1.0368589915334404e10,1.9940417844891014e10,2.6176608626888607e10,2.310528608711372e10,1.3119593909531069e10,4.330134441638459e9,6.314779394056087e8,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,18.666666666666668,-250822.4,-9.21840527146579e6,-1.3309575831290278e8,-1.0317491250125874e9,-4.880582542269025e9,-1.5029793383663677e10,-3.1108875678233482e10,-4.36671203627632e10,-4.102438746924404e10,-2.470622075987824e10,-8.623620610007843e9,-1.3267108630781298e9,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,13613,930252.8430925112,2.189775853092872e7,2.5704415869336855e8,1.7632092507090087e9,7.688769367066271e9,2.233765721776305e10,4.425202515598031e10,6.002764410921827e10,5.486875815318882e10,3.230882151159315e10,1.1067561673572819e10,1.6758453007302692e9,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-287.6,-48836.168107778016,-2.157297016025873e6,-4.150197552329858e7,-4.325356919968865e8,-2.7414740676285434e9,-1.129721454934732e10,-3.1453610225900883e10,-6.027595384543495e10,-7.961419543169162e10,-7.119894052826602e10,-4.116669092530494e10,-1.3885575348907944e10,-2.0748560866184285e9,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,1011.4910195053149,111321.75903879551,4.0295488900919873e6,6.897135012978844e7,6.652503712536638e8,3.9895117085213494e9,1.5770553504337744e10,4.2506951460346924e10,7.936585512341737e10,1.0261545331623116e11,9.014849059168524e10,5.1342279166782936e10,1.7095009931051834e10,2.5259117576224346e9,0,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4991304347826087,-2281.7794378338194,-205750.77203382071,-6.631606823604064e6,-1.0514449275916624e8,-9.603493437127837e8,-5.528469326922443e9,-2.116888539068655e10,-5.561882541965658e10,-1.0169630183320364e11,-1.2921016311537668e11,-1.1184445811395491e11,-6.289520276479862e10,-2.0712476412503963e10,-3.0310941091469216e9,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-36.86666666666667,2612.733333333333,880586.5429315782,2.58769066508707e7,3.190248779785548e8,2.165737490196956e9,9.103826722266722e9,2.516944859639786e10,4.714484837223376e10,6.028345544481031e10,5.188494812822027e10,2.876927277805501e10,9.286976041546907e9,1.3267108630781298e9,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-57.13333333333333,-52928.28618502241,-2.8930003372693355e6,-5.799649101182244e7,-5.943782676834052e8,-3.6117879045470395e9,-1.4095434050579176e10,-3.694310664816257e10,-6.646474288799973e10,-8.235087355324098e10,-6.910511159213396e10,-3.752838135449264e10,-1.1905484323937954e10,-1.6758453007302692e9,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,1288.1362155560298,171329.4262403575,6.378245421382333e6,1.0642760530321938e8,9.777255230809364e8,5.52282590456045e9,2.045420469861058e10,5.153708389209838e10,8.991146463998302e10,1.0868422825737668e11,8.937325837111873e10,4.772044308351795e10,1.4923003392217157e10,2.0748560866184285e9,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.982039010629669,-4163.8773617253355,-374174.74996878806,-1.1581383324811196e7,-1.7326355869602597e8,-1.4804164912081263e9,-7.940429316689499e9,-2.828693012341041e10,-6.914758135245525e10,-1.1774449383689468e11,-1.395287760054435e11,-1.1285112004028159e11,-5.941617567775465e10,-1.8357965809863052e10,-2.5259117576224346e9,0,0,0,0,0,0,0,0,0},{0,0,0,-0.0017391304347826088,19.68235392850819,9071.70504037235,675142.9984015393,1.87165462532353e7,2.6038147706447074e8,2.1128045296213334e9,1.0902989617985832e10,3.76931192037466e10,8.995871805969456e10,1.5020871457643378e11,1.7511705338495316e11,1.3969263524174225e11,7.268311082558556e10,2.2228023467077423e10,3.0310941091469216e9,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,22,-408912.4,-1.760144321133892e7,-2.9861306666560435e8,-2.735742086051796e9,-1.5429018250372686e10,-5.7365925635849785e10,-1.459396829211136e11,-2.5834540566109332e11,-3.181407036536493e11,-2.6734969563212573e11,-1.462262308496573e11,-4.692366842044753e10,-6.703381202921077e9,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,18793,1.5042532023658487e6,4.1496704494122185e7,5.725677207573206e8,4.642875405124088e9,2.4142609768578815e10,8.469481355425212e10,2.0624416519975134e11,3.5284625417378284e11,4.227746181988333e11,3.4738564819211395e11,1.8647020933259586e11,5.8893991997092316e10,8.299424346473714e9,0,0,0,0,0,0,0,0,0,0},{0,0,0,-337.6,-67186.71908304376,-3.473936806561178e6,-7.829175553408918e7,-9.589299292985568e8,-7.183900332775953e9,-3.529847566422289e10,-1.1866407812293896e11,-2.795105576516615e11,-4.6559435752690393e11,-5.4578034888958093e11,-4.4032629265684235e11,-2.3272130603976505e11,-7.25297518974442e10,-1.0103647030489738e10,0,0,0,0,0,0,0,0,0},{0,0,0,1,1186.5310195053148,152876.8874522256,6.472435445144703e6,1.2971987635205658e8,1.4699377328144228e9,1.0417012853749659e10,4.909095266192736e10,1.5974095702715295e11,3.6655776122906323e11,5.976373260031626e11,6.881257568365696e11,5.468004776147498e11,2.8525211689964355e11,8.790172916526073e10,1.2124376436587687e10,0,0,0,0,0,0,0,0},{0,0,0,0,-3.4992592592592593,-2675.669679379713,-282242.09231669543,-1.0633815228365488e7,-1.9732870645890525e8,-2.1167235434403558e9,-1.4395851669845222e10,-6.570092170701432e10,-2.08363647527213e11,-4.6815844108415533e11,-7.499685194097299e11,-8.507323675829946e11,-6.674090341577878e11,-3.4432387109323157e11,-1.0507792911709328e11,-1.4369631332252073e10,0,0,0,0,0,0,0}},{{0.5333333333333333,-43.53333333333333,3629.4,1.4694724226778382e6,5.0982079751051836e7,7.433658698673364e8,5.9978865667303295e9,3.02094865091216e10,1.0127974704935579e11,2.3405817896550006e11,3.7868392857216315e11,4.284339090756366e11,3.3229306521589435e11,1.6843118108433334e11,5.027535902190807e10,6.703381202921077e9,0,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-67.13333333333334,-74599.00473169761,-4.808057892384602e6,-1.1363745491663341e8,-1.3765659670421038e9,-9.93853334295837e9,-4.646297120807411e10,-1.476455595126865e11,-3.276911350438754e11,-5.136740259640373e11,-5.665757674791024e11,-4.3035620039143896e11,-2.143610632661782e11,-6.304370417032917e10,-8.299424346473714e9,0,0,0,0,0,0,0,0,0,0},{0,0,0.2,1539.2381660875133,241314.9715176823,1.0573575649746368e7,2.0780309906924197e8,2.255048448318664e9,1.5127647788083984e10,6.709248572068778e10,2.0490559066010007e11,4.4090160795530695e11,6.741577248596049e11,7.285603048003533e11,5.440348341050625e11,2.6709174817027032e11,7.758157541268906e10,1.0103647030489738e10,0,0,0,0,0,0,0,0,0},{0,0,0,-6.062039010629669,-4980.454188585528,-526689.1747977207,-1.9167077767400973e7,-3.374851933365408e8,-3.4042942107257743e9,-2.167534593874192e10,-9.243454922934729e10,-2.738046230308966e11,-5.748972516712766e11,-8.61570663231068e11,-9.156248791038105e11,-6.740816221370153e11,-3.269296609004137e11,-9.396391738355457e10,-1.2124376436587687e10,0,0,0,0,0,0,0,0},{0,0,0,-0.0014814814814814814,19.963062463129766,10854.591016749811,949896.1873083068,3.0939338982764497e7,5.0627985565643203e8,4.84757118825071e9,2.9683411242703876e10,1.2280305832607028e11,3.5504229585249896e11,7.308189481361008e11,1.0772753882648191e12,1.1289483918947014e12,8.212160109323472e11,3.941685297769809e11,1.1226274478321931e11,1.4369631332252073e10,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,25.6,-642174.4,-3.2001493960675444e7,-6.301171929947947e8,-6.730005930120287e9,-4.45489555789727e10,-1.9627249696235114e11,-5.995497443810022e11,-1.2980003517584287e12,-2.0066420365331858e12,-2.2010916432997065e12,-1.6733714338577625e12,-8.384014633082003e11,-2.4898273039421143e11,-3.3197697385894855e10,0,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,25323.4,2.3470004379713614e6,7.499139768356036e7,1.2012583049576294e9,1.1358261276733395e10,6.933205150119518e10,2.8824587254763275e11,8.428926177352782e11,1.7637070948449934e12,2.6530579083520938e12,2.8455838704309585e12,2.1231780276189883e12,1.0469973628525146e12,3.067178562827242e11,4.0414588121958954e10,0,0,0,0,0,0,0,0,0},{0,0,0,-391.6,-90283.39413633075,-5.402084146905385e6,-1.409712773254586e8,-2.0042036720084534e9,-1.7506077529181057e10,-1.009677881940971e11,-4.0223835666768646e11,-1.1377089895665e12,-2.317805564538369e12,-3.4109110612635464e12,-3.591988921734658e12,-2.6387589471896216e12,-1.2839931153068442e12,-3.718142107220224e11,-4.8497505746350746e10,0,0,0,0,0,0,0,0},{0,0,0,1,1375.5680565423518,205134.69458317457,1.00442903694642e7,2.3300366348778668e8,3.0639399202108026e9,2.531140817273939e10,1.3999475849889786e11,5.397786494220163e11,1.4872042574435613e12,2.9652929630267153e12,4.285977100720373e12,4.445188146394695e12,3.223045360499386e12,1.5505730309458252e12,4.4456046934154846e11,5.747852532900829e10,0,0,0,0,0,0,0},{0,0,0,0,-3.499361430395913,-3101.049500580224,-378382.55774830375,-1.6479398081656067e7,-3.538256790695258e8,-4.4032169385133705e9,-3.490151422566471e10,-1.869146820137703e11,-7.023015906202007e11,-1.8944051915725413e12,-3.7109112830375283e12,-5.283759154390902e12,-5.409848733761012e12,-3.8788481619419673e12,-1.8478757481648335e12,-5.2523480042024817e11,-6.7388615902975235e10,0,0,0,0,0,0}},{{0.5333333333333333,-50.733333333333334,4914.6,2.3567543213508883e6,9.531948442077139e7,1.6222566814226518e9,1.533629951143212e10,9.106927966780995e10,3.6324193033461017e11,1.0115537476095123e12,2.0078489418750176e12,2.859678973879202e12,2.902119927570143e12,2.0490001876928757e12,9.566682602454508e11,2.6558157908715884e11,3.3197697385894855e10,0,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-77.93333333333334,-102426.67594272287,-7.688375333570598e6,-2.1157272142042986e8,-2.9899660626777706e9,-2.5285472574644356e10,-1.39341099517905e11,-5.2671795525996155e11,-1.4085398898401514e12,-2.708603610196061e12,-3.76067732280449e12,-3.7374252386297983e12,-2.5929559786286685e12,-1.1927785557210093e12,-3.269251503437037e11,-4.0414588121958954e10,0,0,0,0,0,0,0,0,0},{0,0,0.2,1814.5882726615152,331222.3335493492,1.6875662577301286e7,3.858469039048684e8,4.882312146902555e9,3.834964651451061e10,2.0043215049773267e11,7.280122943454908e11,1.8871102433942173e12,3.5392202281469395e12,4.81403000415386e12,4.70284874154185e12,3.215586981496385e12,1.4608069383404146e12,3.9606296359519775e11,4.8497505746350746e10,0,0,0,0,0,0,0,0},{0,0,0,-6.136113084703743,-5876.883265298239,-722621.9636936528,-3.0552356959223974e7,-6.254641839081137e8,-7.35329135286915e9,-5.480054731379718e10,-2.753158133060997e11,-9.696738980136191e11,-2.4522191929156543e12,-4.506888343001096e12,-6.027500191226616e12,-5.804540636175082e12,-3.920365399720353e12,-1.7620760421174104e12,-4.732997320060526e11,-5.747852532900829e10,0,0,0,0,0,0,0},{0,0,0,-0.001277139208173691,20.222883663640623,12812.749057488787,1.302854067321981e6,4.927317433912787e7,9.370025785364087e8,1.045225177549322e10,7.488955072282285e10,3.6490079744731726e11,1.254099223039917e12,3.108551076865836e12,5.618437072552979e12,7.408490300586078e12,7.048384464155902e12,4.710622193686491e12,2.09785778289315e12,5.589291083717358e11,6.7388615902975235e10,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,29.466666666666665,-976730,-5.578954646189742e7,-1.2615869100582263e9,-1.5529302994019297e10,-1.1910193801450629e11,-6.125072742936332e11,-2.206143296031422e12,-5.709225768796877e12,-1.0749971748792695e13,-1.4747065224375662e13,-1.4582852118589701e13,-1.0122591368671906e13,-4.679251530995561e12,-1.2932668199026865e12,-1.6165835248783582e11,0,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,33420.2,3.550881250122197e6,1.3009442746062008e8,2.3938339984597726e9,2.6090461836376514e10,1.8454580335053577e11,8.956680843174019e11,3.088494496941551e12,7.725403893782204e12,1.415456345665883e13,1.898742633772399e13,1.842784153284401e13,1.2590136522466424e13,5.741108749446352e12,1.5680860191320073e12,1.9399002298540298e11,0,0,0,0,0,0,0,0},{0,0,0,-449.6,-118882.34141578716,-8.1507702655822905e6,-2.4382796059468478e8,-3.981492068669497e9,-4.008401440642937e10,-2.6788273341492886e11,-1.2457916692080254e12,-4.155022019169404e12,-1.011883380132408e13,-1.8137213625744375e13,-2.3887559953693965e13,-2.2825549173918258e13,-1.538763792071379e13,-6.935816898196855e12,-1.8752368888588955e12,-2.2991410131603317e11,0,0,0,0,0,0,0},{0,0,0,1,1578.6025393009725,269796.6997164444,1.5129675524776911e7,4.02205042950141e8,6.073244823885286e9,5.781867124578261e10,3.705046212385272e11,1.6674750698719607e12,5.417057116138862e12,1.2910569366340434e13,2.272747357675429e13,2.947861243273825e13,2.7800233539143176e13,1.8528636980494258e13,8.268499554905844e12,2.2158962523390093e12,2.6955446361190094e11,0,0,0,0,0,0},{0,0,0,0,-3.49944382647386,-3557.9203447280424,-497291.8376827858,-2.479476383769259e7,-6.098901382048699e8,-8.713451379196568e9,-7.957942158518886e10,-4.937089707091298e11,-2.1650359733823113e12,-6.885306538377396e12,-1.6120601827215521e13,-2.7953517732769695e13,-3.579038142482068e13,-3.3375171285503258e13,-2.2026160316691473e13,-9.744096556853e12,-2.5912009727853706e12,-3.1303099000091724e11,0,0,0,0,0}},{{0.5333333333333333,-58.46666666666667,6511.533333333334,3.65374292379483e6,1.7041039042477334e8,3.3474383786596866e9,3.6634576706844986e10,2.5307096312507574e11,1.1825685116914846e12,3.8959211372933706e12,9.271173514538479e12,1.6125338479467012e13,2.0514656081142355e13,1.8879270148820613e13,1.2234885075983668e13,5.295573999855435e12,1.3740959961466045e12,1.6165835248783582e11,0,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-89.53333333333333,-137512.7002443942,-1.189358210895399e7,-3.7701063823343146e8,-6.146753773932911e9,-6.016166039394057e10,-3.856178138857783e11,-1.7075189529981672e12,-5.401437822018391e12,-1.2451974168004955e13,-2.1111659790717637e13,-2.6300614293483598e13,-2.3782945860158555e13,-1.5184861333257229e13,-6.488778629702592e12,-1.665081030624709e12,-1.9399002298540298e11,0,0,0,0,0,0,0,0},{0,0,0.2,2114.4828315743325,444637.2286422091,2.6068237359630816e7,6.861001365773908e8,1.00114325811189e10,9.098481065241385e10,5.529740045299663e11,2.3523822512552803e12,7.2120144708876045e12,1.621315950309689e13,2.692705307551175e13,3.29716634138851e13,2.938224475952283e13,1.8525493900149555e13,7.830326448629547e12,1.990193939516912e12,2.2991410131603317e11,0,0,0,0,0,0,0},{0,0,0,-6.2050786019451225,-6854.203876665512,-969805.7488195399,-4.71490524203349e7,-1.110535871836198e9,-1.5050298809158161e10,-1.2973475579082533e11,-7.577552802741434e11,-3.1251463627856104e12,-9.3459380263197e12,-2.058641033023447e13,-3.3613123793561336e13,-4.056896085255746e13,-3.57073389951639e13,-2.2272676941597234e13,-9.325906219148117e12,-2.3506734841449595e12,-2.6955446361190094e11,0,0,0,0,0,0},{0,0,0,-0.0011123470522803114,20.46471615241416,14948.520395986918,1.7481414056108568e6,7.598676584469618e7,1.6618757729228277e9,2.1362875654996433e10,1.7699538829298035e11,1.0024052815552432e12,4.0333265266471006e12,1.182051050899169e13,2.5601839654882164e13,4.120957066054989e13,4.913190571704601e13,4.278719239553509e13,2.6441705068033305e13,1.0981003732620514e13,2.747716467785829e12,3.1303099000091724e11,0,0,0,0,0}}}, {{{0,-0.26666666666666666,33.6,-1.4449664e6,-9.378112396360818e7,-2.4134343369641385e9,-3.3903936051757397e10,-2.9801676779554596e11,-1.7669252650270583e12,-7.395409184951448e12,-2.247442917360153e13,-5.039491703618102e13,-8.391129263208694e13,-1.034420381542176e14,-9.311814740541167e13,-5.94700664214626e13,-2.5517770940204883e13,-6.595660781503701e12,-7.759600919416119e11,0,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,43315.4,5.230291427936181e6,2.1780053830000895e8,4.561721534340654e9,5.6748630670697624e10,4.600956128255938e11,2.574621229746886e12,1.0317263052979926e13,3.0307188769397027e13,6.613140421026188e13,1.0767812330799452e14,1.302827448528449e14,1.1543547237775336e14,7.272605132546514e13,3.083902504292948e13,7.888927601406388e12,9.196564052641327e11,0,0,0,0,0,0,0},{0,0,0,-511.6,-153795.69885244747,-1.1978643183124974e7,-4.072033459630186e8,-7.567600637131104e9,-8.695493057921883e10,-6.660723636188911e11,-3.571363466702473e12,-1.384223532826015e13,-3.9588090502665234e13,-8.450579365558694e13,-1.3509302529267044e14,-1.609267891315999e14,-1.4069221688269344e14,-8.761436750764872e13,-3.677597449159481e13,-9.323413211988104e12,-1.0782178544476038e12,0,0,0,0,0,0},{0,0,0,1,1795.6347973654888,348690.3862286264,2.2204228030820765e7,6.705854777632657e8,1.1522110280379248e10,1.2517973983561208e11,9.19332170318912e11,4.770007373158425e12,1.8007053868363406e13,5.039707192316374e13,1.056513773616503e14,1.663261076501606e14,1.955389474170697e14,1.6900738607205572e14,1.0419707990723603e14,4.335070020676101e13,1.0903912818365283e13,1.252123960003669e12,0,0,0,0,0},{0,0,0,0,-3.4995112414467253,-4046.283374356923,-642320.5204937553,-3.6354442541503884e7,-1.0156406403679376e9,-1.6508254693268639e10,-1.7202985544924103e11,-1.2230324761502656e12,-6.182633991853942e12,-2.2846441388588523e13,-6.281007640234248e13,-1.2969530267124028e14,-2.0154019556485406e14,-2.3427740497541834e14,-2.0049551613303962e14,-1.2253405597896867e14,-5.058454321247145e13,-1.2635069050946113e13,-1.4418397115193762e12,0,0,0,0}},{{0.5333333333333333,-66.73333333333333,8466.6,5.500782327216349e6,2.9307562486459124e8,6.580662628830447e9,8.25198689979895e10,6.557192881581038e11,3.544366348591472e12,1.3610364338969898e13,3.81402493752755e13,7.919889465707464e13,1.2257383139758511e14,1.4091199728388275e14,1.1864488533235611e14,7.106501175365262e13,2.8670108813717684e13,6.983640827474507e12,7.759600919416119e11,0,0,0,0,0,0,0,0},{0,0.13333333333333333,-101.93333333333334,-181056.65587236284,-1.787733779890622e7,-6.467215044849563e8,-1.2047942031497614e10,-1.3508357853771237e11,-9.958337708633071e11,-5.100215968856238e12,-1.8803864759217754e13,-5.1043402609364266e13,-1.0331528027101834e14,-1.565720156503844e14,-1.7685958939722884e14,-1.4670592314888475e14,-8.675260770965969e13,-3.461105326764565e13,-8.348755804038454e12,-9.196564052641327e11,0,0,0,0,0,0,0},{0,0,0.2,2439.19770489493,585468.939241731,3.91400351372385e7,1.1749495789312527e9,1.958269650268004e10,2.0382117002694974e11,1.4244548817255012e12,7.007773329261644e12,2.5037504149523434e13,6.627085088332564e13,1.3138571746780752e14,1.956929732604737e14,2.1782474594777912e14,1.7841953684261428e14,1.0435529770005283e14,4.123551524987994e13,9.862522139211904e12,1.0782178544476038e12,0,0,0,0,0,0},{0,0,0,-6.2695947309773805,-7913.383352642443,-1.2767836155293747e6,-7.073831350388925e7,-1.899554623143067e9,-2.939480935713848e10,-2.901204668878392e11,-1.9481763004141086e12,-9.290239953778574e12,-3.237296296631215e13,-8.39479743534346e13,-1.6360610601542472e14,-2.401716637111394e14,-2.6402193545879147e14,-2.1393204742321744e14,-1.2394533297842339e14,-4.856788337344296e13,-1.1529974798367117e13,-1.252123960003669e12,0,0,0,0,0},{0,0,0,-0.0009775171065493646,20.69089338637782,17264.0838134564,2.3011678842776404e6,1.1394226862290737e8,2.840139762731206e9,4.167633267110191e10,3.95266965553167e11,2.5731613895229917e12,1.1969456812409002e13,4.086863287421054e13,1.0419401598474152e14,2.0016347293020044e14,2.902331341320077e14,3.156571512430503e14,2.533843334077847e14,1.4559242461110694e14,5.6631732792034625e13,1.33559889067058e13,1.4418397115193762e12,0,0,0,0}}}, {{{0,-0.26666666666666666,38,-2.0864644e6,-1.5269386717706367e8,-4.4364839170700865e9,-7.052545524685811e10,-7.039261202593761e11,-4.761725707062858e12,-2.288315999285902e13,-8.050868479032589e13,-2.1126861740115747e14,-4.1760113688084575e14,-6.230137174218235e14,-6.97244682853531e14,-5.760027708229431e14,-3.406464803623676e14,-1.3638576338223748e14,-3.3107630589508773e13,-3.678625621056531e12,0,0,0,0,0,0,0},{0,0,-0.06666666666666667,55257,7.524884401159955e6,3.534212218718977e8,8.358422454073611e9,1.1767720205354315e11,1.0834651446175271e12,6.917863829651936e12,3.183148547582819e13,1.0825791495805245e14,2.7646060697452588e14,5.3439199490061275e14,7.825097493435275e14,8.619879647594399e14,7.024798614322576e14,4.105674340973219e14,1.6268776314620662e14,3.913296565848068e13,4.312871417790415e12,0,0,0,0,0,0},{0,0,0,-577.6,-195891.5954785697,-1.720127764558216e7,-6.593956434546355e8,-1.3836051116645775e10,-1.7991428787352527e11,-1.5649809531653018e12,-9.574263945472568e12,-4.260947812998459e13,-1.4108556267746003e14,-3.5246266137808444e14,-6.68904000078248e14,-9.643324596899239e14,-1.0481525855129518e15,-8.443224624053235e14,-4.884650317232749e14,-1.9181971314970422e14,-4.577208698235634e13,-5.008495840014676e12,0,0,0,0,0},{0,0,0,1,2026.6651003957916,443769.2062382361,3.1848062618839644e7,1.084383682742406e9,2.1033538298344963e10,2.5857382719851614e11,2.1562791411962607e12,1.2764669581045951e13,5.532758658800373e13,1.7926934003434116e14,4.398155867559162e14,8.21954813552544e14,1.1694384435544125e15,1.2565957550652905e15,1.0021077247917248e15,5.746217280770576e14,2.2387644402300447e14,5.304452412379179e13,5.767358846077505e12,0,0,0,0},{0,0,0,0,-3.4995670995670998,-4566.139539696959,-817050.1240826164,-5.210286556396761e7,-1.6407138496930685e9,-3.010064457529331e10,-3.548915820326058e11,-2.864643885149056e12,-1.6520807008205463e13,-7.0090278456826984e13,-2.2307320285268588e14,-5.3903548690406256e14,-9.943274230202304e14,-1.3987464189591615e15,-1.488142833281783e15,-1.1763925899836822e15,-6.693106216369468e14,-2.589498048063432e14,-6.0969222087105055e13,-6.591267252660006e12,0,0,0}},{{0.5333333333333333,-75.53333333333333,10829.4,8.072048354127319e6,4.87250210500034e8,1.2400772896941032e10,1.7659692941512448e11,1.5987019273419814e12,9.889499268944688e12,4.3725671416071375e13,1.4222478427288353e14,3.464460612721393e14,6.378941277981012e14,8.892327870204825e14,9.324932431776439e14,7.236581421029889e14,4.029765524699275e14,1.5224983637304378e14,3.494694340003704e13,3.678625621056531e12,0,0,0,0,0,0,0},{0,0.13333333333333333,-115.13333333333334,-234357.4023199112,-2.6202969245825373e7,-1.0729925112854352e9,-2.264892860478733e10,-2.8833628269220435e11,-2.421334407948635e12,-1.4190732511616314e13,-6.023738501346369e13,-1.897848476488173e14,-4.506023042846216e14,-8.123862868785152e14,-1.1127081259761939e15,-1.1495259687556288e15,-8.80694584160074e14,-4.849782163048779e14,-1.8144558258461128e14,-4.128940136737588e13,-4.312871417790415e12,0,0,0,0,0,0},{0,0,0.2,2788.9909571394373,757954.1832518226,5.731896737696369e7,1.9467522753006718e9,3.6752178916813446e10,4.342367668300395e11,3.456417626472393e12,1.945586960892444e13,8.002395364327356e13,2.45820394128803e14,5.716362792738416e14,1.0128387071687611e15,1.366953901980593e15,1.394401321620245e15,1.0566084586443459e15,5.762621684739365e14,2.1376666367087962e14,4.827633490236368e13,5.008495840014676e12,0,0,0,0,0},{0,0,0,-6.330200791583441,-9055.326402164885,-1.652817817493035e6,-1.0353224612455417e8,-3.1443424489415655e9,-5.5099878956043625e10,-6.172115086692606e11,-4.719665182766741e12,-2.5747979102863504e13,-1.0327781515594061e14,-3.107840698734769e14,-7.103751521762541e14,-1.240428258290523e15,-1.6532690684504498e15,-1.6682200228770388e15,-1.2521020933688375e15,-6.771547917071688e14,-2.4931732630126084e14,-5.592820354683055e13,-5.767358846077505e12,0,0,0,0},{0,0,0,-0.0008658008658008658,20.90332181816109,19761.47677528686,2.9786440888161287e6,1.6669440060546213e8,4.697988868588864e9,7.804846936458011e10,8.399601182809939e11,6.225772187860445e12,3.3126459614313613e13,1.3018123394897244e14,3.8510657020790756e14,8.676089997567239e14,1.4962826923778152e15,1.9729018315606848e15,1.9720423433634065e15,1.4678534354359658e15,7.87971726203723e14,2.8819855324002194e14,6.4264855713435055e13,6.591267252660006e12,0,0,0}}}, {{{0,-0.26666666666666666,42.666666666666664,-2.9489904e6,-2.4170614799515897e8,-7.873218384663625e9,-1.405806642582533e11,-1.580544280937379e12,-1.2090386727568768e13,-6.6042366119374336e13,-2.65868882310363e14,-8.051739775983438e14,-1.857133409027708e15,-3.2801533762918805e15,-4.4314102156757605e15,-4.540487334262183e15,-3.465694635513561e15,-1.9084456023722588e15,-7.161903536719025e14,-1.6388911387603578e14,-1.725148567116166e13,0,0,0,0,0,0},{0,0,-0.06666666666666667,69509,1.060304375629801e7,5.578470160261151e8,1.479270594762511e10,2.3394997790297177e11,2.4264918279035615e12,1.7521030242218191e13,9.164276368056673e13,3.5664655366664625e14,1.05113206044863e15,2.370956512005569e15,4.1103527541472025e15,5.465870295900822e15,5.524844013590857e15,4.167585692773008e15,2.2713467255841065e15,8.446251275105141e14,1.917140907650062e14,2.0033983360058703e13,0,0,0,0,0},{0,0,0,-647.6,-246094.15250627516,-2.4198988932992294e7,-1.038980191421611e9,-2.444203632713007e10,-3.570077983612116e11,-3.498184851505777e12,-2.4202280989027707e13,-1.2243539925589284e14,-4.638933812042697e14,-1.3374968892379465e15,-2.9619773218874905e15,-5.055557384458424e15,-6.63336672836086e15,-6.627413577564161e15,-4.948584988121854e15,-2.672802925395651e15,-9.85971732202283e14,-2.2219508817519653e14,-2.306943538431002e13,0,0,0,0},{0,0,0,1,2271.693671824363,557112.5844066336,4.4760097703188986e7,1.7065933499774168e9,3.710782171508295e10,5.123704928625934e11,4.812792440204033e12,3.2217907329529703e13,1.587313473404659e14,5.885027219728265e14,1.6662726075609255e15,3.6337254670711775e15,6.120647631772677e15,7.939169799895172e15,7.852589702803345e15,5.811463115882084e15,3.1140914617754305e15,1.1406361435129525e15,2.5541160604057522e14,2.6365069010640023e13,0,0,0},{0,0,0,0,-3.4996138996138995,-5117.489627447047,-1.0252931044630904e6,-7.317764631938808e7,-2.5799387735712266e9,-5.305164082877038e10,-7.024571823174719e11,-6.386343641756565e12,-4.1646702455182195e13,-2.0082495548407444e14,-7.313240134063729e14,-2.0393725447628995e15,-4.389582156680698e15,-7.310312322718411e15,-9.388355782488322e15,-9.204613694406318e15,-6.75889981067322e15,-3.596449851906305e15,-1.3090123157014138e15,-2.9144089798248025e14,-2.9927916174240027e13,0,0}},{{0.5333333333333333,-84.86666666666666,13652.733333333334,1.1580743990317933e7,7.862366731187782e8,2.251285321019336e10,3.6126970425140875e11,3.6950296972946763e12,2.591996982109244e13,1.3060390853963811e14,4.872588592243463e14,1.3728326184824732e15,2.955623641337104e15,4.887098724271143e15,6.197174104927707e15,5.97435514747484e15,4.3000613327664335e15,2.2374288971381245e15,7.949002570465775e14,1.725148567116166e14,1.725148567116166e13,0,0,0,0,0,0},{0,0.13333333333333333,-129.13333333333333,-298814.1125960173,-3.756041742575181e7,-1.7285393875937688e9,-4.103692427927973e10,-5.885977025139501e11,-5.58378211235412e12,-3.710691956026596e13,-1.7949438370340738e14,-6.486221072613646e14,-1.7811709048134368e15,-3.7547456752020125e15,-6.099911491230204e15,-7.620161622284745e15,-7.252241847091468e15,-5.161779213919494e15,-2.65959108326093e15,-9.367258010130061e14,-2.0173108244503553e14,-2.0033983360058703e13,0,0,0,0,0},{0,0,0.2,3164.105012550278,966660.7328705739,8.210917088666102e7,3.1326839561683073e9,6.649903112671311e10,8.850518794573038e11,7.957226405896327e12,5.07826266196542e13,2.3800231954847772e14,8.384811979980429e14,2.2550231205737835e15,4.671485049782065e15,7.477796091175499e15,9.223459380199674e15,8.681741711096794e15,6.119697195173343e15,3.1262899720312225e15,1.0927437571553231e15,2.3372980586735153e14,2.306943538431002e13,0,0,0,0},{0,0,0,-6.387343648726298,-10280.88273895997,-2.1078979265578426e6,-1.482407551004836e8,-5.055907877161912e9,-9.959690402930423e10,-1.2564964279090027e12,-1.0850994538243352e13,-6.710880700339022e13,-3.066885058028235e14,-1.0583451011894089e15,-2.7975704791687135e15,-5.711120851896802e15,-9.02764697095337e15,-1.10141153245736e16,-1.0268428227212878e16,-7.177155441784758e15,-3.6389915826190465e15,-1.2633984960937452e15,-2.6859414054589525e14,-2.6365069010640023e13,0,0,0},{0,0,0,-0.0007722007722007722,21.103579218418492,22442.61268540996,3.7985964582853154e6,2.3859794710035256e8,7.549734457672135e9,1.4096953641872162e11,1.7083678819651787e12,1.429842236994991e13,8.623782828471784e13,3.860843010721173e14,1.3096501921718585e15,3.4118527798952095e15,6.87871387556754e15,1.0756091873106256e16,1.2998921089798014e16,1.2017683521567574e16,8.337385441942756e15,4.199116583526632e15,1.4491212804099838e15,3.0640485606960025e14,2.9927916174240027e13,0,0}}}, {{{0,-0.26666666666666666,47.6,-4.0895524e6,-3.731306038384463e8,-1.3541340916361624e10,-2.698066970601489e11,-3.3929623532272686e12,-2.912501505968892e13,-1.792856932147624e14,-8.178001345526671e14,-2.825665552462115e15,-7.50119392296909e15,-1.5421119083184214e16,-2.46069867650868e16,-3.036845308130471e16,-2.8690118845028184e16,-2.035084821245431e16,-1.0484659979090722e16,-3.7026001121730715e15,-8.013593344023481e14,-8.013593344023481e13,0,0,0,0,0},{0,0,-0.06666666666666667,86351.4,1.4665579721461162e7,8.590687659123018e8,2.5382910206863052e10,4.4799089906092065e11,5.197549704634442e12,4.2116936060807555e13,2.4826316584141612e14,1.0947767893988114e15,3.681377038739813e15,9.557508586062312e15,1.928610504650084e16,3.02919821648759e16,3.68806750791929e16,3.4434258261705336e16,2.417434564050942e16,1.2341328990945152e16,4.323002238921354e15,9.288483194209035e14,9.227774153724008e13,0,0,0,0},{0,0,0,-721.6,-305383.484221278,-3.3425150558028962e7,-1.5976051302013426e9,-4.187439493752403e10,-6.825325957092296e11,-7.480870721296626e12,-5.808146779339898e13,-3.311329496999199e14,-1.421626589092943e15,-4.676542004989115e15,-1.1920141073940436e16,-2.3681684177511636e16,-3.670117139829947e16,-4.416718389230369e16,-4.0819063755733816e16,-2.8399638601169932e16,-1.4382537224523932e16,-5.001926254562189e15,-1.067785294930921e15,-1.054602760425601e14,0,0,0},{0,0,0,1,2530.72069885139,690925.9210848194,6.1773305205390684e7,2.6215136024899797e9,6.350186022610584e10,9.783737218417522e11,1.0279134468481693e13,7.721651964503972e13,4.287219179136568e14,1.8010359258476095e15,5.818025681991426e15,1.460298629964141e16,2.8630185446713732e16,4.3862993135598696e16,5.225649481076826e16,4.7866759281312376e16,3.3039905722220736e16,1.6614027170527334e16,5.741105116040728e15,1.218493729951201e15,1.1971166469696011e14,0,0},{0,0,0,0,-3.4996534996535,-5700.334296291716,-1.2710928628651593e6,-1.0093436202872059e8,-3.9601706432110143e9,-9.070909301290082e10,-1.3400853937505337e12,-1.3626158227398803e13,-9.970831360069828e13,-5.418127541007572e14,-2.2355599883931558e15,-7.112384380705038e15,-1.7619359196305414e16,-3.415306825634278e16,-5.180484759888663e16,-6.1176142561382664e16,-5.559884636602166e16,-3.810791930105565e16,-1.904137287813753e16,-6.54222329112722e15,-1.3812884388110782e15,-1.350593140170832e14,0}},{{0.5333333333333333,-94.73333333333333,16992.6,1.6284696076892616e7,1.2354648054405298e9,3.953909107382076e10,7.10090176204812e11,8.145748277303172e12,6.428556882265668e13,3.6590982390426875e14,1.5502704689894388e15,4.993707604738265e15,1.2398036774129854e16,2.3903947362329856e16,3.5861500931598584e16,4.170569864198567e16,3.720611350142881e16,2.496972481358118e16,1.2193217903736838e16,4.0882542918542015e15,8.414273011224655e14,8.013593344023481e13,0,0,0,0,0},{0,0.13333333333333333,-143.93333333333334,-375927.24292232457,-5.278450853716055e7,-2.7125229474487467e9,-7.195565577844536e10,-1.1548552468425483e12,-1.2286437334588822e13,-9.185201223250092e13,-5.0188188887196794e14,-2.0594686450678228e15,-6.465664297334423e15,-1.5717197545820644e16,-2.9773055055612476e16,-4.400198164051586e16,-5.051762663082156e16,-4.456554705592129e16,-2.961652536463062e16,-1.4337322088783526e16,-4.770124322093573e15,-9.749871901895235e14,-9.227774153724008e13,0,0,0,0},{0,0,0.2,3564.768442556024,1.2164908134451648e6,1.1533096610258973e8,4.911578657437878e9,1.1646951484526044e11,1.7342546082017852e12,1.7484020896956271e13,1.2551336178335739e14,6.644159134672428e14,2.6578960250785765e15,8.171790366631361e15,1.9520413309070224e16,3.643312168795762e16,5.316310532259258e16,6.036333626184364e16,5.273684513072426e16,3.4747435047530596e16,1.6693177509884468e16,5.516045100269669e15,1.120515432952201e15,1.054602760425601e14,0,0,0},{0,0,0,-6.441397702780352,-11590.853392628731,-2.6527484863642906e6,-2.081436499095543e8,-7.921865093783669e9,-1.742928669332534e11,-2.459659492823631e12,-2.3815795421580676e13,-1.6566332438371656e14,-8.550505095885778e14,-3.35024333679381e15,-1.0123366574848608e16,-2.382922456508392e16,-4.391688037572645e16,-6.338437811869518e16,-7.128043872024897e16,-6.174789017813265e16,-4.037820760670786e16,-1.9267335122747188e16,-6.327906043885648e15,-1.2783495622996812e15,-1.1971166469696011e14,0,0},{0,0,0,-0.000693000693000693,21.292986207825482,25309.29515631317,4.780381324186655e6,3.3492374593636465e8,1.1823731636670485e10,2.4653622561126352e11,3.3416154029679727e12,3.135410116283323e13,2.126729757114602e14,1.0752440457778672e15,4.1409771925451395e15,1.233117595422076e16,2.8664288229529544e16,5.225580879389953e16,7.470388245200797e16,8.330526615716496e16,7.162566653980231e16,4.652411455487196e16,2.2066154752113164e16,7.207543889154556e15,1.4488180958196198e15,1.350593140170832e14,0}}}, {{{0,-0.26666666666666666,52.8,-5575520,-5.632173785675783e8,-2.264573851170883e10,-5.005643706894967e11,-6.997344021760841e12,-6.694984221034684e13,-4.609967645533807e14,-2.3627840501606355e15,-9.225264284921132e15,-2.7870762591869724e16,-6.579211913432579e16,-1.219269835005012e17,-1.7736434748785085e17,-2.014372433713144e17,-1.7653028386935773e17,-1.1695051216654723e17,-5.660662707425071e16,-1.887747613881895e16,-3.8756651445640835e15,-3.691109661489603e14,0,0,0,0},{0,0,-0.06666666666666667,106080.2,1.9949649623509426e7,1.2939911180306041e9,4.2363534986906364e10,8.295293999689657e11,1.0698737964202242e13,9.66363247645834e13,6.372094391758614e14,3.1574388239306565e15,1.1998128373402768e16,3.545022868007551e16,8.214242163461622e16,1.498448307438975e17,2.1504119173799283e17,2.413696663998524e17,2.0935359957837e17,1.3743658725905952e17,6.598443928517343e16,2.1845367673730504e16,4.455696662798164e15,4.218411041702404e14,0,0,0},{0,0,0,-799.6,-374795.69873168645,-4.541501586740491e7,-2.4033232898026366e9,-6.979280795787791e10,-1.2620648339616711e12,-1.5377051478454482e13,-1.3307719247169702e14,-8.486965787241058e14,-4.0942474686362435e15,-1.521973082413072e16,-4.415040755395909e16,-1.0071975616913048e17,-1.8128971785509302e17,-2.5715892674943798e17,-2.8571552176641878e17,-2.4559351140219373e17,-1.5993872560572854e17,-7.623776610305851e16,-2.5076921618640444e16,-5.084895471889925e15,-4.7884665878784044e14,0,0},{0,0,0,1,2803.746339877031,847540.594948172,8.387088415905303e7,3.940171303117425e9,1.057365813099728e11,1.8072133228725144e12,2.1105818071761484e13,1.7671976487014494e14,1.0975457428896409e15,5.180820146125421e15,1.8912018709994548e16,5.402178465503179e16,1.2161716004687645e17,2.1639908949667334e17,3.038797903142797e17,3.3462662569227334e17,2.853611054467527e17,1.845190954017643e17,8.739229013859099e16,2.857951555540064e16,5.764577084638233e15,5.402372560683328e14,0},{0,0,0,0,-3.499687304565353,-6314.674103265669,-1.5587237516807944e6,-1.3697283658064875e8,-5.948433133232432e9,-1.5092828425611444e11,-2.4733417883407153e12,-2.7953736163984633e13,-2.2798507703929834e14,-1.3857335293027922e15,-6.424397479638844e15,-2.30959575834661e16,-6.511275177576189e16,-1.4492407203283318e17,-2.5530540726016147e17,-3.553604828117912e17,-3.882498975703751e17,-3.287640702824053e17,-2.1123805647598467e17,-9.947298157155096e16,-3.2360331425024412e16,-6.496023591260685e15,-6.06119848271788e14}},{{0.5333333333333333,-105.13333333333334,20908.2,2.2492357135156598e7,1.8958309719109235e9,6.741542072724315e10,1.3467332712719966e12,1.721588784468186e13,1.517969171625762e14,9.68623788198903e14,4.620809634242403e15,1.6852457171265348e16,4.7703107096260296e16,1.0578958618367114e17,1.8461804798071936e17,2.5344496869855994e17,2.7218267219337744e17,2.2596420895370938e17,1.4205763700894958e17,6.535328208213089e16,2.074610040494806e16,4.0602206276385635e15,3.691109661489603e14,0,0,0,0},{0,0.13333333333333333,-159.53333333333333,-467299.4470188559,-7.287456290234995e7,-4.157830371714083e9,-1.2252070190736252e11,-2.186990850552188e12,-2.5926110989630664e13,-2.1653318849256094e14,-1.326322841173958e15,-6.127978836743251e15,-2.1781741790169716e16,-6.036681088296472e16,-1.3152785185627565e17,-2.2611628841057744e17,-3.06435432704922e17,-3.2542265994529766e17,-2.6752084016889734e17,-1.667276585666764e17,-7.611122760127998e16,-2.3994120798097664e16,-4.666617214883284e15,-4.218411041702404e14,0,0,0},{0,0,0.2,3991.1974633728914,1.5126843075902709e6,1.591637552639756e8,7.523047958345665e9,1.981274589389424e11,3.28062880467928e12,3.684945335931074e13,2.9550727863338325e14,1.753482804920874e15,7.897512890513422e15,2.748953095986418e16,7.486280786775282e16,1.6070534554507542e17,2.7277027276789126e17,3.6558244328737126e17,3.8447574794727104e17,3.133601408355606e17,1.9380644168944502e17,8.786770088566074e16,2.7529585606062684e16,5.324318801283845e15,4.7884665878784044e14,0,0},{0,0,0,-6.4926797540624035,-12985.995991128793,-3.298836226795991e6,-2.871680700153716e8,-1.2127517294150885e10,-2.9628375638388446e11,-4.648967460183313e12,-5.014705791678989e13,-3.896342464153759e14,-2.254104416220173e15,-9.943117755509682e15,-3.401307144070906e16,-9.127203209515408e16,-1.934632666986177e17,-3.247778760884149e17,-4.311079790213169e17,-4.495396895431404e17,-3.636200897900059e17,-2.2336772996888845e17,-1.0065183695567805e17,-3.1360509612206944e16,-6.034695712672399e15,-5.402372560683328e14,0},{0,0,0,-0.0006253908692933083,21.472659314327856,28363.229946619325,5.944698143021086e6,4.619832444694353e8,1.809376056308954e10,4.1886637559539825e11,6.31178461726564e12,6.596977935869714e13,4.997768062476191e14,2.8319808910505985e15,1.2277848441468622e16,4.138797722399096e16,1.0967212084846331e17,2.299374395484744e17,3.823298988047106e17,5.032265327743345e17,5.208059242745585e17,4.1843448110868006e17,2.5548313610900355e17,1.1449196659647726e17,3.5494695749103796e16,6.799083515396579e15,6.06119848271788e14}}} }; static const double ImEI[21][2][5][27] = { {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.03333333333333333,-0.06666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.3,-0.26666666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.5,2.1333333333333333,1.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-1.8333333333333333,-6.133333333333334,-4.266666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-0.03333333333333333,4.2,12.8,8.533333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.06666666666666667,0.06666666666666667,0.06666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.1,0.43333333333333335,0.26666666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-1.2666666666666666,-2.933333333333333,-1.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.16666666666666666,4.1,8.266666666666667,4.266666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.06666666666666667,-0.4666666666666667,-9,-17.066666666666666,-8.533333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.06666666666666667,1.0666666666666667,1.0666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-2.6,-9.066666666666666,-6.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,1,11.6,27.733333333333334,17.066666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-3.533333333333333,-29.066666666666666,-59.733333333333334,-34.13333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.009523809523809525,8,56.68571428571428,107.27619047619048,58.51428571428571,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.13333333333333333,-0.26666666666666666,-1.6,-1.0666666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.2,5.933333333333334,12.266666666666667,6.4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-3.2,-22.266666666666666,-36.266666666666666,-17.066666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.06666666666666667,10.066666666666666,52.53333333333333,76.8,34.13333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.01904761904761905,-0.26666666666666666,-21.714285714285715,-99.35238095238095,-136.53333333333333,-58.51428571428571,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.1,12.6,38.4,25.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-8.9,-64.26666666666667,-123.73333333333333,-68.26666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,1.5,35.2,170.13333333333333,273.06666666666666,136.53333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-5.271428571428571,-84,-341.9428571428571,-497.37142857142857,-234.05714285714285,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.0015873015873015873,11.88888888888889,159.4920634920635,589.6126984126984,806.1968253968254,364.0888888888889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.2,-1.4,-27,-51.2,-25.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.3,24.233333333333334,113.33333333333333,157.86666666666667,68.26666666666667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-5.4,-81.86666666666666,-281.06666666666666,-341.3333333333333,-136.53333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.04285714285714286,17.1,183.65714285714284,546.7428571428571,614.4,234.05714285714285,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.0031746031746031746,-0.15555555555555556,-36.93015873015873,-337.26984126984127,-924.4444444444445,-988.2412698412699,-364.0888888888889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.13333333333333333,59.733333333333334,332.8,546.1333333333333,273.06666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-21.2,-260.26666666666665,-921.6,-1228.8,-546.1333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,2,79.88571428571429,648.5333333333333,1896.8380952380953,2262.552380952381,936.2285714285714,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-7.015873015873016,-186.48888888888888,-1262.120634920635,-3319.0603174603175,-3692.9015873015874,-1456.3555555555556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.0005772005772005772,15.806060606060607,349.617316017316,2133.1116883116883,5241.461471861472,5560.630303030303,2118.3353535353535,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.26666666666666666,-3.7333333333333334,-149.33333333333334,-554.6666666666666,-682.6666666666666,-273.06666666666666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.4,64.13333333333334,541.8666666666667,1433.6,1501.8666666666666,546.1333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-7.771428571428571,-209.86666666666667,-1260.4952380952382,-2852.5714285714284,-2730.6666666666665,-936.2285714285714,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.031746031746031744,24.755555555555556,462.5015873015873,2365.765079365079,4892.444444444444,4421.079365079365,1456.3555555555556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.0011544011544011544,-0.11313131313131314,-53.58268398268398,-839.8961038961039,-3909.818181818182,-7624.588744588745,-6619.79797979798,-2118.3353535353535,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.16666666666666666,191.66666666666666,1668.2666666666667,4753.066666666667,5461.333333333333,2184.5333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-41.5,-775.8095238095239,-4313.6,-9976.685714285713,-10142.47619047619,-3744.9142857142856,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,2.5,152.63492063492063,1872.888888888889,8569.092063492064,17664.812698412698,16644.06349206349,5825.422222222222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-8.762626262626263,-352.2020202020202,-3580.7676767676767,-14673.19595959596,-28117.59191919192,-25155.23232323232,-8473.341414141414,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.0002775002775002775,19.731934731934732,655.7495837495837,5983.52047952048,22836.666267066266,41605.430303030305,35848.75213675214,11732.318881118881,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.3333333333333333,-7.666666666666667,-528.2,-3225.6,-7074.133333333333,-6553.6,-2184.5333333333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.5,135.11904761904762,1809.8666666666666,7751.314285714286,14345.752380952381,12014.933333333332,3744.9142857142856,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-10.26984126984127,-436.8888888888889,-4089.930158730159,-14826.869841269841,-24894.577777777777,-19556.774603174603,-5825.422222222222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.025252525252525252,32.86363636363637,955.6767676767677,7544.371717171717,24809.761616161617,39106.45656565657,29391.90303030303,8473.341414141414,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.000555000555000555,-0.08935508935508936,-71.26440226440226,-1727.040959040959,-12325.773426573427,-38017.645288045285,-57329.99658119658,-41714.91157731158,-11732.318881118881,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.2,489.6,6106.971428571429,26214.4,50556.34285714286,44938.97142857143,14979.657142857142,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-71.8,-1901.8920634920635,-15197.155555555555,-53000.93968253968,-90398.06984126984,-74066.08253968254,-23301.68888888889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,3,260.43463203463205,4506.052525252525,29564.416738816737,91759.85685425685,144822.26608946608,112271.77373737373,33893.36565656566,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-10.51048951048951,-596.8428904428904,-8522.413053613054,-49961.41351981352,-143888.94731934732,-215275.8303030303,-160341.69137529138,-46929.275524475524,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.0001554001554001554,23.661849261849262,1106.6579642579643,14141.066045066045,77056.03978243978,210652.15602175603,303084.9044289044,219003.28578088578,62572.367365967366,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.4,-13.6,-1447.5428571428572,-13136,-44470.857142857145,-70217.14285714286,-52428.8,-14979.657142857142,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.6,247.18412698412698,4825.422222222222,30428.749206349206,86497.11746031746,123062.04444444444,85716.92698412699,23301.68888888889,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-12.86926406926407,-795.3656565656565,-10742.07215007215,-56978.655122655124,-146297.53535353535,-194603.1468975469,-129218.45656565657,-33893.36565656566,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.02097902097902098,41.329137529137526,1733.909557109557,19631.14219114219,94030.1724941725,225862.41491841493,286647.4368298368,183806.32913752913,46929.275524475524,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.0003108003108003108,-0.07397047397047397,-89.75540015540015,-3126.114063714064,-31870.1898989899,-142693.88282828283,-326997.6515928516,-400854.2284382284,-250289.46946386946,-62572.367365967366,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.23333333333333334,1074.7333333333333,18153.244444444445,108464.35555555555,307655.1111111111,449285.68888888886,326223.64444444445,93206.75555555556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-114.1,-4069.7131313131313,-44104.92121212121,-214282.8606060606,-537693.0909090909,-723676.3151515152,-495690.4727272727,-135573.46262626263,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,3.5,410.27630147630146,9526.587723387724,84649.39362859362,365700.5550893551,848556.257964258,1.0798214464646464e6,709153.4968142968,187717.1020979021,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-12.25897435897436,-936.1311577311577,-17890.690287490288,-141813.89526029525,-567884.4618492619,-1.2480050523698523e6,-1.524549659052059e6,-969871.6941724942,-250289.46946386946,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.0000959824489236254,27.593994241053064,1731.1486631016044,29547.359934183463,217402.40296174414,825519.0614561909,1.7431695357191828e6,2.0641979866721514e6,1.280893167256273e6,323904.019306184,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.4666666666666667,-21.933333333333334,-3355.6222222222223,-42348.08888888889,-203582.57777777777,-479869.15555555554,-594921.2444444444,-372827.02222222224,-93206.75555555556,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.7,410.7262626262626,11022.440404040404,96074.47272727273,386563.103030303,819299.296969697,946101.5272727272,563477.2040404041,135573.46262626263,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-15.552602952602953,-1319.1589743589743,-24329.85236985237,-177655.00916860916,-643821.182905983,-1.273099178865579e6,-1.3992012382284382e6,-803012.0478632479,-187717.1020979021,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.017948717948717947,50.09052059052059,2871.1639471639473,44222.36891996892,290731.34296814294,983393.9045843045,1.851893577000777e6,1.9625562306138305e6,1.0950164289044288e6,250289.46946386946,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.0001919648978472508,-0.06315645139174551,-108.91493212669683,-5170.4839160839165,-71524.53607568901,-438562.81431509665,-1.4125950964486494e6,-2.565467062004662e6,-2.6439125666803783e6,-1.4428451769093652e6,-323904.019306184,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.26666666666666666,2116.266666666667,46478.36998556999,367133.99595959595,1.4218853217893217e6,3.00440476998557e6,3.5321728923520925e6,2.169175402020202e6,542293.8505050505,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-170.4,-7878.639405039405,-111119.03776223776,-714162.356043956,-2.447790332334332e6,-4.76751157962038e6,-5.287365042424242e6,-3.1077609125097124e6,-750868.4083916084,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,4,609.1538683538683,18291.647552447554,211297.13166833165,1.2068968343656345e6,3.8238280972360973e6,7.039391328671329e6,7.482612264180264e6,4.254920980885781e6,1.0011578778554779e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-14.007843137254902,-1385.7954019836372,-34183.56217377394,-351855.81673751085,-1.8614895882261528e6,-5.582810520261438e6,-9.861435769605558e6,-1.0149606059509119e7,-5.624151607952831e6,-1.295616077224736e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.0000635071842502183,31.527506549178376,2558.0482279330577,56272.57883911754,537113.6969927904,2.6926125869276235e6,7.7549386769432835e6,1.3272122169070559e7,1.3318034401472213e7,7.228173904516948e6,1.6365676764944035e6,0,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.5333333333333333,-33.06666666666667,-6906.606637806638,-115649.93939393939,-746992.1893217893,-2.4357735803751806e6,-4.414610876767676e6,-4.515080496392496e6,-2.440322327272727e6,-542293.8505050505,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.8,636.47881007881,22496.094483294484,259039.60572760573,1.3972491252747253e6,4.090821281118881e6,6.898882843023643e6,6.700457672105672e6,3.483195116705517e6,750868.4083916084,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-18.30773670773671,-2043.3143745143745,-49402.28837828838,-475220.8388944389,-2.3042702023310023e6,-6.28517082917083e6,-1.0076758327894328e7,-9.422355652525252e6,-4.75549991981352e6,-1.0011578778554779e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.01568627450980392,59.10452945747063,4444.078065725124,89495.53131313132,773530.6577448695,3.495176651510581e6,9.067520102966314e6,1.400317438010878e7,1.2718753849005897e7,6.2719596465652e6,1.295616077224736e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.0001270143685004366,-0.05512423592918949,-128.64458637337896,-7998.43481348373,-144411.5393015653,-1.162342659386434e6,-4.9947002896331735e6,-1.2482808925253488e7,-1.8729284982381087e7,-1.6625264914387986e7,-8.04645774276415e6,-1.6365676764944035e6,0,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.3,3839.4,106318.05314685314,1.0702797874125873e6,5.392764956643357e6,1.5350685180419581e7,2.580816845874126e7,2.539460421818182e7,1.3515631351048952e7,3.0034736335664336e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-242.7,-14124.181152181152,-251299.74452214452,-2.0592303781551782e6,-9.185474911222111e6,-2.4106659233033635e7,-3.8236604926806524e7,-3.601039741911422e7,-1.852142074032634e7,-4.0046315114219114e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,4.5,864.0628077804548,32599.88898944193,474679.1184031655,3.455516380591957e6,1.4245058289412549e7,3.533020329192376e7,5.370181410996846e7,4.892054909771013e7,2.449892218752228e7,5.182464308898944e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-15.756965944272446,-1961.5696724328304,-60708.62697178982,-786988.0535711966,-5.303549502574206e6,-2.0688066335863516e7,-4.921807658793219e7,-7.241782910112797e7,-6.427015135233064e7,-3.1503927772517268e7,-6.546270705977614e6,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.00004422821760283061,35.461919504643966,3616.1956285200868,99702.79558212686,1.1976321362253844e6,7.643730469367165e6,2.8621924200018764e7,6.595342171821161e7,9.458539786739412e7,8.219612447821817e7,3.9589351412340805e7,8.104906588353236e6,0,0,0,0,0,0,0,0,0,0,0,0}},{{0.6,-47.4,-13003.506293706294,-278936.1678321678,-2.3265602237762236e6,-9.980674506293707e6,-2.4597585633566435e7,-3.625286534265734e7,-3.158926858741259e7,-1.5017368167832168e7,-3.0034736335664336e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0.9,935.4623043623044,42143.00606060606,619613.8922410923,4.308818503096903e6,1.6579424074592074e7,3.799234747545788e7,5.314447145174825e7,4.452023938088578e7,2.0523736496037297e7,4.0046315114219114e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-21.12561556090968,-3003.887892499657,-92251.03664962489,-1.130768793872794e6,-7.0588418527355e6,-2.5277949085518405e7,-5.502439582942548e7,-7.405439677762237e7,-6.019829813355272e7,-2.7090154341971755e7,-5.182464308898944e6,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.01393188854489164,68.33903526813744,6531.570529779818,166762.43296022862,1.8339761297278572e6,1.0656330035982594e7,3.6261947787464544e7,7.597502823061767e7,9.92596311986317e7,7.879468948121847e7,3.477706312550607e7,6.546270705977614e6,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.00008845643520566122,-0.04891640866873065,-148.871487026905,-11752.440015711842,-268684.86844919785,-2.74861261174986e6,-1.5174070609897017e7,-4.97030496228197e7,-1.0110656940201923e8,-1.2902029170934741e8,-1.0047113019907235e8,-4.364180470651743e7,-8.104906588353236e6,0,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.3333333333333333,6533.333333333333,222654.46091686093,2.778624556954157e6,1.7600566104118105e7,6.443886523574203e7,1.4451080095726496e8,2.0156645274156955e8,1.7053055852804974e8,8.009263022843823e7,1.6018526045687646e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-333,-23825.97413044472,-521880.007239819,-5.303014873879062e6,-2.974522501247772e7,-1.0042604004409708e8,-2.1250665797888386e8,-2.837202903655926e8,-2.319741694631016e8,-1.0600495177293295e8,-2.0729857235595778e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,5,1181.999610984131,54754.40911616763,980895.6130251585,8.852088141103067e6,4.5880486491885826e7,1.4637328059863028e8,2.967933223074854e8,3.832574936190464e8,3.0507729190651166e8,1.3638063970786697e8,2.6185082823910456e7,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-17.506265664160402,-2679.1916209005994,-101698.47428388605,-1.6209314727333898e6,-1.3536137961823797e7,-6.6368244028934255e7,-2.0306241420633388e8,-3.984997390155933e8,-5.012577425662849e8,-3.9049673738068247e8,-1.7144994706131846e8,-3.2419626353412945e7,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.000032049433045529426,39.39695786781532,4934.437997592661,166727.4017375813,2.460969788432378e6,1.945561056293358e7,9.154241300341979e7,2.712219032798776e8,5.1868580194167066e8,6.387408437835916e8,4.888559794904897e8,2.114323457831279e8,3.946737121285054e7,0,0,0,0,0,0,0,0,0,0,0}},{{0.6666666666666666,-65.33333333333333,-22842.255167055166,-610794.4205128205,-6.384583827195027e6,-3.4760849444599845e7,-1.1109825668873349e8,-2.199600400907537e8,-2.733161006545454e8,-2.075734000087024e8,-8.810189325128205e7,-1.6018526045687646e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1,1318.9482608894373,73805.46920791626,1.3491923253530783e6,1.1743463056410257e7,5.730339427900727e7,1.7019760844996572e8,3.196860685490927e8,3.8177487075555557e8,2.810897971178939e8,1.1636988039073084e8,2.0729857235595778e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-23.999221968262216,-4237.817551557489,-161226.06704008067,-2.4533664806920635e6,-1.9149318022051428e7,-8.689604748579635e7,-2.450198244808148e8,-4.4258655082519025e8,-5.1267962114181876e8,-3.683579087309619e8,-1.4947318111982217e8,-2.6185082823910456e7,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.012531328320802004,77.76920671347916,9214.54894194213,291039.0946701733,3.9691610755076366e6,2.8811933867454045e7,1.2415265791155085e8,3.367590805724054e8,5.902267861563345e8,6.673985861532614e8,4.701430309700768e8,1.8765976023802492e8,3.2419626353412945e7,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.00006409886609105885,-0.04397182213846637,-169.53941844936594,-16578.624554339185,-468446.0812958478,-5.9377916416310035e6,-4.0923115567559e7,-1.696412196057358e8,-4.465302941617743e8,-7.640784094103152e8,-8.472253347457047e8,-5.871720202796443e8,-2.3116603138955316e8,-3.946737121285054e7,0,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.36666666666666664,10559.266666666666,434294.7652086476,6.574489355455003e6,5.10204267471091e7,2.3250794534097537e8,6.64917593632177e8,1.2277649331804926e9,1.4624266471674209e9,1.0850784646757164e9,4.560568591831071e8,8.291942894238311e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-443.3,-38255.76555264481,-1.0114779064221641e6,-1.2470381821703581e7,-8.571332767814559e7,-3.6026736682270384e8,-9.722698334254823e8,-1.7186034725420127e9,-1.9784568926620624e9,-1.4283144396604905e9,-5.869822733026594e8,-1.0474033129564182e8,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,5.5,1569.961476844449,87625.69572649573,1.8939060047826958e6,2.0732385792547733e7,1.3166046654165429e8,5.228893340210738e8,1.352134487330338e9,2.311593394202756e9,2.5906866318906407e9,1.8295657646295648e9,7.381699538930948e8,1.2967850541365178e8,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-19.255693581780537,-3554.4014008396293,-162426.07358635293,-3.1217844988459083e6,-3.16126055748029e7,-1.8987086397373933e8,-7.230764038384147e8,-1.809469262049569e9,-3.0129885415469217e9,-3.304452922123214e9,-2.2917775413786182e9,-9.105686358393375e8,-1.5786948485140216e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.00002397297591805601,43.33244851258581,6541.62812737135,265926.5903814425,4.731094982759278e6,4.5340842546994835e7,2.612763288477679e8,9.633487135585018e8,2.348932232111619e9,3.828700312931434e9,4.124825501869743e9,2.8177588722517457e9,1.105086393959815e9,1.894433818216826e8,0,0,0,0,0,0,0,0,0,0}},{{0.7333333333333333,-87.26666666666667,-37956.79708396179,-1.2378745500251383e6,-1.5839376732026143e7,-1.06514876608547e8,-4.268125048599296e8,-1.084457648638713e9,-1.7937872069180493e9,-1.927228914871795e9,-1.297559501340573e9,-4.9751657365429866e8,-8.291942894238311e7,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1.1,1798.4311052896192,122419.20256145643,2.723675026625387e6,2.8991573532491863e7,1.7462463657162815e8,6.49987059367659e8,1.5663069635696964e9,2.4893757054309864e9,2.5923743423070254e9,1.7021667641938875e9,6.393524389504802e8,1.0474033129564182e8,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-26.922953688897962,-5782.824037469239,-267059.29319830495,-4.940120546192026e6,-4.71164384933979e7,-2.6376188135589048e8,-9.316258847784076e8,-2.1581550271623797e9,-3.3260680887754226e9,-3.3792200077329974e9,-2.1743360218110523e9,-8.030092065999206e8,-1.2967850541365178e8,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.011387163561076604,87.37526544737474,12575.685027901907,481630.25459747476,7.978130346470807e6,7.071870426544951e7,3.7573583030587316e8,1.2761080113371363e9,2.867315117761134e9,4.312316120466565e9,4.2944103377974663e9,2.717461330888649e9,9.895033782650386e8,1.5786948485140216e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,-0.00004794595183611202,-0.039938977879481315,-190.60366239225843,-22626.351358782555,-774685.3323404123,-1.1919507515836926e7,-1.0026023448105781e8,-5.122220252548393e8,-1.6875254790953407e9,-3.7006690484617324e9,-5.456117441460743e9,-5.344261556173933e9,-3.3347814351400876e9,-1.1998080848706565e9,-1.894433818216826e8,0,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.4,16358.4,798958.1317110135,1.4416265779644504e7,1.3432181467691442e8,7.434303361587911e8,2.626393853597904e9,6.143042747321345e9,9.628736625974842e9,1.0003891869771244e10,6.609352950962489e9,2.5137679510954037e9,4.189613251825673e8,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-575.6,-58965.4028822227,-1.851578588510492e6,-2.721337278865888e7,-2.246109735140044e8,-1.1467505597679276e9,-3.823590344956376e9,-8.562024604039784e9,-1.2971313192672047e10,-1.3113370455110611e10,-8.471497747887982e9,-3.1621604781636624e9,-5.187140216546071e8,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,6,2034.9461170318891,134714.58794018233,3.456620690885645e6,4.5099821439376034e7,3.4389086889063436e8,1.6588888433384745e9,5.299781267706849e9,1.1477806342984741e10,1.6928250138062456e10,1.6740562578044119e10,1.0617264990476751e10,3.9016315541846533e9,6.314779394056087e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,-21.00521739130435,-4602.940974829003,-249320.1853983052,-5.686343886484196e6,-6.861345311881912e7,-4.947368541065237e8,-2.288195708861567e9,-7.073833639317552e9,-1.4920448268974035e10,-2.1533210358591484e10,-2.091140714317489e10,-1.3059753134332243e10,-4.736084545542065e9,-7.577735272867304e8,0,0,0,0,0,0,0,0,0,0},{0,0,0,0.00001840349666436623,47.2682769726248,8466.622898449223,407758.88048708765,8.605464337728756e6,9.82448816901423e7,6.795288568188525e8,3.042463166214668e9,9.163485366790909e9,1.8918381774570183e10,2.681818912368284e10,2.565065895730421e10,1.5811505960561546e10,5.669268611552575e9,8.981019582657546e8,0,0,0,0,0,0,0,0,0}},{{0.8,-113.6,-60265.06342202689,-2.354631489783282e6,-3.6188869743358806e7,-2.9423519790246165e8,-1.4410252993176384e9,-4.548903494657308e9,-9.579486167460339e9,-1.3604387251458832e10,-1.2876514478657967e10,-7.78768167803846e9,-2.7232486136866875e9,-4.189613251825673e8,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1.2,2385.605764445393,194164.23206487356,5.166394900690916e6,6.6000166193341576e7,4.804116328378407e8,2.1848240357089143e9,6.539431397703931e9,1.3229596648755936e10,1.8207931242597847e10,1.6804843678929035e10,9.955319107909575e9,3.4215174889909663e9,5.187140216546071e8,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-29.892234063778012,-7677.3315851704865,-423195.2594681369,-9.353395630081888e6,-1.069960803506276e8,-7.235025322877827e8,-3.121175266299493e9,-8.978155548848114e9,-1.7608717027453564e10,-2.363934658860129e10,-2.1376840213692146e10,-1.2449678653930527e10,-4.217370523887458e9,-6.314779394056087e8,0,0,0,0,0,0,0,0,0,0,0},{0,0,0.010434782608695653,97.14108009278826,16699.23576343072,762726.8199599064,1.5085840946795626e7,1.603035047267927e8,1.0283599406244267e9,4.2643450431212244e9,1.1894505365747297e10,2.2759909848626797e10,2.9943147410467827e10,2.6624309126235004e10,1.5285712870737015e10,5.114971309185431e9,7.577735272867304e8,0,0,0,0,0,0,0,0,0,0},{0,0,-0.00003680699332873246,-0.03658615136876006,-212.02777987521023,-30047.89230250005,-1.2262431435256745e6,-2.251696238611375e7,-2.2695429228591478e8,-1.3994804759815316e9,-5.627673799689461e9,-1.5316193575786037e10,-2.8723952643539726e10,-3.7161678742566864e10,-3.257762113150629e10,-1.8477746149163006e10,-6.118319590685452e9,-8.981019582657546e8,0,0,0,0,0,0,0,0,0}}}, {{{0,-0.43333333333333335,24459.933333333334,1.39948310974227e6,2.9664356557875972e7,3.264766937613553e8,2.1527966210326242e9,9.174872352635342e9,2.63526819412877e10,5.20431450209414e10,7.080795804555496e10,6.521613086318431e10,3.8830607464800354e10,1.3486564563019785e10,2.0748560866184285e9,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,-731.9,-87814.82467992813,-3.230537622359549e6,-5.578284651915676e7,-5.439079051073674e8,-3.308797228275689e9,-1.3310466229841167e10,-3.660457080636495e10,-6.987539486462099e10,-9.251142702281056e10,-8.331826353464978e10,-4.868864058693869e10,-1.6643954260047829e10,-2.5259117576224346e9,0,0,0,0,0,0,0,0,0,0,0},{0,0,6.5,2583.9516267845465,200215.24405318496,6.016616118581815e6,9.221263263214113e7,8.305750837148908e8,4.77383576908197e9,1.840021088352963e10,4.8939353849036934e10,9.094760672013042e10,1.177844008258246e11,1.0414198859975996e11,5.991259714028463e10,2.0207294060979477e10,3.0310941091469216e9,0,0,0,0,0,0,0,0,0,0},{0,0,0,-22.754814814814814,-5840.553656708876,-370080.7888040544,-9.881938796070835e6,-1.4003615801375034e8,-1.1925823709998772e9,-6.57143044116013e9,-2.4508050681444206e10,-6.348184946356478e10,-1.1543549489334048e11,-1.468037932397025e11,-1.27811573462042e11,-7.256032344847891e10,-2.4192621500783764e10,-3.5924078330630183e9,0,0,0,0,0,0,0,0,0},{0,0,0,0.00001443722583152868,51.20436448442445,10738.282242670764,604748.6713855794,1.493782547301189e7,2.0024139920202476e8,1.6355739069693673e9,8.723538381973366e9,3.1694134443060642e10,8.035017116564796e10,1.435061488294865e11,1.797385196878227e11,1.544460759994406e11,8.668740434615086e10,2.861538653232956e10,4.211788493935952e9,0,0,0,0,0,0,0,0}},{{0.8666666666666667,-144.73333333333332,-92115.75281787357,-4.24804535780092e6,-7.720394235745513e7,-7.459561839697425e8,-4.37688462512671e9,-1.675264548351156e10,-4.352291071881835e10,-7.819993218306961e10,-9.728719442636674e10,-8.229722149813876e10,-4.518485423006929e10,-1.4523992606328999e10,-2.0748560866184285e9,0,0,0,0,0,0,0,0,0,0,0,0},{0,1.3,3092.3493598562786,296618.58790897264,9.301895812628992e6,1.4042234137451884e8,1.2141829505065637e9,6.6136711412013e9,2.3997256897036137e10,5.988243978747334e10,1.0425835625270293e11,1.2646490694806935e11,1.0477864663163727e11,5.65370092624084e10,1.7906910138859047e10,2.5259117576224346e9,0,0,0,0,0,0,0,0,0,0,0},{0,0,-32.90325356909285,-9960.403453242889,-646128.1687916917,-1.6817577993811376e7,-2.272190859950398e8,-1.8244572021268456e9,-9.424164410318285e9,-3.2855536243018745e10,-7.94693874291209e10,-1.3493911256397678e11,-1.6035193404744455e11,-1.3059358460620116e11,-6.944791402530933e10,-2.1722841115552937e10,-3.0310941091469216e9,0,0,0,0,0,0,0,0,0,0},{0,0,0.00962962962962963,107.05323934367682,21670.89761846037,1.1640149545323383e6,2.7098524121223144e7,3.3995615473259085e8,2.5888012200866394e9,1.2850503978831438e10,4.34323908124913e10,1.0247227787993118e11,1.704876950572971e11,1.9917787189184882e11,1.5989240688923416e11,8.398305773017148e10,2.5988825417315273e10,3.5924078330630183e9,0,0,0,0,0,0,0,0,0},{0,0,-0.00002887445166305736,-0.033754233994114057,-233.78149683578326,-38998.16031069183,-1.8707910950575937e6,-4.041802774693853e7,-4.8079742512005436e8,-3.518362643932259e9,-1.6932117246290905e10,-5.582666431497299e10,-1.2906973332811464e11,-2.1113776786988696e11,-2.4316208621413403e11,-1.9281924836901074e11,-1.0020538726970265e11,-3.0721280779297535e10,-4.211788493935952e9,0,0,0,0,0,0,0,0}}}, {{{0,-0.4666666666666667,35489.066666666666,2.3512673864932396e6,5.783459782554564e7,7.417629589224231e8,5.737794526335927e9,2.8958539764775536e10,9.980418605461873e10,2.4087583664136777e11,4.1111360367982263e11,4.938686168666484e11,4.0842050111710443e11,2.2130873014861176e11,7.072552921342816e10,1.0103647030489738e10,0,0,0,0,0,0,0,0,0,0,0},{0,0,-914.2,-127000.05298477177,-5.410357632421346e6,-1.084187847239819e8,-1.2320553672292948e9,-8.793144231643013e9,-4.189268519105384e10,-1.3824796054280862e11,-3.2253689193271765e11,-5.3569991047103217e11,-6.2930263262471e11,-5.107830750947536e11,-2.7241958305957956e11,-8.588099975916278e10,-1.2124376436587687e10,0,0,0,0,0,0,0,0,0,0},{0,0,7,3223.9763957964633,289078.1147930231,1.0056934701494202e7,1.7885319900918955e8,1.8774039305941489e9,1.2659112178824976e10,5.778636226399293e10,1.8443310408086594e11,4.188943611564575e11,6.80570218646967e11,7.848818851678533e11,6.271698565745526e11,3.30024403976469e11,1.028326742214289e11,1.4369631332252073e10,0,0,0,0,0,0,0,0,0},{0,0,0,-24.504469987228607,-7282.983796526446,-533794.5211804865,-1.6496528391199792e7,-2.7121016480072916e8,-2.69139348470133e9,-1.7396960801336163e10,-7.683642125146432e10,-2.388197884303981e11,-5.3073846409068134e11,-8.467207746541761e11,-9.615174725410426e11,-7.581688663491782e11,-3.943770868588842e11,-1.2164636179544427e11,-1.6847153975743809e10,0,0,0,0,0,0,0,0},{0,0,0,0.000011535450912536563,55.140655048819674,13385.468430331828,871673.8196526119,2.4913415664470177e7,3.873820740702931e8,3.686591045638684e9,2.3063912016993534e10,9.92281083489501e10,3.018436477318775e11,6.588209340059844e11,1.0351031513181844e12,1.160082623098246e12,9.043453403023804e11,4.6572230892101843e11,1.4238562392402832e11,1.9564436875057327e10,0,0,0,0,0,0,0}},{{0.9333333333333333,-181.06666666666666,-136335.83965314535,-7.327933577454448e6,-1.5542659822206742e8,-1.7593665355350988e9,-1.2169475752962036e10,-5.541107203717101e10,-1.734553628583209e11,-3.823252362645737e11,-5.987312993848872e11,-6.626663891105165e11,-5.067610463730009e11,-2.5477706093710904e11,-7.577735272867303e10,-1.0103647030489738e10,0,0,0,0,0,0,0,0,0,0,0},{0,1.4,3930.705969543536,438914.5575660432,1.6021909399733834e7,2.821148285309416e8,2.8568306121554456e9,1.834034705520107e10,7.915174003764148e10,2.3795742789826575e11,5.0818633097929156e11,7.758814204731168e11,8.410097103451432e11,6.320268394606305e11,3.130867623573008e11,9.194318797745662e10,1.2124376436587687e10,0,0,0,0,0,0,0,0,0,0},{0,0,-35.952791592926204,-12671.688278689997,-955744.668589088,-2.8937820175670214e7,-4.558361881243446e8,-4.2852364908962717e9,-2.6082358434683636e10,-1.0813493285251514e11,-3.150596210807534e11,-6.56127990059077e11,-9.812778081103854e11,-1.045448978125867e12,-7.742480850836678e11,-3.7874643521238617e11,-1.1001748988755493e11,-1.4369631332252073e10,0,0,0,0,0,0,0,0,0},{0,0,0.008939974457215836,117.10041553054182,27577.685460833156,1.7212957303475374e6,4.6594371675881036e7,6.812809157261431e8,6.07243220002907e9,3.551011349027069e10,1.4269874524439893e11,4.054913031711275e11,8.273111760165848e11,1.2162825061370105e12,1.2771474457642676e12,9.341281376272004e11,4.520414263861544e11,1.3006993878331618e11,1.6847153975743809e10,0,0,0,0,0,0,0,0},{0,0,-0.000023070901825073126,-0.031330284678449304,-255.83925591764077,-49634.48688799174,-2.765829691982738e6,-6.945891513716699e7,-9.627476140344408e8,-8.244250951607839e9,-4.673088800021546e10,-1.8316187642444714e11,-5.0994384612902716e11,-1.022841420534557e12,-1.4821974712563923e12,-1.5372206353757112e12,-1.112343356234171e12,-5.3324678896895935e11,-1.5216784236155698e11,-1.9564436875057327e10,0,0,0,0,0,0,0}}}, {{{0,-0.5,50175,3.8110518751832955e6,1.076462696229007e8,1.5907243629794188e9,1.4251013900556408e10,8.39147841034878e10,3.408264309321651e11,9.827003704330287e11,2.041566817044961e12,3.065320744754241e12,3.2952209252682485e12,2.4722631961132183e12,1.2290545345785562e12,3.6373129309763055e11,4.8497505746350746e10,0,0,0,0,0,0,0,0,0,0},{0,0,-1124.5,-179081.18687280125,-8.746490101655236e6,-2.0128246173478386e8,-2.6356156253879805e9,-2.1787106957386932e10,-1.2111135286756642e11,-4.7103679933522406e11,-1.312930805324278e12,-2.654465838545084e12,-3.897567876302638e12,-4.1124050502739814e12,-3.036874638157322e12,-1.489333703666579e12,-4.355794497588909e11,-5.747852532900829e10,0,0,0,0,0,0,0,0,0},{0,0,7.5,3962.019044757294,407072.920718967,1.6232431369128535e7,3.3147987895103717e8,4.0090734366763234e9,3.13099625273733e10,1.6676035684980087e11,6.272725393185522e11,1.702120269314377e12,3.366309892830835e12,4.852504880352651e12,5.040497006172991e12,3.6725169792886714e12,1.7801426017692478e12,5.153247098462812e11,6.7388615902975235e10,0,0,0,0,0,0,0,0},{0,0,0,-26.25417130144605,-8945.976556539295,-751050.1272782461,-2.6597813264939196e7,-5.0203783424558866e8,-5.739732894683955e9,-4.2968855344066925e10,-2.214204398894586e11,-8.110701607930319e11,-2.1534160242155322e12,-4.1819214920925874e12,-5.935635976892781e12,-6.084107901642862e12,-4.381942913426506e12,-2.1025895514418992e12,-6.03236803647601e11,-7.825774750022931e10,0,0,0,0,0,0,0},{0,0,0,9.363190675760198e-6,59.07710774785302,16437.045563842872,1.2257532331766458e6,4.013768184797409e7,7.164271778242302e8,7.854094148649289e9,5.6903267984881676e10,2.856175070922272e11,1.0238847552212717e12,2.6698130647352876e12,5.105908405067799e12,7.152238271875518e12,7.247671528966757e12,5.167805995087918e12,2.457745328571359e12,6.99576833714171e11,9.011498196996101e10,0,0,0,0,0,0}},{{1,-223,-196278.75036659127,-1.2163480027372148e7,-2.9773689168561506e8,-3.901236201224221e9,-3.1389389329419144e10,-1.6743088681163474e11,-6.199947751483894e11,-1.6382802519391409e12,-3.132920728260574e12,-4.3465612386153613e12,-4.3323760798965054e12,-3.0231374871104106e12,-1.4018268987999307e12,-3.8798004597080597e11,-4.8497505746350746e10,0,0,0,0,0,0,0,0,0,0},{0,1.5,4912.873745602497,631897.2803378738,2.656490166119503e7,5.395585963900452e8,6.322823026301706e9,4.720796893278593e10,2.3863565691698135e11,8.485721474191187e11,2.172352790028894e12,4.049809894234472e12,5.50235200650019e12,5.38931258216232e12,3.7052589549104136e12,1.6963462050468354e12,4.643187124233951e11,5.747852532900829e10,0,0,0,0,0,0,0,0,0},{0,0,-39.038089514588414,-15851.374766259272,-1.3756719102298168e6,-4.7943245278919205e7,-8.708307769571735e8,-9.47113944257027e9,-6.703028125916526e10,-3.254547834230943e11,-1.1214448357099817e12,-2.7992820802386875e12,-5.111448386239666e12,-6.825434396193574e12,-6.587638039199097e12,-4.472282579818021e12,-2.0251695912105806e12,-5.4901901779776886e11,-6.7388615902975235e10,0,0,0,0,0,0,0,0},{0,0,0.008342602892102336,127.27291285612064,34507.8303268765,2.4771144537147037e6,7.715353799846987e7,1.3004413372683635e9,1.3407053636109262e10,9.11467268081413e10,4.288886516771684e11,1.4411578341601123e12,3.5239100414919814e12,6.3247528225204e12,8.32319236966487e12,7.933155759027074e12,5.327467452291677e12,2.3895346256094067e12,6.423656773977156e11,7.825774750022931e10,0,0,0,0,0,0,0},{0,0,-0.000018726381351520396,-0.029231881289723337,-278.179190366686,-62116.434369362025,-3.979701958366857e6,-1.1496637205380797e8,-1.8365386839217353e9,-1.8187049742974773e10,-1.198292372617549e11,-5.49880612073813e11,-1.810124500260231e12,-4.3508491817515527e12,-7.696337232599344e12,-1.000270962164139e13,-9.431448443943848e12,-6.273956282611874e12,-2.7906371863090767e12,-7.446343246991516e11,-9.011498196996101e10,0,0,0,0,0,0}}}, {{{0,-0.5333333333333333,69358.93333333333,5.9871611113645565e6,1.924439018268767e8,3.2448156139755497e9,3.330669577632881e10,2.2601945627174777e11,1.0662940872799772e12,3.608672101565586e12,8.923743251707213e12,1.6254636226822168e13,2.1772292854629945e13,2.117283786317375e13,1.453488209257297e13,6.674693753831088e12,1.8393128105282654e12,2.2991410131603317e11,0,0,0,0,0,0,0,0,0},{0,0,-1364.8,-247010.3969398599,-1.3710914253764993e7,-3.5907586422209996e8,-5.365095399350815e9,-5.081736342983615e10,-3.255698706535722e11,-1.470867065526843e12,-4.812414875990048e12,-1.1581712843876643e13,-2.0631072691303906e13,-2.7124046546863812e13,-2.5963317717947027e13,-1.758285432472868e13,-7.979604930158186e12,-2.1762558900431414e12,-2.6955446361190094e11,0,0,0,0,0,0,0,0},{0,0,8,4805.078378923909,560851.6328710681,2.5412128545875855e7,5.904978119526415e8,8.148894279740852e9,7.291974445465744e10,4.476097728118765e11,1.955793734114073e12,6.229626820644424e12,1.4665713663876832e13,2.56478138439078e13,3.319636806334255e13,3.135144116117232e13,2.098522418302309e13,9.426637994127908e12,2.547724446396354e12,3.1303099000091724e11,0,0,0,0,0,0,0},{0,0,0,-28.003910068426197,-10845.277747543556,-1.0340539156313771e6,-4.160211107138518e7,-8.934162310823445e8,-1.1653781015963501e10,-9.995712648139485e10,-5.936175304669795e11,-2.525790561524574e12,-7.87163260522547e12,-1.819637446847215e13,-3.1333388101515715e13,-4.001900002443862e13,-3.736019485586116e13,-2.4754756721440023e13,-1.1020607767604893e13,-2.954822829857143e12,-3.6045992787984406e11,0,0,0,0,0,0},{0,0,0,7.704568327482677e-6,63.01369198098898,19921.879208008424,1.6868344786841804e6,6.273964748932823e7,1.273959927266718e9,1.593305010069684e10,1.3225038205179854e11,7.649853076246484e11,3.185325437278451e12,9.749212126813445e12,2.219341094639236e13,3.771515415332075e13,4.76205488262829e13,4.401174323403532e13,2.890378760514151e13,1.2766176186368576e13,3.3986221771528154e12,4.1195420329125037e11,0,0,0,0,0}},{{1.0666666666666667,-270.93333333333334,-275873.1560624472,-1.9526615598641343e7,-5.463067917939428e8,-8.201340252473525e9,-7.590059501108307e10,-4.682825773172421e11,-2.0210768151063833e12,-6.288523857290183e12,-1.4356521317251836e13,-2.4229695665058094e13,-3.016739913942077e13,-2.7348748241932996e13,-1.7548912264512844e13,-7.551241265098464e12,-1.9542698611862817e12,-2.2991410131603317e11,0,0,0,0,0,0,0,0,0},{0,1.6,6051.193879719814,888285.5021747415,4.261058156357549e7,9.887753453648256e8,1.327213854827666e10,1.1396014858065186e11,6.662406988329823e11,2.7610060006323486e12,8.322298591918423e12,1.852086668895058e13,3.0609487847613902e13,3.744833590963831e13,3.344798330425991e13,2.11898795413883e13,9.017191413252525e12,2.311033121849092e12,2.6955446361190094e11,0,0,0,0,0,0,0,0},{0,0,-42.156757847819044,-19540.15290525303,-1.9336304731780519e6,-7.685712819702701e7,-1.594439517783882e9,-1.9858807743317722e10,-1.6160641862808392e11,-9.073615412262385e11,-3.643384657047884e12,-1.0707067507058748e13,-2.333725913033687e13,-3.790443110434288e13,-4.569379747197401e13,-4.029844176053195e13,-2.5250191501700312e13,-1.0641806906700912e13,-2.7042399413968125e12,-3.1303099000091724e11,0,0,0,0,0,0,0},{0,0,0.007820136852394917,137.56233770685833,42550.691954386595,3.4813989145593178e6,1.2363151215452614e8,2.3794672470258155e9,2.8087829807876396e10,2.19531539097911e11,1.1943955071569575e12,4.67634681344435e12,1.34610069080083e13,2.883661986591e13,4.615458622396285e13,5.4943021866992516e13,4.792868725397259e13,2.9744824442882992e13,1.2430432946055994e13,3.135052793797065e12,3.6045992787984406e11,0,0,0,0,0,0},{0,0,-0.000015409136654965353,-0.027397444972528398,-300.78237626127407,-76605.63532406824,-5.592621537223804e6,-1.841644469419035e8,-3.3586851599070764e9,-3.807661046434377e10,-2.883838211797314e11,-1.5299369967994255e12,-5.867608218199371e12,-1.6601437441364713e13,-3.5048526877146164e13,-5.5398397289151914e13,-6.523376765866994e13,-5.636627223479088e13,-3.46882547466682e13,-1.4388245861827873e13,-3.604599278798441e12,-4.1195420329125037e11,0,0,0,0,0}}}, {{{0,-0.5666666666666667,94002.06666666667,9.151311935305258e6,3.320851910459127e8,6.33521032186008e9,7.382275924950447e10,5.713935821593523e11,3.094041226242078e12,1.2118112094805514e13,3.5055579190329652e13,7.577080308439667e13,1.2277365554920727e14,1.4836959871768953e14,1.316939805223555e14,8.331707351347927e13,3.554854783594292e13,9.164851762804633e12,1.0782178544476038e12,0,0,0,0,0,0,0,0},{0,0,-1637.1,-334159.9205226142,-2.0918744937359024e7,-6.185177808929194e8,-1.0456566421124214e10,-1.1244319702124878e11,-8.217073662582078e11,-4.261136422965968e12,-1.613507388311211e13,-4.54274671317859e13,-9.60274321618125e13,-1.5272694341908484e14,-1.8167523305110694e14,-1.5908213959048006e14,-9.946452714264984e13,-4.200158523126891e13,-1.0730006712809219e13,-1.252123960003669e12,0,0,0,0,0,0,0},{0,0,8.5,5760.15335336423,758011.4560133434,3.872804138514868e7,1.0159241892397866e9,1.586238004713476e10,1.611446504457956e11,1.1282876946995315e12,5.658785050777512e12,2.0860295618072766e13,5.745164785582471e13,1.1922862068135155e14,1.8668579152657497e14,2.1910636544081044e14,1.8963108518772156e14,1.1735697816416962e14,4.9110491347309305e13,1.2445353299430406e13,1.4418397115193762e12,0,0,0,0,0,0},{0,0,0,-29.753679653679654,-12996.633706471774,-1.396745220816542e6,-6.3353746792567894e7,-1.5357532178764133e9,-2.2663668846309917e10,-2.2067759802151013e11,-1.4948161492516946e12,-7.300452192754711e12,-2.633115093534921e13,-7.12076759521055e13,-1.4550478401170806e14,-2.2481450876051734e14,-2.608206421034274e14,-2.2345389682757944e14,-1.3705312915212823e14,-5.689609265768836e13,-1.4315408564370951e13,-1.6478168131650015e12,0,0,0,0,0},{0,0,0,6.416135448393513e-6,66.95038440199731,23868.836113681442,2.2775814000040796e6,9.549105192520149e7,2.1884705815436573e9,3.0963237347720776e10,2.91743710502673e11,1.9247605684553428e12,9.198896562512525e12,3.258322450023937e13,8.677160313048934e13,1.749810194392509e14,2.6727116291968612e14,3.0697010372751906e14,2.6065987367419022e14,1.5860983054210656e14,6.537859338635338e13,1.6344561363015016e13,1.8704947608900017e12,0,0,0,0}},{{1.1333333333333333,-325.26666666666665,-379672.3372771824,-3.044289317860951e7,-9.653190181565726e8,-1.645654568518213e10,-1.7350035488585364e11,-1.224974862145457e12,-6.087121650396307e12,-2.198279146517062e13,-5.886931627391679e13,-1.1819629684730314e14,-1.7844037358940066e14,-2.014677026353088e14,-1.674879308472654e14,-9.947402064977933e13,-3.992880786963631e13,-9.703960690028434e12,-1.0782178544476038e12,0,0,0,0,0,0,0,0},{0,1.7,7358.141045228405,1.2228343356326213e6,6.639078335866816e7,1.7454206071277142e9,2.6599212141387142e10,2.601475592017887e11,1.740271415261319e12,8.302886018750533e12,2.904578302199949e13,7.582019351190167e13,1.490656602100751e14,2.211250836544858e14,2.4596589754150544e14,2.018771799198576e14,1.185708301208829e14,4.713181534517283e13,1.1356068692811053e13,1.252123960003669e12,0,0,0,0,0,0,0},{0,0,-45.30670672845925,-23779.18039507422,-2.661791803943833e6,-1.1969660677337208e8,-2.812574307228695e9,-3.9764345032168434e10,-3.685338752285082e11,-2.367394455421027e12,-1.0942906507013615e13,-3.73202401876562e13,-9.540709750646728e13,-1.843299072761322e14,-2.694183018006003e14,-2.9589668840921594e14,-2.401899624280804e14,-1.3971389256713602e14,-5.5062823051114625e13,-1.3166273155190094e13,-1.4418397115193762e12,0,0,0,0,0,0},{0,0,0.00735930735930736,147.96135233748615,51796.68308694178,4.792105916700205e6,1.9247997245947763e8,4.195150944550882e9,5.6203346619271835e10,5.002227932450558e11,3.113437647355672e12,1.403128377992629e13,4.686853664732211e13,1.1775423667475845e14,2.241800875868455e14,3.235464771315656e14,3.5146497769033325e14,2.825652031993201e14,1.6297151920138706e14,6.37448312874054e13,1.5139316970953451e13,1.6478168131650015e12,0,0,0,0,0},{0,0,-0.000012832270896787026,-0.025780032231645135,-323.6322744648659,-93265.65360101484,-7.69771425123931e6,-2.866519541825688e8,-5.919173280043663e9,-7.614963399570706e10,-6.566791772809753e11,-3.985094039738327e12,-1.7590885222630846e13,-5.775012578906397e13,-1.429804558962491e14,-2.6879959044347166e14,-3.8372757967297875e14,-4.1286846760141056e14,-3.291372259583687e14,-1.8840988086355138e14,-7.320015630019402e13,-1.7279808743460016e13,-1.8704947608900017e12,0,0,0,0}}}, {{{0,-0.6,125193.6,1.3652102441336416e7,5.554014600143847e8,1.1899676153316288e10,1.56165088407177e11,1.366540496131952e12,8.40861783023701e12,3.767209777990931e13,1.2572771066140053e14,3.1699683846911475e14,6.078847468910346e14,8.864741332485448e14,9.755540111565658e14,7.962880116350478e14,4.6711589143195694e14,1.8610613034936884e14,4.507646256013208e13,5.008495840014676e12,0,0,0,0,0,0,0},{0,0,-1943.4,-444350.0575188254,-3.1158621445006426e7,-1.0328718631043336e9,-1.9611734199856762e10,-2.3751855080120044e11,-1.9624234636460256e12,-1.1564556559203219e13,-5.009287309334422e13,-1.6271440389198622e14,-4.0123038305561994e14,-7.55244323016712e14,-1.0841303144905668e15,-1.1770068866194732e15,-9.494737901060278e14,-5.512548272291732e14,-2.1763242435124375e14,-5.228566111772896e13,-5.767358846077505e12,0,0,0,0,0,0},{0,0,9,6834.2430464192685,1.0071578139815058e6,5.7630935107687674e7,1.6947655536972034e9,2.971887868603432e10,3.400242318221734e11,2.691676008673227e12,1.5341040964447729e13,6.469277318651995e13,2.0556218578916944e14,4.9764013132721725e14,9.221943510366396e14,1.306119324762518e15,1.4015595146061295e15,1.1191029056445291e15,6.438857748567351e14,2.5216204623961334e14,6.0145313680522555e13,6.591267252660006e12,0,0,0,0,0},{0,0,0,-31.503474903474903,-15415.791203007979,-1.8549118704564322e6,-9.421570811376691e7,-2.5600544123712883e9,-4.242743900283097e10,-4.6525101895250854e11,-3.5629896100471016e12,-1.977415609780622e13,-8.158625551552306e13,-2.545518754366963e14,-6.067625924438578e14,-1.1095340952535998e15,-1.553365741029738e15,-1.650033451843795e15,-1.3057251452334125e15,-7.452766846539458e14,-2.8978473074627556e14,-6.867387907839006e13,-7.481979043560007e12,0,0,0,0},{0,0,0,5.4000054000054e-6,70.88716688716688,28306.784007021753,3.0236617450400395e6,1.4194238784983155e8,3.6460856395006375e9,5.792852759286986e10,6.146661187977393e11,4.584553043233062e12,2.4898101684512574e13,1.008823224117668e14,3.099519834507942e14,7.291125023795298e14,1.3180326124569462e15,1.826761435393357e15,1.9232229378190795e15,1.5098730462049652e15,8.556875473106161e14,3.305876811925353e14,7.788932029962469e13,8.4412071260677e12,0,0,0}},{{1.2,-386.4,-512904.0826728312,-4.6250508101108156e7,-1.6498943779538748e9,-3.1693433546401592e10,-3.774969633261728e11,-3.0222573837808267e12,-1.7114252146731506e13,-7.088860314805319e13,-2.195652433185797e14,-5.154436720771549e14,-9.229759888796809e14,-1.260086991646628e15,-1.3012905395960398e15,-9.989055197138905e14,-5.52186666361618e14,-2.0770526865943212e14,-4.758071048013942e13,-5.008495840014676e12,0,0,0,0,0,0,0},{0,1.8,8846.315037650835,1.652499890670798e6,1.0081815236953616e8,2.980852295984091e9,5.117658296341241e10,5.653923499515992e11,4.2884376326036885e12,2.3314343858552824e13,9.354089348013502e13,2.8240048108547756e14,6.491502225984054e14,1.142121460503862e15,1.5361570189811522e15,1.5661512339351905e15,1.188884318540835e15,6.508081678370406e14,2.4269387512646872e14,5.516934054076771e13,5.767358846077505e12,0,0,0,0,0,0},{0,0,-48.486092838536685,-28610.053294245357,-3.5971398670573817e6,-1.8170450901651797e8,-4.800628986511418e9,-7.645048609922267e10,-8.002747183060198e11,-5.828318542596038e12,-3.0696178946402035e13,-1.2005854798795881e14,-3.549510824718861e14,-8.017723301469554e14,-1.3898631564766085e15,-1.8456808435841622e15,-1.8609896441157935e15,-1.3990467910248515e15,-7.593074829663808e14,-2.8099884047000084e14,-6.3440947306852555e13,-6.591267252660006e12,0,0,0,0,0},{0,0,0.0069498069498069494,158.46348709704054,62337.20331735644,6.475875533245151e6,2.921192897693864e8,7.157442458806223e9,1.0799555655084192e11,1.0855125833750288e12,7.659196496678287e12,3.932659690536154e13,1.5063960727715928e14,4.376723566398628e14,9.741274125347245e14,1.6673482941700252e15,2.189911586818609e15,2.1868594523613995e15,1.630061509290193e15,8.779941332352192e14,3.227187992148031e14,7.241486860017006e13,7.481979043560007e12,0,0,0,0},{0,0,-0.0000108000108000108,-0.024343224343224345,-346.71430558980086,-112261.86290506809,-1.0402072220276337e7,-4.349568507848248e8,-1.009552791463289e10,-1.4625792737830328e11,-1.4242626335574956e12,-9.797394622514166e12,-4.9269031116791766e13,-1.8547288277928522e14,-5.3100005187471706e14,-1.167000294197266e15,-1.9756813909489115e15,-2.5700586158413735e15,-2.544779679266689e15,-1.882576246583223e15,-1.007168503518773e15,-3.6794961500620994e14,-8.210992386265853e13,-8.4412071260677e12,0,0,0}}}, {{{0,-0.6333333333333333,164158.73333333334,1.9930293177442875e7,9.033522147628825e8,2.159562943718983e10,3.1695435436427655e11,3.1117616133093535e12,2.1572888288816043e13,1.09484309701826e14,4.1677133450584825e14,1.2090804894217778e15,2.6979173704553415e15,4.645555959846248e15,6.155935299753043e15,6.217286496234509e15,4.696578395452082e15,2.568066717852626e15,9.596044046707916e14,2.191596361509452e14,2.306943538431002e13,0,0,0,0,0,0},{0,0,-2285.7,-581877.1667007137,-4.542712920857985e7,-1.6777496857464986e9,-3.554596419337812e10,-4.8146941932528937e11,-4.463236488322537e12,-2.963468073013338e13,-1.4541483616136725e14,-5.387724333982664e14,-1.528682077106105e15,-3.3483222279232085e15,-5.675362800076585e15,-7.419408932698538e15,-7.405721111493924e15,-5.536919691805194e15,-3.000077941416619e15,-1.1119673832339076e15,-2.5211597241424522e14,-2.6365069010640023e13,0,0,0,0,0},{0,0,9.5,8034.346639088207,1.3179673367617e6,8.39534763120524e7,2.750469750609688e9,5.381559497441904e10,6.886135692098751e11,6.116068398456957e12,3.927525531830635e13,1.87621875146192e14,6.800177457846064e14,1.8942591437198682e15,4.0847532803221355e15,6.831268665098625e15,8.82695090814349e15,8.720982640500069e15,6.461561639299811e15,3.4729854777955795e15,1.277987710634628e15,2.8787805081888025e14,2.9927916174240027e13,0,0,0,0},{0,0,0,-33.253291753291755,-18118.497367092852,-2.4263056561244098e6,-1.371723164151261e8,-4.1521251582654886e9,-7.677555171735455e10,-9.415385502549863e11,-8.089827546033466e12,-5.058607217578998e13,-2.364337668337472e14,-8.414253645683544e14,-2.307828334679184e15,-4.910703691264801e15,-8.118041289783834e15,-1.0383658748433438e16,-1.0167288912591014e16,-7.473149461470064e15,-3.9880042421706445e15,-1.4580506661137562e15,-3.2652123928561875e14,-3.37648285042708e13,0,0,0},{0,0,0,4.587809465858246e-6,74.82402515085442,33264.59142595566,3.9539347999028377e6,2.0657696267892247e8,5.910713251530081e9,1.0476957462492262e11,1.2431924580143315e12,1.0402955953492928e13,6.365382991017692e13,2.9216326172935256e14,1.0238733031895974e15,2.7713247980029775e15,5.829535183879195e15,9.540280533475378e15,1.209446128636118e16,1.1748726073620186e16,8.574250203286003e15,4.5463150567317e15,1.6525312353663298e15,3.6811898393680606e14,3.788249051698675e13,0,0}},{{1.2666666666666666,-454.73333333333335,-681521.0882190833,-6.866812258629e7,-2.7377423472293215e9,-5.885373059155742e10,-7.861999036201415e11,-7.081109305222594e12,-4.529513317348146e13,-2.1305179026514706e14,-7.544247442837826e14,-2.042292971648917e15,-4.264112494563583e15,-6.887192122673396e15,-8.579721224269423e15,-8.162941954518764e15,-5.819981799016939e15,-3.0089392479769985e15,-1.064858703611706e15,-2.3069435384310022e14,-2.306943538431002e13,0,0,0,0,0,0},{0,1.9,10528.43340142741,2.1966056588859563e6,1.496340808486337e8,4.94310202090654e9,9.495646973148334e10,1.1764390850983005e12,1.0037702723170137e13,6.163907586873927e13,2.808207197238787e14,9.692149606108888e14,2.56903911487428e15,5.27020715794106e15,8.385800766327233e15,1.0313148662287174e16,9.703156383423962e15,6.850671684428315e15,3.5112616134256495e15,1.2330819190015352e15,2.6529850691956525e14,2.6365069010640023e13,0,0,0,0,0},{0,0,-51.693278176413344,-34074.78014180465,-4.781836743440356e6,-2.6961591339264446e8,-7.957160824871687e9,-1.417663970015018e11,-1.6639977875868992e12,-1.3631292963271166e13,-8.108623737250361e13,-3.6010324340970756e14,-1.2170534965459422e15,-3.1699041795772295e15,-6.406817661291515e15,-1.006485817543921e16,-1.2241435673077942e16,-1.1405817498928164e16,-7.983798180042419e15,-4.0608079407256885e15,-1.4163152517613982e15,-3.0284200890600025e14,-2.9927916174240027e13,0,0,0,0},{0,0,0.006583506583506584,169.06299475396784,74264.58077013028,8.60869260141037e6,4.3336689596040046e8,1.1859561376200863e10,2.0016987814094357e11,2.255834083018215e12,1.7902005880230887e13,1.0381148852085344e14,4.5148680237416356e14,1.499482007722108e15,3.8480749449814715e15,7.679151287997549e15,1.1931083759742532e16,1.4371388164888972e16,1.3276270216445754e16,9.222548421515924e15,4.658972295533745e15,1.614980380412015e15,3.434036535377542e14,3.37648285042708e13,0,0,0},{0,0,-9.175618931716493e-6,-0.023058330375403547,-370.01552049520996,-133761.33977549043,-1.3827819745792182e7,-6.451738118427956e8,-1.6723378636699493e10,-2.709901673195793e11,-2.9584696444771226e12,-2.288771647820421e13,-1.2998082039545089e14,-5.555315701855969e14,-1.8179762075703875e15,-4.606611728235598e15,-9.092222501474912e15,-1.3990963605707124e16,-1.6709589472590812e16,-1.5319694204447672e16,-1.0570016078374418e16,-5.307109848412682e15,-1.8294877603627978e15,-3.8706022919529944e14,-3.788249051698675e13,0,0}}}, {{{0,-0.6666666666666666,212266.66666666666,2.853599258035219e7,1.4330114863456995e9,3.800258146404937e10,6.199274770948887e11,6.782860407787912e12,5.259010470068523e13,2.998352445442762e14,1.289474302995765e15,4.256253873967506e15,1.0902678302444068e16,2.1797926698136784e16,3.403776778865586e16,4.131592071162812e16,3.85489253454479e16,2.709770607257666e16,1.3874444112447926e16,4.881180309397506e15,1.054602760425601e15,1.054602760425601e14,0,0,0,0,0},{0,0,-2666,-751541.6624389548,-6.496750631920008e7,-2.6584414136368732e9,-6.248207318933823e10,-9.406826677470544e11,-9.718503789838549e12,-7.216907849489138e13,-3.978378205026157e14,-1.6653179634893145e15,-5.376204754295016e15,-1.3518436707709178e16,-2.6605608406951144e16,-4.0986885639172104e16,-4.9169772065455784e16,-4.540651511838149e16,-3.162877001568124e16,-1.6063591016532404e16,-5.610415428520925e15,-1.204242341296801e15,-1.1971166469696011e14,0,0,0,0},{0,0,10,9367.463398770313,1.701250849010266e6,1.1998124014091475e8,4.354863213182676e9,9.45208118958657e10,1.344305113466995e12,1.3306614989260633e13,9.556877985629884e13,5.12895265809024e14,2.1002083731150322e15,6.656579614385937e15,1.6478625548324368e16,3.1999232770493936e16,4.8724507460816184e16,5.785749736908936e16,5.294839315410694e16,3.65864067552318e16,1.844784707627131e16,6.401367498840126e15,1.365940789490955e15,1.350593140170832e14,0,0,0},{0,0,0,-35.00312695434646,-21120.499631781146,-3.13075780749621e6,-1.9594466391609663e8,-6.57050375487538e9,-1.3476651743799847e11,-1.8369043800571548e12,-1.7589435314077154e13,-1.2300981206774544e14,-6.45896597792679e14,-2.5969519006174225e15,-8.1043872896729e15,-1.979717247928791e16,-3.800085757405471e16,-5.727840617892459e16,-6.7406697825393336e16,-6.119592653276693e16,-4.198322456673902e16,-2.1032687680075924e16,-7.255685440992997e15,-1.5400055927557658e15,-1.51529962067947e14,0,0},{0,0,0,3.930803703917714e-6,78.76094777966587,38771.1275913068,5.100639029001081e6,2.949841095687273e8,9.349478097378347e9,1.8381938202018082e11,2.42419630975418e12,2.2606778024802125e13,1.547013295439825e14,7.976887641336864e14,3.1582328358075825e15,9.726354425919532e15,2.3487483127377148e16,4.463176708335417e16,6.667543951844797e16,7.784411667165024e16,7.0169853688251656e16,4.78314795584771e16,2.3823442630743476e16,8.174976337050191e15,1.7267367770533495e15,1.6914972509910362e14,0}},{{1.3333333333333333,-530.6666666666666,-892251.827371045,-9.987215970701566e7,-4.424126639899304e9,-1.0578643572033942e11,-1.5747287228400437e12,-1.5845717567057562e13,-1.1362682509291195e14,-6.01771280857198e14,-2.4125671241445005e15,-7.446002113664234e15,-1.7881405459744606e16,-3.35951258854644e16,-4.9401354974251736e16,-5.657957303847233e16,-4.9900402465368104e16,-3.3212859965007824e16,-1.612718315044587e16,-5.388707887852326e15,-1.107332898446881e15,-1.054602760425601e14,0,0,0,0,0},{0,2,12417.32487790964,2.877010547668333e6,2.1757735630149266e8,7.983815399399566e9,1.7056499979904105e11,2.354551408251009e12,2.244295896408418e13,1.5448897973201038e14,7.924454954576368e14,3.09644241377513e15,9.357141993333924e15,2.2077909573687176e16,4.086271515883938e16,5.931957879239599e16,6.7183171140618856e16,5.867380519673225e16,3.8715022071894504e16,1.8654226260365056e16,6.190090662038646e15,1.2640981736452812e15,1.1971166469696011e14,0,0,0,0},{0,0,-54.92679754062404,-40215.75896837982,-6.263591942903851e6,-3.919620881744125e8,-1.2847160247073557e10,-2.5452055340858438e11,-3.3284003694315527e12,-3.045760371601915e13,-2.0308431931952872e14,-1.0153938929148701e15,-3.8851031201166525e15,-1.1535964059895936e16,-2.6816071946032308e16,-4.9000640659284456e16,-7.0346216741010216e16,-7.889814086638738e16,-6.831336974290147e16,-4.473081072704507e16,-2.1405078738350924e16,-7.0590142722074e15,-1.4334704464994968e15,-1.350593140170832e14,0,0,0},{0,0,0.006253908692933083,179.75473573239677,87672.02030488498,1.127655502867755e7,6.299257811345832e8,1.9142375540966686e10,3.592377142778432e11,4.510116251939719e12,3.997869384169198e13,2.598472460491622e14,1.2722572790529712e15,4.783417939546741e15,1.3993927307709768e16,3.2117401194767464e16,5.8041145938566104e16,8.251977130024504e16,9.176083681396456e16,7.884587952758733e16,5.127529010535035e16,2.4385985285874588e16,7.99727636948314e15,1.6157705737897392e15,1.51529962067947e14,0,0},{0,0,-7.861607407835427e-6,-0.021902438238229502,-393.52434085950074,-157932.76854200763,-1.8113190266049244e7,-9.376913624338514e8,-2.698711715217962e10,-4.86188476940676e11,-5.912673590075985e12,-5.109028982891983e13,-3.251901708214681e14,-1.5646005583864498e15,-5.796048104691107e15,-1.6742037879323554e16,-3.800261305735843e16,-6.801536029880263e16,-9.587749223709138e16,-1.0580649570083427e17,-9.029733700258528e16,-5.8363106600548536e16,-2.7603025440299108e16,-9.006629152120784e15,-1.8113116396029015e15,-1.6914972509910362e14,0}}} }; static inline int max(int a, int b) { return a > b ? a : b; } /* Compute the singular field at the point x for the particle at xp */ void effsource_hS(struct coordinate * x, double * hS) { double A[10], s2, s2_35; double r = x->r; double theta = x->theta; double phi = x->phi; double rp = xp.r; double thetap = xp.theta; double phip = xp.phi; double dr = r - rp; double dth = theta - thetap; double dphi = phi - phip; double dr2 = dr*dr; double dth2 = dth*dth; double Q = sin(0.5*dphi); double Q2 = Q*Q; double Q4 = Q2*Q2; double Q6 = Q4*Q2; double Q8 = Q4*Q4; double R = sin(dphi); A[0] = dth2*(dth2*(Q2*(A00420 + A00440*Q2) + dth2*(A00600 + A00800*dth2 + A00620*Q2)) + (A00240 + A00260*Q2)*Q4) + (A00060 + A00080*Q2)*Q6 + dr*(dth2*(dth2*(Q2*(A01420 + A01440*Q2) + dth2*(A01600 + A01800*dth2 + A01620*Q2)) + (A01240 + A01260*Q2)*Q4) + dr*(dth2*(Q2*(A02220 + A02240*Q2) + dth2*(A02400 + A02600*dth2 + A02420*Q2)) + (A02040 + A02060*Q2)*Q4 + dr*(dth2*(Q2*(A03220 + A03240*Q2) + dth2*(A03400 + A03600*dth2 + A03420*Q2)) + dr*(Q2*(A04020 + A04040*Q2) + dth2*(A04200 + A04400*dth2 + A04220*Q2) + dr*(Q2*(A05020 + A05040*Q2) + dth2*(A05200 + A05400*dth2 + A05220*Q2) + dr*(A06000 + A06200*dth2 + A06020*Q2 + dr*(A07000 + dr*(A08000 + A09000*dr) + A07200*dth2 + A07020*Q2)))) + (A03040 + A03060*Q2)*Q4)) + (A01060 + A01080*Q2)*Q6); A[1] = Q6*(A10061*R + A10081*Q2*R) + dth2*(Q4*(A10241*R + A10261*Q2*R) + dth2*(Q2*(A10421*R + A10441*Q2*R) + dth2*(A10601*R + A10801*dth2*R + A10621*Q2*R))) + dr*(A11061*Q6*R + dth2*(A11241*Q4*R + dth2*(A11601*dth2*R + A11421*Q2*R)) + dr*(Q4*(A12041*R + A12061*Q2*R) + dth2*(Q2*(A12221*R + A12241*Q2*R) + dth2*(A12401*R + A12601*dth2*R + A12421*Q2*R)) + dr*(A13041*Q4*R + dth2*(A13401*dth2*R + A13221*Q2*R) + dr*(Q2*(A14021*R + A14041*Q2*R) + dth2*(A14201*R + A14401*dth2*R + A14221*Q2*R) + dr*(A15201*dth2*R + A15021*Q2*R + dr*(A16001*R + A16201*dth2*R + A16021*Q2*R + dr*(A17001*R + A18001*dr*R))))))); A[2] = dth*(A20161*Q6*R + dth2*(A20341*Q4*R + dth2*(A20701*dth2*R + A20521*Q2*R))) + dr*(dth*(A21161*Q6*R + dth2*(A21341*Q4*R + dth2*(A21701*dth2*R + A21521*Q2*R))) + dr*(dth*(A22141*Q4*R + dth2*(A22501*dth2*R + A22321*Q2*R)) + dr*(dth*(A23141*Q4*R + dth2*(A23501*dth2*R + A23321*Q2*R)) + dr*(dth*(A24301*dth2*R + A24121*Q2*R) + dr*(dr*(A26101*dth*R + A27101*dr*dth*R) + dth*(A25301*dth2*R + A25121*Q2*R)))))); A[3] = dth2*(dth2*(Q2*(A30420 + A30440*Q2) + dth2*(A30600 + A30800*dth2 + A30620*Q2)) + (A30240 + A30260*Q2)*Q4) + (A30060 + A30080*Q2)*Q6 + dr*(dth2*(dth2*(Q2*(A31420 + A31440*Q2) + dth2*(A31600 + A31800*dth2 + A31620*Q2)) + (A31240 + A31260*Q2)*Q4) + dr*(dth2*(Q2*(A32220 + A32240*Q2) + dth2*(A32400 + A32600*dth2 + A32420*Q2)) + (A32040 + A32060*Q2)*Q4 + dr*(dth2*(Q2*(A33220 + A33240*Q2) + dth2*(A33400 + A33600*dth2 + A33420*Q2)) + dr*(Q2*(A34020 + A34040*Q2) + dth2*(A34200 + A34400*dth2 + A34220*Q2) + dr*(Q2*(A35020 + A35040*Q2) + dth2*(A35200 + A35400*dth2 + A35220*Q2) + dr*(A36000 + A36200*dth2 + A36020*Q2 + dr*(A37000 + dr*(A38000 + A39000*dr) + A37200*dth2 + A37020*Q2)))) + (A33040 + A33060*Q2)*Q4)) + (A31060 + A31080*Q2)*Q6); A[4] = dth2*(dth2*(dth2*(A40800*dth2 + A40620*Q2) + A40440*Q4) + A40260*Q6) + A40080*Q8 + dr*(dth2*(dth2*(dth2*(A41800*dth2 + A41620*Q2) + A41440*Q4) + A41260*Q6) + dr*(dth2*(dth2*(A42600*dth2 + A42420*Q2) + A42240*Q4) + A42060*Q6 + dr*(dth2*(dth2*(A43600*dth2 + A43420*Q2) + A43240*Q4) + dr*(dth2*(A44400*dth2 + A44220*Q2) + A44040*Q4 + dr*(dth2*(A45400*dth2 + A45220*Q2) + dr*(A46200*dth2 + A46020*Q2 + dr*(dr*(A48000 + A49000*dr) + A47200*dth2 + A47020*Q2)) + A45040*Q4)) + A43060*Q6)) + A41080*Q8); A[5] = dr2*(dr2*(dr2*(A58100*dr2*dth + dth*(A56300*dth2 + A56120*Q2)) + dth*(dth2*(A54500*dth2 + A54320*Q2) + A54140*Q4)) + dth*(dth2*(dth2*(A52700*dth2 + A52520*Q2) + A52340*Q4) + A52160*Q6)) + dth*(dth2*(dth2*(dth2*(A50900*dth2 + A50720*Q2) + A50540*Q4) + A50360*Q6) + A50180*Q8); A[6] = Q6*(A60061*R + A60081*Q2*R) + dth2*(Q4*(A60241*R + A60261*Q2*R) + dth2*(Q2*(A60421*R + A60441*Q2*R) + dth2*(A60601*R + A60801*dth2*R + A60621*Q2*R))) + dr*(A61061*Q6*R + dth2*(A61241*Q4*R + dth2*(A61601*dth2*R + A61421*Q2*R)) + dr*(Q4*(A62041*R + A62061*Q2*R) + dth2*(Q2*(A62221*R + A62241*Q2*R) + dth2*(A62401*R + A62601*dth2*R + A62421*Q2*R)) + dr*(A63041*Q4*R + dth2*(A63401*dth2*R + A63221*Q2*R) + dr*(Q2*(A64021*R + A64041*Q2*R) + dth2*(A64201*R + A64401*dth2*R + A64221*Q2*R) + dr*(A65201*dth2*R + A65021*Q2*R + dr*(A66001*R + A66201*dth2*R + A66021*Q2*R + dr*(A67001*R + A68001*dr*R))))))); A[7] = dth2*(dth2*(dth2*(A70800*dth2 + A70620*Q2) + A70440*Q4) + A70260*Q6) + A70080*Q8 + dr*(dth2*(dth2*(dth2*(A71800*dth2 + A71620*Q2) + A71440*Q4) + A71260*Q6) + dr*(dth2*(dth2*(A72600*dth2 + A72420*Q2) + A72240*Q4) + A72060*Q6 + dr*(dth2*(dth2*(A73600*dth2 + A73420*Q2) + A73240*Q4) + dr*(dth2*(A74400*dth2 + A74220*Q2) + A74040*Q4 + dr*(dth2*(A75400*dth2 + A75220*Q2) + dr*(A76200*dth2 + A76020*Q2 + dr*(dr*(A78000 + A79000*dr) + A77200*dth2 + A77020*Q2)) + A75040*Q4)) + A73060*Q6)) + A71080*Q8); A[8] = dth*(A80161*Q6*R + dth2*(A80341*Q4*R + dth2*(A80701*dth2*R + A80521*Q2*R))) + dr*(dth*(A81161*Q6*R + dth2*(A81341*Q4*R + dth2*(A81701*dth2*R + A81521*Q2*R))) + dr*(dth*(A82141*Q4*R + dth2*(A82501*dth2*R + A82321*Q2*R)) + dr*(dth*(A83141*Q4*R + dth2*(A83501*dth2*R + A83321*Q2*R)) + dr*(dth*(A84301*dth2*R + A84121*Q2*R) + dr*(dr*(A86101*dth*R + A87101*dr*dth*R) + dth*(A85301*dth2*R + A85121*Q2*R)))))); A[9] = dth2*(dth2*(Q2*(A90420 + A90440*Q2) + dth2*(A90600 + A90800*dth2 + A90620*Q2)) + (A90240 + A90260*Q2)*Q4) + (A90060 + A90080*Q2)*Q6 + dr*(dth2*(dth2*(Q2*(A91420 + A91440*Q2) + dth2*(A91600 + A91800*dth2 + A91620*Q2)) + (A91240 + A91260*Q2)*Q4) + dr*(dth2*(Q2*(A92220 + A92240*Q2) + dth2*(A92400 + A92600*dth2 + A92420*Q2)) + (A92040 + A92060*Q2)*Q4 + dr*(dth2*(Q2*(A93220 + A93240*Q2) + dth2*(A93400 + A93600*dth2 + A93420*Q2)) + dr*(Q2*(A94020 + A94040*Q2) + dth2*(A94200 + A94400*dth2 + A94220*Q2) + dr*(Q2*(A95020 + A95040*Q2) + dth2*(A95200 + A95400*dth2 + A95220*Q2) + dr*(A96000 + A96200*dth2 + A96020*Q2 + dr*(A97000 + dr*(A98000 + A99000*dr) + A97200*dth2 + A97020*Q2)))) + (A93040 + A93060*Q2)*Q4)) + (A91060 + A91080*Q2)*Q6); s2 = alpha20*dr2 + alpha02*dth2 + beta*Q2; s2_35 = pow(s2, 3.5); /* hS */ for(int i=0; i<10; i++) { hS[i] = A[i]/s2_35; } } /* Compute the singular field at the point x for the particle at xp */ void effsource_hS_m(int m, struct coordinate * x, double * hS_re, double * hS_im) { double A_re[10][5]; double A_im[10][5]; double alpha, ellE, ellK; if(m>20) { printf("Support for computing mode %d has not yet been added.\n", m); return; } const double r = x->r; const double theta = x->theta; const double rp = xp.r; const double thetap = xp.theta; const double dr = r - rp; const double dth = theta - thetap; const double dr2 = dr*dr; const double dth2 = dth*dth; const double dth3 = dth*dth2; const double dth4 = dth2*dth2; const double dth5 = dth3*dth2; const double dth6 = dth3*dth3; const double dth7 = dth4*dth3; const double dth8 = dth4*dth4; const double dth9 = dth5*dth4; A_re[0][0] = (A00600 + A00800*dth2)*dth6 + dr*(dr*((A02400 + A02600*dth2)*dth4 + dr*(dr*(dth2*(A04200 + A04400*dth2) + dr*(dth2*(A05200 + A05400*dth2) + dr*(A06000 + A06200*dth2 + dr*(A07000 + dr*(A08000 + A09000*dr) + A07200*dth2)))) + (A03400 + A03600*dth2)*dth4)) + (A01600 + A01800*dth2)*dth6); A_re[0][1] = (A00420 + A00620*dth2)*dth4 + dr*(dr*(dth2*(A02220 + A02420*dth2) + dr*(dth2*(A03220 + A03420*dth2) + dr*(A04020 + A04220*dth2 + dr*(A05020 + dr*(A06020 + A07020*dr) + A05220*dth2)))) + (A01420 + A01620*dth2)*dth4); A_re[0][2] = dth2*(A00240 + A00440*dth2) + dr*(dth2*(A01240 + A01440*dth2) + dr*(A02040 + A02240*dth2 + dr*(A03040 + dr*(A04040 + A05040*dr) + A03240*dth2))); A_re[0][3] = A00060 + A00260*dth2 + dr*(A01060 + dr*(A02060 + A03060*dr) + A01260*dth2); A_re[0][4] = A00080 + A01080*dr; A_im[0][0] = A_im[0][1] = A_im[0][2] = A_im[0][3] = A_im[0][4] = 0.0; A_re[1][0] = A_re[1][1] = A_re[1][2] = A_re[1][3] = A_re[1][4] = 0.0; A_im[1][0] = (A10601 + A10801*dth2)*dth6 + dr*(dr*((A12401 + A12601*dth2)*dth4 + dr*(dr*(dth2*(A14201 + A14401*dth2) + dr*(A15201*dth2 + dr*(A16001 + dr*(A17001 + A18001*dr) + A16201*dth2))) + A13401*dth4)) + A11601*dth6); A_im[1][1] = (A10421 + A10621*dth2)*dth4 + dr*(dr*(dth2*(A12221 + A12421*dth2) + dr*(A13221*dth2 + dr*(A14021 + dr*(A15021 + A16021*dr) + A14221*dth2))) + A11421*dth4); A_im[1][2] = dth2*(A10241 + A10441*dth2) + dr*(A11241*dth2 + dr*(A12041 + dr*(A13041 + A14041*dr) + A12241*dth2)); A_im[1][3] = A10061 + dr*(A11061 + A12061*dr) + A10261*dth2; A_im[1][4] = A10081; A_re[2][0] = A_re[2][1] = A_re[2][2] = A_re[2][3] = A_re[2][4] = 0.0; A_im[2][0] = A20701*dth7 + dr*(dr*(A22501*dth5 + dr*(dr*(A24301*dth3 + dr*(dr*(A26101*dth + A27101*dr*dth) + A25301*dth3)) + A23501*dth5)) + A21701*dth7); A_im[2][1] = A20521*dth5 + dr*(dr*(A22321*dth3 + dr*(dr*(A24121*dth + A25121*dr*dth) + A23321*dth3)) + A21521*dth5); A_im[2][2] = A20341*dth3 + dr*(dr*(A22141*dth + A23141*dr*dth) + A21341*dth3); A_im[2][3] = A20161*dth + A21161*dr*dth; A_im[2][4] = 0.0; A_re[3][0] = (A30600 + A30800*dth2)*dth6 + dr*(dr*((A32400 + A32600*dth2)*dth4 + dr*(dr*(dth2*(A34200 + A34400*dth2) + dr*(dth2*(A35200 + A35400*dth2) + dr*(A36000 + A36200*dth2 + dr*(A37000 + dr*(A38000 + A39000*dr) + A37200*dth2)))) + (A33400 + A33600*dth2)*dth4)) + (A31600 + A31800*dth2)*dth6); A_re[3][1] = (A30420 + A30620*dth2)*dth4 + dr*(dr*(dth2*(A32220 + A32420*dth2) + dr*(dth2*(A33220 + A33420*dth2) + dr*(A34020 + A34220*dth2 + dr*(A35020 + dr*(A36020 + A37020*dr) + A35220*dth2)))) + (A31420 + A31620*dth2)*dth4); A_re[3][2] = dth2*(A30240 + A30440*dth2) + dr*(dth2*(A31240 + A31440*dth2) + dr*(A32040 + A32240*dth2 + dr*(A33040 + dr*(A34040 + A35040*dr) + A33240*dth2))); A_re[3][3] = A30060 + A30260*dth2 + dr*(A31060 + dr*(A32060 + A33060*dr) + A31260*dth2); A_re[3][4] = A30080 + A31080*dr; A_im[3][0] = A_im[3][1] = A_im[3][2] = A_im[3][3] = A_im[3][4] = 0.0; A_re[4][0] = A40800*dth8 + dr*(dr*(A42600*dth6 + dr*(dr*(A44400*dth4 + dr*(dr*(A46200*dth2 + dr*(dr*(A48000 + A49000*dr) + A47200*dth2)) + A45400*dth4)) + A43600*dth6)) + A41800*dth8); A_re[4][1] = A40620*dth6 + dr*(dr*(A42420*dth4 + dr*(dr*(A44220*dth2 + dr*(dr*(A46020 + A47020*dr) + A45220*dth2)) + A43420*dth4)) + A41620*dth6); A_re[4][2] = A40440*dth4 + dr*(dr*(A42240*dth2 + dr*(dr*(A44040 + A45040*dr) + A43240*dth2)) + A41440*dth4); A_re[4][3] = A40260*dth2 + dr*(dr*(A42060 + A43060*dr) + A41260*dth2); A_re[4][4] = A40080 + A41080*dr; A_im[4][0] = A_im[4][1] = A_im[4][2] = A_im[4][3] = A_im[4][4] = 0.0; A_re[5][0] = dr2*(dr2*(dr2*(A58100*dr2*dth + A56300*dth3) + A54500*dth5) + A52700*dth7) + A50900*dth9; A_re[5][1] = dr2*(dr2*(A56120*dr2*dth + A54320*dth3) + A52520*dth5) + A50720*dth7; A_re[5][2] = dr2*(A54140*dr2*dth + A52340*dth3) + A50540*dth5; A_re[5][3] = A52160*dr2*dth + A50360*dth3; A_re[5][4] = A50180*dth; A_im[5][0] = A_im[5][1] = A_im[5][2] = A_im[5][3] = A_im[5][4] = 0.0; A_re[6][0] = A_re[6][1] = A_re[6][2] = A_re[6][3] = A_re[6][4] = 0.0; A_im[6][0] = (A60601 + A60801*dth2)*dth6 + dr*(dr*((A62401 + A62601*dth2)*dth4 + dr*(dr*(dth2*(A64201 + A64401*dth2) + dr*(A65201*dth2 + dr*(A66001 + dr*(A67001 + A68001*dr) + A66201*dth2))) + A63401*dth4)) + A61601*dth6); A_im[6][1] = (A60421 + A60621*dth2)*dth4 + dr*(dr*(dth2*(A62221 + A62421*dth2) + dr*(A63221*dth2 + dr*(A64021 + dr*(A65021 + A66021*dr) + A64221*dth2))) + A61421*dth4); A_im[6][2] = dth2*(A60241 + A60441*dth2) + dr*(A61241*dth2 + dr*(A62041 + dr*(A63041 + A64041*dr) + A62241*dth2)); A_im[6][3] = A60061 + dr*(A61061 + A62061*dr) + A60261*dth2; A_im[6][4] = A60081; A_re[7][0] = A70800*dth8 + dr*(dr*(A72600*dth6 + dr*(dr*(A74400*dth4 + dr*(dr*(A76200*dth2 + dr*(dr*(A78000 + A79000*dr) + A77200*dth2)) + A75400*dth4)) + A73600*dth6)) + A71800*dth8); A_re[7][1] = A70620*dth6 + dr*(dr*(A72420*dth4 + dr*(dr*(A74220*dth2 + dr*(dr*(A76020 + A77020*dr) + A75220*dth2)) + A73420*dth4)) + A71620*dth6); A_re[7][2] = A70440*dth4 + dr*(dr*(A72240*dth2 + dr*(dr*(A74040 + A75040*dr) + A73240*dth2)) + A71440*dth4); A_re[7][3] = A70260*dth2 + dr*(dr*(A72060 + A73060*dr) + A71260*dth2); A_re[7][4] = A70080 + A71080*dr; A_im[7][0] = A_im[7][1] = A_im[7][2] = A_im[7][3] = A_im[7][4] = 0.0; A_re[8][0] = A_re[8][1] = A_re[8][2] = A_re[8][3] = A_re[8][4] = 0.0; A_im[8][0] = A80701*dth7 + dr*(dr*(A82501*dth5 + dr*(dr*(A84301*dth3 + dr*(dr*(A86101*dth + A87101*dr*dth) + A85301*dth3)) + A83501*dth5)) + A81701*dth7); A_im[8][1] = A80521*dth5 + dr*(dr*(A82321*dth3 + dr*(dr*(A84121*dth + A85121*dr*dth) + A83321*dth3)) + A81521*dth5); A_im[8][2] = A80341*dth3 + dr*(dr*(A82141*dth + A83141*dr*dth) + A81341*dth3); A_im[8][3] = A80161*dth + A81161*dr*dth; A_im[8][4] = 0.0; A_re[9][0] = (A90600 + A90800*dth2)*dth6 + dr*(dr*((A92400 + A92600*dth2)*dth4 + dr*(dr*(dth2*(A94200 + A94400*dth2) + dr*(dth2*(A95200 + A95400*dth2) + dr*(A96000 + A96200*dth2 + dr*(A97000 + dr*(A98000 + A99000*dr) + A97200*dth2)))) + (A93400 + A93600*dth2)*dth4)) + (A91600 + A91800*dth2)*dth6); A_re[9][1] = (A90420 + A90620*dth2)*dth4 + dr*(dr*(dth2*(A92220 + A92420*dth2) + dr*(dth2*(A93220 + A93420*dth2) + dr*(A94020 + A94220*dth2 + dr*(A95020 + dr*(A96020 + A97020*dr) + A95220*dth2)))) + (A91420 + A91620*dth2)*dth4); A_re[9][2] = dth2*(A90240 + A90440*dth2) + dr*(dth2*(A91240 + A91440*dth2) + dr*(A92040 + A92240*dth2 + dr*(A93040 + dr*(A94040 + A95040*dr) + A93240*dth2))); A_re[9][3] = A90060 + A90260*dth2 + dr*(A91060 + dr*(A92060 + A93060*dr) + A91260*dth2); A_re[9][4] = A90080 + A91080*dr; A_im[9][0] = A_im[9][1] = A_im[9][2] = A_im[9][3] = A_im[9][4] = 0.0; alpha = alpha20*dr2 + alpha02*dth2; /* Powers of C = alpha / beta */ double C[27]; C[0] = 1; C[1] = alpha / beta; for(int i=2; i<=26; i++) C[i] = C[1]*C[i-1]; ellE = gsl_sf_ellint_Ecomp(sqrt(1.0/(1.0+C[1])), GSL_PREC_DOUBLE); ellK = gsl_sf_ellint_Kcomp(sqrt(1.0/(1.0+C[1])), GSL_PREC_DOUBLE); const double fac_re = 4.0/(beta*C[3]*pow(alpha+beta, 2.5)); const double fac_im = -32.0/(beta*beta*C[2]*pow(alpha+beta, 1.5)); for(int l=0; l<10; l++) { hS_re[l] = 0.0; hS_im[l] = 0.0; for(int j=0; j<5; j++) { double fac1K = ellK*A_re[l][j]; for(int k=max(j,0); k<=m+2+j; k++) { hS_re[l] += fac1K*C[k]*ReEI[m][0][j][k]; } double fac1E = ellE*A_re[l][j]; for(int k=max(j-1,0); k<=m+2+j; k++) { hS_re[l] += fac1E*C[k]*ReEI[m][1][j][k]; } double fac2K = ellK*A_im[l][j]; for(int k=max(j-1,0); k<=m+1+j; k++) { hS_im[l] += fac2K*C[k]*ImEI[m][0][j][k]; } double fac2E = ellE*A_im[l][j]; for(int k=max(j-2,0); k<=m+1+j; k++) { hS_im[l] += fac2E*C[k]*ImEI[m][1][j][k]; } } hS_re[l] *= fac_re; hS_im[l] *= fac_im; } } /* Compute the singular field, its derivatives and its d'Alembertian */ void effsource_calc(struct coordinate * x, double *hS, double *dhS_dr, double *dhS_dth, double *dhS_dph, double *dhS_dt, double *src) { double A[10], dA_dr[10], d2A_dr2[10], dA_dth[10], d2A_dth2[10], dA_dQ[10], dA_dR[10], dA_dph[10]; double d2A_dQ2[10], d2A_dQR[10], d2A_dph2[10], dA_dt[10], d2A_dt2[10], d2A_dtph[10]; double s2, sqrts2, s2_15, s2_25, s2_35, s2_45, s2_55, ds2_dr, d2s2_dr2, ds2_dth; double d2s2_dth2, ds2_dQ, ds2_dph, d2s2_dQ2, d2s2_dph2, ds2_dt, d2s2_dt2, d2s2_dtph; double d2hS_dt2[10], d2hS_dtr[10], d2hS_dtth[10]; double d2hS_dtph[10], d2hS_dr2[10], d2hS_drth[10], d2hS_drph[10], d2hS_dth2[10], d2hS_dthph[10], d2hS_dph2[10]; double r = x->r; double theta = x->theta; double phi = x->phi; double rp = xp.r; double thetap = xp.theta; double phip = xp.phi; double Omega = M / (a*M + sqrt(M*rp*rp*rp)); double dr = r - rp; double dth = theta - thetap; double dphi = phi - phip; double dr2 = dr*dr; double dth2 = dth*dth; double Q = sin(0.5*dphi); double Q2 = Q*Q; double Q3 = Q2*Q; double Q4 = Q2*Q2; double Q5 = Q3*Q2; double Q6 = Q4*Q2; double Q7 = Q4*Q3; double Q8 = Q4*Q4; double R = sin(dphi); double dQ_dph = 0.5*cos(0.5*dphi); double dR_dph = cos(dphi); double d2Q_dph2 = -0.25*Q; double d2R_dph2 = -R; /* A */ A[0] = dth2*(dth2*(Q2*(A00420 + A00440*Q2) + dth2*(A00600 + A00800*dth2 + A00620*Q2)) + (A00240 + A00260*Q2)*Q4) + (A00060 + A00080*Q2)*Q6 + dr*(dth2*(dth2*(Q2*(A01420 + A01440*Q2) + dth2*(A01600 + A01800*dth2 + A01620*Q2)) + (A01240 + A01260*Q2)*Q4) + dr*(dth2*(Q2*(A02220 + A02240*Q2) + dth2*(A02400 + A02600*dth2 + A02420*Q2)) + (A02040 + A02060*Q2)*Q4 + dr*(dth2*(Q2*(A03220 + A03240*Q2) + dth2*(A03400 + A03600*dth2 + A03420*Q2)) + dr*(Q2*(A04020 + A04040*Q2) + dth2*(A04200 + A04400*dth2 + A04220*Q2) + dr*(Q2*(A05020 + A05040*Q2) + dth2*(A05200 + A05400*dth2 + A05220*Q2) + dr*(A06000 + A06200*dth2 + A06020*Q2 + dr*(A07000 + dr*(A08000 + A09000*dr) + A07200*dth2 + A07020*Q2)))) + (A03040 + A03060*Q2)*Q4)) + (A01060 + A01080*Q2)*Q6); A[1] = Q6*(A10061*R + A10081*Q2*R) + dth2*(Q4*(A10241*R + A10261*Q2*R) + dth2*(Q2*(A10421*R + A10441*Q2*R) + dth2*(A10601*R + A10801*dth2*R + A10621*Q2*R))) + dr*(A11061*Q6*R + dth2*(A11241*Q4*R + dth2*(A11601*dth2*R + A11421*Q2*R)) + dr*(Q4*(A12041*R + A12061*Q2*R) + dth2*(Q2*(A12221*R + A12241*Q2*R) + dth2*(A12401*R + A12601*dth2*R + A12421*Q2*R)) + dr*(A13041*Q4*R + dth2*(A13401*dth2*R + A13221*Q2*R) + dr*(Q2*(A14021*R + A14041*Q2*R) + dth2*(A14201*R + A14401*dth2*R + A14221*Q2*R) + dr*(A15201*dth2*R + A15021*Q2*R + dr*(A16001*R + A16201*dth2*R + A16021*Q2*R + dr*(A17001*R + A18001*dr*R))))))); A[2] = dth*(A20161*Q6*R + dth2*(A20341*Q4*R + dth2*(A20701*dth2*R + A20521*Q2*R))) + dr*(dth*(A21161*Q6*R + dth2*(A21341*Q4*R + dth2*(A21701*dth2*R + A21521*Q2*R))) + dr*(dth*(A22141*Q4*R + dth2*(A22501*dth2*R + A22321*Q2*R)) + dr*(dth*(A23141*Q4*R + dth2*(A23501*dth2*R + A23321*Q2*R)) + dr*(dth*(A24301*dth2*R + A24121*Q2*R) + dr*(dr*(A26101*dth*R + A27101*dr*dth*R) + dth*(A25301*dth2*R + A25121*Q2*R)))))); A[3] = dth2*(dth2*(Q2*(A30420 + A30440*Q2) + dth2*(A30600 + A30800*dth2 + A30620*Q2)) + (A30240 + A30260*Q2)*Q4) + (A30060 + A30080*Q2)*Q6 + dr*(dth2*(dth2*(Q2*(A31420 + A31440*Q2) + dth2*(A31600 + A31800*dth2 + A31620*Q2)) + (A31240 + A31260*Q2)*Q4) + dr*(dth2*(Q2*(A32220 + A32240*Q2) + dth2*(A32400 + A32600*dth2 + A32420*Q2)) + (A32040 + A32060*Q2)*Q4 + dr*(dth2*(Q2*(A33220 + A33240*Q2) + dth2*(A33400 + A33600*dth2 + A33420*Q2)) + dr*(Q2*(A34020 + A34040*Q2) + dth2*(A34200 + A34400*dth2 + A34220*Q2) + dr*(Q2*(A35020 + A35040*Q2) + dth2*(A35200 + A35400*dth2 + A35220*Q2) + dr*(A36000 + A36200*dth2 + A36020*Q2 + dr*(A37000 + dr*(A38000 + A39000*dr) + A37200*dth2 + A37020*Q2)))) + (A33040 + A33060*Q2)*Q4)) + (A31060 + A31080*Q2)*Q6); A[4] = dth2*(dth2*(dth2*(A40800*dth2 + A40620*Q2) + A40440*Q4) + A40260*Q6) + A40080*Q8 + dr*(dth2*(dth2*(dth2*(A41800*dth2 + A41620*Q2) + A41440*Q4) + A41260*Q6) + dr*(dth2*(dth2*(A42600*dth2 + A42420*Q2) + A42240*Q4) + A42060*Q6 + dr*(dth2*(dth2*(A43600*dth2 + A43420*Q2) + A43240*Q4) + dr*(dth2*(A44400*dth2 + A44220*Q2) + A44040*Q4 + dr*(dth2*(A45400*dth2 + A45220*Q2) + dr*(A46200*dth2 + A46020*Q2 + dr*(dr*(A48000 + A49000*dr) + A47200*dth2 + A47020*Q2)) + A45040*Q4)) + A43060*Q6)) + A41080*Q8); A[5] = dr2*(dr2*(dr2*(A58100*dr2*dth + dth*(A56300*dth2 + A56120*Q2)) + dth*(dth2*(A54500*dth2 + A54320*Q2) + A54140*Q4)) + dth*(dth2*(dth2*(A52700*dth2 + A52520*Q2) + A52340*Q4) + A52160*Q6)) + dth*(dth2*(dth2*(dth2*(A50900*dth2 + A50720*Q2) + A50540*Q4) + A50360*Q6) + A50180*Q8); A[6] = Q6*(A60061*R + A60081*Q2*R) + dth2*(Q4*(A60241*R + A60261*Q2*R) + dth2*(Q2*(A60421*R + A60441*Q2*R) + dth2*(A60601*R + A60801*dth2*R + A60621*Q2*R))) + dr*(A61061*Q6*R + dth2*(A61241*Q4*R + dth2*(A61601*dth2*R + A61421*Q2*R)) + dr*(Q4*(A62041*R + A62061*Q2*R) + dth2*(Q2*(A62221*R + A62241*Q2*R) + dth2*(A62401*R + A62601*dth2*R + A62421*Q2*R)) + dr*(A63041*Q4*R + dth2*(A63401*dth2*R + A63221*Q2*R) + dr*(Q2*(A64021*R + A64041*Q2*R) + dth2*(A64201*R + A64401*dth2*R + A64221*Q2*R) + dr*(A65201*dth2*R + A65021*Q2*R + dr*(A66001*R + A66201*dth2*R + A66021*Q2*R + dr*(A67001*R + A68001*dr*R))))))); A[7] = dth2*(dth2*(dth2*(A70800*dth2 + A70620*Q2) + A70440*Q4) + A70260*Q6) + A70080*Q8 + dr*(dth2*(dth2*(dth2*(A71800*dth2 + A71620*Q2) + A71440*Q4) + A71260*Q6) + dr*(dth2*(dth2*(A72600*dth2 + A72420*Q2) + A72240*Q4) + A72060*Q6 + dr*(dth2*(dth2*(A73600*dth2 + A73420*Q2) + A73240*Q4) + dr*(dth2*(A74400*dth2 + A74220*Q2) + A74040*Q4 + dr*(dth2*(A75400*dth2 + A75220*Q2) + dr*(A76200*dth2 + A76020*Q2 + dr*(dr*(A78000 + A79000*dr) + A77200*dth2 + A77020*Q2)) + A75040*Q4)) + A73060*Q6)) + A71080*Q8); A[8] = dth*(A80161*Q6*R + dth2*(A80341*Q4*R + dth2*(A80701*dth2*R + A80521*Q2*R))) + dr*(dth*(A81161*Q6*R + dth2*(A81341*Q4*R + dth2*(A81701*dth2*R + A81521*Q2*R))) + dr*(dth*(A82141*Q4*R + dth2*(A82501*dth2*R + A82321*Q2*R)) + dr*(dth*(A83141*Q4*R + dth2*(A83501*dth2*R + A83321*Q2*R)) + dr*(dth*(A84301*dth2*R + A84121*Q2*R) + dr*(dr*(A86101*dth*R + A87101*dr*dth*R) + dth*(A85301*dth2*R + A85121*Q2*R)))))); A[9] = dth2*(dth2*(Q2*(A90420 + A90440*Q2) + dth2*(A90600 + A90800*dth2 + A90620*Q2)) + (A90240 + A90260*Q2)*Q4) + (A90060 + A90080*Q2)*Q6 + dr*(dth2*(dth2*(Q2*(A91420 + A91440*Q2) + dth2*(A91600 + A91800*dth2 + A91620*Q2)) + (A91240 + A91260*Q2)*Q4) + dr*(dth2*(Q2*(A92220 + A92240*Q2) + dth2*(A92400 + A92600*dth2 + A92420*Q2)) + (A92040 + A92060*Q2)*Q4 + dr*(dth2*(Q2*(A93220 + A93240*Q2) + dth2*(A93400 + A93600*dth2 + A93420*Q2)) + dr*(Q2*(A94020 + A94040*Q2) + dth2*(A94200 + A94400*dth2 + A94220*Q2) + dr*(Q2*(A95020 + A95040*Q2) + dth2*(A95200 + A95400*dth2 + A95220*Q2) + dr*(A96000 + A96200*dth2 + A96020*Q2 + dr*(A97000 + dr*(A98000 + A99000*dr) + A97200*dth2 + A97020*Q2)))) + (A93040 + A93060*Q2)*Q4)) + (A91060 + A91080*Q2)*Q6); /* dA/dx */ dA_dr[0] = dth2*(dth2*(Q2*(A01420 + A01440*Q2) + dth2*(A01600 + A01800*dth2 + A01620*Q2)) + (A01240 + A01260*Q2)*Q4) + dr*(dth2*(Q2*(2*A02220 + 2*A02240*Q2) + dth2*(2*A02400 + 2*A02600*dth2 + 2*A02420*Q2)) + (2*A02040 + 2*A02060*Q2)*Q4 + dr*(dth2*(Q2*(3*A03220 + 3*A03240*Q2) + dth2*(3*A03400 + 3*A03600*dth2 + 3*A03420*Q2)) + dr*(Q2*(4*A04020 + 4*A04040*Q2) + dth2*(4*A04200 + 4*A04400*dth2 + 4*A04220*Q2) + dr*(Q2*(5*A05020 + 5*A05040*Q2) + dth2*(5*A05200 + 5*A05400*dth2 + 5*A05220*Q2) + dr*(6*A06000 + 6*A06200*dth2 + 6*A06020*Q2 + dr*(7*A07000 + dr*(8*A08000 + 9*A09000*dr) + 7*A07200*dth2 + 7*A07020*Q2)))) + (3*A03040 + 3*A03060*Q2)*Q4)) + (A01060 + A01080*Q2)*Q6; dA_dr[1] = A11061*Q6*R + dth2*(A11241*Q4*R + dth2*(A11601*dth2*R + A11421*Q2*R)) + dr*(Q4*(2*A12041*R + 2*A12061*Q2*R) + dth2*(Q2*(2*A12221*R + 2*A12241*Q2*R) + dth2*(2*A12401*R + 2*A12601*dth2*R + 2*A12421*Q2*R)) + dr*(3*A13041*Q4*R + dth2*(3*A13401*dth2*R + 3*A13221*Q2*R) + dr*(Q2*(4*A14021*R + 4*A14041*Q2*R) + dth2*(4*A14201*R + 4*A14401*dth2*R + 4*A14221*Q2*R) + dr*(5*A15201*dth2*R + 5*A15021*Q2*R + dr*(6*A16001*R + 6*A16201*dth2*R + 6*A16021*Q2*R + dr*(7*A17001*R + 8*A18001*dr*R)))))); dA_dr[2] = dth*(A21161*Q6*R + dth2*(A21341*Q4*R + dth2*(A21701*dth2*R + A21521*Q2*R))) + dr*(dth*(2*A22141*Q4*R + dth2*(2*A22501*dth2*R + 2*A22321*Q2*R)) + dr*(dth*(3*A23141*Q4*R + dth2*(3*A23501*dth2*R + 3*A23321*Q2*R)) + dr*(dth*(4*A24301*dth2*R + 4*A24121*Q2*R) + dr*(dr*(6*A26101*dth*R + 7*A27101*dr*dth*R) + dth*(5*A25301*dth2*R + 5*A25121*Q2*R))))); dA_dr[3] = dth2*(dth2*(Q2*(A31420 + A31440*Q2) + dth2*(A31600 + A31800*dth2 + A31620*Q2)) + (A31240 + A31260*Q2)*Q4) + dr*(dth2*(Q2*(2*A32220 + 2*A32240*Q2) + dth2*(2*A32400 + 2*A32600*dth2 + 2*A32420*Q2)) + (2*A32040 + 2*A32060*Q2)*Q4 + dr*(dth2*(Q2*(3*A33220 + 3*A33240*Q2) + dth2*(3*A33400 + 3*A33600*dth2 + 3*A33420*Q2)) + dr*(Q2*(4*A34020 + 4*A34040*Q2) + dth2*(4*A34200 + 4*A34400*dth2 + 4*A34220*Q2) + dr*(Q2*(5*A35020 + 5*A35040*Q2) + dth2*(5*A35200 + 5*A35400*dth2 + 5*A35220*Q2) + dr*(6*A36000 + 6*A36200*dth2 + 6*A36020*Q2 + dr*(7*A37000 + dr*(8*A38000 + 9*A39000*dr) + 7*A37200*dth2 + 7*A37020*Q2)))) + (3*A33040 + 3*A33060*Q2)*Q4)) + (A31060 + A31080*Q2)*Q6; dA_dr[4] = dth2*(dth2*(dth2*(A41800*dth2 + A41620*Q2) + A41440*Q4) + A41260*Q6) + dr*(dth2*(dth2*(2*A42600*dth2 + 2*A42420*Q2) + 2*A42240*Q4) + 2*A42060*Q6 + dr*(dth2*(dth2*(3*A43600*dth2 + 3*A43420*Q2) + 3*A43240*Q4) + dr*(dth2*(4*A44400*dth2 + 4*A44220*Q2) + 4*A44040*Q4 + dr*(dth2*(5*A45400*dth2 + 5*A45220*Q2) + dr*(6*A46200*dth2 + 6*A46020*Q2 + dr*(dr*(8*A48000 + 9*A49000*dr) + 7*A47200*dth2 + 7*A47020*Q2)) + 5*A45040*Q4)) + 3*A43060*Q6)) + A41080*Q8; dA_dr[5] = dr*(dr2*(dr2*(8*A58100*dr2*dth + dth*(6*A56300*dth2 + 6*A56120*Q2)) + dth*(dth2*(4*A54500*dth2 + 4*A54320*Q2) + 4*A54140*Q4)) + dth*(dth2*(dth2*(2*A52700*dth2 + 2*A52520*Q2) + 2*A52340*Q4) + 2*A52160*Q6)); dA_dr[6] = A61061*Q6*R + dth2*(A61241*Q4*R + dth2*(A61601*dth2*R + A61421*Q2*R)) + dr*(Q4*(2*A62041*R + 2*A62061*Q2*R) + dth2*(Q2*(2*A62221*R + 2*A62241*Q2*R) + dth2*(2*A62401*R + 2*A62601*dth2*R + 2*A62421*Q2*R)) + dr*(3*A63041*Q4*R + dth2*(3*A63401*dth2*R + 3*A63221*Q2*R) + dr*(Q2*(4*A64021*R + 4*A64041*Q2*R) + dth2*(4*A64201*R + 4*A64401*dth2*R + 4*A64221*Q2*R) + dr*(5*A65201*dth2*R + 5*A65021*Q2*R + dr*(6*A66001*R + 6*A66201*dth2*R + 6*A66021*Q2*R + dr*(7*A67001*R + 8*A68001*dr*R)))))); dA_dr[7] = dth2*(dth2*(dth2*(A71800*dth2 + A71620*Q2) + A71440*Q4) + A71260*Q6) + dr*(dth2*(dth2*(2*A72600*dth2 + 2*A72420*Q2) + 2*A72240*Q4) + 2*A72060*Q6 + dr*(dth2*(dth2*(3*A73600*dth2 + 3*A73420*Q2) + 3*A73240*Q4) + dr*(dth2*(4*A74400*dth2 + 4*A74220*Q2) + 4*A74040*Q4 + dr*(dth2*(5*A75400*dth2 + 5*A75220*Q2) + dr*(6*A76200*dth2 + 6*A76020*Q2 + dr*(dr*(8*A78000 + 9*A79000*dr) + 7*A77200*dth2 + 7*A77020*Q2)) + 5*A75040*Q4)) + 3*A73060*Q6)) + A71080*Q8; dA_dr[8] = dth*(A81161*Q6*R + dth2*(A81341*Q4*R + dth2*(A81701*dth2*R + A81521*Q2*R))) + dr*(dth*(2*A82141*Q4*R + dth2*(2*A82501*dth2*R + 2*A82321*Q2*R)) + dr*(dth*(3*A83141*Q4*R + dth2*(3*A83501*dth2*R + 3*A83321*Q2*R)) + dr*(dth*(4*A84301*dth2*R + 4*A84121*Q2*R) + dr*(dr*(6*A86101*dth*R + 7*A87101*dr*dth*R) + dth*(5*A85301*dth2*R + 5*A85121*Q2*R))))); dA_dr[9] = dth2*(dth2*(Q2*(A91420 + A91440*Q2) + dth2*(A91600 + A91800*dth2 + A91620*Q2)) + (A91240 + A91260*Q2)*Q4) + dr*(dth2*(Q2*(2*A92220 + 2*A92240*Q2) + dth2*(2*A92400 + 2*A92600*dth2 + 2*A92420*Q2)) + (2*A92040 + 2*A92060*Q2)*Q4 + dr*(dth2*(Q2*(3*A93220 + 3*A93240*Q2) + dth2*(3*A93400 + 3*A93600*dth2 + 3*A93420*Q2)) + dr*(Q2*(4*A94020 + 4*A94040*Q2) + dth2*(4*A94200 + 4*A94400*dth2 + 4*A94220*Q2) + dr*(Q2*(5*A95020 + 5*A95040*Q2) + dth2*(5*A95200 + 5*A95400*dth2 + 5*A95220*Q2) + dr*(6*A96000 + 6*A96200*dth2 + 6*A96020*Q2 + dr*(7*A97000 + dr*(8*A98000 + 9*A99000*dr) + 7*A97200*dth2 + 7*A97020*Q2)))) + (3*A93040 + 3*A93060*Q2)*Q4)) + (A91060 + A91080*Q2)*Q6; dA_dth[0] = dth*(dth2*(Q2*(4*A00420 + 4*A00440*Q2) + dth2*(6*A00600 + 8*A00800*dth2 + 6*A00620*Q2)) + (2*A00240 + 2*A00260*Q2)*Q4) + dr*(dr*(dth*(Q2*(2*A02220 + 2*A02240*Q2) + dth2*(4*A02400 + 6*A02600*dth2 + 4*A02420*Q2)) + dr*(dth*(Q2*(2*A03220 + 2*A03240*Q2) + dth2*(4*A03400 + 6*A03600*dth2 + 4*A03420*Q2)) + dr*(dth*(2*A04200 + 4*A04400*dth2 + 2*A04220*Q2) + dr*(dr*(2*A06200*dth + 2*A07200*dr*dth) + dth*(2*A05200 + 4*A05400*dth2 + 2*A05220*Q2))))) + dth*(dth2*(Q2*(4*A01420 + 4*A01440*Q2) + dth2*(6*A01600 + 8*A01800*dth2 + 6*A01620*Q2)) + (2*A01240 + 2*A01260*Q2)*Q4)); dA_dth[1] = dth*(Q4*(2*A10241*R + 2*A10261*Q2*R) + dth2*(Q2*(4*A10421*R + 4*A10441*Q2*R) + dth2*(6*A10601*R + 8*A10801*dth2*R + 6*A10621*Q2*R))) + dr*(dth*(2*A11241*Q4*R + dth2*(6*A11601*dth2*R + 4*A11421*Q2*R)) + dr*(dth*(Q2*(2*A12221*R + 2*A12241*Q2*R) + dth2*(4*A12401*R + 6*A12601*dth2*R + 4*A12421*Q2*R)) + dr*(dth*(4*A13401*dth2*R + 2*A13221*Q2*R) + dr*(dr*(2*A15201*dth*R + 2*A16201*dr*dth*R) + dth*(2*A14201*R + 4*A14401*dth2*R + 2*A14221*Q2*R))))); dA_dth[2] = A20161*Q6*R + dth2*(3*A20341*Q4*R + dth2*(7*A20701*dth2*R + 5*A20521*Q2*R)) + dr*(A21161*Q6*R + dth2*(3*A21341*Q4*R + dth2*(7*A21701*dth2*R + 5*A21521*Q2*R)) + dr*(A22141*Q4*R + dth2*(5*A22501*dth2*R + 3*A22321*Q2*R) + dr*(A23141*Q4*R + dth2*(5*A23501*dth2*R + 3*A23321*Q2*R) + dr*(3*A24301*dth2*R + A24121*Q2*R + dr*(3*A25301*dth2*R + A25121*Q2*R + dr*(A26101*R + A27101*dr*R)))))); dA_dth[3] = dth*(dth2*(Q2*(4*A30420 + 4*A30440*Q2) + dth2*(6*A30600 + 8*A30800*dth2 + 6*A30620*Q2)) + (2*A30240 + 2*A30260*Q2)*Q4) + dr*(dr*(dth*(Q2*(2*A32220 + 2*A32240*Q2) + dth2*(4*A32400 + 6*A32600*dth2 + 4*A32420*Q2)) + dr*(dth*(Q2*(2*A33220 + 2*A33240*Q2) + dth2*(4*A33400 + 6*A33600*dth2 + 4*A33420*Q2)) + dr*(dth*(2*A34200 + 4*A34400*dth2 + 2*A34220*Q2) + dr*(dr*(2*A36200*dth + 2*A37200*dr*dth) + dth*(2*A35200 + 4*A35400*dth2 + 2*A35220*Q2))))) + dth*(dth2*(Q2*(4*A31420 + 4*A31440*Q2) + dth2*(6*A31600 + 8*A31800*dth2 + 6*A31620*Q2)) + (2*A31240 + 2*A31260*Q2)*Q4)); dA_dth[4] = dth*(dth2*(dth2*(8*A40800*dth2 + 6*A40620*Q2) + 4*A40440*Q4) + 2*A40260*Q6) + dr*(dr*(dth*(dth2*(6*A42600*dth2 + 4*A42420*Q2) + 2*A42240*Q4) + dr*(dr*(dth*(4*A44400*dth2 + 2*A44220*Q2) + dr*(dr*(2*A46200*dth + 2*A47200*dr*dth) + dth*(4*A45400*dth2 + 2*A45220*Q2))) + dth*(dth2*(6*A43600*dth2 + 4*A43420*Q2) + 2*A43240*Q4))) + dth*(dth2*(dth2*(8*A41800*dth2 + 6*A41620*Q2) + 4*A41440*Q4) + 2*A41260*Q6)); dA_dth[5] = dth2*(dth2*(dth2*(9*A50900*dth2 + 7*A50720*Q2) + 5*A50540*Q4) + 3*A50360*Q6) + dr2*(dth2*(dth2*(7*A52700*dth2 + 5*A52520*Q2) + 3*A52340*Q4) + dr2*(dth2*(5*A54500*dth2 + 3*A54320*Q2) + dr2*(A58100*dr2 + 3*A56300*dth2 + A56120*Q2) + A54140*Q4) + A52160*Q6) + A50180*Q8; dA_dth[6] = dth*(Q4*(2*A60241*R + 2*A60261*Q2*R) + dth2*(Q2*(4*A60421*R + 4*A60441*Q2*R) + dth2*(6*A60601*R + 8*A60801*dth2*R + 6*A60621*Q2*R))) + dr*(dth*(2*A61241*Q4*R + dth2*(6*A61601*dth2*R + 4*A61421*Q2*R)) + dr*(dth*(Q2*(2*A62221*R + 2*A62241*Q2*R) + dth2*(4*A62401*R + 6*A62601*dth2*R + 4*A62421*Q2*R)) + dr*(dth*(4*A63401*dth2*R + 2*A63221*Q2*R) + dr*(dr*(2*A65201*dth*R + 2*A66201*dr*dth*R) + dth*(2*A64201*R + 4*A64401*dth2*R + 2*A64221*Q2*R))))); dA_dth[7] = dth*(dth2*(dth2*(8*A70800*dth2 + 6*A70620*Q2) + 4*A70440*Q4) + 2*A70260*Q6) + dr*(dr*(dth*(dth2*(6*A72600*dth2 + 4*A72420*Q2) + 2*A72240*Q4) + dr*(dr*(dth*(4*A74400*dth2 + 2*A74220*Q2) + dr*(dr*(2*A76200*dth + 2*A77200*dr*dth) + dth*(4*A75400*dth2 + 2*A75220*Q2))) + dth*(dth2*(6*A73600*dth2 + 4*A73420*Q2) + 2*A73240*Q4))) + dth*(dth2*(dth2*(8*A71800*dth2 + 6*A71620*Q2) + 4*A71440*Q4) + 2*A71260*Q6)); dA_dth[8] = A80161*Q6*R + dth2*(3*A80341*Q4*R + dth2*(7*A80701*dth2*R + 5*A80521*Q2*R)) + dr*(A81161*Q6*R + dth2*(3*A81341*Q4*R + dth2*(7*A81701*dth2*R + 5*A81521*Q2*R)) + dr*(A82141*Q4*R + dth2*(5*A82501*dth2*R + 3*A82321*Q2*R) + dr*(A83141*Q4*R + dth2*(5*A83501*dth2*R + 3*A83321*Q2*R) + dr*(3*A84301*dth2*R + A84121*Q2*R + dr*(3*A85301*dth2*R + A85121*Q2*R + dr*(A86101*R + A87101*dr*R)))))); dA_dth[9] = dth*(dth2*(Q2*(4*A90420 + 4*A90440*Q2) + dth2*(6*A90600 + 8*A90800*dth2 + 6*A90620*Q2)) + (2*A90240 + 2*A90260*Q2)*Q4) + dr*(dr*(dth*(Q2*(2*A92220 + 2*A92240*Q2) + dth2*(4*A92400 + 6*A92600*dth2 + 4*A92420*Q2)) + dr*(dth*(Q2*(2*A93220 + 2*A93240*Q2) + dth2*(4*A93400 + 6*A93600*dth2 + 4*A93420*Q2)) + dr*(dth*(2*A94200 + 4*A94400*dth2 + 2*A94220*Q2) + dr*(dr*(2*A96200*dth + 2*A97200*dr*dth) + dth*(2*A95200 + 4*A95400*dth2 + 2*A95220*Q2))))) + dth*(dth2*(Q2*(4*A91420 + 4*A91440*Q2) + dth2*(6*A91600 + 8*A91800*dth2 + 6*A91620*Q2)) + (2*A91240 + 2*A91260*Q2)*Q4)); dA_dQ[0] = dth2*(dth2*(2*A00620*dth2*Q + Q*(2*A00420 + 4*A00440*Q2)) + (4*A00240 + 6*A00260*Q2)*Q3) + (6*A00060 + 8*A00080*Q2)*Q5 + dr*(dth2*(dth2*(2*A01620*dth2*Q + Q*(2*A01420 + 4*A01440*Q2)) + (4*A01240 + 6*A01260*Q2)*Q3) + dr*(dth2*(2*A02420*dth2*Q + Q*(2*A02220 + 4*A02240*Q2)) + (4*A02040 + 6*A02060*Q2)*Q3 + dr*(dth2*(2*A03420*dth2*Q + Q*(2*A03220 + 4*A03240*Q2)) + dr*(2*A04220*dth2*Q + Q*(2*A04020 + 4*A04040*Q2) + dr*(2*A05220*dth2*Q + dr*(2*A06020*Q + 2*A07020*dr*Q) + Q*(2*A05020 + 4*A05040*Q2))) + (4*A03040 + 6*A03060*Q2)*Q3)) + (6*A01060 + 8*A01080*Q2)*Q5); dA_dQ[1] = Q5*(6*A10061*R + 8*A10081*Q2*R) + dth2*(Q3*(4*A10241*R + 6*A10261*Q2*R) + dth2*(2*A10621*dth2*Q*R + Q*(2*A10421*R + 4*A10441*Q2*R))) + dr*(6*A11061*Q5*R + dth2*(2*A11421*dth2*Q*R + 4*A11241*Q3*R) + dr*(Q3*(4*A12041*R + 6*A12061*Q2*R) + dth2*(2*A12421*dth2*Q*R + Q*(2*A12221*R + 4*A12241*Q2*R)) + dr*(2*A13221*dth2*Q*R + 4*A13041*Q3*R + dr*(2*A14221*dth2*Q*R + dr*(2*A15021*Q*R + 2*A16021*dr*Q*R) + Q*(2*A14021*R + 4*A14041*Q2*R))))); dA_dQ[2] = dth*(6*A20161*Q5*R + dth2*(2*A20521*dth2*Q*R + 4*A20341*Q3*R)) + dr*(dth*(6*A21161*Q5*R + dth2*(2*A21521*dth2*Q*R + 4*A21341*Q3*R)) + dr*(dth*(2*A22321*dth2*Q*R + 4*A22141*Q3*R) + dr*(dr*(2*A24121*dth*Q*R + 2*A25121*dr*dth*Q*R) + dth*(2*A23321*dth2*Q*R + 4*A23141*Q3*R)))); dA_dQ[3] = dth2*(dth2*(2*A30620*dth2*Q + Q*(2*A30420 + 4*A30440*Q2)) + (4*A30240 + 6*A30260*Q2)*Q3) + (6*A30060 + 8*A30080*Q2)*Q5 + dr*(dth2*(dth2*(2*A31620*dth2*Q + Q*(2*A31420 + 4*A31440*Q2)) + (4*A31240 + 6*A31260*Q2)*Q3) + dr*(dth2*(2*A32420*dth2*Q + Q*(2*A32220 + 4*A32240*Q2)) + (4*A32040 + 6*A32060*Q2)*Q3 + dr*(dth2*(2*A33420*dth2*Q + Q*(2*A33220 + 4*A33240*Q2)) + dr*(2*A34220*dth2*Q + Q*(2*A34020 + 4*A34040*Q2) + dr*(2*A35220*dth2*Q + dr*(2*A36020*Q + 2*A37020*dr*Q) + Q*(2*A35020 + 4*A35040*Q2))) + (4*A33040 + 6*A33060*Q2)*Q3)) + (6*A31060 + 8*A31080*Q2)*Q5); dA_dQ[4] = dth2*(dth2*(2*A40620*dth2*Q + 4*A40440*Q3) + 6*A40260*Q5) + 8*A40080*Q7 + dr*(dth2*(dth2*(2*A41620*dth2*Q + 4*A41440*Q3) + 6*A41260*Q5) + dr*(dth2*(2*A42420*dth2*Q + 4*A42240*Q3) + 6*A42060*Q5 + dr*(dth2*(2*A43420*dth2*Q + 4*A43240*Q3) + dr*(2*A44220*dth2*Q + 4*A44040*Q3 + dr*(2*A45220*dth2*Q + dr*(2*A46020*Q + 2*A47020*dr*Q) + 4*A45040*Q3)) + 6*A43060*Q5)) + 8*A41080*Q7); dA_dQ[5] = dr2*(dr2*(2*A56120*dr2*dth*Q + dth*(2*A54320*dth2*Q + 4*A54140*Q3)) + dth*(dth2*(2*A52520*dth2*Q + 4*A52340*Q3) + 6*A52160*Q5)) + dth*(dth2*(dth2*(2*A50720*dth2*Q + 4*A50540*Q3) + 6*A50360*Q5) + 8*A50180*Q7); dA_dQ[6] = Q5*(6*A60061*R + 8*A60081*Q2*R) + dth2*(Q3*(4*A60241*R + 6*A60261*Q2*R) + dth2*(2*A60621*dth2*Q*R + Q*(2*A60421*R + 4*A60441*Q2*R))) + dr*(6*A61061*Q5*R + dth2*(2*A61421*dth2*Q*R + 4*A61241*Q3*R) + dr*(Q3*(4*A62041*R + 6*A62061*Q2*R) + dth2*(2*A62421*dth2*Q*R + Q*(2*A62221*R + 4*A62241*Q2*R)) + dr*(2*A63221*dth2*Q*R + 4*A63041*Q3*R + dr*(2*A64221*dth2*Q*R + dr*(2*A65021*Q*R + 2*A66021*dr*Q*R) + Q*(2*A64021*R + 4*A64041*Q2*R))))); dA_dQ[7] = dth2*(dth2*(2*A70620*dth2*Q + 4*A70440*Q3) + 6*A70260*Q5) + 8*A70080*Q7 + dr*(dth2*(dth2*(2*A71620*dth2*Q + 4*A71440*Q3) + 6*A71260*Q5) + dr*(dth2*(2*A72420*dth2*Q + 4*A72240*Q3) + 6*A72060*Q5 + dr*(dth2*(2*A73420*dth2*Q + 4*A73240*Q3) + dr*(2*A74220*dth2*Q + 4*A74040*Q3 + dr*(2*A75220*dth2*Q + dr*(2*A76020*Q + 2*A77020*dr*Q) + 4*A75040*Q3)) + 6*A73060*Q5)) + 8*A71080*Q7); dA_dQ[8] = dth*(6*A80161*Q5*R + dth2*(2*A80521*dth2*Q*R + 4*A80341*Q3*R)) + dr*(dth*(6*A81161*Q5*R + dth2*(2*A81521*dth2*Q*R + 4*A81341*Q3*R)) + dr*(dth*(2*A82321*dth2*Q*R + 4*A82141*Q3*R) + dr*(dr*(2*A84121*dth*Q*R + 2*A85121*dr*dth*Q*R) + dth*(2*A83321*dth2*Q*R + 4*A83141*Q3*R)))); dA_dQ[9] = dth2*(dth2*(2*A90620*dth2*Q + Q*(2*A90420 + 4*A90440*Q2)) + (4*A90240 + 6*A90260*Q2)*Q3) + (6*A90060 + 8*A90080*Q2)*Q5 + dr*(dth2*(dth2*(2*A91620*dth2*Q + Q*(2*A91420 + 4*A91440*Q2)) + (4*A91240 + 6*A91260*Q2)*Q3) + dr*(dth2*(2*A92420*dth2*Q + Q*(2*A92220 + 4*A92240*Q2)) + (4*A92040 + 6*A92060*Q2)*Q3 + dr*(dth2*(2*A93420*dth2*Q + Q*(2*A93220 + 4*A93240*Q2)) + dr*(2*A94220*dth2*Q + Q*(2*A94020 + 4*A94040*Q2) + dr*(2*A95220*dth2*Q + dr*(2*A96020*Q + 2*A97020*dr*Q) + Q*(2*A95020 + 4*A95040*Q2))) + (4*A93040 + 6*A93060*Q2)*Q3)) + (6*A91060 + 8*A91080*Q2)*Q5); dA_dR[0] = 0; dA_dR[1] = dth2*(dth2*(Q2*(A10421 + A10441*Q2) + dth2*(A10601 + A10801*dth2 + A10621*Q2)) + (A10241 + A10261*Q2)*Q4) + (A10061 + A10081*Q2)*Q6 + dr*(dth2*(dth2*(A11601*dth2 + A11421*Q2) + A11241*Q4) + dr*(dth2*(Q2*(A12221 + A12241*Q2) + dth2*(A12401 + A12601*dth2 + A12421*Q2)) + (A12041 + A12061*Q2)*Q4 + dr*(dth2*(A13401*dth2 + A13221*Q2) + dr*(Q2*(A14021 + A14041*Q2) + dth2*(A14201 + A14401*dth2 + A14221*Q2) + dr*(A15201*dth2 + A15021*Q2 + dr*(A16001 + dr*(A17001 + A18001*dr) + A16201*dth2 + A16021*Q2))) + A13041*Q4)) + A11061*Q6); dA_dR[2] = dth*(dth2*(dth2*(A20701*dth2 + A20521*Q2) + A20341*Q4) + A20161*Q6) + dr*(dr*(dth*(dth2*(A22501*dth2 + A22321*Q2) + A22141*Q4) + dr*(dr*(dth*(A24301*dth2 + A24121*Q2) + dr*(dr*(A26101*dth + A27101*dr*dth) + dth*(A25301*dth2 + A25121*Q2))) + dth*(dth2*(A23501*dth2 + A23321*Q2) + A23141*Q4))) + dth*(dth2*(dth2*(A21701*dth2 + A21521*Q2) + A21341*Q4) + A21161*Q6)); dA_dR[3] = 0; dA_dR[4] = 0; dA_dR[5] = 0; dA_dR[6] = dth2*(dth2*(Q2*(A60421 + A60441*Q2) + dth2*(A60601 + A60801*dth2 + A60621*Q2)) + (A60241 + A60261*Q2)*Q4) + (A60061 + A60081*Q2)*Q6 + dr*(dth2*(dth2*(A61601*dth2 + A61421*Q2) + A61241*Q4) + dr*(dth2*(Q2*(A62221 + A62241*Q2) + dth2*(A62401 + A62601*dth2 + A62421*Q2)) + (A62041 + A62061*Q2)*Q4 + dr*(dth2*(A63401*dth2 + A63221*Q2) + dr*(Q2*(A64021 + A64041*Q2) + dth2*(A64201 + A64401*dth2 + A64221*Q2) + dr*(A65201*dth2 + A65021*Q2 + dr*(A66001 + dr*(A67001 + A68001*dr) + A66201*dth2 + A66021*Q2))) + A63041*Q4)) + A61061*Q6); dA_dR[7] = 0; dA_dR[8] = dth*(dth2*(dth2*(A80701*dth2 + A80521*Q2) + A80341*Q4) + A80161*Q6) + dr*(dr*(dth*(dth2*(A82501*dth2 + A82321*Q2) + A82141*Q4) + dr*(dr*(dth*(A84301*dth2 + A84121*Q2) + dr*(dr*(A86101*dth + A87101*dr*dth) + dth*(A85301*dth2 + A85121*Q2))) + dth*(dth2*(A83501*dth2 + A83321*Q2) + A83141*Q4))) + dth*(dth2*(dth2*(A81701*dth2 + A81521*Q2) + A81341*Q4) + A81161*Q6)); dA_dR[9] = 0; for(int i=0; i<10; i++) { dA_dph[i] = dA_dQ[i]*dQ_dph + dA_dR[i]*dR_dph; dA_dt[i] = -Omega*dA_dph[i]; } /* d^2A/dx^2 */ d2A_dr2[0] = dth2*(Q2*(2*A02220 + 2*A02240*Q2) + dth2*(2*A02400 + 2*A02600*dth2 + 2*A02420*Q2)) + (2*A02040 + 2*A02060*Q2)*Q4 + dr*(dth2*(Q2*(6*A03220 + 6*A03240*Q2) + dth2*(6*A03400 + 6*A03600*dth2 + 6*A03420*Q2)) + dr*(Q2*(12*A04020 + 12*A04040*Q2) + dth2*(12*A04200 + 12*A04400*dth2 + 12*A04220*Q2) + dr*(Q2*(20*A05020 + 20*A05040*Q2) + dth2*(20*A05200 + 20*A05400*dth2 + 20*A05220*Q2) + dr*(30*A06000 + 30*A06200*dth2 + 30*A06020*Q2 + dr*(42*A07000 + dr*(56*A08000 + 72*A09000*dr) + 42*A07200*dth2 + 42*A07020*Q2)))) + (6*A03040 + 6*A03060*Q2)*Q4); d2A_dr2[1] = Q4*(2*A12041*R + 2*A12061*Q2*R) + dth2*(Q2*(2*A12221*R + 2*A12241*Q2*R) + dth2*(2*A12401*R + 2*A12601*dth2*R + 2*A12421*Q2*R)) + dr*(6*A13041*Q4*R + dth2*(6*A13401*dth2*R + 6*A13221*Q2*R) + dr*(Q2*(12*A14021*R + 12*A14041*Q2*R) + dth2*(12*A14201*R + 12*A14401*dth2*R + 12*A14221*Q2*R) + dr*(20*A15201*dth2*R + 20*A15021*Q2*R + dr*(30*A16001*R + 30*A16201*dth2*R + 30*A16021*Q2*R + dr*(42*A17001*R + 56*A18001*dr*R))))); d2A_dr2[2] = dth*(2*A22141*Q4*R + dth2*(2*A22501*dth2*R + 2*A22321*Q2*R)) + dr*(dth*(6*A23141*Q4*R + dth2*(6*A23501*dth2*R + 6*A23321*Q2*R)) + dr*(dth*(12*A24301*dth2*R + 12*A24121*Q2*R) + dr*(dr*(30*A26101*dth*R + 42*A27101*dr*dth*R) + dth*(20*A25301*dth2*R + 20*A25121*Q2*R)))); d2A_dr2[3] = dth2*(Q2*(2*A32220 + 2*A32240*Q2) + dth2*(2*A32400 + 2*A32600*dth2 + 2*A32420*Q2)) + (2*A32040 + 2*A32060*Q2)*Q4 + dr*(dth2*(Q2*(6*A33220 + 6*A33240*Q2) + dth2*(6*A33400 + 6*A33600*dth2 + 6*A33420*Q2)) + dr*(Q2*(12*A34020 + 12*A34040*Q2) + dth2*(12*A34200 + 12*A34400*dth2 + 12*A34220*Q2) + dr*(Q2*(20*A35020 + 20*A35040*Q2) + dth2*(20*A35200 + 20*A35400*dth2 + 20*A35220*Q2) + dr*(30*A36000 + 30*A36200*dth2 + 30*A36020*Q2 + dr*(42*A37000 + dr*(56*A38000 + 72*A39000*dr) + 42*A37200*dth2 + 42*A37020*Q2)))) + (6*A33040 + 6*A33060*Q2)*Q4); d2A_dr2[4] = dth2*(dth2*(2*A42600*dth2 + 2*A42420*Q2) + 2*A42240*Q4) + 2*A42060*Q6 + dr*(dth2*(dth2*(6*A43600*dth2 + 6*A43420*Q2) + 6*A43240*Q4) + dr*(dth2*(12*A44400*dth2 + 12*A44220*Q2) + 12*A44040*Q4 + dr*(dth2*(20*A45400*dth2 + 20*A45220*Q2) + dr*(30*A46200*dth2 + 30*A46020*Q2 + dr*(dr*(56*A48000 + 72*A49000*dr) + 42*A47200*dth2 + 42*A47020*Q2)) + 20*A45040*Q4)) + 6*A43060*Q6); d2A_dr2[5] = dr2*(dr2*(56*A58100*dr2*dth + dth*(30*A56300*dth2 + 30*A56120*Q2)) + dth*(dth2*(12*A54500*dth2 + 12*A54320*Q2) + 12*A54140*Q4)) + dth*(dth2*(dth2*(2*A52700*dth2 + 2*A52520*Q2) + 2*A52340*Q4) + 2*A52160*Q6); d2A_dr2[6] = Q4*(2*A62041*R + 2*A62061*Q2*R) + dth2*(Q2*(2*A62221*R + 2*A62241*Q2*R) + dth2*(2*A62401*R + 2*A62601*dth2*R + 2*A62421*Q2*R)) + dr*(6*A63041*Q4*R + dth2*(6*A63401*dth2*R + 6*A63221*Q2*R) + dr*(Q2*(12*A64021*R + 12*A64041*Q2*R) + dth2*(12*A64201*R + 12*A64401*dth2*R + 12*A64221*Q2*R) + dr*(20*A65201*dth2*R + 20*A65021*Q2*R + dr*(30*A66001*R + 30*A66201*dth2*R + 30*A66021*Q2*R + dr*(42*A67001*R + 56*A68001*dr*R))))); d2A_dr2[7] = dth2*(dth2*(2*A72600*dth2 + 2*A72420*Q2) + 2*A72240*Q4) + 2*A72060*Q6 + dr*(dth2*(dth2*(6*A73600*dth2 + 6*A73420*Q2) + 6*A73240*Q4) + dr*(dth2*(12*A74400*dth2 + 12*A74220*Q2) + 12*A74040*Q4 + dr*(dth2*(20*A75400*dth2 + 20*A75220*Q2) + dr*(30*A76200*dth2 + 30*A76020*Q2 + dr*(dr*(56*A78000 + 72*A79000*dr) + 42*A77200*dth2 + 42*A77020*Q2)) + 20*A75040*Q4)) + 6*A73060*Q6); d2A_dr2[8] = dth*(2*A82141*Q4*R + dth2*(2*A82501*dth2*R + 2*A82321*Q2*R)) + dr*(dth*(6*A83141*Q4*R + dth2*(6*A83501*dth2*R + 6*A83321*Q2*R)) + dr*(dth*(12*A84301*dth2*R + 12*A84121*Q2*R) + dr*(dr*(30*A86101*dth*R + 42*A87101*dr*dth*R) + dth*(20*A85301*dth2*R + 20*A85121*Q2*R)))); d2A_dr2[9] = dth2*(Q2*(2*A92220 + 2*A92240*Q2) + dth2*(2*A92400 + 2*A92600*dth2 + 2*A92420*Q2)) + (2*A92040 + 2*A92060*Q2)*Q4 + dr*(dth2*(Q2*(6*A93220 + 6*A93240*Q2) + dth2*(6*A93400 + 6*A93600*dth2 + 6*A93420*Q2)) + dr*(Q2*(12*A94020 + 12*A94040*Q2) + dth2*(12*A94200 + 12*A94400*dth2 + 12*A94220*Q2) + dr*(Q2*(20*A95020 + 20*A95040*Q2) + dth2*(20*A95200 + 20*A95400*dth2 + 20*A95220*Q2) + dr*(30*A96000 + 30*A96200*dth2 + 30*A96020*Q2 + dr*(42*A97000 + dr*(56*A98000 + 72*A99000*dr) + 42*A97200*dth2 + 42*A97020*Q2)))) + (6*A93040 + 6*A93060*Q2)*Q4); d2A_dth2[0] = dth2*(Q2*(12*A00420 + 12*A00440*Q2) + dth2*(30*A00600 + 56*A00800*dth2 + 30*A00620*Q2)) + (2*A00240 + 2*A00260*Q2)*Q4 + dr*(dth2*(Q2*(12*A01420 + 12*A01440*Q2) + dth2*(30*A01600 + 56*A01800*dth2 + 30*A01620*Q2)) + dr*(Q2*(2*A02220 + 2*A02240*Q2) + dth2*(12*A02400 + 30*A02600*dth2 + 12*A02420*Q2) + dr*(Q2*(2*A03220 + 2*A03240*Q2) + dth2*(12*A03400 + 30*A03600*dth2 + 12*A03420*Q2) + dr*(2*A04200 + 12*A04400*dth2 + 2*A04220*Q2 + dr*(2*A05200 + dr*(2*A06200 + 2*A07200*dr) + 12*A05400*dth2 + 2*A05220*Q2)))) + (2*A01240 + 2*A01260*Q2)*Q4); d2A_dth2[1] = Q4*(2*A10241*R + 2*A10261*Q2*R) + dth2*(Q2*(12*A10421*R + 12*A10441*Q2*R) + dth2*(30*A10601*R + 56*A10801*dth2*R + 30*A10621*Q2*R)) + dr*(2*A11241*Q4*R + dth2*(30*A11601*dth2*R + 12*A11421*Q2*R) + dr*(Q2*(2*A12221*R + 2*A12241*Q2*R) + dth2*(12*A12401*R + 30*A12601*dth2*R + 12*A12421*Q2*R) + dr*(12*A13401*dth2*R + 2*A13221*Q2*R + dr*(2*A14201*R + 12*A14401*dth2*R + 2*A14221*Q2*R + dr*(2*A15201*R + 2*A16201*dr*R))))); d2A_dth2[2] = dth*(6*A20341*Q4*R + dth2*(42*A20701*dth2*R + 20*A20521*Q2*R)) + dr*(dth*(6*A21341*Q4*R + dth2*(42*A21701*dth2*R + 20*A21521*Q2*R)) + dr*(dth*(20*A22501*dth2*R + 6*A22321*Q2*R) + dr*(dr*(6*A24301*dth*R + 6*A25301*dr*dth*R) + dth*(20*A23501*dth2*R + 6*A23321*Q2*R)))); d2A_dth2[3] = dth2*(Q2*(12*A30420 + 12*A30440*Q2) + dth2*(30*A30600 + 56*A30800*dth2 + 30*A30620*Q2)) + (2*A30240 + 2*A30260*Q2)*Q4 + dr*(dth2*(Q2*(12*A31420 + 12*A31440*Q2) + dth2*(30*A31600 + 56*A31800*dth2 + 30*A31620*Q2)) + dr*(Q2*(2*A32220 + 2*A32240*Q2) + dth2*(12*A32400 + 30*A32600*dth2 + 12*A32420*Q2) + dr*(Q2*(2*A33220 + 2*A33240*Q2) + dth2*(12*A33400 + 30*A33600*dth2 + 12*A33420*Q2) + dr*(2*A34200 + 12*A34400*dth2 + 2*A34220*Q2 + dr*(2*A35200 + dr*(2*A36200 + 2*A37200*dr) + 12*A35400*dth2 + 2*A35220*Q2)))) + (2*A31240 + 2*A31260*Q2)*Q4); d2A_dth2[4] = dth2*(dth2*(56*A40800*dth2 + 30*A40620*Q2) + 12*A40440*Q4) + 2*A40260*Q6 + dr*(dth2*(dth2*(56*A41800*dth2 + 30*A41620*Q2) + 12*A41440*Q4) + dr*(dth2*(30*A42600*dth2 + 12*A42420*Q2) + 2*A42240*Q4 + dr*(dth2*(30*A43600*dth2 + 12*A43420*Q2) + dr*(12*A44400*dth2 + 2*A44220*Q2 + dr*(dr*(2*A46200 + 2*A47200*dr) + 12*A45400*dth2 + 2*A45220*Q2)) + 2*A43240*Q4)) + 2*A41260*Q6); d2A_dth2[5] = dr2*(dr2*(6*A56300*dr2*dth + dth*(20*A54500*dth2 + 6*A54320*Q2)) + dth*(dth2*(42*A52700*dth2 + 20*A52520*Q2) + 6*A52340*Q4)) + dth*(dth2*(dth2*(72*A50900*dth2 + 42*A50720*Q2) + 20*A50540*Q4) + 6*A50360*Q6); d2A_dth2[6] = Q4*(2*A60241*R + 2*A60261*Q2*R) + dth2*(Q2*(12*A60421*R + 12*A60441*Q2*R) + dth2*(30*A60601*R + 56*A60801*dth2*R + 30*A60621*Q2*R)) + dr*(2*A61241*Q4*R + dth2*(30*A61601*dth2*R + 12*A61421*Q2*R) + dr*(Q2*(2*A62221*R + 2*A62241*Q2*R) + dth2*(12*A62401*R + 30*A62601*dth2*R + 12*A62421*Q2*R) + dr*(12*A63401*dth2*R + 2*A63221*Q2*R + dr*(2*A64201*R + 12*A64401*dth2*R + 2*A64221*Q2*R + dr*(2*A65201*R + 2*A66201*dr*R))))); d2A_dth2[7] = dth2*(dth2*(56*A70800*dth2 + 30*A70620*Q2) + 12*A70440*Q4) + 2*A70260*Q6 + dr*(dth2*(dth2*(56*A71800*dth2 + 30*A71620*Q2) + 12*A71440*Q4) + dr*(dth2*(30*A72600*dth2 + 12*A72420*Q2) + 2*A72240*Q4 + dr*(dth2*(30*A73600*dth2 + 12*A73420*Q2) + dr*(12*A74400*dth2 + 2*A74220*Q2 + dr*(dr*(2*A76200 + 2*A77200*dr) + 12*A75400*dth2 + 2*A75220*Q2)) + 2*A73240*Q4)) + 2*A71260*Q6); d2A_dth2[8] = dth*(6*A80341*Q4*R + dth2*(42*A80701*dth2*R + 20*A80521*Q2*R)) + dr*(dth*(6*A81341*Q4*R + dth2*(42*A81701*dth2*R + 20*A81521*Q2*R)) + dr*(dth*(20*A82501*dth2*R + 6*A82321*Q2*R) + dr*(dr*(6*A84301*dth*R + 6*A85301*dr*dth*R) + dth*(20*A83501*dth2*R + 6*A83321*Q2*R)))); d2A_dth2[9] = dth2*(Q2*(12*A90420 + 12*A90440*Q2) + dth2*(30*A90600 + 56*A90800*dth2 + 30*A90620*Q2)) + (2*A90240 + 2*A90260*Q2)*Q4 + dr*(dth2*(Q2*(12*A91420 + 12*A91440*Q2) + dth2*(30*A91600 + 56*A91800*dth2 + 30*A91620*Q2)) + dr*(Q2*(2*A92220 + 2*A92240*Q2) + dth2*(12*A92400 + 30*A92600*dth2 + 12*A92420*Q2) + dr*(Q2*(2*A93220 + 2*A93240*Q2) + dth2*(12*A93400 + 30*A93600*dth2 + 12*A93420*Q2) + dr*(2*A94200 + 12*A94400*dth2 + 2*A94220*Q2 + dr*(2*A95200 + dr*(2*A96200 + 2*A97200*dr) + 12*A95400*dth2 + 2*A95220*Q2)))) + (2*A91240 + 2*A91260*Q2)*Q4); d2A_dQ2[0] = dth2*(Q2*(12*A00240 + 30*A00260*Q2) + dth2*(2*A00420 + 2*A00620*dth2 + 12*A00440*Q2)) + (30*A00060 + 56*A00080*Q2)*Q4 + dr*(dth2*(Q2*(12*A01240 + 30*A01260*Q2) + dth2*(2*A01420 + 2*A01620*dth2 + 12*A01440*Q2)) + dr*(Q2*(12*A02040 + 30*A02060*Q2) + dth2*(2*A02220 + 2*A02420*dth2 + 12*A02240*Q2) + dr*(Q2*(12*A03040 + 30*A03060*Q2) + dth2*(2*A03220 + 2*A03420*dth2 + 12*A03240*Q2) + dr*(2*A04020 + 2*A04220*dth2 + 12*A04040*Q2 + dr*(2*A05020 + dr*(2*A06020 + 2*A07020*dr) + 2*A05220*dth2 + 12*A05040*Q2)))) + (30*A01060 + 56*A01080*Q2)*Q4); d2A_dQ2[1] = Q4*(30*A10061*R + 56*A10081*Q2*R) + dth2*(Q2*(12*A10241*R + 30*A10261*Q2*R) + dth2*(2*A10421*R + 2*A10621*dth2*R + 12*A10441*Q2*R)) + dr*(30*A11061*Q4*R + dth2*(2*A11421*dth2*R + 12*A11241*Q2*R) + dr*(Q2*(12*A12041*R + 30*A12061*Q2*R) + dth2*(2*A12221*R + 2*A12421*dth2*R + 12*A12241*Q2*R) + dr*(2*A13221*dth2*R + 12*A13041*Q2*R + dr*(2*A14021*R + 2*A14221*dth2*R + 12*A14041*Q2*R + dr*(2*A15021*R + 2*A16021*dr*R))))); d2A_dQ2[2] = dth*(30*A20161*Q4*R + dth2*(2*A20521*dth2*R + 12*A20341*Q2*R)) + dr*(dth*(30*A21161*Q4*R + dth2*(2*A21521*dth2*R + 12*A21341*Q2*R)) + dr*(dth*(2*A22321*dth2*R + 12*A22141*Q2*R) + dr*(dr*(2*A24121*dth*R + 2*A25121*dr*dth*R) + dth*(2*A23321*dth2*R + 12*A23141*Q2*R)))); d2A_dQ2[3] = dth2*(Q2*(12*A30240 + 30*A30260*Q2) + dth2*(2*A30420 + 2*A30620*dth2 + 12*A30440*Q2)) + (30*A30060 + 56*A30080*Q2)*Q4 + dr*(dth2*(Q2*(12*A31240 + 30*A31260*Q2) + dth2*(2*A31420 + 2*A31620*dth2 + 12*A31440*Q2)) + dr*(Q2*(12*A32040 + 30*A32060*Q2) + dth2*(2*A32220 + 2*A32420*dth2 + 12*A32240*Q2) + dr*(Q2*(12*A33040 + 30*A33060*Q2) + dth2*(2*A33220 + 2*A33420*dth2 + 12*A33240*Q2) + dr*(2*A34020 + 2*A34220*dth2 + 12*A34040*Q2 + dr*(2*A35020 + dr*(2*A36020 + 2*A37020*dr) + 2*A35220*dth2 + 12*A35040*Q2)))) + (30*A31060 + 56*A31080*Q2)*Q4); d2A_dQ2[4] = dth2*(dth2*(2*A40620*dth2 + 12*A40440*Q2) + 30*A40260*Q4) + 56*A40080*Q6 + dr*(dth2*(dth2*(2*A41620*dth2 + 12*A41440*Q2) + 30*A41260*Q4) + dr*(dth2*(2*A42420*dth2 + 12*A42240*Q2) + 30*A42060*Q4 + dr*(dth2*(2*A43420*dth2 + 12*A43240*Q2) + dr*(2*A44220*dth2 + 12*A44040*Q2 + dr*(dr*(2*A46020 + 2*A47020*dr) + 2*A45220*dth2 + 12*A45040*Q2)) + 30*A43060*Q4)) + 56*A41080*Q6); d2A_dQ2[5] = dr2*(dr2*(2*A56120*dr2*dth + dth*(2*A54320*dth2 + 12*A54140*Q2)) + dth*(dth2*(2*A52520*dth2 + 12*A52340*Q2) + 30*A52160*Q4)) + dth*(dth2*(dth2*(2*A50720*dth2 + 12*A50540*Q2) + 30*A50360*Q4) + 56*A50180*Q6); d2A_dQ2[6] = Q4*(30*A60061*R + 56*A60081*Q2*R) + dth2*(Q2*(12*A60241*R + 30*A60261*Q2*R) + dth2*(2*A60421*R + 2*A60621*dth2*R + 12*A60441*Q2*R)) + dr*(30*A61061*Q4*R + dth2*(2*A61421*dth2*R + 12*A61241*Q2*R) + dr*(Q2*(12*A62041*R + 30*A62061*Q2*R) + dth2*(2*A62221*R + 2*A62421*dth2*R + 12*A62241*Q2*R) + dr*(2*A63221*dth2*R + 12*A63041*Q2*R + dr*(2*A64021*R + 2*A64221*dth2*R + 12*A64041*Q2*R + dr*(2*A65021*R + 2*A66021*dr*R))))); d2A_dQ2[7] = dth2*(dth2*(2*A70620*dth2 + 12*A70440*Q2) + 30*A70260*Q4) + 56*A70080*Q6 + dr*(dth2*(dth2*(2*A71620*dth2 + 12*A71440*Q2) + 30*A71260*Q4) + dr*(dth2*(2*A72420*dth2 + 12*A72240*Q2) + 30*A72060*Q4 + dr*(dth2*(2*A73420*dth2 + 12*A73240*Q2) + dr*(2*A74220*dth2 + 12*A74040*Q2 + dr*(dr*(2*A76020 + 2*A77020*dr) + 2*A75220*dth2 + 12*A75040*Q2)) + 30*A73060*Q4)) + 56*A71080*Q6); d2A_dQ2[8] = dth*(30*A80161*Q4*R + dth2*(2*A80521*dth2*R + 12*A80341*Q2*R)) + dr*(dth*(30*A81161*Q4*R + dth2*(2*A81521*dth2*R + 12*A81341*Q2*R)) + dr*(dth*(2*A82321*dth2*R + 12*A82141*Q2*R) + dr*(dr*(2*A84121*dth*R + 2*A85121*dr*dth*R) + dth*(2*A83321*dth2*R + 12*A83141*Q2*R)))); d2A_dQ2[9] = dth2*(Q2*(12*A90240 + 30*A90260*Q2) + dth2*(2*A90420 + 2*A90620*dth2 + 12*A90440*Q2)) + (30*A90060 + 56*A90080*Q2)*Q4 + dr*(dth2*(Q2*(12*A91240 + 30*A91260*Q2) + dth2*(2*A91420 + 2*A91620*dth2 + 12*A91440*Q2)) + dr*(Q2*(12*A92040 + 30*A92060*Q2) + dth2*(2*A92220 + 2*A92420*dth2 + 12*A92240*Q2) + dr*(Q2*(12*A93040 + 30*A93060*Q2) + dth2*(2*A93220 + 2*A93420*dth2 + 12*A93240*Q2) + dr*(2*A94020 + 2*A94220*dth2 + 12*A94040*Q2 + dr*(2*A95020 + dr*(2*A96020 + 2*A97020*dr) + 2*A95220*dth2 + 12*A95040*Q2)))) + (30*A91060 + 56*A91080*Q2)*Q4); d2A_dQR[0] = 0; d2A_dQR[1] = dth2*(dth2*(2*A10621*dth2*Q + Q*(2*A10421 + 4*A10441*Q2)) + (4*A10241 + 6*A10261*Q2)*Q3) + (6*A10061 + 8*A10081*Q2)*Q5 + dr*(dth2*(2*A11421*dth2*Q + 4*A11241*Q3) + dr*(dth2*(2*A12421*dth2*Q + Q*(2*A12221 + 4*A12241*Q2)) + (4*A12041 + 6*A12061*Q2)*Q3 + dr*(2*A13221*dth2*Q + dr*(2*A14221*dth2*Q + dr*(2*A15021*Q + 2*A16021*dr*Q) + Q*(2*A14021 + 4*A14041*Q2)) + 4*A13041*Q3)) + 6*A11061*Q5); d2A_dQR[2] = dth*(dth2*(2*A20521*dth2*Q + 4*A20341*Q3) + 6*A20161*Q5) + dr*(dr*(dth*(2*A22321*dth2*Q + 4*A22141*Q3) + dr*(dr*(2*A24121*dth*Q + 2*A25121*dr*dth*Q) + dth*(2*A23321*dth2*Q + 4*A23141*Q3))) + dth*(dth2*(2*A21521*dth2*Q + 4*A21341*Q3) + 6*A21161*Q5)); d2A_dQR[3] = 0; d2A_dQR[4] = 0; d2A_dQR[5] = 0; d2A_dQR[6] = dth2*(dth2*(2*A60621*dth2*Q + Q*(2*A60421 + 4*A60441*Q2)) + (4*A60241 + 6*A60261*Q2)*Q3) + (6*A60061 + 8*A60081*Q2)*Q5 + dr*(dth2*(2*A61421*dth2*Q + 4*A61241*Q3) + dr*(dth2*(2*A62421*dth2*Q + Q*(2*A62221 + 4*A62241*Q2)) + (4*A62041 + 6*A62061*Q2)*Q3 + dr*(2*A63221*dth2*Q + dr*(2*A64221*dth2*Q + dr*(2*A65021*Q + 2*A66021*dr*Q) + Q*(2*A64021 + 4*A64041*Q2)) + 4*A63041*Q3)) + 6*A61061*Q5); d2A_dQR[7] = 0; d2A_dQR[8] = dth*(dth2*(2*A80521*dth2*Q + 4*A80341*Q3) + 6*A80161*Q5) + dr*(dr*(dth*(2*A82321*dth2*Q + 4*A82141*Q3) + dr*(dr*(2*A84121*dth*Q + 2*A85121*dr*dth*Q) + dth*(2*A83321*dth2*Q + 4*A83141*Q3))) + dth*(dth2*(2*A81521*dth2*Q + 4*A81341*Q3) + 6*A81161*Q5)); d2A_dQR[9] = 0; for(int i=0; i<10; i++) { d2A_dph2[i] = dA_dR[i]*d2R_dph2 + dA_dQ[i]*d2Q_dph2 + 2.0*dQ_dph*dR_dph*d2A_dQR[i] + dQ_dph*dQ_dph*d2A_dQ2[i]; d2A_dtph[i] = -Omega*d2A_dph2[i]; d2A_dt2[i] = Omega*Omega*d2A_dph2[i]; } /* s */ s2 = alpha20*dr2 + alpha02*dth2 + beta*Q2; /* ds/dx */ ds2_dr = 2*alpha20*dr; ds2_dth = 2*alpha02*dth; ds2_dQ = 2*beta*Q; ds2_dph = ds2_dQ*dQ_dph; ds2_dt = -Omega*ds2_dph; /* d^2s/dx^2 */ d2s2_dr2 = 2*alpha20; d2s2_dth2 = 2*alpha02; d2s2_dQ2 = 2*beta; d2s2_dph2 = ds2_dQ*d2Q_dph2 + dQ_dph*dQ_dph*d2s2_dQ2; d2s2_dtph = -Omega*d2s2_dph2; d2s2_dt2 = Omega*Omega*d2s2_dph2; sqrts2 = sqrt(s2); s2_15 = s2*sqrts2; s2_25 = s2*s2_15; s2_35 = s2*s2_25; s2_45 = s2*s2_35; s2_55 = s2*s2_45; /* hS */ for(int i=0; i<10; i++) { hS[i] = A[i]/s2_35; } /* First derivatives of PhiS */ for(int i=0; i<10; i++) { dhS_dt[i] = (-7*ds2_dt*A[i] + 2*dA_dt[i]*s2)/(2.*s2_45); dhS_dr[i] = (-7*ds2_dr*A[i] + 2*dA_dr[i]*s2) /(2.*s2_45); dhS_dth[i] = (-7*ds2_dth*A[i] + 2*dA_dth[i]*s2)/(2.*s2_45); dhS_dph[i] = (-7*ds2_dph*A[i] + 2*dA_dph[i]*s2)/(2.*s2_45); } /* Second derivatives of hS */ for(int i=0; i<10; i++) { d2hS_dr2[i] = (63*ds2_dr*ds2_dr*A[i] - 14*s2*(2*dA_dr[i]*ds2_dr + d2s2_dr2*A[i]) + 4*d2A_dr2[i]*s2*s2)/(4.*s2_55); d2hS_dth2[i] = (63*ds2_dth*ds2_dth*A[i] - 14*s2*(2*dA_dth[i]*ds2_dth + d2s2_dth2*A[i]) + 4*d2A_dth2[i]*s2*s2)/(4.*s2_55); d2hS_dph2[i] = (63*ds2_dph*ds2_dph*A[i] - 14*s2*(2*dA_dph[i]*ds2_dph + d2s2_dph2*A[i]) + 4*d2A_dph2[i]*s2*s2)/(4.*s2_55); d2hS_dt2[i] = (63*ds2_dt*ds2_dt*A[i] - 14*s2*(2*dA_dt[i]*ds2_dt + d2s2_dt2*A[i]) + 4*d2A_dt2[i]*s2*s2)/(4.*s2_55); d2hS_dtph[i] = (63*ds2_dph*ds2_dt*A[i] - 14*s2*(dA_dt[i]*ds2_dph + dA_dph[i]*ds2_dt + d2s2_dtph*A[i]) + 4*d2A_dtph[i]*s2*s2)/(4.*s2_55); d2hS_dtr[i] = NAN; d2hS_dtth[i] = NAN; d2hS_drth[i] = NAN; d2hS_drph[i] = NAN; d2hS_dthph[i] = NAN; } double a10, a2, a2p2r2pa2c2th2, a2p2r2pa2c2th3, a2p2r2pa2c2th4, a2p2r2pa2c2th5, a2pr2m2Mr2, a2pr2m2Mr3, a3, a4, a6, a8, costh2, costh4, M2, M3, r10, r11, r2, r2pa2cth22, r2pa2cth23, r3, r4, r5, r6, r7, r8, r9, sinth2, sinth3, sinth4, sin4th, cos2th, cos4th, cos6th, cos8th, cos10th, sin2th, r2pa2cth2, a2p2r2pa2c2th, a2pr2m2Mr, costh, sinth, tanth; M2 = M*M; M3 = M2*M; a2 = a*a; a3 = a2*a; a4 = a2*a2; a6 = a4*a2; a8 = a4*a4; a10 = a6*a4; r2 = r*r; r3 = r2*r; r4 = r2*r2; r5 = r3*r2; r6 = r3*r3; r7 = r4*r3; r8 = r4*r4; r9 = r5*r4; r10 = r5*r5; r11 = r6*r5; sinth = sin(theta); costh = cos(theta); tanth = sinth/costh; costh2 = costh*costh; costh4 = costh2*costh2; sinth2 = sinth*sinth; sinth3 = sinth2*sinth; sinth4 = sinth2*sinth2; cos2th = costh2 - sinth2; sin2th = 2.0*costh*sinth; sin4th = 2.0*cos2th*sin2th; cos4th = cos2th*cos2th - sin2th*sin2th; cos6th = cos2th*cos2th*cos2th - 3.0*cos2th*sin2th*sin2th; cos8th = cos4th*cos4th - sin4th*sin4th; cos10th = cos2th*cos2th*cos2th*cos2th*cos2th - 10.0*cos2th*cos2th*cos2th*sin2th*sin2th + 5.0*cos2th*sin2th*sin2th*sin2th*sin2th; r2pa2cth2 = a2*costh2 + r2; r2pa2cth22 = r2pa2cth2*r2pa2cth2; r2pa2cth23 = r2pa2cth22*r2pa2cth2; a2p2r2pa2c2th = a2 + a2*cos2th + 2*r2; a2p2r2pa2c2th2 = a2p2r2pa2c2th*a2p2r2pa2c2th; a2p2r2pa2c2th3 = a2p2r2pa2c2th2*a2p2r2pa2c2th; a2p2r2pa2c2th4 = a2p2r2pa2c2th2*a2p2r2pa2c2th2; a2p2r2pa2c2th5 = a2p2r2pa2c2th3*a2p2r2pa2c2th2; a2pr2m2Mr = a2 + r*(-2*M + r); a2pr2m2Mr2 = a2pr2m2Mr*a2pr2m2Mr; a2pr2m2Mr3 = a2pr2m2Mr2*a2pr2m2Mr; src[0] = (-8*a*d2hS_dtph[0]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (16*dhS_dt[1]*M*(a2 + a2*cos2th - 2*r2)*(a2 + r2))/a2p2r2pa2c2th3 + d2hS_dth2[0]/r2pa2cth2 + (d2hS_dr2[0]*(a2 - 2*M*r + r2))/r2pa2cth2 + (4*a*dhS_dr[3]*M*(a2*costh2 - r2))/r2pa2cth23 + (4*a*dhS_dph[1]*M*(-(a2*costh2) + r2))/r2pa2cth23 - (d2hS_dt2[0]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) + (16*hS[7]*M*r*(-9*a4 + 3*a4*cos4th + 20*a2*M*r - 2*a2*cos2th*(3*a2 + 5*r*(-2*M + r)) + 2*a2*r2 - 8*M*r3 + 4*r4))/a2p2r2pa2c2th5 + (2*dhS_dr[0]*(5*a4*M - a4*cos4th*(M - r) + 3*a4*r - 16*a2*M*r2 + 8*a2*r3 + 4*a2*cos2th*(a2*(M + r) + 2*r3) - 24*M*r4 + 8*r5))/a2p2r2pa2c2th3 - (8*a2pr2m2Mr*hS[4]*M*(3*a4*M - 27*a4*r + a4*cos4th*(M + 3*r) + 40*a2*M*r2 + 4*a2*cos2th*(a2*(M - 6*r) + (10*M - 7*r)*r2) - 4*a2*r3 - 24*M*r4 + 16*r5))/a2p2r2pa2c2th5 + (16*a*hS[3]*M2*(3*a6 + 29*a4*r2 + a4*cos4th*(a2 + 7*r2) - 80*a2*M*r3 + 32*a2*r4 + 4*a2*cos2th*(a4 + 9*a2*r2 - 20*M*r3 + 6*r4) + 32*M*r5 - 8*r6))/(a2p2r2pa2c2th5*a2pr2m2Mr) + (8*hS[0]*M2*(3*a8 + 2*a6*r2 - 20*a4*M*r3 + a4*cos4th*(a4 - 2*a2*r2 + 20*M*r3 - 3*r4) - a4*r4 + 16*a2*M*r5 + 4*a2*cos2th*(a6 - 3*a2*r4 - 2*(2*M + r)*r5) + 8*a2*r6 + 8*r8))/(a2p2r2pa2c2th5*a2pr2m2Mr) - (32*a2*dhS_dt[2]*M*r*sin2th)/a2p2r2pa2c2th3 - (96*a2*a2pr2m2Mr*hS[5]*M*(a2 + a2*cos2th - 6*r2)*sin2th)/a2p2r2pa2c2th5 + (d2hS_dph2[0]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (2*hS[9]*M*(-2*a6*M + a6*cos6th*M + 30*a6*r + 3*a6*cos6th*r - 200*a4*M*r2 + 2*a4*cos4th*(a2*(M + 9*r) + 2*(-14*M + 5*r)*r2) + 60*a4*r3 + 320*a2*M2*r3 - a2*cos2th*(a4*(M - 45*r) + 16*a2*(16*M - 5*r)*r2 - 16*(20*M2 - 11*M*r + r2)*r3) - 208*a2*M*r4 + 16*a2*r5 - 128*M2*r5 + 128*M*r6 - 32*r7))/(a2p2r2pa2c2th5*a2pr2m2Mr*sinth2) - (64*a*dhS_dph[2]*M*r)/(a2p2r2pa2c2th3*tanth) + (64*a*dhS_dth[3]*M*r)/(a2p2r2pa2c2th3*tanth) + (dhS_dth[0]*(3*a4 + a4*cos4th + 32*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-4*M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth); src[1] = (-8*a*d2hS_dtph[1]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dt[4]*M*(a2 + a2*cos2th - 2*r2)*(a2 + r2))/a2p2r2pa2c2th3 + d2hS_dth2[1]/r2pa2cth2 + (d2hS_dr2[1]*(a2 - 2*M*r + r2))/r2pa2cth2 - (2*dhS_dth[2]*r)/r2pa2cth22 + (2*a*dhS_dr[6]*M*(a2*costh2 - r2))/r2pa2cth23 + (2*a*dhS_dph[4]*M*(-(a2*costh2) + r2))/r2pa2cth23 - (4*a*dhS_dph[0]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (4*a*dhS_dt[3]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (d2hS_dt2[1]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) + (4*dhS_dr[1]*(-(a4*M) - a4*cos4th*(M - r) + a4*r - 6*a2*M*r2 - 2*a2*cos2th*(a2*(M - r) + (M - 3*r)*r2) + 2*a2*r3 - 4*M*r4 + 4*r5))/a2p2r2pa2c2th3 - (8*a*hS[6]*M*(3*a4*M + a4*cos4th*(M - r) - 23*a4*r + 40*a2*M*r2 + 4*a2*cos2th*(a2*(M - 6*r) + 5*(2*M - r)*r2) - 12*a2*r3 - 24*M*r4 + 16*r5))/(a2p2r2pa2c2th4*a2pr2m2Mr) - (4*dhS_dt[0]*M*(a6 + a2*(4*M - 3*r)*r3 + a2*cos2th*(a4 + 2*a2*r2 + (-4*M + r)*r3) - 2*r6))/(a2p2r2pa2c2th2*a2pr2m2Mr2) + (hS[1]*(10*a8 + a8*cos6th - 24*a6*M2 + 116*a6*M*r - 2*a6*cos6th*M*r + 22*a6*r2 + a6*cos6th*r2 - 248*a4*M2*r2 + 2*a4*cos4th*(3*a4 + 2*r2*(6*M2 - 4*M*r + r2) + a2*(-4*M2 - 10*M*r + 5*r2)) + 208*a4*M*r3 - 4*a4*r4 - 128*a2*M2*r4 + a2*cos2th*(15*a6 - 32*a2*M*(7*M - 8*r)*r2 + a4*(-32*M2 + 98*M*r + 31*r2) - 16*(20*M2 - 12*M*r + r2)*r4) + 128*a2*M*r5 - 48*a2*r6 - 64*M2*r6 + 64*M*r7 - 32*r8))/(a2p2r2pa2c2th4*a2pr2m2Mr) - (16*a2*dhS_dt[5]*M*r*sin2th)/a2p2r2pa2c2th3 - (32*a3*hS[8]*M*(a2 + a2*cos2th - 4*r2)*sin2th)/(a2p2r2pa2c2th4*a2pr2m2Mr) - (2*a2*costh*dhS_dr[2]*sinth)/r2pa2cth22 + (d2hS_dph2[1]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (dhS_dph[3]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 20*a2*M*r2 + 4*a2*cos2th*r*(a2 - 3*M*r + 2*r2) + 8*a2*r3 + 32*M2*r3 - 32*M*r4 + 8*r5))/(a2p2r2pa2c2th2*a2pr2m2Mr2*sinth2) - (32*a*dhS_dph[5]*M*r)/(a2p2r2pa2c2th3*tanth) + (32*a*dhS_dth[6]*M*r)/(a2p2r2pa2c2th3*tanth) + (dhS_dth[1]*(5*a4 - a4*cos4th + 16*a2*M*r + 4*a2*cos2th*(a2 - 4*M*r) + 16*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (4*hS[2]*(4*a6*M + 3*a6*r - 34*a4*M*r2 + a4*cos4th*(a2*(-4*M + r) + (-6*M + r)*r2) + 11*a4*r3 + 4*a2*cos2th*r*(a4 + 3*a2*r*(2*M + r) + 2*(2*M + r)*r3) - 48*a2*M*r4 + 16*a2*r5 - 16*M*r6 + 8*r7))/(a2p2r2pa2c2th4*a2pr2m2Mr*tanth); src[2] = (-8*a*d2hS_dtph[2]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dt[5]*M*(a2 + a2*cos2th - 2*r2)*(a2 + r2))/a2p2r2pa2c2th3 + d2hS_dth2[2]/r2pa2cth2 + (d2hS_dr2[2]*(a2 - 2*M*r + r2))/r2pa2cth2 + (2*a2pr2m2Mr*dhS_dth[1]*r)/r2pa2cth22 + (2*a*dhS_dr[8]*M*(a2*costh2 - r2))/r2pa2cth23 + (2*a*dhS_dph[5]*M*(-(a2*costh2) + r2))/r2pa2cth23 - (d2hS_dt2[2]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*a3*dhS_dph[0]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (8*a3*dhS_dt[3]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (16*a2*dhS_dt[7]*M*r*sin2th)/a2p2r2pa2c2th3 - (8*a2*dhS_dt[0]*M*r*(a2 + r2)*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (a2*a2pr2m2Mr*dhS_dr[1]*sin2th)/r2pa2cth22 + (4*a2*hS[1]*(-7*a4*M - a4*cos4th*(M - r) + 3*a4*r + 8*a2*M2*r - 4*a2*cos2th*(a2*(2*M - r) + r*(-2*M2 + 3*M*r - 2*r2)) + 28*a2*M*r2 + 8*a2*r3 - 80*M2*r3 + 32*M*r4 + 8*r5)*sin2th)/a2p2r2pa2c2th4 + (d2hS_dph2[2]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) + (8*a*hS[8]*M*r*(-a2 + 5*a2*cos4th + 4*cos2th*(a2 - r2) + 12*r2))/(a2p2r2pa2c2th4*sinth2) - (hS[2]*(15*a6 + 6*a6*cos6th + a6*cos8th + 96*a4*M*r + 16*a4*cos6th*M*r + 56*a4*r2 + 8*a4*cos6th*r2 - 160*a2*M*r3 + 8*a2*cos4th*(2*a4 + a2*r*(-12*M + 5*r) + 2*(-6*M + r)*r3) + 80*a2*r4 - 128*M*r5 + 2*cos2th*(13*a6 + a4*(-8*M*r + 44*r2) + 16*a2*(8*M + 3*r)*r3 + 64*M*r5) + 64*r6))/(4.*a2p2r2pa2c2th4*sinth2) - (8*a2*dhS_dr[2]*(-(a2*cos2th*(M - r)) + a2*(-M + r) + 2*(M + r)*r2)*sinth2)/a2p2r2pa2c2th3 - (32*a*dhS_dph[7]*M*r)/(a2p2r2pa2c2th3*tanth) + (32*a*dhS_dth[8]*M*r)/(a2p2r2pa2c2th3*tanth) - (32*a*a2pr2m2Mr*hS[6]*M*(a2 + a2*cos2th - 10*r2))/(a2p2r2pa2c2th4*tanth) + (dhS_dth[2]*(5*a4 - a4*cos4th + 16*a2*M*r + 4*a2*cos2th*(a2 - 4*M*r) + 16*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (dhS_dph[3]*(3*a4 + a4*cos4th + 4*a2*cos2th*(a2 + 2*r*(-2*M + r)) + 8*a2*r2 - 16*M*r3 + 8*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr*sinth2*tanth); src[3] = (-8*a*d2hS_dtph[3]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dt[6]*M*(a2 + a2*cos2th - 2*r2)*(a2 + r2))/a2p2r2pa2c2th3 + d2hS_dth2[3]/r2pa2cth2 + (d2hS_dr2[3]*(a2 - 2*M*r + r2))/r2pa2cth2 + (2*a*dhS_dr[9]*M*(a2*costh2 - r2))/r2pa2cth23 + (2*a*dhS_dph[6]*M*(-(a2*costh2) + r2))/r2pa2cth23 - (d2hS_dt2[3]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*a*hS[7]*M*r*(-3*a4 + 10*a2*M*r + 17*a2*r2 + a2*cos4th*(11*a2 - 10*M*r + 11*r2) - 8*M*r3 + 4*cos2th*(2*a4 + a2*r2 + (2*M - r)*r3) + 20*r4))/a2p2r2pa2c2th5 + (2*dhS_dph[1]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 12*a2*M*r2 + 4*a2*cos2th*r*(a2 - M*r + 2*r2) + 8*a2*r3 - 16*M*r4 + 8*r5))/a2p2r2pa2c2th3 - (4*hS[3]*M*(2*a8*M - a8*cos6th*M + 30*a8*r + 3*a8*cos6th*r - 54*a6*M*r2 - 5*a6*cos6th*M*r2 + 90*a6*r3 + 3*a6*cos6th*r3 - 80*a4*M2*r3 - 2*a4*cos4th*(a4*(M - 9*r) + a2*(21*M - 19*r)*r2 - 2*(20*M2 - 12*M*r + 5*r2)*r3) - 96*a4*M*r4 + 76*a4*r5 + 64*a2*M2*r5 + a2*cos2th*(a6*(M + 45*r) + a4*(-91*M + 125*r)*r2 + 16*a2*(-11*M + 6*r)*r4 + 16*(-4*M2 - 5*M*r + r2)*r5) + 16*a2*M*r6 - 16*a2*r7 + 64*M*r8 - 32*r9))/(a2p2r2pa2c2th5*a2pr2m2Mr) - (16*a2*dhS_dt[8]*M*r*sin2th)/a2p2r2pa2c2th3 - (16*a*a2pr2m2Mr*hS[5]*M*(-3*a4 + a4*cos4th + 26*a2*r2 - 2*a2*cos2th*(a2 + 5*r2) + 20*r4)*sin2th)/a2p2r2pa2c2th5 + (d2hS_dph2[3]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (a*hS[9]*M*(3*a6*M + a6*cos8th*(M - r) + 85*a6*r + 124*a6*cos2th*r + 4*a6*cos6th*r - 80*a4*M*r2 - 216*a4*cos2th*M*r2 - 40*a4*cos6th*M*r2 + 280*a4*r3 + 380*a4*cos2th*r3 + 4*a4*cos6th*r3 - 320*a2*M2*r3 - 4*a2*cos4th*(a4*(M - 11*r) + 2*a2*(22*M - 13*r)*r2 - 20*(4*M2 - 3*M*r + r2)*r3) - 208*a2*M*r4 - 576*a2*cos2th*M*r4 + 304*a2*r5 + 384*a2*cos2th*r5 + 256*M2*r5 - 256*cos2th*M2*r5 - 256*M*r6 - 256*cos2th*M*r6 + 64*r7 + 192*cos2th*r7))/(2.*a2p2r2pa2c2th5*a2pr2m2Mr*sinth2) - (8*a*dhS_dr[0]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*dhS_dt[1]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*a2pr2m2Mr*hS[4]*M*(3*a4*M + a4*cos4th*(M - r) - 39*a4*r + 40*a2*M*r2 + 4*a2*cos2th*(a2*(M - 10*r) + (10*M - 9*r)*r2) - 12*a2*r3 - 24*M*r4 + 32*r5)*sinth2)/a2p2r2pa2c2th5 - (8*a*hS[0]*M2*(3*a8 - 22*a6*r2 - 20*a4*M*r3 + a4*cos4th*(a4 - 10*a2*r2 + 20*M*r3 - 11*r4) - 41*a4*r4 + 16*a2*M*r5 + 4*a2*cos2th*(a6 - 8*a4*r2 - 15*a2*r4 - 2*(2*M + 3*r)*r5) + 24*a2*r6 + 40*r8)*sinth2)/(a2p2r2pa2c2th5*a2pr2m2Mr) - (32*a3*costh*dhS_dth[0]*M*r*sinth3)/a2p2r2pa2c2th3 + (32*a3*costh*dhS_dt[2]*M*r*sinth3)/a2p2r2pa2c2th3 - (2*dhS_dth[3])/(a2p2r2pa2c2th*tanth) - (32*a*dhS_dph[8]*M*r)/(a2p2r2pa2c2th3*tanth) + (32*a*dhS_dth[9]*M*r)/(a2p2r2pa2c2th3*tanth) + (2*dhS_dph[2]*(3*a4 + a4*cos4th + 8*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth); src[4] = (-8*a*d2hS_dtph[4]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (4*dhS_dr[4]*(3*a2*cos2th*(M - r) + a2*(3*M + r) - 2*(M + r)*r2))/a2p2r2pa2c2th2 + d2hS_dth2[4]/r2pa2cth2 + (d2hS_dr2[4]*(a2 - 2*M*r + r2))/r2pa2cth2 - (4*dhS_dth[5]*r)/r2pa2cth22 - (8*a*dhS_dph[1]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (8*a*dhS_dt[6]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (d2hS_dt2[4]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) + (2*hS[4]*(7*a6 + 3*a4*M2 + 4*a4*M*r + 10*a4*r2 - 40*a2*M2*r2 + a4*cos4th*(a2 + M2 - 4*M*r + 2*r2) + 4*a2*cos2th*(2*a4 + 2*M*(-5*M + 3*r)*r2 + a2*(M2 + r2)) + 40*a2*M*r3 - 16*a2*r4 - 56*M2*r4 + 64*M*r5 - 16*r6))/(a2p2r2pa2c2th3*a2pr2m2Mr) - (8*dhS_dt[1]*M*(a6 + a2*(4*M - 3*r)*r3 + a2*cos2th*(a4 + 2*a2*r2 + (-4*M + r)*r3) - 2*r6))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (4*a*hS[3]*M*(3*a6*M - 39*a6*r + a4*cos4th*(M - r)*(a2 - r2) + 101*a4*M*r2 - 45*a4*r3 - 48*a2*M2*r3 + 4*a2*cos2th*(a4*(M - 10*r) + a2*(25*M - 17*r)*r2 + (-12*M2 + 18*M*r - 5*r2)*r3) - 16*a2*M*r4 + 36*a2*r5 + 96*M2*r5 - 136*M*r6 + 48*r7))/(a2p2r2pa2c2th3*a2pr2m2Mr3) - (2*hS[0]*M*(3*a8*M - 27*a8*r + 62*a6*M*r2 - 58*a6*r3 - 12*a4*M2*r3 + a4*cos4th*(a4*(M + 3*r) + 2*a2*(-7*M + 3*r)*r2 + (12*M2 - 11*M*r + 3*r2)*r3) + 39*a4*M*r4 - 19*a4*r5 + 48*a2*M2*r5 + 4*a2*cos2th*(a6*(M - 6*r) + a4*(12*M - 19*r)*r2 + a2*(29*M - 20*r)*r4 + (-12*M2 + 22*M*r - 7*r2)*r5) - 56*a2*M*r6 + 28*a2*r7 - 24*M*r8 + 16*r9))/(a2p2r2pa2c2th3*a2pr2m2Mr3) - (4*a2*costh*dhS_dr[5]*sinth)/r2pa2cth22 + (d2hS_dph2[4]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (2*dhS_dph[6]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 20*a2*M*r2 + 4*a2*cos2th*r*(a2 - 3*M*r + 2*r2) + 8*a2*r3 + 32*M2*r3 - 32*M*r4 + 8*r5))/(a2p2r2pa2c2th2*a2pr2m2Mr2*sinth2) + (hS[9]*(-2*a6*M2 + a6*cos6th*M2 + 76*a6*M*r - 2*a6*cos6th*M*r + 10*a6*r2 + a6*cos6th*r2 - 248*a4*M2*r2 + 2*a4*cos4th*(a2*(M2 - 14*M*r + 3*r2) + 2*r2*(14*M2 - 12*M*r + 3*r2)) - 16*a4*M*r3 + 192*a2*M3*r3 - a2*cos2th*(a4*(M2 - 50*M*r - 15*r2) - 16*a2*r2*(-12*M2 + 2*M*r + 3*r2) - 16*r3*(12*M3 - 7*M2*r - 5*M*r2 + 3*r3)) + 36*a4*r4 + 240*a2*M2*r4 - 272*a2*M*r5 - 384*M3*r5 + 48*a2*r6 + 512*M2*r6 - 224*M*r7 + 32*r8))/(2.*a2p2r2pa2c2th3*a2pr2m2Mr3*sinth2) + (hS[7]*(3*a2*cos2th*M*r + r*(3*a2*M + 2*a2*r - 6*M*r2 + 2*r3) + 2*a4*costh2*sinth2))/(a2pr2m2Mr*r2pa2cth23) - (2*dhS_dth[4]*(-5*a2 + 3*a2*cos2th - 2*r2))/(a2p2r2pa2c2th2*tanth) + (8*hS[5]*(a2*(M - 3*r) - a2*cos2th*(M - r) + 2*(2*M - r)*r2))/(a2p2r2pa2c2th2*a2pr2m2Mr*tanth); src[5] = (-8*a*d2hS_dtph[5]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dr[5]*(a2*cos2th*(M - r) + a2*(M + r) - 2*M*r2))/a2p2r2pa2c2th2 + d2hS_dth2[5]/r2pa2cth2 + (d2hS_dr2[5]*(a2 - 2*M*r + r2))/r2pa2cth2 + (2*a2pr2m2Mr*dhS_dth[4]*r)/r2pa2cth22 - (2*dhS_dth[7]*r)/r2pa2cth22 - (4*a*dhS_dph[2]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (4*a*dhS_dt[8]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (d2hS_dt2[5]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (4*dhS_dt[2]*M*(a6 + a2*(4*M - 3*r)*r3 + a2*cos2th*(a4 + 2*a2*r2 + (-4*M + r)*r3) - 2*r6))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (8*a3*dhS_dph[1]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (8*a3*dhS_dt[6]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (12*a2*hS[4]*(-M + r)*sin2th)/a2p2r2pa2c2th2 - (8*a2*dhS_dt[1]*M*r*(a2 + r2)*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (a2*a2pr2m2Mr*dhS_dr[4]*sin2th)/r2pa2cth22 - (4*a2*hS[0]*M*(3*a6 - 4*a4*r*(M + 3*r) + a2*(32*M - 33*r)*r3 + a2*cos2th*(3*a4 + a2*(-4*M*r + 6*r2) + (-8*M + 3*r)*r3) + 2*(16*M - 9*r)*r5)*sin2th)/(a2p2r2pa2c2th3*a2pr2m2Mr2) - (2*a2*costh*dhS_dr[7]*sinth)/r2pa2cth22 + (d2hS_dph2[5]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (hS[5]*(a4 + 3*a4*cos4th + a4*cos6th + 8*a2*r2 - 32*M*r3 + cos2th*(3*a4 + 8*a2*r2 + 16*(2*M - r)*r3) + 24*r4))/(a2p2r2pa2c2th3*sinth2) - (dhS_dph[8]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 20*a2*M*r2 + 4*a2*cos2th*r*(a2 - 3*M*r + 2*r2) + 8*a2*r3 + 32*M2*r3 - 32*M*r4 + 8*r5))/(a2p2r2pa2c2th2*a2pr2m2Mr2*sinth2) - (8*hS[7]*r)/(a2p2r2pa2c2th2*tanth) - (2*dhS_dth[5]*(-5*a2 + 3*a2*cos2th - 2*r2))/(a2p2r2pa2c2th2*tanth) + (8*a*hS[3]*M*(-3*a6 + 5*a4*M*r + a4*cos4th*(a2 - M*r) + 20*a4*r2 - 48*a2*M*r3 - 2*a2*cos2th*(a4 - 2*a2*(M - 4*r)*r + (-16*M + 9*r)*r3) + 38*a2*r4 - 24*M*r5 + 12*r6))/(a2p2r2pa2c2th3*a2pr2m2Mr2*tanth) - (dhS_dph[6]*(3*a4 + a4*cos4th + 4*a2*cos2th*(a2 + 2*r*(-2*M + r)) + 8*a2*r2 - 16*M*r3 + 8*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr*sinth2*tanth) + (hS[9]*(-10*a6*M - a6*cos6th*M + 10*a6*r + a6*cos6th*r + 16*a4*M2*r + 92*a4*M*r2 + 36*a4*r3 - 256*a2*M2*r3 + 2*a4*cos4th*(5*a2*M + 3*a2*r - 8*M2*r - 6*M*r2 + 6*r3) + a2*cos2th*(a4*(M + 15*r) + 16*a2*(-13*M + 3*r)*r2 + 48*(8*M2 - 6*M*r + r2)*r3) + 32*a2*M*r4 + 48*a2*r5 + 128*M2*r5 - 128*M*r6 + 32*r7))/(2.*a2p2r2pa2c2th3*a2pr2m2Mr2*sinth2*tanth); src[6] = (-8*a*d2hS_dtph[6]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) + d2hS_dth2[6]/r2pa2cth2 + (d2hS_dr2[6]*(a2 - 2*M*r + r2))/r2pa2cth2 - (2*dhS_dth[8]*r)/r2pa2cth22 - (4*a*dhS_dph[3]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (4*a*dhS_dt[9]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (d2hS_dt2[6]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (2*dhS_dr[6]*(7*a4*M + a4*cos4th*(M - r) + a4*r - 4*a2*M*r2 + 4*a2*cos2th*(2*a2*M + (M - r)*r2) + 4*a2*r3 - 16*M*r4))/a2p2r2pa2c2th3 + (2*dhS_dph[4]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 12*a2*M*r2 + 4*a2*cos2th*r*(a2 - M*r + 2*r2) + 8*a2*r3 - 16*M*r4 + 8*r5))/a2p2r2pa2c2th3 - (4*dhS_dt[3]*M*(a6 + a2*(4*M - 3*r)*r3 + a2*cos2th*(a4 + 2*a2*r2 + (-4*M + r)*r3) - 2*r6))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (2*hS[6]*(-2*a6*M2 + a6*cos6th*M2 + 24*a6*M*r - 2*a6*cos6th*M*r + 10*a6*r2 + a6*cos6th*r2 - 40*a4*M2*r2 + 2*a4*cos4th*(a2*(M2 - 12*M*r + 3*r2) + 2*r2*(10*M2 - 9*M*r + 3*r2)) - 44*a4*M*r3 + 36*a4*r4 + 112*a2*M2*r4 - a2*cos2th*(a4*(M2 - 2*M*r - 15*r2) + 48*a2*(M - r)*r3 - 16*(M2 - 5*M*r + 3*r2)*r4) - 176*a2*M*r5 + 48*a2*r6 + 128*M2*r6 - 128*M*r7 + 32*r8))/(a2p2r2pa2c2th4*a2pr2m2Mr) + (4*a*hS[2]*M*(5*a6 - 21*a4*r2 + cos4th*(-a6 + a4*r2) - 56*a2*r4 + 4*a2*cos2th*(a4 + 3*a2*r2 + 4*r4) - 24*r6)*sin2th)/(a2p2r2pa2c2th4*a2pr2m2Mr) - (2*a2*costh*dhS_dr[8]*sinth)/r2pa2cth22 + (d2hS_dph2[6]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (dhS_dph[9]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 20*a2*M*r2 + 4*a2*cos2th*r*(a2 - 3*M*r + 2*r2) + 8*a2*r3 + 32*M2*r3 - 32*M*r4 + 8*r5))/(a2p2r2pa2c2th2*a2pr2m2Mr2*sinth2) - (8*a*dhS_dr[1]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*dhS_dt[4]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*hS[1]*M*(3*a6*M - 20*a6*r + 31*a4*M*r2 - 26*a4*r3 + a4*cos4th*(a2*M - 3*M*r2 + 2*r3) + 4*a2*cos2th*(a4*(M - 5*r) + a2*(7*M - 8*r)*r2 + (6*M - r)*r4) + 12*a2*r5 - 24*M*r6 + 24*r7)*sinth2)/(a2p2r2pa2c2th4*a2pr2m2Mr) - (32*a3*costh*dhS_dth[1]*M*r*sinth3)/a2p2r2pa2c2th3 + (32*a3*costh*dhS_dt[5]*M*r*sinth3)/a2p2r2pa2c2th3 - (dhS_dth[6]*(a4 + 3*a4*cos4th + 16*a2*M*r + 4*a2*cos2th*(a2 + 4*r*(-M + r)) + 8*r4))/(a2p2r2pa2c2th3*tanth) + (2*dhS_dph[5]*(3*a4 + a4*cos4th + 8*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (2*hS[8]*(-6*a6*M - a6*cos6th*M + 4*a6*r + a6*cos6th*r + 52*a4*M*r2 + 2*a4*cos4th*(a2*(3*M + 2*r) + (-2*M + 5*r)*r2) + 14*a4*r3 + 48*a2*M*r4 + a2*cos2th*(a4*(M + 7*r) + 8*a2*(-10*M + 3*r)*r2 + 16*(-7*M + 2*r)*r4) + 16*a2*r5 - 32*M*r6 + 16*r7))/(a2p2r2pa2c2th4*a2pr2m2Mr*tanth); src[7] = (-8*a*d2hS_dtph[7]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (4*dhS_dr[7]*(a2*cos2th*(M - r) + a2*(M + 3*r) + 2*(-3*M + r)*r2))/a2p2r2pa2c2th2 + d2hS_dth2[7]/r2pa2cth2 + (d2hS_dr2[7]*(a2 - 2*M*r + r2))/r2pa2cth2 + (4*a2pr2m2Mr*dhS_dth[5]*r)/r2pa2cth22 - (d2hS_dt2[7]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) + (8*a*hS[3]*M*r*(-15*a4 + a4*cos4th + 16*a2*M*r - 2*a2*cos2th*(7*a2 + r*(-8*M + 7*r)) - 2*a2*r2 - 16*M*r3 + 12*r4))/(a2p2r2pa2c2th3*a2pr2m2Mr) + (4*hS[0]*M*r*(-9*a6 + 4*a4*M*r - 7*a4*r2 + a4*cos4th*(3*a2 - 4*M*r + 3*r2) - 8*a2*M*r3 - 2*a2*cos2th*(3*a4 + 8*a2*r2 + (-4*M + 5*r)*r3) + 6*a2*r4 + 4*r6))/(a2p2r2pa2c2th3*a2pr2m2Mr) - (16*a3*dhS_dph[2]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (16*a3*dhS_dt[8]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (16*a2*hS[5]*(-M + r)*sin2th)/a2p2r2pa2c2th2 - (16*a2*dhS_dt[2]*M*r*(a2 + r2)*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (2*a2*a2pr2m2Mr*dhS_dr[5]*sin2th)/r2pa2cth22 + (d2hS_dph2[7]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (hS[7]*(6*a4 + a4*cos6th + 8*a2*r2 + 2*a2*cos4th*(5*a2 + 4*r2) + 32*M*r3 + cos2th*(15*a4 + 48*a2*r2 + 16*(-2*M + r)*r3) + 16*r4))/(2.*a2p2r2pa2c2th3*sinth2) + (a2pr2m2Mr*hS[4]*(3*a2*cos2th*M*r + r*(3*a2*M + 2*a2*r - 6*M*r2 + 2*r3) + 2*a4*costh2*sinth2))/r2pa2cth23 - (2*dhS_dth[7]*(-5*a2 + 3*a2*cos2th - 2*r2))/(a2p2r2pa2c2th2*tanth) - (2*dhS_dph[8]*(3*a4 + a4*cos4th + 4*a2*cos2th*(a2 + 2*r*(-2*M + r)) + 8*a2*r2 - 16*M*r3 + 8*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr*sinth2*tanth) + (hS[9]*(35*a6 + 8*a6*cos6th + a6*cos8th - 168*a4*M*r - 36*a4*cos6th*M*r + 120*a4*r2 + 12*a4*cos6th*r2 + 128*a2*M2*r2 + 4*a2*cos4th*(7*a4 + 2*a2*r*(5*M + 9*r) - 4*(8*M2 + M*r - 3*r2)*r2) - 48*a2*M*r3 + 144*a2*r4 - 256*M2*r4 + 64*r6 + 4*cos2th*(14*a6 + a4*r*(-23*M + 45*r) - 16*a2*(7*M - 3*r)*r3 + 16*r4*pow(-2*M + r,2))))/(8.*a2p2r2pa2c2th3*a2pr2m2Mr*sinth4); src[8] = (-8*a*d2hS_dtph[8]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) + d2hS_dth2[8]/r2pa2cth2 + (d2hS_dr2[8]*(a2 - 2*M*r + r2))/r2pa2cth2 + (2*a2pr2m2Mr*dhS_dth[6]*r)/r2pa2cth22 - (d2hS_dt2[8]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dr[8]*(a4*(M + r) + 3*a2*(-M + r)*r2 + a2*cos2th*(a2*(M + r) + (-M + r)*r2) + 2*(-3*M + r)*r4))/a2p2r2pa2c2th3 + (2*dhS_dph[5]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 12*a2*M*r2 + 4*a2*cos2th*r*(a2 - M*r + 2*r2) + 8*a2*r3 - 16*M*r4 + 8*r5))/a2p2r2pa2c2th3 - (8*a3*dhS_dph[3]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (8*a3*dhS_dt[9]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (8*a2*dhS_dt[3]*M*r*(a2 + r2)*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (a2*a2pr2m2Mr*dhS_dr[6]*sin2th)/r2pa2cth22 + (d2hS_dph2[8]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (hS[8]*(55*a6 + 10*a6*cos6th + a6*cos8th - 80*a4*M*r - 24*a4*cos6th*M*r + 184*a4*r2 + 16*a4*cos6th*r2 + 224*a2*M*r3 + 8*a2*cos4th*(5*a4 + a2*r*(10*M + 13*r) + 2*(2*M + 5*r)*r3) + 208*a2*r4 + 256*M*r5 + 2*cos2th*(43*a6 + 4*a4*r*(3*M + 34*r) - 16*a2*(8*M - 9*r)*r3 + 64*(-2*M + r)*r5) + 64*r6))/(4.*a2p2r2pa2c2th4*sinth2) - (8*a*dhS_dr[2]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*dhS_dt[5]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (32*a*hS[2]*M*r*(4*a4 - a2*r2 + a2*cos2th*(4*a2 + 3*r2) - 6*r4)*sinth2)/a2p2r2pa2c2th4 - (32*a3*costh*dhS_dth[2]*M*r*sinth3)/a2p2r2pa2c2th3 + (32*a3*costh*dhS_dt[7]*M*r*sinth3)/a2p2r2pa2c2th3 + (32*a2pr2m2Mr*a3*costh*hS[1]*M*(a2 + a2*cos2th - 10*r2)*sinth3)/a2p2r2pa2c2th4 - (dhS_dth[8]*(a4 + 3*a4*cos4th + 16*a2*M*r + 4*a2*cos2th*(a2 + 4*r*(-M + r)) + 8*r4))/(a2p2r2pa2c2th3*tanth) + (2*dhS_dph[7]*(3*a4 + a4*cos4th + 8*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (2*hS[6]*(-2*a6*M - a6*cos6th*M + 10*a6*r + a6*cos6th*r + 8*a4*M2*r + 60*a4*M*r2 + 2*a4*cos4th*(a2*(M + 3*r) + 2*r*(-2*M2 - 3*M*r + 3*r2)) + 36*a4*r3 - 160*a2*M2*r3 + a2*cos2th*(a4*(M + 15*r) - 16*a2*(7*M - 3*r)*r2 + 16*(10*M2 - 10*M*r + 3*r2)*r3) + 32*a2*M*r4 + 48*a2*r5 - 64*M*r6 + 32*r7))/(a2p2r2pa2c2th4*tanth) - (dhS_dph[9]*(3*a4 + a4*cos4th + 4*a2*cos2th*(a2 + 2*r*(-2*M + r)) + 8*a2*r2 - 16*M*r3 + 8*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr*sinth2*tanth); src[9] = (-8*a*d2hS_dtph[9]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) + d2hS_dth2[9]/r2pa2cth2 + (d2hS_dr2[9]*(a2 - 2*M*r + r2))/r2pa2cth2 - (d2hS_dt2[9]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (2*dhS_dr[9]*(5*a4*M - a4*cos4th*(M - r) + 3*a4*r - 16*a2*M*r2 + 8*a2*r3 + 4*a2*cos2th*(a2*(M + r) + 2*r3) - 24*M*r4 + 8*r5))/a2p2r2pa2c2th3 + (4*dhS_dph[6]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 12*a2*M*r2 + 4*a2*cos2th*r*(a2 - M*r + 2*r2) + 8*a2*r3 - 16*M*r4 + 8*r5))/a2p2r2pa2c2th3 + (hS[7]*(35*a8 + 8*a8*cos6th + a8*cos8th - 78*a6*M*r - 36*a6*cos6th*M*r - 2*a6*cos8th*M*r + 155*a6*r2 + 20*a6*cos6th*r2 + a6*cos8th*r2 + 80*a4*M2*r2 + 40*a4*cos6th*M2*r2 + 88*a4*M*r3 - 44*a4*cos6th*M*r3 + 264*a4*r4 + 12*a4*cos6th*r4 - 96*a2*M2*r4 + 4*a2*cos4th*(7*a6 + 5*a4*r*(4*M + 5*r) + 4*(-2*M2 + M*r + 3*r2)*r4 + a2*(-20*M2*r2 + 26*M*r3 + 30*r4)) + 304*a2*M*r5 + 208*a2*r6 + 128*M*r7 + 4*cos2th*(14*a8 + a6*r*(9*M + 59*r) + a4*r2*(-10*M2 - 37*M*r + 93*r2) + 16*a2*(2*M2 - 5*M*r + 4*r2)*r4 + 16*(-2*M + r)*r7) + 64*r8))/(2.*a2p2r2pa2c2th5) + (2*a2pr2m2Mr*hS[5]*(-10*a6*M - a6*cos6th*M + 10*a6*r + a6*cos6th*r + 140*a4*M*r2 + 2*a4*cos4th*(a2*(5*M + 3*r) + 2*(M + 3*r)*r2) + 36*a4*r3 + 160*a2*M*r4 + a2*cos2th*(a4*(M + 15*r) - 48*a2*(3*M - r)*r2 + 16*(-10*M + 3*r)*r4) + 48*a2*r5 + 32*r7)*sin2th)/a2p2r2pa2c2th5 + (d2hS_dph2[9]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) + (hS[9]*(126*a10 + a10*cos10th + 45*a10*cos6th + 10*a10*cos8th + 6*a8*M2 - a8*cos10th*M2 + 3*a8*cos6th*M2 + 2*a8*cos8th*M2 - 160*a8*M*r - 160*a8*cos6th*M*r - 32*a8*cos8th*M*r + 512*r10 + 700*a8*r2 + 160*a8*cos6th*r2 + 20*a8*cos8th*r2 - 120*a6*M2*r2 + 160*a6*cos6th*M2*r2 + 24*a6*cos8th*M2*r2 - 840*a6*M*r3 - 384*a6*cos6th*M*r3 - 24*a6*cos8th*M*r3 - 640*a4*M3*r3 - 320*a4*cos6th*M3*r3 + 1600*a6*r4 + 160*a6*cos6th*r4 - 96*a4*M2*r4 + 240*a4*cos6th*M2*r4 - 1856*a4*M*r5 - 160*a4*cos6th*M*r5 + 768*a2*M3*r5 + 8*a2*cos4th*(15*a8 - a6*(M2 + 40*M*r - 70*r2) + 4*a4*r2*(3*M2 - 37*M*r + 30*r2) + 4*a2*r3*(20*M3 + 11*M2*r - 38*M*r2 + 20*r3) + 16*M*(2*M2 + 2*M*r - r2)*r5) + 1920*a4*r6 + 768*a2*M2*r6 - 2432*a2*M*r7 + 1280*a2*r8 + 1024*M2*r8 + 2*cos2th*(105*a10 - a8*(M2 + 176*M*r - 560*r2) + 16*a6*r2*(-5*M2 - 52*M*r + 75*r2) + 8*a4*r3*(20*M3 - 31*M2*r - 182*M*r2 + 160*r3) - 128*a2*(4*M3 + 4*M2*r + 6*M*r2 - 5*r3)*r5 + 256*M*(-2*M + r)*r8) - 1536*M*r9))/(8.*a2p2r2pa2c2th5*a2pr2m2Mr*sinth2) - (16*a*dhS_dr[3]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (16*a*dhS_dt[6]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (2*a2pr2m2Mr*hS[4]*(-2*a6*M2 + a6*cos6th*M2 + 76*a6*M*r - 2*a6*cos6th*M*r + 10*a6*r2 + a6*cos6th*r2 - 40*a4*M2*r2 + 2*a4*cos4th*(a2*(M2 - 14*M*r + 3*r2) + 2*r2*(10*M2 - 8*M*r + 3*r2)) + 32*a4*M*r3 + 36*a4*r4 + 48*a2*M2*r4 - a2*cos2th*(a4*(M2 - 50*M*r - 15*r2) - 48*a2*(2*M + r)*r3 - 48*(-M2 + M*r + r2)*r4) - 144*a2*M*r5 + 48*a2*r6 - 96*M*r7 + 32*r8)*sinth2)/a2p2r2pa2c2th5 + (4*a*hS[3]*M*(2*a8*M - a8*cos6th*M + 30*a8*r + 3*a8*cos6th*r - 130*a6*M*r2 - 3*a6*cos6th*M*r2 + 70*a6*r3 + a6*cos6th*r3 - 80*a4*M2*r3 - 2*a4*cos4th*(a4*(M - 9*r) + a2*(31*M - 13*r)*r2 + 2*(-20*M2 + 14*M*r + r2)*r3) - 184*a4*M*r4 + 4*a4*r5 + 64*a2*M2*r5 + a2*cos2th*(a6*(M + 45*r) + a4*(-189*M + 95*r)*r2 - 272*a2*M*r4 - 16*(4*M2 + 3*M*r + 5*r2)*r5) + 176*a2*M*r6 - 112*a2*r7 + 256*M*r8 - 96*r9)*sinth2)/(a2p2r2pa2c2th5*a2pr2m2Mr) - (2*hS[0]*M*(-2*a10*M + a10*cos6th*M + 30*a10*r + 3*a10*cos6th*r - 32*r11 + 28*a8*M*r2 - 18*a8*cos6th*M*r2 + 120*a8*r3 + 6*a8*cos6th*r3 + 40*a6*M2*r3 + 20*a6*cos6th*M2*r3 + 46*a6*M*r4 - 15*a6*cos6th*M*r4 + 166*a6*r5 + 3*a6*cos6th*r5 - 48*a4*M2*r5 + 2*a4*cos4th*(a6*(M + 9*r) - 14*a4*(M - 2*r)*r2 + a2*(-20*M2 - 31*M*r + 29*r2)*r3 + 2*(-4*M2 - 2*M*r + 5*r2)*r5) - 152*a4*M*r6 + 60*a4*r7 - 208*a2*M*r8 + a2*cos2th*(-(a8*(M - 45*r)) + 2*a6*(9*M + 85*r)*r2 + a4*(-20*M2 + 31*M*r + 221*r2)*r3 + 16*a2*(4*M2 + 10*M*r + 7*r2)*r5 + 16*(13*M + r)*r8) - 48*a2*r9)*sinth2)/(a2p2r2pa2c2th5*a2pr2m2Mr) - (64*a3*costh*dhS_dth[3]*M*r*sinth3)/a2p2r2pa2c2th3 + (64*a3*costh*dhS_dt[8]*M*r*sinth3)/a2p2r2pa2c2th3 + (4*dhS_dph[8]*(3*a4 + a4*cos4th + 8*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (dhS_dth[9]*(9*a4 + 3*a4*cos4th + 32*a2*M*r + 24*a2*r2 + 4*a2*cos2th*(3*a2 - 8*M*r + 6*r2) + 24*r4))/(a2p2r2pa2c2th3*tanth); } /* Compute the 2D singular field, its derivatives and its d'Alembertian */ void effsource_calc_m(int m, struct coordinate * x, double *hS_re, double *hS_im, double *dhS_dr_re, double *dhS_dr_im, double *dhS_dth_re, double *dhS_dth_im, double *dhS_dph_re, double *dhS_dph_im, double *dhS_dt_re, double *dhS_dt_im, double *src_re, double *src_im) { double A_re[10][5], A_im[10][5]; double dA_dr_re[10][5], dA_dr_im[10][5], dA_dth_re[10][5], dA_dth_im[10][5]; double d2A_dr2_re[10][5], d2A_dr2_im[10][5]; double d2A_dth2_re[10][5], d2A_dth2_im[10][5]; double d2hS_dt2_re[10], d2hS_dt2_im[10], d2hS_dtr_re[10], d2hS_dtr_im[10]; double d2hS_dtth_re[10], d2hS_dtth_im[10], d2hS_dtph_re[10], d2hS_dtph_im[10]; double d2hS_dr2_re[10], d2hS_dr2_im[10], d2hS_drth_re[10], d2hS_drth_im[10]; double d2hS_drph_re[10], d2hS_drph_im[10], d2hS_dth2_re[10], d2hS_dth2_im[10]; double d2hS_dthph_re[10], d2hS_dthph_im[10], d2hS_dph2_re[10], d2hS_dph2_im[10]; if(m>20) { printf("Support for computing mode %d has not yet been added.\n", m); return; } const double r = x->r; const double theta = x->theta; const double rp = xp.r; const double thetap = xp.theta; double Omega = M / (a*M + sqrt(M*rp*rp*rp)); const double dr = r - rp; const double dth = theta - thetap; const double dr2 = dr*dr; const double dth2 = dth*dth; const double dth3 = dth*dth2; const double dth4 = dth2*dth2; const double dth5 = dth3*dth2; const double dth6 = dth3*dth3; const double dth7 = dth4*dth3; const double dth8 = dth4*dth4; const double dth9 = dth5*dth4; /* A */ A_re[0][0] = (A00600 + A00800*dth2)*dth6 + dr*(dr*((A02400 + A02600*dth2)*dth4 + dr*(dr*(dth2*(A04200 + A04400*dth2) + dr*(dth2*(A05200 + A05400*dth2) + dr*(A06000 + A06200*dth2 + dr*(A07000 + dr*(A08000 + A09000*dr) + A07200*dth2)))) + (A03400 + A03600*dth2)*dth4)) + (A01600 + A01800*dth2)*dth6); A_re[0][1] = (A00420 + A00620*dth2)*dth4 + dr*(dr*(dth2*(A02220 + A02420*dth2) + dr*(dth2*(A03220 + A03420*dth2) + dr*(A04020 + A04220*dth2 + dr*(A05020 + dr*(A06020 + A07020*dr) + A05220*dth2)))) + (A01420 + A01620*dth2)*dth4); A_re[0][2] = dth2*(A00240 + A00440*dth2) + dr*(dth2*(A01240 + A01440*dth2) + dr*(A02040 + A02240*dth2 + dr*(A03040 + dr*(A04040 + A05040*dr) + A03240*dth2))); A_re[0][3] = A00060 + A00260*dth2 + dr*(A01060 + dr*(A02060 + A03060*dr) + A01260*dth2); A_re[0][4] = A00080 + A01080*dr; A_im[0][0] = A_im[0][1] = A_im[0][2] = A_im[0][3] = A_im[0][4] = 0.0; A_re[1][0] = A_re[1][1] = A_re[1][2] = A_re[1][3] = A_re[1][4] = 0.0; A_im[1][0] = (A10601 + A10801*dth2)*dth6 + dr*(dr*((A12401 + A12601*dth2)*dth4 + dr*(dr*(dth2*(A14201 + A14401*dth2) + dr*(A15201*dth2 + dr*(A16001 + dr*(A17001 + A18001*dr) + A16201*dth2))) + A13401*dth4)) + A11601*dth6); A_im[1][1] = (A10421 + A10621*dth2)*dth4 + dr*(dr*(dth2*(A12221 + A12421*dth2) + dr*(A13221*dth2 + dr*(A14021 + dr*(A15021 + A16021*dr) + A14221*dth2))) + A11421*dth4); A_im[1][2] = dth2*(A10241 + A10441*dth2) + dr*(A11241*dth2 + dr*(A12041 + dr*(A13041 + A14041*dr) + A12241*dth2)); A_im[1][3] = A10061 + dr*(A11061 + A12061*dr) + A10261*dth2; A_im[1][4] = A10081; A_re[2][0] = A_re[2][1] = A_re[2][2] = A_re[2][3] = A_re[2][4] = 0.0; A_im[2][0] = A20701*dth7 + dr*(dr*(A22501*dth5 + dr*(dr*(A24301*dth3 + dr*(dr*(A26101*dth + A27101*dr*dth) + A25301*dth3)) + A23501*dth5)) + A21701*dth7); A_im[2][1] = A20521*dth5 + dr*(dr*(A22321*dth3 + dr*(dr*(A24121*dth + A25121*dr*dth) + A23321*dth3)) + A21521*dth5); A_im[2][2] = A20341*dth3 + dr*(dr*(A22141*dth + A23141*dr*dth) + A21341*dth3); A_im[2][3] = A20161*dth + A21161*dr*dth; A_im[2][4] = 0.0; A_re[3][0] = (A30600 + A30800*dth2)*dth6 + dr*(dr*((A32400 + A32600*dth2)*dth4 + dr*(dr*(dth2*(A34200 + A34400*dth2) + dr*(dth2*(A35200 + A35400*dth2) + dr*(A36000 + A36200*dth2 + dr*(A37000 + dr*(A38000 + A39000*dr) + A37200*dth2)))) + (A33400 + A33600*dth2)*dth4)) + (A31600 + A31800*dth2)*dth6); A_re[3][1] = (A30420 + A30620*dth2)*dth4 + dr*(dr*(dth2*(A32220 + A32420*dth2) + dr*(dth2*(A33220 + A33420*dth2) + dr*(A34020 + A34220*dth2 + dr*(A35020 + dr*(A36020 + A37020*dr) + A35220*dth2)))) + (A31420 + A31620*dth2)*dth4); A_re[3][2] = dth2*(A30240 + A30440*dth2) + dr*(dth2*(A31240 + A31440*dth2) + dr*(A32040 + A32240*dth2 + dr*(A33040 + dr*(A34040 + A35040*dr) + A33240*dth2))); A_re[3][3] = A30060 + A30260*dth2 + dr*(A31060 + dr*(A32060 + A33060*dr) + A31260*dth2); A_re[3][4] = A30080 + A31080*dr; A_im[3][0] = A_im[3][1] = A_im[3][2] = A_im[3][3] = A_im[3][4] = 0.0; A_re[4][0] = A40800*dth8 + dr*(dr*(A42600*dth6 + dr*(dr*(A44400*dth4 + dr*(dr*(A46200*dth2 + dr*(dr*(A48000 + A49000*dr) + A47200*dth2)) + A45400*dth4)) + A43600*dth6)) + A41800*dth8); A_re[4][1] = A40620*dth6 + dr*(dr*(A42420*dth4 + dr*(dr*(A44220*dth2 + dr*(dr*(A46020 + A47020*dr) + A45220*dth2)) + A43420*dth4)) + A41620*dth6); A_re[4][2] = A40440*dth4 + dr*(dr*(A42240*dth2 + dr*(dr*(A44040 + A45040*dr) + A43240*dth2)) + A41440*dth4); A_re[4][3] = A40260*dth2 + dr*(dr*(A42060 + A43060*dr) + A41260*dth2); A_re[4][4] = A40080 + A41080*dr; A_im[4][0] = A_im[4][1] = A_im[4][2] = A_im[4][3] = A_im[4][4] = 0.0; A_re[5][0] = dr2*(dr2*(dr2*(A58100*dr2*dth + A56300*dth3) + A54500*dth5) + A52700*dth7) + A50900*dth9; A_re[5][1] = dr2*(dr2*(A56120*dr2*dth + A54320*dth3) + A52520*dth5) + A50720*dth7; A_re[5][2] = dr2*(A54140*dr2*dth + A52340*dth3) + A50540*dth5; A_re[5][3] = A52160*dr2*dth + A50360*dth3; A_re[5][4] = A50180*dth; A_im[5][0] = A_im[5][1] = A_im[5][2] = A_im[5][3] = A_im[5][4] = 0.0; A_re[6][0] = A_re[6][1] = A_re[6][2] = A_re[6][3] = A_re[6][4] = 0.0; A_im[6][0] = (A60601 + A60801*dth2)*dth6 + dr*(dr*((A62401 + A62601*dth2)*dth4 + dr*(dr*(dth2*(A64201 + A64401*dth2) + dr*(A65201*dth2 + dr*(A66001 + dr*(A67001 + A68001*dr) + A66201*dth2))) + A63401*dth4)) + A61601*dth6); A_im[6][1] = (A60421 + A60621*dth2)*dth4 + dr*(dr*(dth2*(A62221 + A62421*dth2) + dr*(A63221*dth2 + dr*(A64021 + dr*(A65021 + A66021*dr) + A64221*dth2))) + A61421*dth4); A_im[6][2] = dth2*(A60241 + A60441*dth2) + dr*(A61241*dth2 + dr*(A62041 + dr*(A63041 + A64041*dr) + A62241*dth2)); A_im[6][3] = A60061 + dr*(A61061 + A62061*dr) + A60261*dth2; A_im[6][4] = A60081; A_re[7][0] = A70800*dth8 + dr*(dr*(A72600*dth6 + dr*(dr*(A74400*dth4 + dr*(dr*(A76200*dth2 + dr*(dr*(A78000 + A79000*dr) + A77200*dth2)) + A75400*dth4)) + A73600*dth6)) + A71800*dth8); A_re[7][1] = A70620*dth6 + dr*(dr*(A72420*dth4 + dr*(dr*(A74220*dth2 + dr*(dr*(A76020 + A77020*dr) + A75220*dth2)) + A73420*dth4)) + A71620*dth6); A_re[7][2] = A70440*dth4 + dr*(dr*(A72240*dth2 + dr*(dr*(A74040 + A75040*dr) + A73240*dth2)) + A71440*dth4); A_re[7][3] = A70260*dth2 + dr*(dr*(A72060 + A73060*dr) + A71260*dth2); A_re[7][4] = A70080 + A71080*dr; A_im[7][0] = A_im[7][1] = A_im[7][2] = A_im[7][3] = A_im[7][4] = 0.0; A_re[8][0] = A_re[8][1] = A_re[8][2] = A_re[8][3] = A_re[8][4] = 0.0; A_im[8][0] = A80701*dth7 + dr*(dr*(A82501*dth5 + dr*(dr*(A84301*dth3 + dr*(dr*(A86101*dth + A87101*dr*dth) + A85301*dth3)) + A83501*dth5)) + A81701*dth7); A_im[8][1] = A80521*dth5 + dr*(dr*(A82321*dth3 + dr*(dr*(A84121*dth + A85121*dr*dth) + A83321*dth3)) + A81521*dth5); A_im[8][2] = A80341*dth3 + dr*(dr*(A82141*dth + A83141*dr*dth) + A81341*dth3); A_im[8][3] = A80161*dth + A81161*dr*dth; A_im[8][4] = 0.0; A_re[9][0] = (A90600 + A90800*dth2)*dth6 + dr*(dr*((A92400 + A92600*dth2)*dth4 + dr*(dr*(dth2*(A94200 + A94400*dth2) + dr*(dth2*(A95200 + A95400*dth2) + dr*(A96000 + A96200*dth2 + dr*(A97000 + dr*(A98000 + A99000*dr) + A97200*dth2)))) + (A93400 + A93600*dth2)*dth4)) + (A91600 + A91800*dth2)*dth6); A_re[9][1] = (A90420 + A90620*dth2)*dth4 + dr*(dr*(dth2*(A92220 + A92420*dth2) + dr*(dth2*(A93220 + A93420*dth2) + dr*(A94020 + A94220*dth2 + dr*(A95020 + dr*(A96020 + A97020*dr) + A95220*dth2)))) + (A91420 + A91620*dth2)*dth4); A_re[9][2] = dth2*(A90240 + A90440*dth2) + dr*(dth2*(A91240 + A91440*dth2) + dr*(A92040 + A92240*dth2 + dr*(A93040 + dr*(A94040 + A95040*dr) + A93240*dth2))); A_re[9][3] = A90060 + A90260*dth2 + dr*(A91060 + dr*(A92060 + A93060*dr) + A91260*dth2); A_re[9][4] = A90080 + A91080*dr; A_im[9][0] = A_im[9][1] = A_im[9][2] = A_im[9][3] = A_im[9][4] = 0.0; /* dA/dr */ dA_dr_re[0][0] = dr*((2*A02400 + 2*A02600*dth2)*dth4 + dr*(dr*(dth2*(4*A04200 + 4*A04400*dth2) + dr*(dth2*(5*A05200 + 5*A05400*dth2) + dr*(6*A06000 + 6*A06200*dth2 + dr*(7*A07000 + dr*(8*A08000 + 9*A09000*dr) + 7*A07200*dth2)))) + (3*A03400 + 3*A03600*dth2)*dth4)) + (A01600 + A01800*dth2)*dth6; dA_dr_re[0][1] = dr*(dth2*(2*A02220 + 2*A02420*dth2) + dr*(dth2*(3*A03220 + 3*A03420*dth2) + dr*(4*A04020 + 4*A04220*dth2 + dr*(5*A05020 + dr*(6*A06020 + 7*A07020*dr) + 5*A05220*dth2)))) + (A01420 + A01620*dth2)*dth4; dA_dr_re[0][2] = dth2*(A01240 + A01440*dth2) + dr*(2*A02040 + 2*A02240*dth2 + dr*(3*A03040 + dr*(4*A04040 + 5*A05040*dr) + 3*A03240*dth2)); dA_dr_re[0][3] = A01060 + dr*(2*A02060 + 3*A03060*dr) + A01260*dth2; dA_dr_re[0][4] = A01080; dA_dr_im[0][0] = dA_dr_im[0][1] = dA_dr_im[0][2] = dA_dr_im[0][3] = dA_dr_im[0][4] = 0.0; dA_dr_re[1][0] = dA_dr_re[1][1] = dA_dr_re[1][2] = dA_dr_re[1][3] = dA_dr_re[1][4] = 0.0; dA_dr_im[1][0] = dr*((2*A12401 + 2*A12601*dth2)*dth4 + dr*(dr*(dth2*(4*A14201 + 4*A14401*dth2) + dr*(5*A15201*dth2 + dr*(6*A16001 + dr*(7*A17001 + 8*A18001*dr) + 6*A16201*dth2))) + 3*A13401*dth4)) + A11601*dth6; dA_dr_im[1][1] = dr*(dth2*(2*A12221 + 2*A12421*dth2) + dr*(3*A13221*dth2 + dr*(4*A14021 + dr*(5*A15021 + 6*A16021*dr) + 4*A14221*dth2))) + A11421*dth4; dA_dr_im[1][2] = A11241*dth2 + dr*(2*A12041 + dr*(3*A13041 + 4*A14041*dr) + 2*A12241*dth2); dA_dr_im[1][3] = A11061 + 2*A12061*dr; dA_dr_im[1][4] = 0.0; dA_dr_re[2][0] = dA_dr_re[2][1] = dA_dr_re[2][2] = dA_dr_re[2][3] = dA_dr_re[2][4] = 0.0; dA_dr_im[2][0] = dr*(2*A22501*dth5 + dr*(dr*(4*A24301*dth3 + dr*(dr*(6*A26101*dth + 7*A27101*dr*dth) + 5*A25301*dth3)) + 3*A23501*dth5)) + A21701*dth7; dA_dr_im[2][1] = dr*(2*A22321*dth3 + dr*(dr*(4*A24121*dth + 5*A25121*dr*dth) + 3*A23321*dth3)) + A21521*dth5; dA_dr_im[2][2] = dr*(2*A22141*dth + 3*A23141*dr*dth) + A21341*dth3; dA_dr_im[2][3] = A21161*dth; dA_dr_im[2][4] = 0.0; dA_dr_re[3][0] = dr*((2*A32400 + 2*A32600*dth2)*dth4 + dr*(dr*(dth2*(4*A34200 + 4*A34400*dth2) + dr*(dth2*(5*A35200 + 5*A35400*dth2) + dr*(6*A36000 + 6*A36200*dth2 + dr*(7*A37000 + dr*(8*A38000 + 9*A39000*dr) + 7*A37200*dth2)))) + (3*A33400 + 3*A33600*dth2)*dth4)) + (A31600 + A31800*dth2)*dth6; dA_dr_re[3][1] = dr*(dth2*(2*A32220 + 2*A32420*dth2) + dr*(dth2*(3*A33220 + 3*A33420*dth2) + dr*(4*A34020 + 4*A34220*dth2 + dr*(5*A35020 + dr*(6*A36020 + 7*A37020*dr) + 5*A35220*dth2)))) + (A31420 + A31620*dth2)*dth4; dA_dr_re[3][2] = dth2*(A31240 + A31440*dth2) + dr*(2*A32040 + 2*A32240*dth2 + dr*(3*A33040 + dr*(4*A34040 + 5*A35040*dr) + 3*A33240*dth2)); dA_dr_re[3][3] = A31060 + dr*(2*A32060 + 3*A33060*dr) + A31260*dth2; dA_dr_re[3][4] = A31080; dA_dr_im[3][0] = dA_dr_im[3][1] = dA_dr_im[3][2] = dA_dr_im[3][3] = dA_dr_im[3][4] = 0.0; dA_dr_re[4][0] = dr*(2*A42600*dth6 + dr*(dr*(4*A44400*dth4 + dr*(dr*(6*A46200*dth2 + dr*(dr*(8*A48000 + 9*A49000*dr) + 7*A47200*dth2)) + 5*A45400*dth4)) + 3*A43600*dth6)) + A41800*dth8; dA_dr_re[4][1] = dr*(2*A42420*dth4 + dr*(dr*(4*A44220*dth2 + dr*(dr*(6*A46020 + 7*A47020*dr) + 5*A45220*dth2)) + 3*A43420*dth4)) + A41620*dth6; dA_dr_re[4][2] = dr*(2*A42240*dth2 + dr*(dr*(4*A44040 + 5*A45040*dr) + 3*A43240*dth2)) + A41440*dth4; dA_dr_re[4][3] = dr*(2*A42060 + 3*A43060*dr) + A41260*dth2; dA_dr_re[4][4] = A41080; dA_dr_im[4][0] = dA_dr_im[4][1] = dA_dr_im[4][2] = dA_dr_im[4][3] = dA_dr_im[4][4] = 0.0; dA_dr_re[5][0] = dr*(dr2*(dr2*(8*A58100*dr2*dth + 6*A56300*dth3) + 4*A54500*dth5) + 2*A52700*dth7); dA_dr_re[5][1] = dr*(dr2*(6*A56120*dr2*dth + 4*A54320*dth3) + 2*A52520*dth5); dA_dr_re[5][2] = dr*(4*A54140*dr2*dth + 2*A52340*dth3); dA_dr_re[5][3] = 2*A52160*dr*dth; dA_dr_re[5][4] = 0.0; dA_dr_im[5][0] = dA_dr_im[5][1] = dA_dr_im[5][2] = dA_dr_im[5][3] = dA_dr_im[5][4] = 0.0; dA_dr_re[6][0] = dA_dr_re[6][1] = dA_dr_re[6][2] = dA_dr_re[6][3] = dA_dr_re[6][4] = 0.0; dA_dr_im[6][0] = dr*((2*A62401 + 2*A62601*dth2)*dth4 + dr*(dr*(dth2*(4*A64201 + 4*A64401*dth2) + dr*(5*A65201*dth2 + dr*(6*A66001 + dr*(7*A67001 + 8*A68001*dr) + 6*A66201*dth2))) + 3*A63401*dth4)) + A61601*dth6; dA_dr_im[6][1] = dr*(dth2*(2*A62221 + 2*A62421*dth2) + dr*(3*A63221*dth2 + dr*(4*A64021 + dr*(5*A65021 + 6*A66021*dr) + 4*A64221*dth2))) + A61421*dth4; dA_dr_im[6][2] = A61241*dth2 + dr*(2*A62041 + dr*(3*A63041 + 4*A64041*dr) + 2*A62241*dth2); dA_dr_im[6][3] = A61061 + 2*A62061*dr; dA_dr_im[6][4] = 0.0; dA_dr_re[7][0] = dr*(2*A72600*dth6 + dr*(dr*(4*A74400*dth4 + dr*(dr*(6*A76200*dth2 + dr*(dr*(8*A78000 + 9*A79000*dr) + 7*A77200*dth2)) + 5*A75400*dth4)) + 3*A73600*dth6)) + A71800*dth8; dA_dr_re[7][1] = dr*(2*A72420*dth4 + dr*(dr*(4*A74220*dth2 + dr*(dr*(6*A76020 + 7*A77020*dr) + 5*A75220*dth2)) + 3*A73420*dth4)) + A71620*dth6; dA_dr_re[7][2] = dr*(2*A72240*dth2 + dr*(dr*(4*A74040 + 5*A75040*dr) + 3*A73240*dth2)) + A71440*dth4; dA_dr_re[7][3] = dr*(2*A72060 + 3*A73060*dr) + A71260*dth2; dA_dr_re[7][4] = A71080; dA_dr_im[7][0] = dA_dr_im[7][1] = dA_dr_im[7][2] = dA_dr_im[7][3] = dA_dr_im[7][4] = 0.0; dA_dr_re[8][0] = dA_dr_re[8][1] = dA_dr_re[8][2] = dA_dr_re[8][3] = dA_dr_re[8][4] = 0.0; dA_dr_im[8][0] = dr*(2*A82501*dth5 + dr*(dr*(4*A84301*dth3 + dr*(dr*(6*A86101*dth + 7*A87101*dr*dth) + 5*A85301*dth3)) + 3*A83501*dth5)) + A81701*dth7; dA_dr_im[8][1] = dr*(2*A82321*dth3 + dr*(dr*(4*A84121*dth + 5*A85121*dr*dth) + 3*A83321*dth3)) + A81521*dth5; dA_dr_im[8][2] = dr*(2*A82141*dth + 3*A83141*dr*dth) + A81341*dth3; dA_dr_im[8][3] = A81161*dth; dA_dr_im[8][4] = 0.0; dA_dr_re[9][0] = dr*((2*A92400 + 2*A92600*dth2)*dth4 + dr*(dr*(dth2*(4*A94200 + 4*A94400*dth2) + dr*(dth2*(5*A95200 + 5*A95400*dth2) + dr*(6*A96000 + 6*A96200*dth2 + dr*(7*A97000 + dr*(8*A98000 + 9*A99000*dr) + 7*A97200*dth2)))) + (3*A93400 + 3*A93600*dth2)*dth4)) + (A91600 + A91800*dth2)*dth6; dA_dr_re[9][1] = dr*(dth2*(2*A92220 + 2*A92420*dth2) + dr*(dth2*(3*A93220 + 3*A93420*dth2) + dr*(4*A94020 + 4*A94220*dth2 + dr*(5*A95020 + dr*(6*A96020 + 7*A97020*dr) + 5*A95220*dth2)))) + (A91420 + A91620*dth2)*dth4; dA_dr_re[9][2] = dth2*(A91240 + A91440*dth2) + dr*(2*A92040 + 2*A92240*dth2 + dr*(3*A93040 + dr*(4*A94040 + 5*A95040*dr) + 3*A93240*dth2)); dA_dr_re[9][3] = A91060 + dr*(2*A92060 + 3*A93060*dr) + A91260*dth2; dA_dr_re[9][4] = A91080; dA_dr_im[9][0] = dA_dr_im[9][1] = dA_dr_im[9][2] = dA_dr_im[9][3] = dA_dr_im[9][4] = 0.0; /* dA/dth */ dA_dth_re[0][0] = (6*A00600 + 8*A00800*dth2)*dth5 + dr*(dr*((4*A02400 + 6*A02600*dth2)*dth3 + dr*(dr*(dth*(2*A04200 + 4*A04400*dth2) + dr*(dr*(2*A06200*dth + 2*A07200*dr*dth) + dth*(2*A05200 + 4*A05400*dth2))) + (4*A03400 + 6*A03600*dth2)*dth3)) + (6*A01600 + 8*A01800*dth2)*dth5); dA_dth_re[0][1] = (4*A00420 + 6*A00620*dth2)*dth3 + dr*(dr*(dth*(2*A02220 + 4*A02420*dth2) + dr*(dr*(2*A04220*dth + 2*A05220*dr*dth) + dth*(2*A03220 + 4*A03420*dth2))) + (4*A01420 + 6*A01620*dth2)*dth3); dA_dth_re[0][2] = dth*(2*A00240 + 4*A00440*dth2) + dr*(dr*(2*A02240*dth + 2*A03240*dr*dth) + dth*(2*A01240 + 4*A01440*dth2)); dA_dth_re[0][3] = 2*A00260*dth + 2*A01260*dr*dth; dA_dth_re[0][4] = 0.0; dA_dth_im[0][0] = dA_dth_im[0][1] = dA_dth_im[0][2] = dA_dth_im[0][3] = dA_dth_im[0][4] = 0.0; dA_dth_re[1][0] = dA_dth_re[1][1] = dA_dth_re[1][2] = dA_dth_re[1][3] = dA_dth_re[1][4] = 0.0; dA_dth_im[1][0] = (6*A10601 + 8*A10801*dth2)*dth5 + dr*(dr*((4*A12401 + 6*A12601*dth2)*dth3 + dr*(dr*(dr*(2*A15201*dth + 2*A16201*dr*dth) + dth*(2*A14201 + 4*A14401*dth2)) + 4*A13401*dth3)) + 6*A11601*dth5); dA_dth_im[1][1] = (4*A10421 + 6*A10621*dth2)*dth3 + dr*(dr*(dr*(2*A13221*dth + 2*A14221*dr*dth) + dth*(2*A12221 + 4*A12421*dth2)) + 4*A11421*dth3); dA_dth_im[1][2] = dr*(2*A11241*dth + 2*A12241*dr*dth) + dth*(2*A10241 + 4*A10441*dth2); dA_dth_im[1][3] = 2*A10261*dth; dA_dth_im[1][4] = 0.0; dA_dth_re[2][0] = dA_dth_re[2][1] = dA_dth_re[2][2] = dA_dth_re[2][3] = dA_dth_re[2][4] = 0.0; dA_dth_im[2][0] = 7*A20701*dth6 + dr*(dr*(5*A22501*dth4 + dr*(dr*(3*A24301*dth2 + dr*(dr*(A26101 + A27101*dr) + 3*A25301*dth2)) + 5*A23501*dth4)) + 7*A21701*dth6); dA_dth_im[2][1] = 5*A20521*dth4 + dr*(dr*(3*A22321*dth2 + dr*(dr*(A24121 + A25121*dr) + 3*A23321*dth2)) + 5*A21521*dth4); dA_dth_im[2][2] = 3*A20341*dth2 + dr*(dr*(A22141 + A23141*dr) + 3*A21341*dth2); dA_dth_im[2][3] = A20161 + A21161*dr; dA_dth_im[2][4] = 0.0; dA_dth_re[3][0] = (6*A30600 + 8*A30800*dth2)*dth5 + dr*(dr*((4*A32400 + 6*A32600*dth2)*dth3 + dr*(dr*(dth*(2*A34200 + 4*A34400*dth2) + dr*(dr*(2*A36200*dth + 2*A37200*dr*dth) + dth*(2*A35200 + 4*A35400*dth2))) + (4*A33400 + 6*A33600*dth2)*dth3)) + (6*A31600 + 8*A31800*dth2)*dth5); dA_dth_re[3][1] = (4*A30420 + 6*A30620*dth2)*dth3 + dr*(dr*(dth*(2*A32220 + 4*A32420*dth2) + dr*(dr*(2*A34220*dth + 2*A35220*dr*dth) + dth*(2*A33220 + 4*A33420*dth2))) + (4*A31420 + 6*A31620*dth2)*dth3); dA_dth_re[3][2] = dth*(2*A30240 + 4*A30440*dth2) + dr*(dr*(2*A32240*dth + 2*A33240*dr*dth) + dth*(2*A31240 + 4*A31440*dth2)); dA_dth_re[3][3] = 2*A30260*dth + 2*A31260*dr*dth; dA_dth_re[3][4] = 0.0; dA_dth_im[3][0] = dA_dth_im[3][1] = dA_dth_im[3][2] = dA_dth_im[3][3] = dA_dth_im[3][4] = 0.0; dA_dth_re[4][0] = 8*A40800*dth7 + dr*(dr*(6*A42600*dth5 + dr*(dr*(4*A44400*dth3 + dr*(dr*(2*A46200*dth + 2*A47200*dr*dth) + 4*A45400*dth3)) + 6*A43600*dth5)) + 8*A41800*dth7); dA_dth_re[4][1] = 6*A40620*dth5 + dr*(dr*(4*A42420*dth3 + dr*(dr*(2*A44220*dth + 2*A45220*dr*dth) + 4*A43420*dth3)) + 6*A41620*dth5); dA_dth_re[4][2] = 4*A40440*dth3 + dr*(dr*(2*A42240*dth + 2*A43240*dr*dth) + 4*A41440*dth3); dA_dth_re[4][3] = 2*A40260*dth + 2*A41260*dr*dth; dA_dth_re[4][4] = 0.0; dA_dth_im[4][0] = dA_dth_im[4][1] = dA_dth_im[4][2] = dA_dth_im[4][3] = dA_dth_im[4][4] = 0.0; dA_dth_re[5][0] = dr2*(dr2*(dr2*(A58100*dr2 + 3*A56300*dth2) + 5*A54500*dth4) + 7*A52700*dth6) + 9*A50900*dth8; dA_dth_re[5][1] = dr2*(dr2*(A56120*dr2 + 3*A54320*dth2) + 5*A52520*dth4) + 7*A50720*dth6; dA_dth_re[5][2] = dr2*(A54140*dr2 + 3*A52340*dth2) + 5*A50540*dth4; dA_dth_re[5][3] = A52160*dr2 + 3*A50360*dth2; dA_dth_re[5][4] = A50180; dA_dth_im[5][0] = dA_dth_im[5][1] = dA_dth_im[5][2] = dA_dth_im[5][3] = dA_dth_im[5][4] = 0.0; dA_dth_re[6][0] = dA_dth_re[6][1] = dA_dth_re[6][2] = dA_dth_re[6][3] = dA_dth_re[6][4] = 0.0; dA_dth_im[6][0] = (6*A60601 + 8*A60801*dth2)*dth5 + dr*(dr*((4*A62401 + 6*A62601*dth2)*dth3 + dr*(dr*(dr*(2*A65201*dth + 2*A66201*dr*dth) + dth*(2*A64201 + 4*A64401*dth2)) + 4*A63401*dth3)) + 6*A61601*dth5); dA_dth_im[6][1] = (4*A60421 + 6*A60621*dth2)*dth3 + dr*(dr*(dr*(2*A63221*dth + 2*A64221*dr*dth) + dth*(2*A62221 + 4*A62421*dth2)) + 4*A61421*dth3); dA_dth_im[6][2] = dr*(2*A61241*dth + 2*A62241*dr*dth) + dth*(2*A60241 + 4*A60441*dth2); dA_dth_im[6][3] = 2*A60261*dth; dA_dth_im[6][4] = 0.0; dA_dth_re[7][0] = 8*A70800*dth7 + dr*(dr*(6*A72600*dth5 + dr*(dr*(4*A74400*dth3 + dr*(dr*(2*A76200*dth + 2*A77200*dr*dth) + 4*A75400*dth3)) + 6*A73600*dth5)) + 8*A71800*dth7); dA_dth_re[7][1] = 6*A70620*dth5 + dr*(dr*(4*A72420*dth3 + dr*(dr*(2*A74220*dth + 2*A75220*dr*dth) + 4*A73420*dth3)) + 6*A71620*dth5); dA_dth_re[7][2] = 4*A70440*dth3 + dr*(dr*(2*A72240*dth + 2*A73240*dr*dth) + 4*A71440*dth3); dA_dth_re[7][3] = 2*A70260*dth + 2*A71260*dr*dth; dA_dth_re[7][4] = 0.0; dA_dth_im[7][0] = dA_dth_im[7][1] = dA_dth_im[7][2] = dA_dth_im[7][3] = dA_dth_im[7][4] = 0.0; dA_dth_re[8][0] = dA_dth_re[8][1] = dA_dth_re[8][2] = dA_dth_re[8][3] = dA_dth_re[8][4] = 0.0; dA_dth_im[8][0] = 7*A80701*dth6 + dr*(dr*(5*A82501*dth4 + dr*(dr*(3*A84301*dth2 + dr*(dr*(A86101 + A87101*dr) + 3*A85301*dth2)) + 5*A83501*dth4)) + 7*A81701*dth6); dA_dth_im[8][1] = 5*A80521*dth4 + dr*(dr*(3*A82321*dth2 + dr*(dr*(A84121 + A85121*dr) + 3*A83321*dth2)) + 5*A81521*dth4); dA_dth_im[8][2] = 3*A80341*dth2 + dr*(dr*(A82141 + A83141*dr) + 3*A81341*dth2); dA_dth_im[8][3] = A80161 + A81161*dr; dA_dth_im[8][4] = 0.0; dA_dth_re[9][0] = (6*A90600 + 8*A90800*dth2)*dth5 + dr*(dr*((4*A92400 + 6*A92600*dth2)*dth3 + dr*(dr*(dth*(2*A94200 + 4*A94400*dth2) + dr*(dr*(2*A96200*dth + 2*A97200*dr*dth) + dth*(2*A95200 + 4*A95400*dth2))) + (4*A93400 + 6*A93600*dth2)*dth3)) + (6*A91600 + 8*A91800*dth2)*dth5); dA_dth_re[9][1] = (4*A90420 + 6*A90620*dth2)*dth3 + dr*(dr*(dth*(2*A92220 + 4*A92420*dth2) + dr*(dr*(2*A94220*dth + 2*A95220*dr*dth) + dth*(2*A93220 + 4*A93420*dth2))) + (4*A91420 + 6*A91620*dth2)*dth3); dA_dth_re[9][2] = dth*(2*A90240 + 4*A90440*dth2) + dr*(dr*(2*A92240*dth + 2*A93240*dr*dth) + dth*(2*A91240 + 4*A91440*dth2)); dA_dth_re[9][3] = 2*A90260*dth + 2*A91260*dr*dth; dA_dth_re[9][4] = 0.0; dA_dth_im[9][0] = dA_dth_im[9][1] = dA_dth_im[9][2] = dA_dth_im[9][3] = dA_dth_im[9][4] = 0.0; /* d2A/dr2 */ d2A_dr2_re[0][0] = (2*A02400 + 2*A02600*dth2)*dth4 + dr*(dr*(dth2*(12*A04200 + 12*A04400*dth2) + dr*(dth2*(20*A05200 + 20*A05400*dth2) + dr*(30*A06000 + 30*A06200*dth2 + dr*(42*A07000 + dr*(56*A08000 + 72*A09000*dr) + 42*A07200*dth2)))) + (6*A03400 + 6*A03600*dth2)*dth4); d2A_dr2_re[0][1] = dth2*(2*A02220 + 2*A02420*dth2) + dr*(dth2*(6*A03220 + 6*A03420*dth2) + dr*(12*A04020 + 12*A04220*dth2 + dr*(20*A05020 + dr*(30*A06020 + 42*A07020*dr) + 20*A05220*dth2))); d2A_dr2_re[0][2] = 2*A02040 + 2*A02240*dth2 + dr*(6*A03040 + dr*(12*A04040 + 20*A05040*dr) + 6*A03240*dth2); d2A_dr2_re[0][3] = 2*A02060 + 6*A03060*dr; d2A_dr2_re[0][4] = 0.0; d2A_dr2_im[0][0] = d2A_dr2_im[0][1] = d2A_dr2_im[0][2] = d2A_dr2_im[0][3] = d2A_dr2_im[0][4] = 0.0; d2A_dr2_re[1][0] = d2A_dr2_re[1][1] = d2A_dr2_re[1][2] = d2A_dr2_re[1][3] = d2A_dr2_re[1][4] = 0.0; d2A_dr2_im[1][0] = (2*A12401 + 2*A12601*dth2)*dth4 + dr*(dr*(dth2*(12*A14201 + 12*A14401*dth2) + dr*(20*A15201*dth2 + dr*(30*A16001 + dr*(42*A17001 + 56*A18001*dr) + 30*A16201*dth2))) + 6*A13401*dth4); d2A_dr2_im[1][1] = dth2*(2*A12221 + 2*A12421*dth2) + dr*(6*A13221*dth2 + dr*(12*A14021 + dr*(20*A15021 + 30*A16021*dr) + 12*A14221*dth2)); d2A_dr2_im[1][2] = 2*A12041 + dr*(6*A13041 + 12*A14041*dr) + 2*A12241*dth2; d2A_dr2_im[1][3] = 2*A12061; d2A_dr2_im[1][4] = 0.0; d2A_dr2_re[2][0] = d2A_dr2_re[2][1] = d2A_dr2_re[2][2] = d2A_dr2_re[2][3] = d2A_dr2_re[2][4] = 0.0; d2A_dr2_im[2][0] = 2*A22501*dth5 + dr*(dr*(12*A24301*dth3 + dr*(dr*(30*A26101*dth + 42*A27101*dr*dth) + 20*A25301*dth3)) + 6*A23501*dth5); d2A_dr2_im[2][1] = 2*A22321*dth3 + dr*(dr*(12*A24121*dth + 20*A25121*dr*dth) + 6*A23321*dth3); d2A_dr2_im[2][2] = 2*A22141*dth + 6*A23141*dr*dth; d2A_dr2_im[2][3] = 0.0; d2A_dr2_im[2][4] = 0.0; d2A_dr2_re[3][0] = (2*A32400 + 2*A32600*dth2)*dth4 + dr*(dr*(dth2*(12*A34200 + 12*A34400*dth2) + dr*(dth2*(20*A35200 + 20*A35400*dth2) + dr*(30*A36000 + 30*A36200*dth2 + dr*(42*A37000 + dr*(56*A38000 + 72*A39000*dr) + 42*A37200*dth2)))) + (6*A33400 + 6*A33600*dth2)*dth4); d2A_dr2_re[3][1] = dth2*(2*A32220 + 2*A32420*dth2) + dr*(dth2*(6*A33220 + 6*A33420*dth2) + dr*(12*A34020 + 12*A34220*dth2 + dr*(20*A35020 + dr*(30*A36020 + 42*A37020*dr) + 20*A35220*dth2))); d2A_dr2_re[3][2] = 2*A32040 + 2*A32240*dth2 + dr*(6*A33040 + dr*(12*A34040 + 20*A35040*dr) + 6*A33240*dth2); d2A_dr2_re[3][3] = 2*A32060 + 6*A33060*dr; d2A_dr2_re[3][4] = 0.0; d2A_dr2_im[3][0] = d2A_dr2_im[3][1] = d2A_dr2_im[3][2] = d2A_dr2_im[3][3] = d2A_dr2_im[3][4] = 0.0; d2A_dr2_re[4][0] = 2*A42600*dth6 + dr*(dr*(12*A44400*dth4 + dr*(dr*(30*A46200*dth2 + dr*(dr*(56*A48000 + 72*A49000*dr) + 42*A47200*dth2)) + 20*A45400*dth4)) + 6*A43600*dth6); d2A_dr2_re[4][1] = 2*A42420*dth4 + dr*(dr*(12*A44220*dth2 + dr*(dr*(30*A46020 + 42*A47020*dr) + 20*A45220*dth2)) + 6*A43420*dth4); d2A_dr2_re[4][2] = 2*A42240*dth2 + dr*(dr*(12*A44040 + 20*A45040*dr) + 6*A43240*dth2); d2A_dr2_re[4][3] = 2*A42060 + 6*A43060*dr; d2A_dr2_re[4][4] = 0.0; d2A_dr2_im[4][0] = d2A_dr2_im[4][1] = d2A_dr2_im[4][2] = d2A_dr2_im[4][3] = d2A_dr2_im[4][4] = 0.0; d2A_dr2_re[5][0] = dr2*(dr2*(56*A58100*dr2*dth + 30*A56300*dth3) + 12*A54500*dth5) + 2*A52700*dth7; d2A_dr2_re[5][1] = dr2*(30*A56120*dr2*dth + 12*A54320*dth3) + 2*A52520*dth5; d2A_dr2_re[5][2] = 12*A54140*dr2*dth + 2*A52340*dth3; d2A_dr2_re[5][3] = 2*A52160*dth; d2A_dr2_re[5][4] = 0.0; d2A_dr2_im[5][0] = d2A_dr2_im[5][1] = d2A_dr2_im[5][2] = d2A_dr2_im[5][3] = d2A_dr2_im[5][4] = 0.0; d2A_dr2_re[6][0] = d2A_dr2_re[6][1] = d2A_dr2_re[6][2] = d2A_dr2_re[6][3] = d2A_dr2_re[6][4] = 0.0; d2A_dr2_im[6][0] = (2*A62401 + 2*A62601*dth2)*dth4 + dr*(dr*(dth2*(12*A64201 + 12*A64401*dth2) + dr*(20*A65201*dth2 + dr*(30*A66001 + dr*(42*A67001 + 56*A68001*dr) + 30*A66201*dth2))) + 6*A63401*dth4); d2A_dr2_im[6][1] = dth2*(2*A62221 + 2*A62421*dth2) + dr*(6*A63221*dth2 + dr*(12*A64021 + dr*(20*A65021 + 30*A66021*dr) + 12*A64221*dth2)); d2A_dr2_im[6][2] = 2*A62041 + dr*(6*A63041 + 12*A64041*dr) + 2*A62241*dth2; d2A_dr2_im[6][3] = 2*A62061; d2A_dr2_im[6][4] = 0.0; d2A_dr2_re[7][0] = 2*A72600*dth6 + dr*(dr*(12*A74400*dth4 + dr*(dr*(30*A76200*dth2 + dr*(dr*(56*A78000 + 72*A79000*dr) + 42*A77200*dth2)) + 20*A75400*dth4)) + 6*A73600*dth6); d2A_dr2_re[7][1] = 2*A72420*dth4 + dr*(dr*(12*A74220*dth2 + dr*(dr*(30*A76020 + 42*A77020*dr) + 20*A75220*dth2)) + 6*A73420*dth4); d2A_dr2_re[7][2] = 2*A72240*dth2 + dr*(dr*(12*A74040 + 20*A75040*dr) + 6*A73240*dth2); d2A_dr2_re[7][3] = 2*A72060 + 6*A73060*dr; d2A_dr2_re[7][4] = 0.0; d2A_dr2_im[7][0] = d2A_dr2_im[7][1] = d2A_dr2_im[7][2] = d2A_dr2_im[7][3] = d2A_dr2_im[7][4] = 0.0; d2A_dr2_re[8][0] = d2A_dr2_re[8][1] = d2A_dr2_re[8][2] = d2A_dr2_re[8][3] = d2A_dr2_re[8][4] = 0.0; d2A_dr2_im[8][0] = 2*A82501*dth5 + dr*(dr*(12*A84301*dth3 + dr*(dr*(30*A86101*dth + 42*A87101*dr*dth) + 20*A85301*dth3)) + 6*A83501*dth5); d2A_dr2_im[8][1] = 2*A82321*dth3 + dr*(dr*(12*A84121*dth + 20*A85121*dr*dth) + 6*A83321*dth3); d2A_dr2_im[8][2] = 2*A82141*dth + 6*A83141*dr*dth; d2A_dr2_im[8][3] = 0.0; d2A_dr2_im[8][4] = 0.0; d2A_dr2_re[9][0] = (2*A92400 + 2*A92600*dth2)*dth4 + dr*(dr*(dth2*(12*A94200 + 12*A94400*dth2) + dr*(dth2*(20*A95200 + 20*A95400*dth2) + dr*(30*A96000 + 30*A96200*dth2 + dr*(42*A97000 + dr*(56*A98000 + 72*A99000*dr) + 42*A97200*dth2)))) + (6*A93400 + 6*A93600*dth2)*dth4); d2A_dr2_re[9][1] = dth2*(2*A92220 + 2*A92420*dth2) + dr*(dth2*(6*A93220 + 6*A93420*dth2) + dr*(12*A94020 + 12*A94220*dth2 + dr*(20*A95020 + dr*(30*A96020 + 42*A97020*dr) + 20*A95220*dth2))); d2A_dr2_re[9][2] = 2*A92040 + 2*A92240*dth2 + dr*(6*A93040 + dr*(12*A94040 + 20*A95040*dr) + 6*A93240*dth2); d2A_dr2_re[9][3] = 2*A92060 + 6*A93060*dr; d2A_dr2_re[9][4] = 0.0; d2A_dr2_im[9][0] = d2A_dr2_im[9][1] = d2A_dr2_im[9][2] = d2A_dr2_im[9][3] = d2A_dr2_im[9][4] = 0.0; /* d2A/dth2 */ d2A_dth2_re[0][0] = (30*A00600 + 56*A00800*dth2)*dth4 + dr*(dr*(dth2*(12*A02400 + 30*A02600*dth2) + dr*(dth2*(12*A03400 + 30*A03600*dth2) + dr*(2*A04200 + 12*A04400*dth2 + dr*(2*A05200 + dr*(2*A06200 + 2*A07200*dr) + 12*A05400*dth2)))) + (30*A01600 + 56*A01800*dth2)*dth4); d2A_dth2_re[0][1] = dth2*(12*A00420 + 30*A00620*dth2) + dr*(dth2*(12*A01420 + 30*A01620*dth2) + dr*(2*A02220 + 12*A02420*dth2 + dr*(2*A03220 + dr*(2*A04220 + 2*A05220*dr) + 12*A03420*dth2))); d2A_dth2_re[0][2] = 2*A00240 + 12*A00440*dth2 + dr*(2*A01240 + dr*(2*A02240 + 2*A03240*dr) + 12*A01440*dth2); d2A_dth2_re[0][3] = 2*A00260 + 2*A01260*dr; d2A_dth2_re[0][4] = 0.0; d2A_dth2_im[0][0] = d2A_dth2_im[0][1] = d2A_dth2_im[0][2] = d2A_dth2_im[0][3] = d2A_dth2_im[0][4] = 0.0; d2A_dth2_re[1][0] = d2A_dth2_re[1][1] = d2A_dth2_re[1][2] = d2A_dth2_re[1][3] = d2A_dth2_re[1][4] = 0.0; d2A_dth2_im[1][0] = (30*A10601 + 56*A10801*dth2)*dth4 + dr*(dr*(dth2*(12*A12401 + 30*A12601*dth2) + dr*(12*A13401*dth2 + dr*(2*A14201 + dr*(2*A15201 + 2*A16201*dr) + 12*A14401*dth2))) + 30*A11601*dth4); d2A_dth2_im[1][1] = dth2*(12*A10421 + 30*A10621*dth2) + dr*(12*A11421*dth2 + dr*(2*A12221 + dr*(2*A13221 + 2*A14221*dr) + 12*A12421*dth2)); d2A_dth2_im[1][2] = 2*A10241 + dr*(2*A11241 + 2*A12241*dr) + 12*A10441*dth2; d2A_dth2_im[1][3] = 2*A10261; d2A_dth2_im[1][4] = 0.0; d2A_dth2_re[2][0] = d2A_dth2_re[2][1] = d2A_dth2_re[2][2] = d2A_dth2_re[2][3] = d2A_dth2_re[2][4] = 0.0; d2A_dth2_im[2][0] = 42*A20701*dth5 + dr*(dr*(20*A22501*dth3 + dr*(dr*(6*A24301*dth + 6*A25301*dr*dth) + 20*A23501*dth3)) + 42*A21701*dth5); d2A_dth2_im[2][1] = 20*A20521*dth3 + dr*(dr*(6*A22321*dth + 6*A23321*dr*dth) + 20*A21521*dth3); d2A_dth2_im[2][2] = 6*A20341*dth + 6*A21341*dr*dth; d2A_dth2_im[2][3] = 0.0; d2A_dth2_im[2][4] = 0.0; d2A_dth2_re[3][0] = (30*A30600 + 56*A30800*dth2)*dth4 + dr*(dr*(dth2*(12*A32400 + 30*A32600*dth2) + dr*(dth2*(12*A33400 + 30*A33600*dth2) + dr*(2*A34200 + 12*A34400*dth2 + dr*(2*A35200 + dr*(2*A36200 + 2*A37200*dr) + 12*A35400*dth2)))) + (30*A31600 + 56*A31800*dth2)*dth4); d2A_dth2_re[3][1] = dth2*(12*A30420 + 30*A30620*dth2) + dr*(dth2*(12*A31420 + 30*A31620*dth2) + dr*(2*A32220 + 12*A32420*dth2 + dr*(2*A33220 + dr*(2*A34220 + 2*A35220*dr) + 12*A33420*dth2))); d2A_dth2_re[3][2] = 2*A30240 + 12*A30440*dth2 + dr*(2*A31240 + dr*(2*A32240 + 2*A33240*dr) + 12*A31440*dth2); d2A_dth2_re[3][3] = 2*A30260 + 2*A31260*dr; d2A_dth2_re[3][4] = 0.0; d2A_dth2_im[3][0] = d2A_dth2_im[3][1] = d2A_dth2_im[3][2] = d2A_dth2_im[3][3] = d2A_dth2_im[3][4] = 0.0; d2A_dth2_re[4][0] = 56*A40800*dth6 + dr*(dr*(30*A42600*dth4 + dr*(dr*(12*A44400*dth2 + dr*(dr*(2*A46200 + 2*A47200*dr) + 12*A45400*dth2)) + 30*A43600*dth4)) + 56*A41800*dth6); d2A_dth2_re[4][1] = 30*A40620*dth4 + dr*(dr*(12*A42420*dth2 + dr*(dr*(2*A44220 + 2*A45220*dr) + 12*A43420*dth2)) + 30*A41620*dth4); d2A_dth2_re[4][2] = 12*A40440*dth2 + dr*(dr*(2*A42240 + 2*A43240*dr) + 12*A41440*dth2); d2A_dth2_re[4][3] = 2*A40260 + 2*A41260*dr; d2A_dth2_re[4][4] = 0.0; d2A_dth2_im[4][0] = d2A_dth2_im[4][1] = d2A_dth2_im[4][2] = d2A_dth2_im[4][3] = d2A_dth2_im[4][4] = 0.0; d2A_dth2_re[5][0] = dr2*(dr2*(6*A56300*dr2*dth + 20*A54500*dth3) + 42*A52700*dth5) + 72*A50900*dth7; d2A_dth2_re[5][1] = dr2*(6*A54320*dr2*dth + 20*A52520*dth3) + 42*A50720*dth5; d2A_dth2_re[5][2] = 6*A52340*dr2*dth + 20*A50540*dth3; d2A_dth2_re[5][3] = 6*A50360*dth; d2A_dth2_re[5][4] = 0.0; d2A_dth2_im[5][0] = d2A_dth2_im[5][1] = d2A_dth2_im[5][2] = d2A_dth2_im[5][3] = d2A_dth2_im[5][4] = 0.0; d2A_dth2_re[6][0] = d2A_dth2_re[6][1] = d2A_dth2_re[6][2] = d2A_dth2_re[6][3] = d2A_dth2_re[6][4] = 0.0; d2A_dth2_im[6][0] = (30*A60601 + 56*A60801*dth2)*dth4 + dr*(dr*(dth2*(12*A62401 + 30*A62601*dth2) + dr*(12*A63401*dth2 + dr*(2*A64201 + dr*(2*A65201 + 2*A66201*dr) + 12*A64401*dth2))) + 30*A61601*dth4); d2A_dth2_im[6][1] = dth2*(12*A60421 + 30*A60621*dth2) + dr*(12*A61421*dth2 + dr*(2*A62221 + dr*(2*A63221 + 2*A64221*dr) + 12*A62421*dth2)); d2A_dth2_im[6][2] = 2*A60241 + dr*(2*A61241 + 2*A62241*dr) + 12*A60441*dth2; d2A_dth2_im[6][3] = 2*A60261; d2A_dth2_im[6][4] = 0.0; d2A_dth2_re[7][0] = 56*A70800*dth6 + dr*(dr*(30*A72600*dth4 + dr*(dr*(12*A74400*dth2 + dr*(dr*(2*A76200 + 2*A77200*dr) + 12*A75400*dth2)) + 30*A73600*dth4)) + 56*A71800*dth6); d2A_dth2_re[7][1] = 30*A70620*dth4 + dr*(dr*(12*A72420*dth2 + dr*(dr*(2*A74220 + 2*A75220*dr) + 12*A73420*dth2)) + 30*A71620*dth4); d2A_dth2_re[7][2] = 12*A70440*dth2 + dr*(dr*(2*A72240 + 2*A73240*dr) + 12*A71440*dth2); d2A_dth2_re[7][3] = 2*A70260 + 2*A71260*dr; d2A_dth2_re[7][4] = 0.0; d2A_dth2_im[7][0] = d2A_dth2_im[7][1] = d2A_dth2_im[7][2] = d2A_dth2_im[7][3] = d2A_dth2_im[7][4] = 0.0; d2A_dth2_re[8][0] = d2A_dth2_re[8][1] = d2A_dth2_re[8][2] = d2A_dth2_re[8][3] = d2A_dth2_re[8][4] = 0.0; d2A_dth2_im[8][0] = 42*A80701*dth5 + dr*(dr*(20*A82501*dth3 + dr*(dr*(6*A84301*dth + 6*A85301*dr*dth) + 20*A83501*dth3)) + 42*A81701*dth5); d2A_dth2_im[8][1] = 20*A80521*dth3 + dr*(dr*(6*A82321*dth + 6*A83321*dr*dth) + 20*A81521*dth3); d2A_dth2_im[8][2] = 6*A80341*dth + 6*A81341*dr*dth; d2A_dth2_im[8][3] = 0.0; d2A_dth2_im[8][4] = 0.0; d2A_dth2_re[9][0] = (30*A90600 + 56*A90800*dth2)*dth4 + dr*(dr*(dth2*(12*A92400 + 30*A92600*dth2) + dr*(dth2*(12*A93400 + 30*A93600*dth2) + dr*(2*A94200 + 12*A94400*dth2 + dr*(2*A95200 + dr*(2*A96200 + 2*A97200*dr) + 12*A95400*dth2)))) + (30*A91600 + 56*A91800*dth2)*dth4); d2A_dth2_re[9][1] = dth2*(12*A90420 + 30*A90620*dth2) + dr*(dth2*(12*A91420 + 30*A91620*dth2) + dr*(2*A92220 + 12*A92420*dth2 + dr*(2*A93220 + dr*(2*A94220 + 2*A95220*dr) + 12*A93420*dth2))); d2A_dth2_re[9][2] = 2*A90240 + 12*A90440*dth2 + dr*(2*A91240 + dr*(2*A92240 + 2*A93240*dr) + 12*A91440*dth2); d2A_dth2_re[9][3] = 2*A90260 + 2*A91260*dr; d2A_dth2_re[9][4] = 0.0; d2A_dth2_im[9][0] = d2A_dth2_im[9][1] = d2A_dth2_im[9][2] = d2A_dth2_im[9][3] = d2A_dth2_im[9][4] = 0.0; /* alpha term appearing in the denominator */ double alpha = alpha20*dr2 + alpha02*dth2; /* Derivatives of alpha */ double dalpha_dr = 2*alpha20*dr; double d2alpha_dr2 = 2*alpha20; double dalpha_dth = 2*alpha02*dth; double d2alpha_dth2 = 2*alpha02; /* Powers of C = alpha / beta */ const double beta_inv = 1.0 / beta; double C[27]; C[0] = 1; C[1] = alpha * beta_inv; for(int i=2; i<=26; i++) C[i] = C[1]*C[i-1]; double dC1_dr = dalpha_dr * beta_inv; double d2C1_dr2 = d2alpha_dr2 * beta_inv; double dC1_dth = dalpha_dth * beta_inv; double d2C1_dth2 = d2alpha_dth2 * beta_inv; double dC_dr[27]; dC_dr[0] = 0; for(int i=1; i<=26; i++) dC_dr[i] = i*C[i-1]*dC1_dr; double d2C_dr2[27]; d2C_dr2[0] = 0; d2C_dr2[1] = d2C1_dr2; for(int i=2; i<=26; i++) d2C_dr2[i] = i*(i-1)*C[i-2]*dC1_dr*dC1_dr + i*C[i-1]*d2C1_dr2; double dC_dth[27]; dC_dth[0] = 0; for(int i=1; i<=26; i++) dC_dth[i] = i*C[i-1]*dC1_dth; double d2C_dth2[27]; d2C_dth2[0] = 0; d2C_dth2[1] = d2C1_dth2; for(int i=2; i<=26; i++) d2C_dth2[i] = i*(i-1)*C[i-2]*dC1_dth*dC1_dth + i*C[i-1]*d2C1_dth2; /* Elliptic integrals */ double gam = sqrt(1.0/(1.0+C[1])); double ellE = gsl_sf_ellint_Ecomp(gam, GSL_PREC_DOUBLE); double ellK = gsl_sf_ellint_Kcomp(gam, GSL_PREC_DOUBLE); /* Derivatives of elliptic integrals */ double dellE_dC = (ellK - ellE)/(2.*(1+C[1])); double dellK_dC = (C[1]*ellK - (1+C[1])*ellE)/(2.*C[1]*(1+C[1])); double d2ellE_dC2 = -(2*C[1]*ellK - (2*C[1]-1)*ellE)/(4.*C[1]*(1+C[1])*(1+C[1])); double d2ellK_dC2 = -(C[1]*(1+2*C[1])*ellK - 2*(1+C[1])*(1+C[1])*ellE)/(4.*C[1]*C[1]*(1+C[1])*(1+C[1])); double dellE_dr = dellE_dC * dC1_dr; double dellE_dth = dellE_dC * dC1_dth; double d2ellE_dr2 = d2ellE_dC2 * dC1_dr * dC1_dr + dellE_dC * d2C1_dr2; double d2ellE_dth2 = d2ellE_dC2 * dC1_dth * dC1_dth + dellE_dC * d2C1_dth2; double dellK_dr = dellK_dC * dC1_dr; double dellK_dth = dellK_dC * dC1_dth; double d2ellK_dr2 = d2ellK_dC2 * dC1_dr * dC1_dr + dellK_dC * d2C1_dr2; double d2ellK_dth2 = d2ellK_dC2 * dC1_dth * dC1_dth + dellK_dC * d2C1_dth2; /* Denominator - there is a different denominator for real and imaginary parts */ double alpha_plus_beta_10 = alpha+beta; double alpha_plus_beta_05 = sqrt(alpha_plus_beta_10); double alpha_plus_beta_15 = alpha_plus_beta_10*alpha_plus_beta_05; double alpha_plus_beta_20 = alpha_plus_beta_10*alpha_plus_beta_10; double alpha_plus_beta_25 = alpha_plus_beta_10*alpha_plus_beta_15; double beta_2 = beta*beta; double den_re = beta*C[3]*alpha_plus_beta_25/4.0; double dden_dr_re = beta*(6.0*C[2]*alpha_plus_beta_25*dC1_dr + C[3]*5.0*alpha_plus_beta_15*dalpha_dr)/8.0; double dden_dth_re = beta*(6.0*C[2]*alpha_plus_beta_25*dC1_dth + C[3]*5.0*alpha_plus_beta_15*dalpha_dth)/8.0; double d2den_dr2_re = beta*C[1]*alpha_plus_beta_05*(24*alpha_plus_beta_20*dC1_dr*dC1_dr + 60.0*C[1]*(alpha+beta)*dalpha_dr*dC1_dr + C[1]*(12.0*alpha_plus_beta_20*d2C1_dr2 + 5.0*C[1]*(3.0*dalpha_dr*dalpha_dr + 2.0*(alpha+beta)*d2alpha_dr2)))/16.0; double d2den_dth2_re = beta*C[1]*alpha_plus_beta_05*(24*alpha_plus_beta_20*dC1_dth*dC1_dth + 60.0*C[1]*(alpha+beta)*dalpha_dth*dC1_dth + C[1]*(12.0*alpha_plus_beta_20*d2C1_dth2 + 5.0*C[1]*(3.0*dalpha_dth*dalpha_dth + 2.0*(alpha+beta)*d2alpha_dth2)))/16.0; double den_im = -(beta_2*C[2]*alpha_plus_beta_15)/32.0; double dden_dr_im = -(beta_2*C[1]*alpha_plus_beta_05*(4.0*alpha_plus_beta_10*dC1_dr + 3*C[1]*dalpha_dr))/64.; double dden_dth_im = -(beta_2*C[1]*alpha_plus_beta_05*(4.0*alpha_plus_beta_10*dC1_dth + 3*C[1]*dalpha_dth))/64.; double d2den_dr2_im = -(beta_2*(C[1]*(8*alpha_plus_beta_20*d2C1_dr2 + 3.0*C[1]*(2.0*alpha_plus_beta_10*d2alpha_dr2 + dalpha_dr*dalpha_dr)) + 24.0*alpha_plus_beta_10*C[1]*dalpha_dr*dC1_dr + 8.0*alpha_plus_beta_20*dC1_dr*dC1_dr))/(128.*alpha_plus_beta_05); double d2den_dth2_im = -(beta_2*(C[1]*(8*alpha_plus_beta_20*d2C1_dth2 + 3.0*C[1]*(2.0*alpha_plus_beta_10*d2alpha_dth2 + dalpha_dth*dalpha_dth)) + 24.0*alpha_plus_beta_10*C[1]*dalpha_dth*dC1_dth + 8.0*alpha_plus_beta_20*dC1_dth*dC1_dth))/(128.*alpha_plus_beta_05); for(int l=0; l<10; l++) { /* First, compute derivatives of numerator - we will add the denominator at the end */ /* hS */ hS_re[l] = 0.0; hS_im[l] = 0.0; for(int j=0; j<5; j++) { double fac1K = ellK*A_re[l][j]; for(int k=max(j,0); k<=m+2+j; k++) { hS_re[l] += fac1K*C[k]*ReEI[m][0][j][k]; } double fac1E = ellE*A_re[l][j]; for(int k=max(j-1,0); k<=m+2+j; k++) { hS_re[l] += fac1E*C[k]*ReEI[m][1][j][k]; } double fac2K = ellK*A_im[l][j]; for(int k=max(j-1,0); k<=m+1+j; k++) { hS_im[l] += fac2K*C[k]*ImEI[m][0][j][k]; } double fac2E = ellE*A_im[l][j]; for(int k=max(j-2,0); k<=m+1+j; k++) { hS_im[l] += fac2E*C[k]*ImEI[m][1][j][k]; } } /* dhS_dr */ dhS_dr_re[l] = 0.0; dhS_dr_im[l] = 0.0; for(int j=0; j<5; j++) { double fac1K = (dellK_dr*A_re[l][j] + ellK*dA_dr_re[l][j]); double fac2K = ellK*A_re[l][j]; for(int k=max(j,0); k<=m+2+j; k++) { dhS_dr_re[l] += ReEI[m][0][j][k]*(C[k]*fac1K + fac2K*dC_dr[k]); } double fac1E = (dellE_dr*A_re[l][j] + ellE*dA_dr_re[l][j]); double fac2E = ellE*A_re[l][j]; for(int k=max(j-1,0); k<=m+2+j; k++) { dhS_dr_re[l] += ReEI[m][1][j][k]*(C[k]*fac1E + fac2E*dC_dr[k]); } double fac3K = (dellK_dr*A_im[l][j] + ellK*dA_dr_im[l][j]); double fac4K = ellK*A_im[l][j]; for(int k=max(j-1,0); k<=m+1+j; k++) { dhS_dr_im[l] += ImEI[m][0][j][k]*(C[k]*fac3K + fac4K*dC_dr[k]); } double fac3E = (dellE_dr*A_im[l][j] + ellE*dA_dr_im[l][j]); double fac4E = ellE*A_im[l][j]; for(int k=max(j-2,0); k<=m+1+j; k++) { dhS_dr_im[l] += ImEI[m][1][j][k]*(C[k]*fac3E + fac4E*dC_dr[k]); } } /* dhS_dth */ dhS_dth_re[l] = 0.0; dhS_dth_im[l] = 0.0; for(int j=0; j<5; j++) { double fac1K = (dellK_dth*A_re[l][j] + ellK*dA_dth_re[l][j]); double fac2K = ellK*A_re[l][j]; for(int k=max(j,0); k<=m+2+j; k++) { dhS_dth_re[l] += ReEI[m][0][j][k]*(C[k]*fac1K + fac2K*dC_dth[k]); } double fac1E = (dellE_dth*A_re[l][j] + ellE*dA_dth_re[l][j]); double fac2E = ellE*A_re[l][j]; for(int k=max(j-1,0); k<=m+2+j; k++) { dhS_dth_re[l] += ReEI[m][1][j][k]*(C[k]*fac1E + fac2E*dC_dth[k]); } double fac3K = (dellK_dth*A_im[l][j] + ellK*dA_dth_im[l][j]); double fac4K = ellK*A_im[l][j]; for(int k=max(j-1,0); k<=m+1+j; k++) { dhS_dth_im[l] += ImEI[m][0][j][k]*(C[k]*fac3K + fac4K*dC_dth[k]); } double fac3E = (dellE_dth*A_im[l][j] + ellE*dA_dth_im[l][j]); double fac4E = ellE*A_im[l][j]; for(int k=max(j-2,0); k<=m+1+j; k++) { dhS_dth_im[l] += ImEI[m][1][j][k]*(C[k]*fac3E + fac4E*dC_dth[k]); } } /* d2hS_dr2 */ d2hS_dr2_re[l] = 0.0; d2hS_dr2_im[l] = 0.0; for(int j=0; j<5; j++) { double fac1K = (d2ellK_dr2*A_re[l][j] + 2.0*dellK_dr*dA_dr_re[l][j] + ellK*d2A_dr2_re[l][j]); double fac2K = (dellK_dr*A_re[l][j] + ellK*dA_dr_re[l][j]); double fac3K = ellK*A_re[l][j]; for(int k=max(j,0); k<=m+2+j; k++) { d2hS_dr2_re[l] += ReEI[m][0][j][k]*(C[k]*fac1K + 2.0*dC_dr[k]*fac2K + fac3K*d2C_dr2[k]); } double fac1E = (d2ellE_dr2*A_re[l][j] + 2.0*dellE_dr*dA_dr_re[l][j] + ellE*d2A_dr2_re[l][j]); double fac2E = (dellE_dr*A_re[l][j] + ellE*dA_dr_re[l][j]); double fac3E = ellE*A_re[l][j]; for(int k=max(j-1,0); k<=m+2+j; k++) { d2hS_dr2_re[l] += ReEI[m][1][j][k]*(C[k]*fac1E + 2.0*dC_dr[k]*fac2E + fac3E*d2C_dr2[k]); } double fac4K = (d2ellK_dr2*A_im[l][j] + 2.0*dellK_dr*dA_dr_im[l][j] + ellK*d2A_dr2_im[l][j]); double fac5K = (dellK_dr*A_im[l][j] + ellK*dA_dr_im[l][j]); double fac6K = ellK*A_im[l][j]; for(int k=max(j-1,0); k<=m+1+j; k++) { d2hS_dr2_im[l] += ImEI[m][0][j][k]*(C[k]*fac4K + 2.0*dC_dr[k]*fac5K + fac6K*d2C_dr2[k]); } double fac4E = (d2ellE_dr2*A_im[l][j] + 2.0*dellE_dr*dA_dr_im[l][j] + ellE*d2A_dr2_im[l][j]); double fac5E = (dellE_dr*A_im[l][j] + ellE*dA_dr_im[l][j]); double fac6E = ellE*A_im[l][j]; for(int k=max(j-2,0); k<=m+1+j; k++) { d2hS_dr2_im[l] += ImEI[m][1][j][k]*(C[k]*fac4E + 2.0*dC_dr[k]*fac5E + fac6E*d2C_dr2[k]); } } /* d2hS_dth2 */ d2hS_dth2_re[l] = 0.0; d2hS_dth2_im[l] = 0.0; for(int j=0; j<5; j++) { double fac1K = (d2ellK_dth2*A_re[l][j] + 2.0*dellK_dth*dA_dth_re[l][j] + ellK*d2A_dth2_re[l][j]); double fac2K = (dellK_dth*A_re[l][j] + ellK*dA_dth_re[l][j]); double fac3K = ellK*A_re[l][j]; for(int k=max(j,0); k<=m+2+j; k++) { d2hS_dth2_re[l] += ReEI[m][0][j][k]*(C[k]*fac1K + 2.0*dC_dth[k]*fac2K + fac3K*d2C_dth2[k]); } double fac1E = (d2ellE_dth2*A_re[l][j] + 2.0*dellE_dth*dA_dth_re[l][j] + ellE*d2A_dth2_re[l][j]); double fac2E = (dellE_dth*A_re[l][j] + ellE*dA_dth_re[l][j]); double fac3E = ellE*A_re[l][j]; for(int k=max(j-1,0); k<=m+2+j; k++) { d2hS_dth2_re[l] += ReEI[m][1][j][k]*(C[k]*fac1E + 2.0*dC_dth[k]*fac2E + fac3E*d2C_dth2[k]); } double fac4K = (d2ellK_dth2*A_im[l][j] + 2.0*dellK_dth*dA_dth_im[l][j] + ellK*d2A_dth2_im[l][j]); double fac5K = (dellK_dth*A_im[l][j] + ellK*dA_dth_im[l][j]); double fac6K = ellK*A_im[l][j]; for(int k=max(j-1,0); k<=m+1+j; k++) { d2hS_dth2_im[l] += ImEI[m][0][j][k]*(C[k]*fac4K + 2.0*dC_dth[k]*fac5K + fac6K*d2C_dth2[k]); } double fac4E = (d2ellE_dth2*A_im[l][j] + 2.0*dellE_dth*dA_dth_im[l][j] + ellE*d2A_dth2_im[l][j]); double fac5E = (dellE_dth*A_im[l][j] + ellE*dA_dth_im[l][j]); double fac6E = ellE*A_im[l][j]; for(int k=max(j-2,0); k<=m+1+j; k++) { d2hS_dth2_im[l] += ImEI[m][1][j][k]*(C[k]*fac4E + 2.0*dC_dth[k]*fac5E + fac6E*d2C_dth2[k]); } } /* Quotient rule of differentiation to include the denominator*/ d2hS_dr2_re[l] = (d2hS_dr2_re[l]*den_re*den_re - 2.0*dden_dr_re*den_re*dhS_dr_re[l] + 2.0*dden_dr_re*dden_dr_re*hS_re[l] - den_re*d2den_dr2_re*hS_re[l])/(den_re*den_re*den_re); d2hS_dr2_im[l] = (d2hS_dr2_im[l]*den_im*den_im - 2*dden_dr_im*den_im*dhS_dr_im[l] + 2*dden_dr_im*dden_dr_im*hS_im[l] - den_im*d2den_dr2_im*hS_im[l])/(den_im*den_im*den_im); d2hS_dth2_re[l] = (d2hS_dth2_re[l]*den_re*den_re - 2*dden_dth_re*den_re*dhS_dth_re[l] + 2*dden_dth_re*dden_dth_re*hS_re[l] - den_re*d2den_dth2_re*hS_re[l])/(den_re*den_re*den_re); d2hS_dth2_im[l] = (d2hS_dth2_im[l]*den_im*den_im - 2*dden_dth_im*den_im*dhS_dth_im[l] + 2*dden_dth_im*dden_dth_im*hS_im[l] - den_im*d2den_dth2_im*hS_im[l])/(den_im*den_im*den_im); dhS_dr_re[l] = (den_re*dhS_dr_re[l] - dden_dr_re*hS_re[l])/(den_re*den_re); dhS_dr_im[l] = (den_im*dhS_dr_im[l] - dden_dr_im*hS_im[l])/(den_im*den_im); dhS_dth_re[l] = (den_re*dhS_dth_re[l] - dden_dth_re*hS_re[l])/(den_re*den_re); dhS_dth_im[l] = (den_im*dhS_dth_im[l] - dden_dth_im*hS_im[l])/(den_im*den_im); hS_re[l] /= den_re; hS_im[l] /= den_im; } for(int i=0; i<10; i++) { dhS_dph_re[i] = -m*hS_im[i]; dhS_dph_im[i] = m*hS_re[i]; dhS_dt_re[i] = -Omega*dhS_dph_re[i]; dhS_dt_im[i] = -Omega*dhS_dph_im[i]; d2hS_dph2_re[i] = -m*dhS_dph_im[i]; d2hS_dph2_im[i] = m*dhS_dph_re[i]; d2hS_dtph_re[i] = -Omega*d2hS_dph2_re[i]; d2hS_dtph_im[i] = -Omega*d2hS_dph2_im[i]; d2hS_dt2_re[i] = -Omega*d2hS_dtph_re[i]; d2hS_dt2_im[i] = -Omega*d2hS_dtph_im[i]; d2hS_dtr_re[i] = NAN; d2hS_dtr_im[i] = NAN; d2hS_dtth_re[i] = NAN; d2hS_dtth_im[i] = NAN; d2hS_drth_re[i] = NAN; d2hS_drth_im[i] = NAN; d2hS_drph_re[i] = NAN; d2hS_drph_im[i] = NAN; d2hS_dthph_re[i] = NAN; d2hS_dthph_im[i] = NAN; } double a10, a2, a2p2r2pa2c2th2, a2p2r2pa2c2th3, a2p2r2pa2c2th4, a2p2r2pa2c2th5, a2pr2m2Mr2, a2pr2m2Mr3, a3, a4, a6, a8, costh2, costh4, M2, M3, r10, r11, r2, r2pa2cth22, r2pa2cth23, r3, r4, r5, r6, r7, r8, r9, sinth2, sinth3, sinth4, sin4th, cos2th, cos4th, cos6th, cos8th, cos10th, sin2th, r2pa2cth2, a2p2r2pa2c2th, a2pr2m2Mr, costh, sinth, tanth; M2 = M*M; M3 = M2*M; a2 = a*a; a3 = a2*a; a4 = a2*a2; a6 = a4*a2; a8 = a4*a4; a10 = a6*a4; r2 = r*r; r3 = r2*r; r4 = r2*r2; r5 = r3*r2; r6 = r3*r3; r7 = r4*r3; r8 = r4*r4; r9 = r5*r4; r10 = r5*r5; r11 = r6*r5; sinth = sin(theta); costh = cos(theta); tanth = sinth/costh; costh2 = costh*costh; costh4 = costh2*costh2; sinth2 = sinth*sinth; sinth3 = sinth2*sinth; sinth4 = sinth2*sinth2; cos2th = costh2 - sinth2; sin2th = 2.0*costh*sinth; sin4th = 2.0*cos2th*sin2th; cos4th = cos2th*cos2th - sin2th*sin2th; cos6th = cos2th*cos2th*cos2th - 3.0*cos2th*sin2th*sin2th; cos8th = cos4th*cos4th - sin4th*sin4th; cos10th = cos2th*cos2th*cos2th*cos2th*cos2th - 10.0*cos2th*cos2th*cos2th*sin2th*sin2th + 5.0*cos2th*sin2th*sin2th*sin2th*sin2th; r2pa2cth2 = a2*costh2 + r2; r2pa2cth22 = r2pa2cth2*r2pa2cth2; r2pa2cth23 = r2pa2cth22*r2pa2cth2; a2p2r2pa2c2th = a2 + a2*cos2th + 2*r2; a2p2r2pa2c2th2 = a2p2r2pa2c2th*a2p2r2pa2c2th; a2p2r2pa2c2th3 = a2p2r2pa2c2th2*a2p2r2pa2c2th; a2p2r2pa2c2th4 = a2p2r2pa2c2th2*a2p2r2pa2c2th2; a2p2r2pa2c2th5 = a2p2r2pa2c2th3*a2p2r2pa2c2th2; a2pr2m2Mr = a2 + r*(-2*M + r); a2pr2m2Mr2 = a2pr2m2Mr*a2pr2m2Mr; a2pr2m2Mr3 = a2pr2m2Mr2*a2pr2m2Mr; src_re[0] = (-8*a*d2hS_dtph_re[0]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (16*dhS_dt_re[1]*M*(a2 + a2*cos2th - 2*r2)*(a2 + r2))/a2p2r2pa2c2th3 + d2hS_dth2_re[0]/r2pa2cth2 + (d2hS_dr2_re[0]*(a2 - 2*M*r + r2))/r2pa2cth2 + (4*a*dhS_dr_re[3]*M*(a2*costh2 - r2))/r2pa2cth23 + (4*a*dhS_dph_re[1]*M*(-(a2*costh2) + r2))/r2pa2cth23 - (d2hS_dt2_re[0]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) + (16*hS_re[7]*M*r*(-9*a4 + 3*a4*cos4th + 20*a2*M*r - 2*a2*cos2th*(3*a2 + 5*r*(-2*M + r)) + 2*a2*r2 - 8*M*r3 + 4*r4))/a2p2r2pa2c2th5 + (2*dhS_dr_re[0]*(5*a4*M - a4*cos4th*(M - r) + 3*a4*r - 16*a2*M*r2 + 8*a2*r3 + 4*a2*cos2th*(a2*(M + r) + 2*r3) - 24*M*r4 + 8*r5))/a2p2r2pa2c2th3 - (8*a2pr2m2Mr*hS_re[4]*M*(3*a4*M - 27*a4*r + a4*cos4th*(M + 3*r) + 40*a2*M*r2 + 4*a2*cos2th*(a2*(M - 6*r) + (10*M - 7*r)*r2) - 4*a2*r3 - 24*M*r4 + 16*r5))/a2p2r2pa2c2th5 + (16*a*hS_re[3]*M2*(3*a6 + 29*a4*r2 + a4*cos4th*(a2 + 7*r2) - 80*a2*M*r3 + 32*a2*r4 + 4*a2*cos2th*(a4 + 9*a2*r2 - 20*M*r3 + 6*r4) + 32*M*r5 - 8*r6))/(a2p2r2pa2c2th5*a2pr2m2Mr) + (8*hS_re[0]*M2*(3*a8 + 2*a6*r2 - 20*a4*M*r3 + a4*cos4th*(a4 - 2*a2*r2 + 20*M*r3 - 3*r4) - a4*r4 + 16*a2*M*r5 + 4*a2*cos2th*(a6 - 3*a2*r4 - 2*(2*M + r)*r5) + 8*a2*r6 + 8*r8))/(a2p2r2pa2c2th5*a2pr2m2Mr) - (32*a2*dhS_dt_re[2]*M*r*sin2th)/a2p2r2pa2c2th3 - (96*a2*a2pr2m2Mr*hS_re[5]*M*(a2 + a2*cos2th - 6*r2)*sin2th)/a2p2r2pa2c2th5 + (d2hS_dph2_re[0]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (2*hS_re[9]*M*(-2*a6*M + a6*cos6th*M + 30*a6*r + 3*a6*cos6th*r - 200*a4*M*r2 + 2*a4*cos4th*(a2*(M + 9*r) + 2*(-14*M + 5*r)*r2) + 60*a4*r3 + 320*a2*M2*r3 - a2*cos2th*(a4*(M - 45*r) + 16*a2*(16*M - 5*r)*r2 - 16*(20*M2 - 11*M*r + r2)*r3) - 208*a2*M*r4 + 16*a2*r5 - 128*M2*r5 + 128*M*r6 - 32*r7))/(a2p2r2pa2c2th5*a2pr2m2Mr*sinth2) - (64*a*dhS_dph_re[2]*M*r)/(a2p2r2pa2c2th3*tanth) + (64*a*dhS_dth_re[3]*M*r)/(a2p2r2pa2c2th3*tanth) + (dhS_dth_re[0]*(3*a4 + a4*cos4th + 32*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-4*M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth); src_re[1] = (-8*a*d2hS_dtph_re[1]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dt_re[4]*M*(a2 + a2*cos2th - 2*r2)*(a2 + r2))/a2p2r2pa2c2th3 + d2hS_dth2_re[1]/r2pa2cth2 + (d2hS_dr2_re[1]*(a2 - 2*M*r + r2))/r2pa2cth2 - (2*dhS_dth_re[2]*r)/r2pa2cth22 + (2*a*dhS_dr_re[6]*M*(a2*costh2 - r2))/r2pa2cth23 + (2*a*dhS_dph_re[4]*M*(-(a2*costh2) + r2))/r2pa2cth23 - (4*a*dhS_dph_re[0]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (4*a*dhS_dt_re[3]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (d2hS_dt2_re[1]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) + (4*dhS_dr_re[1]*(-(a4*M) - a4*cos4th*(M - r) + a4*r - 6*a2*M*r2 - 2*a2*cos2th*(a2*(M - r) + (M - 3*r)*r2) + 2*a2*r3 - 4*M*r4 + 4*r5))/a2p2r2pa2c2th3 - (8*a*hS_re[6]*M*(3*a4*M + a4*cos4th*(M - r) - 23*a4*r + 40*a2*M*r2 + 4*a2*cos2th*(a2*(M - 6*r) + 5*(2*M - r)*r2) - 12*a2*r3 - 24*M*r4 + 16*r5))/(a2p2r2pa2c2th4*a2pr2m2Mr) - (4*dhS_dt_re[0]*M*(a6 + a2*(4*M - 3*r)*r3 + a2*cos2th*(a4 + 2*a2*r2 + (-4*M + r)*r3) - 2*r6))/(a2p2r2pa2c2th2*a2pr2m2Mr2) + (hS_re[1]*(10*a8 + a8*cos6th - 24*a6*M2 + 116*a6*M*r - 2*a6*cos6th*M*r + 22*a6*r2 + a6*cos6th*r2 - 248*a4*M2*r2 + 2*a4*cos4th*(3*a4 + 2*r2*(6*M2 - 4*M*r + r2) + a2*(-4*M2 - 10*M*r + 5*r2)) + 208*a4*M*r3 - 4*a4*r4 - 128*a2*M2*r4 + a2*cos2th*(15*a6 - 32*a2*M*(7*M - 8*r)*r2 + a4*(-32*M2 + 98*M*r + 31*r2) - 16*(20*M2 - 12*M*r + r2)*r4) + 128*a2*M*r5 - 48*a2*r6 - 64*M2*r6 + 64*M*r7 - 32*r8))/(a2p2r2pa2c2th4*a2pr2m2Mr) - (16*a2*dhS_dt_re[5]*M*r*sin2th)/a2p2r2pa2c2th3 - (32*a3*hS_re[8]*M*(a2 + a2*cos2th - 4*r2)*sin2th)/(a2p2r2pa2c2th4*a2pr2m2Mr) - (2*a2*costh*dhS_dr_re[2]*sinth)/r2pa2cth22 + (d2hS_dph2_re[1]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (dhS_dph_re[3]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 20*a2*M*r2 + 4*a2*cos2th*r*(a2 - 3*M*r + 2*r2) + 8*a2*r3 + 32*M2*r3 - 32*M*r4 + 8*r5))/(a2p2r2pa2c2th2*a2pr2m2Mr2*sinth2) - (32*a*dhS_dph_re[5]*M*r)/(a2p2r2pa2c2th3*tanth) + (32*a*dhS_dth_re[6]*M*r)/(a2p2r2pa2c2th3*tanth) + (dhS_dth_re[1]*(5*a4 - a4*cos4th + 16*a2*M*r + 4*a2*cos2th*(a2 - 4*M*r) + 16*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (4*hS_re[2]*(4*a6*M + 3*a6*r - 34*a4*M*r2 + a4*cos4th*(a2*(-4*M + r) + (-6*M + r)*r2) + 11*a4*r3 + 4*a2*cos2th*r*(a4 + 3*a2*r*(2*M + r) + 2*(2*M + r)*r3) - 48*a2*M*r4 + 16*a2*r5 - 16*M*r6 + 8*r7))/(a2p2r2pa2c2th4*a2pr2m2Mr*tanth); src_re[2] = (-8*a*d2hS_dtph_re[2]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dt_re[5]*M*(a2 + a2*cos2th - 2*r2)*(a2 + r2))/a2p2r2pa2c2th3 + d2hS_dth2_re[2]/r2pa2cth2 + (d2hS_dr2_re[2]*(a2 - 2*M*r + r2))/r2pa2cth2 + (2*a2pr2m2Mr*dhS_dth_re[1]*r)/r2pa2cth22 + (2*a*dhS_dr_re[8]*M*(a2*costh2 - r2))/r2pa2cth23 + (2*a*dhS_dph_re[5]*M*(-(a2*costh2) + r2))/r2pa2cth23 - (d2hS_dt2_re[2]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*a3*dhS_dph_re[0]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (8*a3*dhS_dt_re[3]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (16*a2*dhS_dt_re[7]*M*r*sin2th)/a2p2r2pa2c2th3 - (8*a2*dhS_dt_re[0]*M*r*(a2 + r2)*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (a2*a2pr2m2Mr*dhS_dr_re[1]*sin2th)/r2pa2cth22 + (4*a2*hS_re[1]*(-7*a4*M - a4*cos4th*(M - r) + 3*a4*r + 8*a2*M2*r - 4*a2*cos2th*(a2*(2*M - r) + r*(-2*M2 + 3*M*r - 2*r2)) + 28*a2*M*r2 + 8*a2*r3 - 80*M2*r3 + 32*M*r4 + 8*r5)*sin2th)/a2p2r2pa2c2th4 + (d2hS_dph2_re[2]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) + (8*a*hS_re[8]*M*r*(-a2 + 5*a2*cos4th + 4*cos2th*(a2 - r2) + 12*r2))/(a2p2r2pa2c2th4*sinth2) - (hS_re[2]*(15*a6 + 6*a6*cos6th + a6*cos8th + 96*a4*M*r + 16*a4*cos6th*M*r + 56*a4*r2 + 8*a4*cos6th*r2 - 160*a2*M*r3 + 8*a2*cos4th*(2*a4 + a2*r*(-12*M + 5*r) + 2*(-6*M + r)*r3) + 80*a2*r4 - 128*M*r5 + 2*cos2th*(13*a6 + a4*(-8*M*r + 44*r2) + 16*a2*(8*M + 3*r)*r3 + 64*M*r5) + 64*r6))/(4.*a2p2r2pa2c2th4*sinth2) - (8*a2*dhS_dr_re[2]*(-(a2*cos2th*(M - r)) + a2*(-M + r) + 2*(M + r)*r2)*sinth2)/a2p2r2pa2c2th3 - (32*a*dhS_dph_re[7]*M*r)/(a2p2r2pa2c2th3*tanth) + (32*a*dhS_dth_re[8]*M*r)/(a2p2r2pa2c2th3*tanth) - (32*a*a2pr2m2Mr*hS_re[6]*M*(a2 + a2*cos2th - 10*r2))/(a2p2r2pa2c2th4*tanth) + (dhS_dth_re[2]*(5*a4 - a4*cos4th + 16*a2*M*r + 4*a2*cos2th*(a2 - 4*M*r) + 16*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (dhS_dph_re[3]*(3*a4 + a4*cos4th + 4*a2*cos2th*(a2 + 2*r*(-2*M + r)) + 8*a2*r2 - 16*M*r3 + 8*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr*sinth2*tanth); src_re[3] = (-8*a*d2hS_dtph_re[3]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dt_re[6]*M*(a2 + a2*cos2th - 2*r2)*(a2 + r2))/a2p2r2pa2c2th3 + d2hS_dth2_re[3]/r2pa2cth2 + (d2hS_dr2_re[3]*(a2 - 2*M*r + r2))/r2pa2cth2 + (2*a*dhS_dr_re[9]*M*(a2*costh2 - r2))/r2pa2cth23 + (2*a*dhS_dph_re[6]*M*(-(a2*costh2) + r2))/r2pa2cth23 - (d2hS_dt2_re[3]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*a*hS_re[7]*M*r*(-3*a4 + 10*a2*M*r + 17*a2*r2 + a2*cos4th*(11*a2 - 10*M*r + 11*r2) - 8*M*r3 + 4*cos2th*(2*a4 + a2*r2 + (2*M - r)*r3) + 20*r4))/a2p2r2pa2c2th5 + (2*dhS_dph_re[1]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 12*a2*M*r2 + 4*a2*cos2th*r*(a2 - M*r + 2*r2) + 8*a2*r3 - 16*M*r4 + 8*r5))/a2p2r2pa2c2th3 - (4*hS_re[3]*M*(2*a8*M - a8*cos6th*M + 30*a8*r + 3*a8*cos6th*r - 54*a6*M*r2 - 5*a6*cos6th*M*r2 + 90*a6*r3 + 3*a6*cos6th*r3 - 80*a4*M2*r3 - 2*a4*cos4th*(a4*(M - 9*r) + a2*(21*M - 19*r)*r2 - 2*(20*M2 - 12*M*r + 5*r2)*r3) - 96*a4*M*r4 + 76*a4*r5 + 64*a2*M2*r5 + a2*cos2th*(a6*(M + 45*r) + a4*(-91*M + 125*r)*r2 + 16*a2*(-11*M + 6*r)*r4 + 16*(-4*M2 - 5*M*r + r2)*r5) + 16*a2*M*r6 - 16*a2*r7 + 64*M*r8 - 32*r9))/(a2p2r2pa2c2th5*a2pr2m2Mr) - (16*a2*dhS_dt_re[8]*M*r*sin2th)/a2p2r2pa2c2th3 - (16*a*a2pr2m2Mr*hS_re[5]*M*(-3*a4 + a4*cos4th + 26*a2*r2 - 2*a2*cos2th*(a2 + 5*r2) + 20*r4)*sin2th)/a2p2r2pa2c2th5 + (d2hS_dph2_re[3]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (a*hS_re[9]*M*(3*a6*M + a6*cos8th*(M - r) + 85*a6*r + 124*a6*cos2th*r + 4*a6*cos6th*r - 80*a4*M*r2 - 216*a4*cos2th*M*r2 - 40*a4*cos6th*M*r2 + 280*a4*r3 + 380*a4*cos2th*r3 + 4*a4*cos6th*r3 - 320*a2*M2*r3 - 4*a2*cos4th*(a4*(M - 11*r) + 2*a2*(22*M - 13*r)*r2 - 20*(4*M2 - 3*M*r + r2)*r3) - 208*a2*M*r4 - 576*a2*cos2th*M*r4 + 304*a2*r5 + 384*a2*cos2th*r5 + 256*M2*r5 - 256*cos2th*M2*r5 - 256*M*r6 - 256*cos2th*M*r6 + 64*r7 + 192*cos2th*r7))/(2.*a2p2r2pa2c2th5*a2pr2m2Mr*sinth2) - (8*a*dhS_dr_re[0]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*dhS_dt_re[1]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*a2pr2m2Mr*hS_re[4]*M*(3*a4*M + a4*cos4th*(M - r) - 39*a4*r + 40*a2*M*r2 + 4*a2*cos2th*(a2*(M - 10*r) + (10*M - 9*r)*r2) - 12*a2*r3 - 24*M*r4 + 32*r5)*sinth2)/a2p2r2pa2c2th5 - (8*a*hS_re[0]*M2*(3*a8 - 22*a6*r2 - 20*a4*M*r3 + a4*cos4th*(a4 - 10*a2*r2 + 20*M*r3 - 11*r4) - 41*a4*r4 + 16*a2*M*r5 + 4*a2*cos2th*(a6 - 8*a4*r2 - 15*a2*r4 - 2*(2*M + 3*r)*r5) + 24*a2*r6 + 40*r8)*sinth2)/(a2p2r2pa2c2th5*a2pr2m2Mr) - (32*a3*costh*dhS_dth_re[0]*M*r*sinth3)/a2p2r2pa2c2th3 + (32*a3*costh*dhS_dt_re[2]*M*r*sinth3)/a2p2r2pa2c2th3 - (2*dhS_dth_re[3])/(a2p2r2pa2c2th*tanth) - (32*a*dhS_dph_re[8]*M*r)/(a2p2r2pa2c2th3*tanth) + (32*a*dhS_dth_re[9]*M*r)/(a2p2r2pa2c2th3*tanth) + (2*dhS_dph_re[2]*(3*a4 + a4*cos4th + 8*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth); src_re[4] = (-8*a*d2hS_dtph_re[4]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (4*dhS_dr_re[4]*(3*a2*cos2th*(M - r) + a2*(3*M + r) - 2*(M + r)*r2))/a2p2r2pa2c2th2 + d2hS_dth2_re[4]/r2pa2cth2 + (d2hS_dr2_re[4]*(a2 - 2*M*r + r2))/r2pa2cth2 - (4*dhS_dth_re[5]*r)/r2pa2cth22 - (8*a*dhS_dph_re[1]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (8*a*dhS_dt_re[6]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (d2hS_dt2_re[4]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) + (2*hS_re[4]*(7*a6 + 3*a4*M2 + 4*a4*M*r + 10*a4*r2 - 40*a2*M2*r2 + a4*cos4th*(a2 + M2 - 4*M*r + 2*r2) + 4*a2*cos2th*(2*a4 + 2*M*(-5*M + 3*r)*r2 + a2*(M2 + r2)) + 40*a2*M*r3 - 16*a2*r4 - 56*M2*r4 + 64*M*r5 - 16*r6))/(a2p2r2pa2c2th3*a2pr2m2Mr) - (8*dhS_dt_re[1]*M*(a6 + a2*(4*M - 3*r)*r3 + a2*cos2th*(a4 + 2*a2*r2 + (-4*M + r)*r3) - 2*r6))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (4*a*hS_re[3]*M*(3*a6*M - 39*a6*r + a4*cos4th*(M - r)*(a2 - r2) + 101*a4*M*r2 - 45*a4*r3 - 48*a2*M2*r3 + 4*a2*cos2th*(a4*(M - 10*r) + a2*(25*M - 17*r)*r2 + (-12*M2 + 18*M*r - 5*r2)*r3) - 16*a2*M*r4 + 36*a2*r5 + 96*M2*r5 - 136*M*r6 + 48*r7))/(a2p2r2pa2c2th3*a2pr2m2Mr3) - (2*hS_re[0]*M*(3*a8*M - 27*a8*r + 62*a6*M*r2 - 58*a6*r3 - 12*a4*M2*r3 + a4*cos4th*(a4*(M + 3*r) + 2*a2*(-7*M + 3*r)*r2 + (12*M2 - 11*M*r + 3*r2)*r3) + 39*a4*M*r4 - 19*a4*r5 + 48*a2*M2*r5 + 4*a2*cos2th*(a6*(M - 6*r) + a4*(12*M - 19*r)*r2 + a2*(29*M - 20*r)*r4 + (-12*M2 + 22*M*r - 7*r2)*r5) - 56*a2*M*r6 + 28*a2*r7 - 24*M*r8 + 16*r9))/(a2p2r2pa2c2th3*a2pr2m2Mr3) - (4*a2*costh*dhS_dr_re[5]*sinth)/r2pa2cth22 + (d2hS_dph2_re[4]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (2*dhS_dph_re[6]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 20*a2*M*r2 + 4*a2*cos2th*r*(a2 - 3*M*r + 2*r2) + 8*a2*r3 + 32*M2*r3 - 32*M*r4 + 8*r5))/(a2p2r2pa2c2th2*a2pr2m2Mr2*sinth2) + (hS_re[9]*(-2*a6*M2 + a6*cos6th*M2 + 76*a6*M*r - 2*a6*cos6th*M*r + 10*a6*r2 + a6*cos6th*r2 - 248*a4*M2*r2 + 2*a4*cos4th*(a2*(M2 - 14*M*r + 3*r2) + 2*r2*(14*M2 - 12*M*r + 3*r2)) - 16*a4*M*r3 + 192*a2*M3*r3 - a2*cos2th*(a4*(M2 - 50*M*r - 15*r2) - 16*a2*r2*(-12*M2 + 2*M*r + 3*r2) - 16*r3*(12*M3 - 7*M2*r - 5*M*r2 + 3*r3)) + 36*a4*r4 + 240*a2*M2*r4 - 272*a2*M*r5 - 384*M3*r5 + 48*a2*r6 + 512*M2*r6 - 224*M*r7 + 32*r8))/(2.*a2p2r2pa2c2th3*a2pr2m2Mr3*sinth2) + (hS_re[7]*(3*a2*cos2th*M*r + r*(3*a2*M + 2*a2*r - 6*M*r2 + 2*r3) + 2*a4*costh2*sinth2))/(a2pr2m2Mr*r2pa2cth23) - (2*dhS_dth_re[4]*(-5*a2 + 3*a2*cos2th - 2*r2))/(a2p2r2pa2c2th2*tanth) + (8*hS_re[5]*(a2*(M - 3*r) - a2*cos2th*(M - r) + 2*(2*M - r)*r2))/(a2p2r2pa2c2th2*a2pr2m2Mr*tanth); src_re[5] = (-8*a*d2hS_dtph_re[5]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dr_re[5]*(a2*cos2th*(M - r) + a2*(M + r) - 2*M*r2))/a2p2r2pa2c2th2 + d2hS_dth2_re[5]/r2pa2cth2 + (d2hS_dr2_re[5]*(a2 - 2*M*r + r2))/r2pa2cth2 + (2*a2pr2m2Mr*dhS_dth_re[4]*r)/r2pa2cth22 - (2*dhS_dth_re[7]*r)/r2pa2cth22 - (4*a*dhS_dph_re[2]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (4*a*dhS_dt_re[8]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (d2hS_dt2_re[5]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (4*dhS_dt_re[2]*M*(a6 + a2*(4*M - 3*r)*r3 + a2*cos2th*(a4 + 2*a2*r2 + (-4*M + r)*r3) - 2*r6))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (8*a3*dhS_dph_re[1]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (8*a3*dhS_dt_re[6]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (12*a2*hS_re[4]*(-M + r)*sin2th)/a2p2r2pa2c2th2 - (8*a2*dhS_dt_re[1]*M*r*(a2 + r2)*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (a2*a2pr2m2Mr*dhS_dr_re[4]*sin2th)/r2pa2cth22 - (4*a2*hS_re[0]*M*(3*a6 - 4*a4*r*(M + 3*r) + a2*(32*M - 33*r)*r3 + a2*cos2th*(3*a4 + a2*(-4*M*r + 6*r2) + (-8*M + 3*r)*r3) + 2*(16*M - 9*r)*r5)*sin2th)/(a2p2r2pa2c2th3*a2pr2m2Mr2) - (2*a2*costh*dhS_dr_re[7]*sinth)/r2pa2cth22 + (d2hS_dph2_re[5]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (hS_re[5]*(a4 + 3*a4*cos4th + a4*cos6th + 8*a2*r2 - 32*M*r3 + cos2th*(3*a4 + 8*a2*r2 + 16*(2*M - r)*r3) + 24*r4))/(a2p2r2pa2c2th3*sinth2) - (dhS_dph_re[8]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 20*a2*M*r2 + 4*a2*cos2th*r*(a2 - 3*M*r + 2*r2) + 8*a2*r3 + 32*M2*r3 - 32*M*r4 + 8*r5))/(a2p2r2pa2c2th2*a2pr2m2Mr2*sinth2) - (8*hS_re[7]*r)/(a2p2r2pa2c2th2*tanth) - (2*dhS_dth_re[5]*(-5*a2 + 3*a2*cos2th - 2*r2))/(a2p2r2pa2c2th2*tanth) + (8*a*hS_re[3]*M*(-3*a6 + 5*a4*M*r + a4*cos4th*(a2 - M*r) + 20*a4*r2 - 48*a2*M*r3 - 2*a2*cos2th*(a4 - 2*a2*(M - 4*r)*r + (-16*M + 9*r)*r3) + 38*a2*r4 - 24*M*r5 + 12*r6))/(a2p2r2pa2c2th3*a2pr2m2Mr2*tanth) - (dhS_dph_re[6]*(3*a4 + a4*cos4th + 4*a2*cos2th*(a2 + 2*r*(-2*M + r)) + 8*a2*r2 - 16*M*r3 + 8*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr*sinth2*tanth) + (hS_re[9]*(-10*a6*M - a6*cos6th*M + 10*a6*r + a6*cos6th*r + 16*a4*M2*r + 92*a4*M*r2 + 36*a4*r3 - 256*a2*M2*r3 + 2*a4*cos4th*(5*a2*M + 3*a2*r - 8*M2*r - 6*M*r2 + 6*r3) + a2*cos2th*(a4*(M + 15*r) + 16*a2*(-13*M + 3*r)*r2 + 48*(8*M2 - 6*M*r + r2)*r3) + 32*a2*M*r4 + 48*a2*r5 + 128*M2*r5 - 128*M*r6 + 32*r7))/(2.*a2p2r2pa2c2th3*a2pr2m2Mr2*sinth2*tanth); src_re[6] = (-8*a*d2hS_dtph_re[6]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) + d2hS_dth2_re[6]/r2pa2cth2 + (d2hS_dr2_re[6]*(a2 - 2*M*r + r2))/r2pa2cth2 - (2*dhS_dth_re[8]*r)/r2pa2cth22 - (4*a*dhS_dph_re[3]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (4*a*dhS_dt_re[9]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (d2hS_dt2_re[6]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (2*dhS_dr_re[6]*(7*a4*M + a4*cos4th*(M - r) + a4*r - 4*a2*M*r2 + 4*a2*cos2th*(2*a2*M + (M - r)*r2) + 4*a2*r3 - 16*M*r4))/a2p2r2pa2c2th3 + (2*dhS_dph_re[4]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 12*a2*M*r2 + 4*a2*cos2th*r*(a2 - M*r + 2*r2) + 8*a2*r3 - 16*M*r4 + 8*r5))/a2p2r2pa2c2th3 - (4*dhS_dt_re[3]*M*(a6 + a2*(4*M - 3*r)*r3 + a2*cos2th*(a4 + 2*a2*r2 + (-4*M + r)*r3) - 2*r6))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (2*hS_re[6]*(-2*a6*M2 + a6*cos6th*M2 + 24*a6*M*r - 2*a6*cos6th*M*r + 10*a6*r2 + a6*cos6th*r2 - 40*a4*M2*r2 + 2*a4*cos4th*(a2*(M2 - 12*M*r + 3*r2) + 2*r2*(10*M2 - 9*M*r + 3*r2)) - 44*a4*M*r3 + 36*a4*r4 + 112*a2*M2*r4 - a2*cos2th*(a4*(M2 - 2*M*r - 15*r2) + 48*a2*(M - r)*r3 - 16*(M2 - 5*M*r + 3*r2)*r4) - 176*a2*M*r5 + 48*a2*r6 + 128*M2*r6 - 128*M*r7 + 32*r8))/(a2p2r2pa2c2th4*a2pr2m2Mr) + (4*a*hS_re[2]*M*(5*a6 - 21*a4*r2 + cos4th*(-a6 + a4*r2) - 56*a2*r4 + 4*a2*cos2th*(a4 + 3*a2*r2 + 4*r4) - 24*r6)*sin2th)/(a2p2r2pa2c2th4*a2pr2m2Mr) - (2*a2*costh*dhS_dr_re[8]*sinth)/r2pa2cth22 + (d2hS_dph2_re[6]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (dhS_dph_re[9]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 20*a2*M*r2 + 4*a2*cos2th*r*(a2 - 3*M*r + 2*r2) + 8*a2*r3 + 32*M2*r3 - 32*M*r4 + 8*r5))/(a2p2r2pa2c2th2*a2pr2m2Mr2*sinth2) - (8*a*dhS_dr_re[1]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*dhS_dt_re[4]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*hS_re[1]*M*(3*a6*M - 20*a6*r + 31*a4*M*r2 - 26*a4*r3 + a4*cos4th*(a2*M - 3*M*r2 + 2*r3) + 4*a2*cos2th*(a4*(M - 5*r) + a2*(7*M - 8*r)*r2 + (6*M - r)*r4) + 12*a2*r5 - 24*M*r6 + 24*r7)*sinth2)/(a2p2r2pa2c2th4*a2pr2m2Mr) - (32*a3*costh*dhS_dth_re[1]*M*r*sinth3)/a2p2r2pa2c2th3 + (32*a3*costh*dhS_dt_re[5]*M*r*sinth3)/a2p2r2pa2c2th3 - (dhS_dth_re[6]*(a4 + 3*a4*cos4th + 16*a2*M*r + 4*a2*cos2th*(a2 + 4*r*(-M + r)) + 8*r4))/(a2p2r2pa2c2th3*tanth) + (2*dhS_dph_re[5]*(3*a4 + a4*cos4th + 8*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (2*hS_re[8]*(-6*a6*M - a6*cos6th*M + 4*a6*r + a6*cos6th*r + 52*a4*M*r2 + 2*a4*cos4th*(a2*(3*M + 2*r) + (-2*M + 5*r)*r2) + 14*a4*r3 + 48*a2*M*r4 + a2*cos2th*(a4*(M + 7*r) + 8*a2*(-10*M + 3*r)*r2 + 16*(-7*M + 2*r)*r4) + 16*a2*r5 - 32*M*r6 + 16*r7))/(a2p2r2pa2c2th4*a2pr2m2Mr*tanth); src_re[7] = (-8*a*d2hS_dtph_re[7]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (4*dhS_dr_re[7]*(a2*cos2th*(M - r) + a2*(M + 3*r) + 2*(-3*M + r)*r2))/a2p2r2pa2c2th2 + d2hS_dth2_re[7]/r2pa2cth2 + (d2hS_dr2_re[7]*(a2 - 2*M*r + r2))/r2pa2cth2 + (4*a2pr2m2Mr*dhS_dth_re[5]*r)/r2pa2cth22 - (d2hS_dt2_re[7]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) + (8*a*hS_re[3]*M*r*(-15*a4 + a4*cos4th + 16*a2*M*r - 2*a2*cos2th*(7*a2 + r*(-8*M + 7*r)) - 2*a2*r2 - 16*M*r3 + 12*r4))/(a2p2r2pa2c2th3*a2pr2m2Mr) + (4*hS_re[0]*M*r*(-9*a6 + 4*a4*M*r - 7*a4*r2 + a4*cos4th*(3*a2 - 4*M*r + 3*r2) - 8*a2*M*r3 - 2*a2*cos2th*(3*a4 + 8*a2*r2 + (-4*M + 5*r)*r3) + 6*a2*r4 + 4*r6))/(a2p2r2pa2c2th3*a2pr2m2Mr) - (16*a3*dhS_dph_re[2]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (16*a3*dhS_dt_re[8]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (16*a2*hS_re[5]*(-M + r)*sin2th)/a2p2r2pa2c2th2 - (16*a2*dhS_dt_re[2]*M*r*(a2 + r2)*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (2*a2*a2pr2m2Mr*dhS_dr_re[5]*sin2th)/r2pa2cth22 + (d2hS_dph2_re[7]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (hS_re[7]*(6*a4 + a4*cos6th + 8*a2*r2 + 2*a2*cos4th*(5*a2 + 4*r2) + 32*M*r3 + cos2th*(15*a4 + 48*a2*r2 + 16*(-2*M + r)*r3) + 16*r4))/(2.*a2p2r2pa2c2th3*sinth2) + (a2pr2m2Mr*hS_re[4]*(3*a2*cos2th*M*r + r*(3*a2*M + 2*a2*r - 6*M*r2 + 2*r3) + 2*a4*costh2*sinth2))/r2pa2cth23 - (2*dhS_dth_re[7]*(-5*a2 + 3*a2*cos2th - 2*r2))/(a2p2r2pa2c2th2*tanth) - (2*dhS_dph_re[8]*(3*a4 + a4*cos4th + 4*a2*cos2th*(a2 + 2*r*(-2*M + r)) + 8*a2*r2 - 16*M*r3 + 8*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr*sinth2*tanth) + (hS_re[9]*(35*a6 + 8*a6*cos6th + a6*cos8th - 168*a4*M*r - 36*a4*cos6th*M*r + 120*a4*r2 + 12*a4*cos6th*r2 + 128*a2*M2*r2 + 4*a2*cos4th*(7*a4 + 2*a2*r*(5*M + 9*r) - 4*(8*M2 + M*r - 3*r2)*r2) - 48*a2*M*r3 + 144*a2*r4 - 256*M2*r4 + 64*r6 + 4*cos2th*(14*a6 + a4*r*(-23*M + 45*r) - 16*a2*(7*M - 3*r)*r3 + 16*r4*pow(-2*M + r,2))))/(8.*a2p2r2pa2c2th3*a2pr2m2Mr*sinth4); src_re[8] = (-8*a*d2hS_dtph_re[8]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) + d2hS_dth2_re[8]/r2pa2cth2 + (d2hS_dr2_re[8]*(a2 - 2*M*r + r2))/r2pa2cth2 + (2*a2pr2m2Mr*dhS_dth_re[6]*r)/r2pa2cth22 - (d2hS_dt2_re[8]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dr_re[8]*(a4*(M + r) + 3*a2*(-M + r)*r2 + a2*cos2th*(a2*(M + r) + (-M + r)*r2) + 2*(-3*M + r)*r4))/a2p2r2pa2c2th3 + (2*dhS_dph_re[5]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 12*a2*M*r2 + 4*a2*cos2th*r*(a2 - M*r + 2*r2) + 8*a2*r3 - 16*M*r4 + 8*r5))/a2p2r2pa2c2th3 - (8*a3*dhS_dph_re[3]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (8*a3*dhS_dt_re[9]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (8*a2*dhS_dt_re[3]*M*r*(a2 + r2)*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (a2*a2pr2m2Mr*dhS_dr_re[6]*sin2th)/r2pa2cth22 + (d2hS_dph2_re[8]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (hS_re[8]*(55*a6 + 10*a6*cos6th + a6*cos8th - 80*a4*M*r - 24*a4*cos6th*M*r + 184*a4*r2 + 16*a4*cos6th*r2 + 224*a2*M*r3 + 8*a2*cos4th*(5*a4 + a2*r*(10*M + 13*r) + 2*(2*M + 5*r)*r3) + 208*a2*r4 + 256*M*r5 + 2*cos2th*(43*a6 + 4*a4*r*(3*M + 34*r) - 16*a2*(8*M - 9*r)*r3 + 64*(-2*M + r)*r5) + 64*r6))/(4.*a2p2r2pa2c2th4*sinth2) - (8*a*dhS_dr_re[2]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*dhS_dt_re[5]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (32*a*hS_re[2]*M*r*(4*a4 - a2*r2 + a2*cos2th*(4*a2 + 3*r2) - 6*r4)*sinth2)/a2p2r2pa2c2th4 - (32*a3*costh*dhS_dth_re[2]*M*r*sinth3)/a2p2r2pa2c2th3 + (32*a3*costh*dhS_dt_re[7]*M*r*sinth3)/a2p2r2pa2c2th3 + (32*a2pr2m2Mr*a3*costh*hS_re[1]*M*(a2 + a2*cos2th - 10*r2)*sinth3)/a2p2r2pa2c2th4 - (dhS_dth_re[8]*(a4 + 3*a4*cos4th + 16*a2*M*r + 4*a2*cos2th*(a2 + 4*r*(-M + r)) + 8*r4))/(a2p2r2pa2c2th3*tanth) + (2*dhS_dph_re[7]*(3*a4 + a4*cos4th + 8*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (2*hS_re[6]*(-2*a6*M - a6*cos6th*M + 10*a6*r + a6*cos6th*r + 8*a4*M2*r + 60*a4*M*r2 + 2*a4*cos4th*(a2*(M + 3*r) + 2*r*(-2*M2 - 3*M*r + 3*r2)) + 36*a4*r3 - 160*a2*M2*r3 + a2*cos2th*(a4*(M + 15*r) - 16*a2*(7*M - 3*r)*r2 + 16*(10*M2 - 10*M*r + 3*r2)*r3) + 32*a2*M*r4 + 48*a2*r5 - 64*M*r6 + 32*r7))/(a2p2r2pa2c2th4*tanth) - (dhS_dph_re[9]*(3*a4 + a4*cos4th + 4*a2*cos2th*(a2 + 2*r*(-2*M + r)) + 8*a2*r2 - 16*M*r3 + 8*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr*sinth2*tanth); src_re[9] = (-8*a*d2hS_dtph_re[9]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) + d2hS_dth2_re[9]/r2pa2cth2 + (d2hS_dr2_re[9]*(a2 - 2*M*r + r2))/r2pa2cth2 - (d2hS_dt2_re[9]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (2*dhS_dr_re[9]*(5*a4*M - a4*cos4th*(M - r) + 3*a4*r - 16*a2*M*r2 + 8*a2*r3 + 4*a2*cos2th*(a2*(M + r) + 2*r3) - 24*M*r4 + 8*r5))/a2p2r2pa2c2th3 + (4*dhS_dph_re[6]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 12*a2*M*r2 + 4*a2*cos2th*r*(a2 - M*r + 2*r2) + 8*a2*r3 - 16*M*r4 + 8*r5))/a2p2r2pa2c2th3 + (hS_re[7]*(35*a8 + 8*a8*cos6th + a8*cos8th - 78*a6*M*r - 36*a6*cos6th*M*r - 2*a6*cos8th*M*r + 155*a6*r2 + 20*a6*cos6th*r2 + a6*cos8th*r2 + 80*a4*M2*r2 + 40*a4*cos6th*M2*r2 + 88*a4*M*r3 - 44*a4*cos6th*M*r3 + 264*a4*r4 + 12*a4*cos6th*r4 - 96*a2*M2*r4 + 4*a2*cos4th*(7*a6 + 5*a4*r*(4*M + 5*r) + 4*(-2*M2 + M*r + 3*r2)*r4 + a2*(-20*M2*r2 + 26*M*r3 + 30*r4)) + 304*a2*M*r5 + 208*a2*r6 + 128*M*r7 + 4*cos2th*(14*a8 + a6*r*(9*M + 59*r) + a4*r2*(-10*M2 - 37*M*r + 93*r2) + 16*a2*(2*M2 - 5*M*r + 4*r2)*r4 + 16*(-2*M + r)*r7) + 64*r8))/(2.*a2p2r2pa2c2th5) + (2*a2pr2m2Mr*hS_re[5]*(-10*a6*M - a6*cos6th*M + 10*a6*r + a6*cos6th*r + 140*a4*M*r2 + 2*a4*cos4th*(a2*(5*M + 3*r) + 2*(M + 3*r)*r2) + 36*a4*r3 + 160*a2*M*r4 + a2*cos2th*(a4*(M + 15*r) - 48*a2*(3*M - r)*r2 + 16*(-10*M + 3*r)*r4) + 48*a2*r5 + 32*r7)*sin2th)/a2p2r2pa2c2th5 + (d2hS_dph2_re[9]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) + (hS_re[9]*(126*a10 + a10*cos10th + 45*a10*cos6th + 10*a10*cos8th + 6*a8*M2 - a8*cos10th*M2 + 3*a8*cos6th*M2 + 2*a8*cos8th*M2 - 160*a8*M*r - 160*a8*cos6th*M*r - 32*a8*cos8th*M*r + 512*r10 + 700*a8*r2 + 160*a8*cos6th*r2 + 20*a8*cos8th*r2 - 120*a6*M2*r2 + 160*a6*cos6th*M2*r2 + 24*a6*cos8th*M2*r2 - 840*a6*M*r3 - 384*a6*cos6th*M*r3 - 24*a6*cos8th*M*r3 - 640*a4*M3*r3 - 320*a4*cos6th*M3*r3 + 1600*a6*r4 + 160*a6*cos6th*r4 - 96*a4*M2*r4 + 240*a4*cos6th*M2*r4 - 1856*a4*M*r5 - 160*a4*cos6th*M*r5 + 768*a2*M3*r5 + 8*a2*cos4th*(15*a8 - a6*(M2 + 40*M*r - 70*r2) + 4*a4*r2*(3*M2 - 37*M*r + 30*r2) + 4*a2*r3*(20*M3 + 11*M2*r - 38*M*r2 + 20*r3) + 16*M*(2*M2 + 2*M*r - r2)*r5) + 1920*a4*r6 + 768*a2*M2*r6 - 2432*a2*M*r7 + 1280*a2*r8 + 1024*M2*r8 + 2*cos2th*(105*a10 - a8*(M2 + 176*M*r - 560*r2) + 16*a6*r2*(-5*M2 - 52*M*r + 75*r2) + 8*a4*r3*(20*M3 - 31*M2*r - 182*M*r2 + 160*r3) - 128*a2*(4*M3 + 4*M2*r + 6*M*r2 - 5*r3)*r5 + 256*M*(-2*M + r)*r8) - 1536*M*r9))/(8.*a2p2r2pa2c2th5*a2pr2m2Mr*sinth2) - (16*a*dhS_dr_re[3]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (16*a*dhS_dt_re[6]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (2*a2pr2m2Mr*hS_re[4]*(-2*a6*M2 + a6*cos6th*M2 + 76*a6*M*r - 2*a6*cos6th*M*r + 10*a6*r2 + a6*cos6th*r2 - 40*a4*M2*r2 + 2*a4*cos4th*(a2*(M2 - 14*M*r + 3*r2) + 2*r2*(10*M2 - 8*M*r + 3*r2)) + 32*a4*M*r3 + 36*a4*r4 + 48*a2*M2*r4 - a2*cos2th*(a4*(M2 - 50*M*r - 15*r2) - 48*a2*(2*M + r)*r3 - 48*(-M2 + M*r + r2)*r4) - 144*a2*M*r5 + 48*a2*r6 - 96*M*r7 + 32*r8)*sinth2)/a2p2r2pa2c2th5 + (4*a*hS_re[3]*M*(2*a8*M - a8*cos6th*M + 30*a8*r + 3*a8*cos6th*r - 130*a6*M*r2 - 3*a6*cos6th*M*r2 + 70*a6*r3 + a6*cos6th*r3 - 80*a4*M2*r3 - 2*a4*cos4th*(a4*(M - 9*r) + a2*(31*M - 13*r)*r2 + 2*(-20*M2 + 14*M*r + r2)*r3) - 184*a4*M*r4 + 4*a4*r5 + 64*a2*M2*r5 + a2*cos2th*(a6*(M + 45*r) + a4*(-189*M + 95*r)*r2 - 272*a2*M*r4 - 16*(4*M2 + 3*M*r + 5*r2)*r5) + 176*a2*M*r6 - 112*a2*r7 + 256*M*r8 - 96*r9)*sinth2)/(a2p2r2pa2c2th5*a2pr2m2Mr) - (2*hS_re[0]*M*(-2*a10*M + a10*cos6th*M + 30*a10*r + 3*a10*cos6th*r - 32*r11 + 28*a8*M*r2 - 18*a8*cos6th*M*r2 + 120*a8*r3 + 6*a8*cos6th*r3 + 40*a6*M2*r3 + 20*a6*cos6th*M2*r3 + 46*a6*M*r4 - 15*a6*cos6th*M*r4 + 166*a6*r5 + 3*a6*cos6th*r5 - 48*a4*M2*r5 + 2*a4*cos4th*(a6*(M + 9*r) - 14*a4*(M - 2*r)*r2 + a2*(-20*M2 - 31*M*r + 29*r2)*r3 + 2*(-4*M2 - 2*M*r + 5*r2)*r5) - 152*a4*M*r6 + 60*a4*r7 - 208*a2*M*r8 + a2*cos2th*(-(a8*(M - 45*r)) + 2*a6*(9*M + 85*r)*r2 + a4*(-20*M2 + 31*M*r + 221*r2)*r3 + 16*a2*(4*M2 + 10*M*r + 7*r2)*r5 + 16*(13*M + r)*r8) - 48*a2*r9)*sinth2)/(a2p2r2pa2c2th5*a2pr2m2Mr) - (64*a3*costh*dhS_dth_re[3]*M*r*sinth3)/a2p2r2pa2c2th3 + (64*a3*costh*dhS_dt_re[8]*M*r*sinth3)/a2p2r2pa2c2th3 + (4*dhS_dph_re[8]*(3*a4 + a4*cos4th + 8*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (dhS_dth_re[9]*(9*a4 + 3*a4*cos4th + 32*a2*M*r + 24*a2*r2 + 4*a2*cos2th*(3*a2 - 8*M*r + 6*r2) + 24*r4))/(a2p2r2pa2c2th3*tanth); src_im[0] = (-8*a*d2hS_dtph_im[0]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (16*dhS_dt_im[1]*M*(a2 + a2*cos2th - 2*r2)*(a2 + r2))/a2p2r2pa2c2th3 + d2hS_dth2_im[0]/r2pa2cth2 + (d2hS_dr2_im[0]*(a2 - 2*M*r + r2))/r2pa2cth2 + (4*a*dhS_dr_im[3]*M*(a2*costh2 - r2))/r2pa2cth23 + (4*a*dhS_dph_im[1]*M*(-(a2*costh2) + r2))/r2pa2cth23 - (d2hS_dt2_im[0]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) + (16*hS_im[7]*M*r*(-9*a4 + 3*a4*cos4th + 20*a2*M*r - 2*a2*cos2th*(3*a2 + 5*r*(-2*M + r)) + 2*a2*r2 - 8*M*r3 + 4*r4))/a2p2r2pa2c2th5 + (2*dhS_dr_im[0]*(5*a4*M - a4*cos4th*(M - r) + 3*a4*r - 16*a2*M*r2 + 8*a2*r3 + 4*a2*cos2th*(a2*(M + r) + 2*r3) - 24*M*r4 + 8*r5))/a2p2r2pa2c2th3 - (8*a2pr2m2Mr*hS_im[4]*M*(3*a4*M - 27*a4*r + a4*cos4th*(M + 3*r) + 40*a2*M*r2 + 4*a2*cos2th*(a2*(M - 6*r) + (10*M - 7*r)*r2) - 4*a2*r3 - 24*M*r4 + 16*r5))/a2p2r2pa2c2th5 + (16*a*hS_im[3]*M2*(3*a6 + 29*a4*r2 + a4*cos4th*(a2 + 7*r2) - 80*a2*M*r3 + 32*a2*r4 + 4*a2*cos2th*(a4 + 9*a2*r2 - 20*M*r3 + 6*r4) + 32*M*r5 - 8*r6))/(a2p2r2pa2c2th5*a2pr2m2Mr) + (8*hS_im[0]*M2*(3*a8 + 2*a6*r2 - 20*a4*M*r3 + a4*cos4th*(a4 - 2*a2*r2 + 20*M*r3 - 3*r4) - a4*r4 + 16*a2*M*r5 + 4*a2*cos2th*(a6 - 3*a2*r4 - 2*(2*M + r)*r5) + 8*a2*r6 + 8*r8))/(a2p2r2pa2c2th5*a2pr2m2Mr) - (32*a2*dhS_dt_im[2]*M*r*sin2th)/a2p2r2pa2c2th3 - (96*a2*a2pr2m2Mr*hS_im[5]*M*(a2 + a2*cos2th - 6*r2)*sin2th)/a2p2r2pa2c2th5 + (d2hS_dph2_im[0]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (2*hS_im[9]*M*(-2*a6*M + a6*cos6th*M + 30*a6*r + 3*a6*cos6th*r - 200*a4*M*r2 + 2*a4*cos4th*(a2*(M + 9*r) + 2*(-14*M + 5*r)*r2) + 60*a4*r3 + 320*a2*M2*r3 - a2*cos2th*(a4*(M - 45*r) + 16*a2*(16*M - 5*r)*r2 - 16*(20*M2 - 11*M*r + r2)*r3) - 208*a2*M*r4 + 16*a2*r5 - 128*M2*r5 + 128*M*r6 - 32*r7))/(a2p2r2pa2c2th5*a2pr2m2Mr*sinth2) - (64*a*dhS_dph_im[2]*M*r)/(a2p2r2pa2c2th3*tanth) + (64*a*dhS_dth_im[3]*M*r)/(a2p2r2pa2c2th3*tanth) + (dhS_dth_im[0]*(3*a4 + a4*cos4th + 32*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-4*M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth); src_im[1] = (-8*a*d2hS_dtph_im[1]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dt_im[4]*M*(a2 + a2*cos2th - 2*r2)*(a2 + r2))/a2p2r2pa2c2th3 + d2hS_dth2_im[1]/r2pa2cth2 + (d2hS_dr2_im[1]*(a2 - 2*M*r + r2))/r2pa2cth2 - (2*dhS_dth_im[2]*r)/r2pa2cth22 + (2*a*dhS_dr_im[6]*M*(a2*costh2 - r2))/r2pa2cth23 + (2*a*dhS_dph_im[4]*M*(-(a2*costh2) + r2))/r2pa2cth23 - (4*a*dhS_dph_im[0]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (4*a*dhS_dt_im[3]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (d2hS_dt2_im[1]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) + (4*dhS_dr_im[1]*(-(a4*M) - a4*cos4th*(M - r) + a4*r - 6*a2*M*r2 - 2*a2*cos2th*(a2*(M - r) + (M - 3*r)*r2) + 2*a2*r3 - 4*M*r4 + 4*r5))/a2p2r2pa2c2th3 - (8*a*hS_im[6]*M*(3*a4*M + a4*cos4th*(M - r) - 23*a4*r + 40*a2*M*r2 + 4*a2*cos2th*(a2*(M - 6*r) + 5*(2*M - r)*r2) - 12*a2*r3 - 24*M*r4 + 16*r5))/(a2p2r2pa2c2th4*a2pr2m2Mr) - (4*dhS_dt_im[0]*M*(a6 + a2*(4*M - 3*r)*r3 + a2*cos2th*(a4 + 2*a2*r2 + (-4*M + r)*r3) - 2*r6))/(a2p2r2pa2c2th2*a2pr2m2Mr2) + (hS_im[1]*(10*a8 + a8*cos6th - 24*a6*M2 + 116*a6*M*r - 2*a6*cos6th*M*r + 22*a6*r2 + a6*cos6th*r2 - 248*a4*M2*r2 + 2*a4*cos4th*(3*a4 + 2*r2*(6*M2 - 4*M*r + r2) + a2*(-4*M2 - 10*M*r + 5*r2)) + 208*a4*M*r3 - 4*a4*r4 - 128*a2*M2*r4 + a2*cos2th*(15*a6 - 32*a2*M*(7*M - 8*r)*r2 + a4*(-32*M2 + 98*M*r + 31*r2) - 16*(20*M2 - 12*M*r + r2)*r4) + 128*a2*M*r5 - 48*a2*r6 - 64*M2*r6 + 64*M*r7 - 32*r8))/(a2p2r2pa2c2th4*a2pr2m2Mr) - (16*a2*dhS_dt_im[5]*M*r*sin2th)/a2p2r2pa2c2th3 - (32*a3*hS_im[8]*M*(a2 + a2*cos2th - 4*r2)*sin2th)/(a2p2r2pa2c2th4*a2pr2m2Mr) - (2*a2*costh*dhS_dr_im[2]*sinth)/r2pa2cth22 + (d2hS_dph2_im[1]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (dhS_dph_im[3]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 20*a2*M*r2 + 4*a2*cos2th*r*(a2 - 3*M*r + 2*r2) + 8*a2*r3 + 32*M2*r3 - 32*M*r4 + 8*r5))/(a2p2r2pa2c2th2*a2pr2m2Mr2*sinth2) - (32*a*dhS_dph_im[5]*M*r)/(a2p2r2pa2c2th3*tanth) + (32*a*dhS_dth_im[6]*M*r)/(a2p2r2pa2c2th3*tanth) + (dhS_dth_im[1]*(5*a4 - a4*cos4th + 16*a2*M*r + 4*a2*cos2th*(a2 - 4*M*r) + 16*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (4*hS_im[2]*(4*a6*M + 3*a6*r - 34*a4*M*r2 + a4*cos4th*(a2*(-4*M + r) + (-6*M + r)*r2) + 11*a4*r3 + 4*a2*cos2th*r*(a4 + 3*a2*r*(2*M + r) + 2*(2*M + r)*r3) - 48*a2*M*r4 + 16*a2*r5 - 16*M*r6 + 8*r7))/(a2p2r2pa2c2th4*a2pr2m2Mr*tanth); src_im[2] = (-8*a*d2hS_dtph_im[2]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dt_im[5]*M*(a2 + a2*cos2th - 2*r2)*(a2 + r2))/a2p2r2pa2c2th3 + d2hS_dth2_im[2]/r2pa2cth2 + (d2hS_dr2_im[2]*(a2 - 2*M*r + r2))/r2pa2cth2 + (2*a2pr2m2Mr*dhS_dth_im[1]*r)/r2pa2cth22 + (2*a*dhS_dr_im[8]*M*(a2*costh2 - r2))/r2pa2cth23 + (2*a*dhS_dph_im[5]*M*(-(a2*costh2) + r2))/r2pa2cth23 - (d2hS_dt2_im[2]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*a3*dhS_dph_im[0]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (8*a3*dhS_dt_im[3]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (16*a2*dhS_dt_im[7]*M*r*sin2th)/a2p2r2pa2c2th3 - (8*a2*dhS_dt_im[0]*M*r*(a2 + r2)*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (a2*a2pr2m2Mr*dhS_dr_im[1]*sin2th)/r2pa2cth22 + (4*a2*hS_im[1]*(-7*a4*M - a4*cos4th*(M - r) + 3*a4*r + 8*a2*M2*r - 4*a2*cos2th*(a2*(2*M - r) + r*(-2*M2 + 3*M*r - 2*r2)) + 28*a2*M*r2 + 8*a2*r3 - 80*M2*r3 + 32*M*r4 + 8*r5)*sin2th)/a2p2r2pa2c2th4 + (d2hS_dph2_im[2]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) + (8*a*hS_im[8]*M*r*(-a2 + 5*a2*cos4th + 4*cos2th*(a2 - r2) + 12*r2))/(a2p2r2pa2c2th4*sinth2) - (hS_im[2]*(15*a6 + 6*a6*cos6th + a6*cos8th + 96*a4*M*r + 16*a4*cos6th*M*r + 56*a4*r2 + 8*a4*cos6th*r2 - 160*a2*M*r3 + 8*a2*cos4th*(2*a4 + a2*r*(-12*M + 5*r) + 2*(-6*M + r)*r3) + 80*a2*r4 - 128*M*r5 + 2*cos2th*(13*a6 + a4*(-8*M*r + 44*r2) + 16*a2*(8*M + 3*r)*r3 + 64*M*r5) + 64*r6))/(4.*a2p2r2pa2c2th4*sinth2) - (8*a2*dhS_dr_im[2]*(-(a2*cos2th*(M - r)) + a2*(-M + r) + 2*(M + r)*r2)*sinth2)/a2p2r2pa2c2th3 - (32*a*dhS_dph_im[7]*M*r)/(a2p2r2pa2c2th3*tanth) + (32*a*dhS_dth_im[8]*M*r)/(a2p2r2pa2c2th3*tanth) - (32*a*a2pr2m2Mr*hS_im[6]*M*(a2 + a2*cos2th - 10*r2))/(a2p2r2pa2c2th4*tanth) + (dhS_dth_im[2]*(5*a4 - a4*cos4th + 16*a2*M*r + 4*a2*cos2th*(a2 - 4*M*r) + 16*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (dhS_dph_im[3]*(3*a4 + a4*cos4th + 4*a2*cos2th*(a2 + 2*r*(-2*M + r)) + 8*a2*r2 - 16*M*r3 + 8*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr*sinth2*tanth); src_im[3] = (-8*a*d2hS_dtph_im[3]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dt_im[6]*M*(a2 + a2*cos2th - 2*r2)*(a2 + r2))/a2p2r2pa2c2th3 + d2hS_dth2_im[3]/r2pa2cth2 + (d2hS_dr2_im[3]*(a2 - 2*M*r + r2))/r2pa2cth2 + (2*a*dhS_dr_im[9]*M*(a2*costh2 - r2))/r2pa2cth23 + (2*a*dhS_dph_im[6]*M*(-(a2*costh2) + r2))/r2pa2cth23 - (d2hS_dt2_im[3]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*a*hS_im[7]*M*r*(-3*a4 + 10*a2*M*r + 17*a2*r2 + a2*cos4th*(11*a2 - 10*M*r + 11*r2) - 8*M*r3 + 4*cos2th*(2*a4 + a2*r2 + (2*M - r)*r3) + 20*r4))/a2p2r2pa2c2th5 + (2*dhS_dph_im[1]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 12*a2*M*r2 + 4*a2*cos2th*r*(a2 - M*r + 2*r2) + 8*a2*r3 - 16*M*r4 + 8*r5))/a2p2r2pa2c2th3 - (4*hS_im[3]*M*(2*a8*M - a8*cos6th*M + 30*a8*r + 3*a8*cos6th*r - 54*a6*M*r2 - 5*a6*cos6th*M*r2 + 90*a6*r3 + 3*a6*cos6th*r3 - 80*a4*M2*r3 - 2*a4*cos4th*(a4*(M - 9*r) + a2*(21*M - 19*r)*r2 - 2*(20*M2 - 12*M*r + 5*r2)*r3) - 96*a4*M*r4 + 76*a4*r5 + 64*a2*M2*r5 + a2*cos2th*(a6*(M + 45*r) + a4*(-91*M + 125*r)*r2 + 16*a2*(-11*M + 6*r)*r4 + 16*(-4*M2 - 5*M*r + r2)*r5) + 16*a2*M*r6 - 16*a2*r7 + 64*M*r8 - 32*r9))/(a2p2r2pa2c2th5*a2pr2m2Mr) - (16*a2*dhS_dt_im[8]*M*r*sin2th)/a2p2r2pa2c2th3 - (16*a*a2pr2m2Mr*hS_im[5]*M*(-3*a4 + a4*cos4th + 26*a2*r2 - 2*a2*cos2th*(a2 + 5*r2) + 20*r4)*sin2th)/a2p2r2pa2c2th5 + (d2hS_dph2_im[3]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (a*hS_im[9]*M*(3*a6*M + a6*cos8th*(M - r) + 85*a6*r + 124*a6*cos2th*r + 4*a6*cos6th*r - 80*a4*M*r2 - 216*a4*cos2th*M*r2 - 40*a4*cos6th*M*r2 + 280*a4*r3 + 380*a4*cos2th*r3 + 4*a4*cos6th*r3 - 320*a2*M2*r3 - 4*a2*cos4th*(a4*(M - 11*r) + 2*a2*(22*M - 13*r)*r2 - 20*(4*M2 - 3*M*r + r2)*r3) - 208*a2*M*r4 - 576*a2*cos2th*M*r4 + 304*a2*r5 + 384*a2*cos2th*r5 + 256*M2*r5 - 256*cos2th*M2*r5 - 256*M*r6 - 256*cos2th*M*r6 + 64*r7 + 192*cos2th*r7))/(2.*a2p2r2pa2c2th5*a2pr2m2Mr*sinth2) - (8*a*dhS_dr_im[0]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*dhS_dt_im[1]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*a2pr2m2Mr*hS_im[4]*M*(3*a4*M + a4*cos4th*(M - r) - 39*a4*r + 40*a2*M*r2 + 4*a2*cos2th*(a2*(M - 10*r) + (10*M - 9*r)*r2) - 12*a2*r3 - 24*M*r4 + 32*r5)*sinth2)/a2p2r2pa2c2th5 - (8*a*hS_im[0]*M2*(3*a8 - 22*a6*r2 - 20*a4*M*r3 + a4*cos4th*(a4 - 10*a2*r2 + 20*M*r3 - 11*r4) - 41*a4*r4 + 16*a2*M*r5 + 4*a2*cos2th*(a6 - 8*a4*r2 - 15*a2*r4 - 2*(2*M + 3*r)*r5) + 24*a2*r6 + 40*r8)*sinth2)/(a2p2r2pa2c2th5*a2pr2m2Mr) - (32*a3*costh*dhS_dth_im[0]*M*r*sinth3)/a2p2r2pa2c2th3 + (32*a3*costh*dhS_dt_im[2]*M*r*sinth3)/a2p2r2pa2c2th3 - (2*dhS_dth_im[3])/(a2p2r2pa2c2th*tanth) - (32*a*dhS_dph_im[8]*M*r)/(a2p2r2pa2c2th3*tanth) + (32*a*dhS_dth_im[9]*M*r)/(a2p2r2pa2c2th3*tanth) + (2*dhS_dph_im[2]*(3*a4 + a4*cos4th + 8*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth); src_im[4] = (-8*a*d2hS_dtph_im[4]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (4*dhS_dr_im[4]*(3*a2*cos2th*(M - r) + a2*(3*M + r) - 2*(M + r)*r2))/a2p2r2pa2c2th2 + d2hS_dth2_im[4]/r2pa2cth2 + (d2hS_dr2_im[4]*(a2 - 2*M*r + r2))/r2pa2cth2 - (4*dhS_dth_im[5]*r)/r2pa2cth22 - (8*a*dhS_dph_im[1]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (8*a*dhS_dt_im[6]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (d2hS_dt2_im[4]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) + (2*hS_im[4]*(7*a6 + 3*a4*M2 + 4*a4*M*r + 10*a4*r2 - 40*a2*M2*r2 + a4*cos4th*(a2 + M2 - 4*M*r + 2*r2) + 4*a2*cos2th*(2*a4 + 2*M*(-5*M + 3*r)*r2 + a2*(M2 + r2)) + 40*a2*M*r3 - 16*a2*r4 - 56*M2*r4 + 64*M*r5 - 16*r6))/(a2p2r2pa2c2th3*a2pr2m2Mr) - (8*dhS_dt_im[1]*M*(a6 + a2*(4*M - 3*r)*r3 + a2*cos2th*(a4 + 2*a2*r2 + (-4*M + r)*r3) - 2*r6))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (4*a*hS_im[3]*M*(3*a6*M - 39*a6*r + a4*cos4th*(M - r)*(a2 - r2) + 101*a4*M*r2 - 45*a4*r3 - 48*a2*M2*r3 + 4*a2*cos2th*(a4*(M - 10*r) + a2*(25*M - 17*r)*r2 + (-12*M2 + 18*M*r - 5*r2)*r3) - 16*a2*M*r4 + 36*a2*r5 + 96*M2*r5 - 136*M*r6 + 48*r7))/(a2p2r2pa2c2th3*a2pr2m2Mr3) - (2*hS_im[0]*M*(3*a8*M - 27*a8*r + 62*a6*M*r2 - 58*a6*r3 - 12*a4*M2*r3 + a4*cos4th*(a4*(M + 3*r) + 2*a2*(-7*M + 3*r)*r2 + (12*M2 - 11*M*r + 3*r2)*r3) + 39*a4*M*r4 - 19*a4*r5 + 48*a2*M2*r5 + 4*a2*cos2th*(a6*(M - 6*r) + a4*(12*M - 19*r)*r2 + a2*(29*M - 20*r)*r4 + (-12*M2 + 22*M*r - 7*r2)*r5) - 56*a2*M*r6 + 28*a2*r7 - 24*M*r8 + 16*r9))/(a2p2r2pa2c2th3*a2pr2m2Mr3) - (4*a2*costh*dhS_dr_im[5]*sinth)/r2pa2cth22 + (d2hS_dph2_im[4]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (2*dhS_dph_im[6]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 20*a2*M*r2 + 4*a2*cos2th*r*(a2 - 3*M*r + 2*r2) + 8*a2*r3 + 32*M2*r3 - 32*M*r4 + 8*r5))/(a2p2r2pa2c2th2*a2pr2m2Mr2*sinth2) + (hS_im[9]*(-2*a6*M2 + a6*cos6th*M2 + 76*a6*M*r - 2*a6*cos6th*M*r + 10*a6*r2 + a6*cos6th*r2 - 248*a4*M2*r2 + 2*a4*cos4th*(a2*(M2 - 14*M*r + 3*r2) + 2*r2*(14*M2 - 12*M*r + 3*r2)) - 16*a4*M*r3 + 192*a2*M3*r3 - a2*cos2th*(a4*(M2 - 50*M*r - 15*r2) - 16*a2*r2*(-12*M2 + 2*M*r + 3*r2) - 16*r3*(12*M3 - 7*M2*r - 5*M*r2 + 3*r3)) + 36*a4*r4 + 240*a2*M2*r4 - 272*a2*M*r5 - 384*M3*r5 + 48*a2*r6 + 512*M2*r6 - 224*M*r7 + 32*r8))/(2.*a2p2r2pa2c2th3*a2pr2m2Mr3*sinth2) + (hS_im[7]*(3*a2*cos2th*M*r + r*(3*a2*M + 2*a2*r - 6*M*r2 + 2*r3) + 2*a4*costh2*sinth2))/(a2pr2m2Mr*r2pa2cth23) - (2*dhS_dth_im[4]*(-5*a2 + 3*a2*cos2th - 2*r2))/(a2p2r2pa2c2th2*tanth) + (8*hS_im[5]*(a2*(M - 3*r) - a2*cos2th*(M - r) + 2*(2*M - r)*r2))/(a2p2r2pa2c2th2*a2pr2m2Mr*tanth); src_im[5] = (-8*a*d2hS_dtph_im[5]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dr_im[5]*(a2*cos2th*(M - r) + a2*(M + r) - 2*M*r2))/a2p2r2pa2c2th2 + d2hS_dth2_im[5]/r2pa2cth2 + (d2hS_dr2_im[5]*(a2 - 2*M*r + r2))/r2pa2cth2 + (2*a2pr2m2Mr*dhS_dth_im[4]*r)/r2pa2cth22 - (2*dhS_dth_im[7]*r)/r2pa2cth22 - (4*a*dhS_dph_im[2]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (4*a*dhS_dt_im[8]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (d2hS_dt2_im[5]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (4*dhS_dt_im[2]*M*(a6 + a2*(4*M - 3*r)*r3 + a2*cos2th*(a4 + 2*a2*r2 + (-4*M + r)*r3) - 2*r6))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (8*a3*dhS_dph_im[1]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (8*a3*dhS_dt_im[6]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (12*a2*hS_im[4]*(-M + r)*sin2th)/a2p2r2pa2c2th2 - (8*a2*dhS_dt_im[1]*M*r*(a2 + r2)*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (a2*a2pr2m2Mr*dhS_dr_im[4]*sin2th)/r2pa2cth22 - (4*a2*hS_im[0]*M*(3*a6 - 4*a4*r*(M + 3*r) + a2*(32*M - 33*r)*r3 + a2*cos2th*(3*a4 + a2*(-4*M*r + 6*r2) + (-8*M + 3*r)*r3) + 2*(16*M - 9*r)*r5)*sin2th)/(a2p2r2pa2c2th3*a2pr2m2Mr2) - (2*a2*costh*dhS_dr_im[7]*sinth)/r2pa2cth22 + (d2hS_dph2_im[5]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (hS_im[5]*(a4 + 3*a4*cos4th + a4*cos6th + 8*a2*r2 - 32*M*r3 + cos2th*(3*a4 + 8*a2*r2 + 16*(2*M - r)*r3) + 24*r4))/(a2p2r2pa2c2th3*sinth2) - (dhS_dph_im[8]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 20*a2*M*r2 + 4*a2*cos2th*r*(a2 - 3*M*r + 2*r2) + 8*a2*r3 + 32*M2*r3 - 32*M*r4 + 8*r5))/(a2p2r2pa2c2th2*a2pr2m2Mr2*sinth2) - (8*hS_im[7]*r)/(a2p2r2pa2c2th2*tanth) - (2*dhS_dth_im[5]*(-5*a2 + 3*a2*cos2th - 2*r2))/(a2p2r2pa2c2th2*tanth) + (8*a*hS_im[3]*M*(-3*a6 + 5*a4*M*r + a4*cos4th*(a2 - M*r) + 20*a4*r2 - 48*a2*M*r3 - 2*a2*cos2th*(a4 - 2*a2*(M - 4*r)*r + (-16*M + 9*r)*r3) + 38*a2*r4 - 24*M*r5 + 12*r6))/(a2p2r2pa2c2th3*a2pr2m2Mr2*tanth) - (dhS_dph_im[6]*(3*a4 + a4*cos4th + 4*a2*cos2th*(a2 + 2*r*(-2*M + r)) + 8*a2*r2 - 16*M*r3 + 8*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr*sinth2*tanth) + (hS_im[9]*(-10*a6*M - a6*cos6th*M + 10*a6*r + a6*cos6th*r + 16*a4*M2*r + 92*a4*M*r2 + 36*a4*r3 - 256*a2*M2*r3 + 2*a4*cos4th*(5*a2*M + 3*a2*r - 8*M2*r - 6*M*r2 + 6*r3) + a2*cos2th*(a4*(M + 15*r) + 16*a2*(-13*M + 3*r)*r2 + 48*(8*M2 - 6*M*r + r2)*r3) + 32*a2*M*r4 + 48*a2*r5 + 128*M2*r5 - 128*M*r6 + 32*r7))/(2.*a2p2r2pa2c2th3*a2pr2m2Mr2*sinth2*tanth); src_im[6] = (-8*a*d2hS_dtph_im[6]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) + d2hS_dth2_im[6]/r2pa2cth2 + (d2hS_dr2_im[6]*(a2 - 2*M*r + r2))/r2pa2cth2 - (2*dhS_dth_im[8]*r)/r2pa2cth22 - (4*a*dhS_dph_im[3]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (4*a*dhS_dt_im[9]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 + 8*M*r3 - 6*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (d2hS_dt2_im[6]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (2*dhS_dr_im[6]*(7*a4*M + a4*cos4th*(M - r) + a4*r - 4*a2*M*r2 + 4*a2*cos2th*(2*a2*M + (M - r)*r2) + 4*a2*r3 - 16*M*r4))/a2p2r2pa2c2th3 + (2*dhS_dph_im[4]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 12*a2*M*r2 + 4*a2*cos2th*r*(a2 - M*r + 2*r2) + 8*a2*r3 - 16*M*r4 + 8*r5))/a2p2r2pa2c2th3 - (4*dhS_dt_im[3]*M*(a6 + a2*(4*M - 3*r)*r3 + a2*cos2th*(a4 + 2*a2*r2 + (-4*M + r)*r3) - 2*r6))/(a2p2r2pa2c2th2*a2pr2m2Mr2) - (2*hS_im[6]*(-2*a6*M2 + a6*cos6th*M2 + 24*a6*M*r - 2*a6*cos6th*M*r + 10*a6*r2 + a6*cos6th*r2 - 40*a4*M2*r2 + 2*a4*cos4th*(a2*(M2 - 12*M*r + 3*r2) + 2*r2*(10*M2 - 9*M*r + 3*r2)) - 44*a4*M*r3 + 36*a4*r4 + 112*a2*M2*r4 - a2*cos2th*(a4*(M2 - 2*M*r - 15*r2) + 48*a2*(M - r)*r3 - 16*(M2 - 5*M*r + 3*r2)*r4) - 176*a2*M*r5 + 48*a2*r6 + 128*M2*r6 - 128*M*r7 + 32*r8))/(a2p2r2pa2c2th4*a2pr2m2Mr) + (4*a*hS_im[2]*M*(5*a6 - 21*a4*r2 + cos4th*(-a6 + a4*r2) - 56*a2*r4 + 4*a2*cos2th*(a4 + 3*a2*r2 + 4*r4) - 24*r6)*sin2th)/(a2p2r2pa2c2th4*a2pr2m2Mr) - (2*a2*costh*dhS_dr_im[8]*sinth)/r2pa2cth22 + (d2hS_dph2_im[6]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (dhS_dph_im[9]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 20*a2*M*r2 + 4*a2*cos2th*r*(a2 - 3*M*r + 2*r2) + 8*a2*r3 + 32*M2*r3 - 32*M*r4 + 8*r5))/(a2p2r2pa2c2th2*a2pr2m2Mr2*sinth2) - (8*a*dhS_dr_im[1]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*dhS_dt_im[4]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*hS_im[1]*M*(3*a6*M - 20*a6*r + 31*a4*M*r2 - 26*a4*r3 + a4*cos4th*(a2*M - 3*M*r2 + 2*r3) + 4*a2*cos2th*(a4*(M - 5*r) + a2*(7*M - 8*r)*r2 + (6*M - r)*r4) + 12*a2*r5 - 24*M*r6 + 24*r7)*sinth2)/(a2p2r2pa2c2th4*a2pr2m2Mr) - (32*a3*costh*dhS_dth_im[1]*M*r*sinth3)/a2p2r2pa2c2th3 + (32*a3*costh*dhS_dt_im[5]*M*r*sinth3)/a2p2r2pa2c2th3 - (dhS_dth_im[6]*(a4 + 3*a4*cos4th + 16*a2*M*r + 4*a2*cos2th*(a2 + 4*r*(-M + r)) + 8*r4))/(a2p2r2pa2c2th3*tanth) + (2*dhS_dph_im[5]*(3*a4 + a4*cos4th + 8*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (2*hS_im[8]*(-6*a6*M - a6*cos6th*M + 4*a6*r + a6*cos6th*r + 52*a4*M*r2 + 2*a4*cos4th*(a2*(3*M + 2*r) + (-2*M + 5*r)*r2) + 14*a4*r3 + 48*a2*M*r4 + a2*cos2th*(a4*(M + 7*r) + 8*a2*(-10*M + 3*r)*r2 + 16*(-7*M + 2*r)*r4) + 16*a2*r5 - 32*M*r6 + 16*r7))/(a2p2r2pa2c2th4*a2pr2m2Mr*tanth); src_im[7] = (-8*a*d2hS_dtph_im[7]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) - (4*dhS_dr_im[7]*(a2*cos2th*(M - r) + a2*(M + 3*r) + 2*(-3*M + r)*r2))/a2p2r2pa2c2th2 + d2hS_dth2_im[7]/r2pa2cth2 + (d2hS_dr2_im[7]*(a2 - 2*M*r + r2))/r2pa2cth2 + (4*a2pr2m2Mr*dhS_dth_im[5]*r)/r2pa2cth22 - (d2hS_dt2_im[7]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) + (8*a*hS_im[3]*M*r*(-15*a4 + a4*cos4th + 16*a2*M*r - 2*a2*cos2th*(7*a2 + r*(-8*M + 7*r)) - 2*a2*r2 - 16*M*r3 + 12*r4))/(a2p2r2pa2c2th3*a2pr2m2Mr) + (4*hS_im[0]*M*r*(-9*a6 + 4*a4*M*r - 7*a4*r2 + a4*cos4th*(3*a2 - 4*M*r + 3*r2) - 8*a2*M*r3 - 2*a2*cos2th*(3*a4 + 8*a2*r2 + (-4*M + 5*r)*r3) + 6*a2*r4 + 4*r6))/(a2p2r2pa2c2th3*a2pr2m2Mr) - (16*a3*dhS_dph_im[2]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (16*a3*dhS_dt_im[8]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (16*a2*hS_im[5]*(-M + r)*sin2th)/a2p2r2pa2c2th2 - (16*a2*dhS_dt_im[2]*M*r*(a2 + r2)*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (2*a2*a2pr2m2Mr*dhS_dr_im[5]*sin2th)/r2pa2cth22 + (d2hS_dph2_im[7]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (hS_im[7]*(6*a4 + a4*cos6th + 8*a2*r2 + 2*a2*cos4th*(5*a2 + 4*r2) + 32*M*r3 + cos2th*(15*a4 + 48*a2*r2 + 16*(-2*M + r)*r3) + 16*r4))/(2.*a2p2r2pa2c2th3*sinth2) + (a2pr2m2Mr*hS_im[4]*(3*a2*cos2th*M*r + r*(3*a2*M + 2*a2*r - 6*M*r2 + 2*r3) + 2*a4*costh2*sinth2))/r2pa2cth23 - (2*dhS_dth_im[7]*(-5*a2 + 3*a2*cos2th - 2*r2))/(a2p2r2pa2c2th2*tanth) - (2*dhS_dph_im[8]*(3*a4 + a4*cos4th + 4*a2*cos2th*(a2 + 2*r*(-2*M + r)) + 8*a2*r2 - 16*M*r3 + 8*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr*sinth2*tanth) + (hS_im[9]*(35*a6 + 8*a6*cos6th + a6*cos8th - 168*a4*M*r - 36*a4*cos6th*M*r + 120*a4*r2 + 12*a4*cos6th*r2 + 128*a2*M2*r2 + 4*a2*cos4th*(7*a4 + 2*a2*r*(5*M + 9*r) - 4*(8*M2 + M*r - 3*r2)*r2) - 48*a2*M*r3 + 144*a2*r4 - 256*M2*r4 + 64*r6 + 4*cos2th*(14*a6 + a4*r*(-23*M + 45*r) - 16*a2*(7*M - 3*r)*r3 + 16*r4*pow(-2*M + r,2))))/(8.*a2p2r2pa2c2th3*a2pr2m2Mr*sinth4); src_im[8] = (-8*a*d2hS_dtph_im[8]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) + d2hS_dth2_im[8]/r2pa2cth2 + (d2hS_dr2_im[8]*(a2 - 2*M*r + r2))/r2pa2cth2 + (2*a2pr2m2Mr*dhS_dth_im[6]*r)/r2pa2cth22 - (d2hS_dt2_im[8]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (8*dhS_dr_im[8]*(a4*(M + r) + 3*a2*(-M + r)*r2 + a2*cos2th*(a2*(M + r) + (-M + r)*r2) + 2*(-3*M + r)*r4))/a2p2r2pa2c2th3 + (2*dhS_dph_im[5]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 12*a2*M*r2 + 4*a2*cos2th*r*(a2 - M*r + 2*r2) + 8*a2*r3 - 16*M*r4 + 8*r5))/a2p2r2pa2c2th3 - (8*a3*dhS_dph_im[3]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (8*a3*dhS_dt_im[9]*M*r*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) - (8*a2*dhS_dt_im[3]*M*r*(a2 + r2)*sin2th)/(a2p2r2pa2c2th2*a2pr2m2Mr) + (a2*a2pr2m2Mr*dhS_dr_im[6]*sin2th)/r2pa2cth22 + (d2hS_dph2_im[8]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) - (hS_im[8]*(55*a6 + 10*a6*cos6th + a6*cos8th - 80*a4*M*r - 24*a4*cos6th*M*r + 184*a4*r2 + 16*a4*cos6th*r2 + 224*a2*M*r3 + 8*a2*cos4th*(5*a4 + a2*r*(10*M + 13*r) + 2*(2*M + 5*r)*r3) + 208*a2*r4 + 256*M*r5 + 2*cos2th*(43*a6 + 4*a4*r*(3*M + 34*r) - 16*a2*(8*M - 9*r)*r3 + 64*(-2*M + r)*r5) + 64*r6))/(4.*a2p2r2pa2c2th4*sinth2) - (8*a*dhS_dr_im[2]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (8*a*dhS_dt_im[5]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (32*a*hS_im[2]*M*r*(4*a4 - a2*r2 + a2*cos2th*(4*a2 + 3*r2) - 6*r4)*sinth2)/a2p2r2pa2c2th4 - (32*a3*costh*dhS_dth_im[2]*M*r*sinth3)/a2p2r2pa2c2th3 + (32*a3*costh*dhS_dt_im[7]*M*r*sinth3)/a2p2r2pa2c2th3 + (32*a2pr2m2Mr*a3*costh*hS_im[1]*M*(a2 + a2*cos2th - 10*r2)*sinth3)/a2p2r2pa2c2th4 - (dhS_dth_im[8]*(a4 + 3*a4*cos4th + 16*a2*M*r + 4*a2*cos2th*(a2 + 4*r*(-M + r)) + 8*r4))/(a2p2r2pa2c2th3*tanth) + (2*dhS_dph_im[7]*(3*a4 + a4*cos4th + 8*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (2*hS_im[6]*(-2*a6*M - a6*cos6th*M + 10*a6*r + a6*cos6th*r + 8*a4*M2*r + 60*a4*M*r2 + 2*a4*cos4th*(a2*(M + 3*r) + 2*r*(-2*M2 - 3*M*r + 3*r2)) + 36*a4*r3 - 160*a2*M2*r3 + a2*cos2th*(a4*(M + 15*r) - 16*a2*(7*M - 3*r)*r2 + 16*(10*M2 - 10*M*r + 3*r2)*r3) + 32*a2*M*r4 + 48*a2*r5 - 64*M*r6 + 32*r7))/(a2p2r2pa2c2th4*tanth) - (dhS_dph_im[9]*(3*a4 + a4*cos4th + 4*a2*cos2th*(a2 + 2*r*(-2*M + r)) + 8*a2*r2 - 16*M*r3 + 8*r4))/(a2p2r2pa2c2th2*a2pr2m2Mr*sinth2*tanth); src_im[9] = (-8*a*d2hS_dtph_im[9]*M*r)/(a2p2r2pa2c2th*a2pr2m2Mr) + d2hS_dth2_im[9]/r2pa2cth2 + (d2hS_dr2_im[9]*(a2 - 2*M*r + r2))/r2pa2cth2 - (d2hS_dt2_im[9]*(a4 + a2*a2pr2m2Mr*cos2th + a2*r*(2*M + 3*r) + 2*r4))/(a2p2r2pa2c2th*a2pr2m2Mr) - (2*dhS_dr_im[9]*(5*a4*M - a4*cos4th*(M - r) + 3*a4*r - 16*a2*M*r2 + 8*a2*r3 + 4*a2*cos2th*(a2*(M + r) + 2*r3) - 24*M*r4 + 8*r5))/a2p2r2pa2c2th3 + (4*dhS_dph_im[6]*(a4*M - a4*cos4th*(M - r) + 3*a4*r - 12*a2*M*r2 + 4*a2*cos2th*r*(a2 - M*r + 2*r2) + 8*a2*r3 - 16*M*r4 + 8*r5))/a2p2r2pa2c2th3 + (hS_im[7]*(35*a8 + 8*a8*cos6th + a8*cos8th - 78*a6*M*r - 36*a6*cos6th*M*r - 2*a6*cos8th*M*r + 155*a6*r2 + 20*a6*cos6th*r2 + a6*cos8th*r2 + 80*a4*M2*r2 + 40*a4*cos6th*M2*r2 + 88*a4*M*r3 - 44*a4*cos6th*M*r3 + 264*a4*r4 + 12*a4*cos6th*r4 - 96*a2*M2*r4 + 4*a2*cos4th*(7*a6 + 5*a4*r*(4*M + 5*r) + 4*(-2*M2 + M*r + 3*r2)*r4 + a2*(-20*M2*r2 + 26*M*r3 + 30*r4)) + 304*a2*M*r5 + 208*a2*r6 + 128*M*r7 + 4*cos2th*(14*a8 + a6*r*(9*M + 59*r) + a4*r2*(-10*M2 - 37*M*r + 93*r2) + 16*a2*(2*M2 - 5*M*r + 4*r2)*r4 + 16*(-2*M + r)*r7) + 64*r8))/(2.*a2p2r2pa2c2th5) + (2*a2pr2m2Mr*hS_im[5]*(-10*a6*M - a6*cos6th*M + 10*a6*r + a6*cos6th*r + 140*a4*M*r2 + 2*a4*cos4th*(a2*(5*M + 3*r) + 2*(M + 3*r)*r2) + 36*a4*r3 + 160*a2*M*r4 + a2*cos2th*(a4*(M + 15*r) - 48*a2*(3*M - r)*r2 + 16*(-10*M + 3*r)*r4) + 48*a2*r5 + 32*r7)*sin2th)/a2p2r2pa2c2th5 + (d2hS_dph2_im[9]*(a2 + a2*cos2th + 2*r*(-2*M + r)))/(a2p2r2pa2c2th*a2pr2m2Mr*sinth2) + (hS_im[9]*(126*a10 + a10*cos10th + 45*a10*cos6th + 10*a10*cos8th + 6*a8*M2 - a8*cos10th*M2 + 3*a8*cos6th*M2 + 2*a8*cos8th*M2 - 160*a8*M*r - 160*a8*cos6th*M*r - 32*a8*cos8th*M*r + 512*r10 + 700*a8*r2 + 160*a8*cos6th*r2 + 20*a8*cos8th*r2 - 120*a6*M2*r2 + 160*a6*cos6th*M2*r2 + 24*a6*cos8th*M2*r2 - 840*a6*M*r3 - 384*a6*cos6th*M*r3 - 24*a6*cos8th*M*r3 - 640*a4*M3*r3 - 320*a4*cos6th*M3*r3 + 1600*a6*r4 + 160*a6*cos6th*r4 - 96*a4*M2*r4 + 240*a4*cos6th*M2*r4 - 1856*a4*M*r5 - 160*a4*cos6th*M*r5 + 768*a2*M3*r5 + 8*a2*cos4th*(15*a8 - a6*(M2 + 40*M*r - 70*r2) + 4*a4*r2*(3*M2 - 37*M*r + 30*r2) + 4*a2*r3*(20*M3 + 11*M2*r - 38*M*r2 + 20*r3) + 16*M*(2*M2 + 2*M*r - r2)*r5) + 1920*a4*r6 + 768*a2*M2*r6 - 2432*a2*M*r7 + 1280*a2*r8 + 1024*M2*r8 + 2*cos2th*(105*a10 - a8*(M2 + 176*M*r - 560*r2) + 16*a6*r2*(-5*M2 - 52*M*r + 75*r2) + 8*a4*r3*(20*M3 - 31*M2*r - 182*M*r2 + 160*r3) - 128*a2*(4*M3 + 4*M2*r + 6*M*r2 - 5*r3)*r5 + 256*M*(-2*M + r)*r8) - 1536*M*r9))/(8.*a2p2r2pa2c2th5*a2pr2m2Mr*sinth2) - (16*a*dhS_dr_im[3]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (16*a*dhS_dt_im[6]*M*(a4 + a2*cos2th*(a2 - r2) - 3*a2*r2 - 6*r4)*sinth2)/a2p2r2pa2c2th3 + (2*a2pr2m2Mr*hS_im[4]*(-2*a6*M2 + a6*cos6th*M2 + 76*a6*M*r - 2*a6*cos6th*M*r + 10*a6*r2 + a6*cos6th*r2 - 40*a4*M2*r2 + 2*a4*cos4th*(a2*(M2 - 14*M*r + 3*r2) + 2*r2*(10*M2 - 8*M*r + 3*r2)) + 32*a4*M*r3 + 36*a4*r4 + 48*a2*M2*r4 - a2*cos2th*(a4*(M2 - 50*M*r - 15*r2) - 48*a2*(2*M + r)*r3 - 48*(-M2 + M*r + r2)*r4) - 144*a2*M*r5 + 48*a2*r6 - 96*M*r7 + 32*r8)*sinth2)/a2p2r2pa2c2th5 + (4*a*hS_im[3]*M*(2*a8*M - a8*cos6th*M + 30*a8*r + 3*a8*cos6th*r - 130*a6*M*r2 - 3*a6*cos6th*M*r2 + 70*a6*r3 + a6*cos6th*r3 - 80*a4*M2*r3 - 2*a4*cos4th*(a4*(M - 9*r) + a2*(31*M - 13*r)*r2 + 2*(-20*M2 + 14*M*r + r2)*r3) - 184*a4*M*r4 + 4*a4*r5 + 64*a2*M2*r5 + a2*cos2th*(a6*(M + 45*r) + a4*(-189*M + 95*r)*r2 - 272*a2*M*r4 - 16*(4*M2 + 3*M*r + 5*r2)*r5) + 176*a2*M*r6 - 112*a2*r7 + 256*M*r8 - 96*r9)*sinth2)/(a2p2r2pa2c2th5*a2pr2m2Mr) - (2*hS_im[0]*M*(-2*a10*M + a10*cos6th*M + 30*a10*r + 3*a10*cos6th*r - 32*r11 + 28*a8*M*r2 - 18*a8*cos6th*M*r2 + 120*a8*r3 + 6*a8*cos6th*r3 + 40*a6*M2*r3 + 20*a6*cos6th*M2*r3 + 46*a6*M*r4 - 15*a6*cos6th*M*r4 + 166*a6*r5 + 3*a6*cos6th*r5 - 48*a4*M2*r5 + 2*a4*cos4th*(a6*(M + 9*r) - 14*a4*(M - 2*r)*r2 + a2*(-20*M2 - 31*M*r + 29*r2)*r3 + 2*(-4*M2 - 2*M*r + 5*r2)*r5) - 152*a4*M*r6 + 60*a4*r7 - 208*a2*M*r8 + a2*cos2th*(-(a8*(M - 45*r)) + 2*a6*(9*M + 85*r)*r2 + a4*(-20*M2 + 31*M*r + 221*r2)*r3 + 16*a2*(4*M2 + 10*M*r + 7*r2)*r5 + 16*(13*M + r)*r8) - 48*a2*r9)*sinth2)/(a2p2r2pa2c2th5*a2pr2m2Mr) - (64*a3*costh*dhS_dth_im[3]*M*r*sinth3)/a2p2r2pa2c2th3 + (64*a3*costh*dhS_dt_im[8]*M*r*sinth3)/a2p2r2pa2c2th3 + (4*dhS_dph_im[8]*(3*a4 + a4*cos4th + 8*a2*M*r + 4*a2*cos2th*(a2 + 2*r*(-M + r)) + 8*a2*r2 + 8*r4))/(a2p2r2pa2c2th3*tanth) - (dhS_dth_im[9]*(9*a4 + 3*a4*cos4th + 32*a2*M*r + 24*a2*r2 + 4*a2*cos2th*(3*a2 - 8*M*r + 6*r2) + 24*r4))/(a2p2r2pa2c2th3*tanth); } /* Initialize some constants. */ void effsource_init(double mass, double spin) { M = mass; a = spin; } /* Initialize coefficients of pows of dr, dtheta and Q=sin(dphi/2), R=sin(dphi). */ void effsource_set_particle(struct coordinate * x, double E, double L, double ur) { xp = *x; double r0 = xp.r; double E_2 = E*E; double E_3 = E_2*E; double E_4 = E_2*E_2; double L_2 = L*L; double L_3 = L_2*L; double L_4 = L_2*L_2; double L_6 = L_4*L_2; double L_8 = L_4*L_4; double L_10 = L_6*L_4; double r0_2 = r0*r0; double r0_3 = r0_2*r0; double r0_4 = r0_2*r0_2; double r0_5 = r0_3*r0_2; double r0_6 = r0_3*r0_3; double r0_7 = r0_4*r0_3; double r0_8 = r0_4*r0_4; double r0_9 = r0_5*r0_4; double r0_10 = r0_5*r0_5; double r0_11 = r0_6*r0_5; double M_2 = M*M; double M_3 = M_2*M; double M_4 = M_2*M_2; double M_5 = M_3*M_2; double M_6 = M_3*M_3; double M_7 = M_4*M_3; double a_2 = a*a; double a_3 = a_2*a; double a_4 = a_2*a_2; double a_5 = a_3*a_2; double a_6 = a_3*a_3; double a_7 = a_4*a_3; double a_8 = a_4*a_4; double a_9 = a_5*a_4; double a_10 = a_5*a_5; double a_11 = a_6*a_5; double a_12 = a_6*a_6; double a_13 = a_7*a_6; double a_14 = a_7*a_7; double r0_2M = r0 - 2*M; double r0_2M_2 = r0_2M*r0_2M; double r0_p_2M = 2*M + r0; double r0_p_2M_2 = r0_p_2M*r0_p_2M; double r0_p_2M_3 = r0_p_2M_2*r0_p_2M; double r0_p_2M_4 = r0_p_2M_2*r0_p_2M_2; double expr1 = a_2*(2*M + r0) + r0*(L_2 + r0_2); double expr1_2 = expr1*expr1; double expr1_3 = expr1_2*expr1; double expr1_4 = expr1_2*expr1_2; double expr2 = a_2 + r0*(-2*M + r0); double expr2_2 = expr2*expr2; double expr2_3 = expr2_2*expr2; double expr2_4 = expr2_2*expr2_2; double expr2_5 = expr2_3*expr2_2; double expr2_6 = expr2_3*expr2_3; double expr2_7 = expr2_4*expr2_3; double expr3 = a_3 + 3*a*r0_2; double expr3_2 = expr3*expr3; double expr4 = L_2 + r0_2 + (a_2*(2*M + r0))/r0; double expr4_2 = expr4*expr4; double expr4_3 = expr4_2*expr4; double expr5 = a_2*M + (2*M - r0)*r0_2; double expr5_2 = expr5*expr5; double expr6 = r0_3 + a_2*(2*M + r0); double expr6_2 = expr6*expr6; double expr7 = 2*a*E*M + L*(-2*M + r0); double expr7_2 = expr7*expr7; double expr8 = -2*a*L*M + E*r0_3 + a_2*E*(2*M + r0); double expr8_2 = expr8*expr8; /* A_{t,t} */ { A00060 = 256*E_2*expr4_3; A00080 = (-128*expr1_2*(-(a_8*E_2*M_2*(48*M + 25*r0)) + 4*a_7*E*L*M_2*(12*M + (6 + E_2)*r0) + r0_2*(24*L_6*M*r0_2M_2 + 2*E_2*M*r0_7*(-2*M + r0 + 2*E_2*r0) + 24*L_4*M*(2*M - r0)*r0_2*(4*M - (2 + E_2)*r0) + L_2*(2*M - r0)*r0_4*(48*M_2 - 8*(3 + 4*E_2)*M*r0 + 3*E_2*r0_2)) + 4*a*E*L*M*r0_2*(12*L_4*M*(-2*M + r0) - 6*L_2*r0_2*(16*M_2 - 2*(5 + E_2)*M*r0 + r0_2) + r0_4*(-72*M_2 + 2*(24 + 7*E_2)*M*r0 - 3*(2 + E_2)*r0_2)) + 4*a_5*E*L*M*(-192*M_4 + 8*(-15 + 4*E_2)*M_3*r0 + 6*(12 + 5*E_2)*M_2*r0_2 - (6 + E_2)*r0_4 + 6*M*r0*(L_2 + 2*(3 + E_2)*r0_2)) + 4*a_3*E*L*M*r0*(-6*L_2*(24*M_3 + (2 - 4*E_2)*M_2*r0 - (9 + 2*E_2)*M*r0_2 + r0_3) + r0_2*(-240*M_3 + 2*(6 + 13*E_2)*M_2*r0 + 3*(26 + 7*E_2)*M*r0_2 - 4*(3 + E_2)*r0_3)) + 2*a_6*E_2*M*(192*M_4 + 16*(15 + E_2)*M_3*r0 + 2*(-11 + 12*E_2)*M_2*r0_2 + (1 + 2*E_2)*r0_4 + M*(-14*L_2*r0 + (-61 + 12*E_2)*r0_3)) + a_2*r0*(24*L_4*M*(4*M - (2 + E_2)*r0)*(4*M_2 - r0_2) + 2*E_2*M*r0_5*(124*M_2 + 6*(-7 + 2*E_2)*M*r0 + 3*(1 + 2*E_2)*r0_2) + L_2*r0_2*(384*M_4 + 16*(-12 + 5*E_2)*M_3*r0 - 96*(1 + E_2)*M_2*r0_2 + 16*(3 + 4*E_2)*M*r0_3 - 3*E_2*r0_4)) + a_4*M*(E_2*r0_3*(668*M_3 + 4*(61 + 12*E_2)*M_2*r0 + 3*(-59 + 16*E_2)*M*r0_2 + 6*(1 + 2*E_2)*r0_3) + 4*L_2*(96*M_4 + 8*E_2*M_3*r0 + 6*(-8 + 3*E_2)*M_2*r0_2 - 15*E_2*M*r0_3 + 2*(3 + 4*E_2)*r0_4))))/(3.*r0_9*(a_2 + r0*(-2*M + r0))); A00240 = 192*E_2*expr1_2; A00260 = (-64*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-2*a_7*E*L*M*(12*(-7 + 2*E_2)*M_2 + 2*(-33 + 8*E_2)*M*r0 + 3*(-4 + E_2)*r0_2) + a_8*E_2*M*(24*(-7 + E_2)*M_2 + (-139 + 24*E_2)*M*r0 + 3*(-9 + 2*E_2)*r0_2) + a_6*E_2*(768*M_5 + 16*(69 + E_2)*M_4*r0 + 12*(7 + 6*E_2)*M_3*r0_2 + 6*(-57 + 14*E_2)*M_2*r0_3 + (-89 + 26*E_2)*M*r0_4 - 3*r0_5 + L_2*M*(24*M_2 + 4*(-31 + 3*E_2)*M*r0 + 3*(-17 + 2*E_2)*r0_2)) + 2*a*E*L*M*r0_2*(12*L_4*(-10*M_2 + 3*M*r0 + r0_2) + L_2*r0_2*(-384*M_2 + 2*(90 + 23*E_2)*M*r0 + 3*(2 - 3*E_2)*r0_2) + r0_4*(-264*M_2 + 2*(72 + 25*E_2)*M*r0 - 3*(2 + 5*E_2)*r0_2)) - 2*a_5*E*L*M*(768*M_4 - 8*(-69 + 16*E_2)*M_3*r0 - 8*(27 + 11*E_2)*M_2*r0_2 + 2*M*r0*((-33 + 6*E_2)*L_2 + (-102 + 7*E_2)*r0_2) + r0_2*(3*(-8 + E_2)*L_2 + (-18 + 17*E_2)*r0_2)) + r0_2*(48*L_6*M*r0_2M_2 + E_2*r0_7*(-8*M_2 + 2*(5 + 4*E_2)*M*r0 - 3*r0_2) + 2*L_4*(2*M - r0)*r0_2*(96*M_2 - 2*(24 + 11*E_2)*M*r0 + 3*E_2*r0_2) + 2*L_2*r0_4*(96*M_3 - 6*(16 + 9*E_2)*M_2*r0 + (24 + 39*E_2 + 2*E_4)*M*r0_2 - 6*E_2*r0_3)) + 2*a_3*E*L*M*r0*(12*L_4*r0 + r0_2*(-912*M_3 + 4*(-15 + 32*E_2)*M_2*r0 + 2*(141 + 22*E_2)*M*r0_2 - 29*E_2*r0_3) + L_2*(-624*M_3 + 4*(-33 + 20*E_2)*M_2*r0 + 2*(105 + 11*E_2)*M*r0_2 + 6*(5 - 2*E_2)*r0_3)) + a_2*r0*(E_2*r0_5*(412*M_3 + 12*(-4 + 3*E_2)*M_2*r0 + 15*(-1 + 2*E_2)*M*r0_2 - 9*r0_3) + L_2*r0_2*(768*M_4 + 4*(-96 + 41*E_2)*M_3*r0 + 4*(-48 + 3*E_2 + E_4)*M_2*r0_2 + (96 + 57*E_2 + 14*E_4)*M*r0_3 - 21*E_2*r0_4) + 2*L_4*(384*M_4 - 4*(48 + 13*E_2)*M_3*r0 + 6*(-16 + 5*E_2)*M_2*r0_2 + 2*(24 + 5*E_2)*M*r0_3 - 3*E_2*r0_4)) + a_4*(12*E_2*L_4*M*(M - 2*r0)*r0 + E_2*r0_3*(1204*M_4 + 8*(85 + 6*E_2)*M_3*r0 + 3*(-81 + 32*E_2)*M_2*r0_2 + 3*(-29 + 14*E_2)*M*r0_3 - 9*r0_4) + L_2*(768*M_5 + 208*E_2*M_4*r0 - 8*(48 - 50*E_2 + E_4)*M_3*r0_2 + 8*E_2*(-5 + 2*E_2)*M_2*r0_3 + 2*(24 - 33*E_2 + 8*E_4)*M*r0_4 - 9*E_2*r0_5))))/(3.*r0_6*(a_2 + r0*(-2*M + r0))); A00420 = 48*E_2*r0_3*(a_2*(2*M + r0) + r0*(L_2 + r0_2)); A00440 = (8*((16*a_2*E_2*L_4*M_3)/(r0*(a_2 + r0*(-2*M + r0))) - (16*a*E_3*L_3*M_2*(r0_3 + a_2*(2*M + r0)))/(r0*(a_2 + r0*(-2*M + r0))) + (4*E_4*L_2*M*expr6_2)/(r0*(a_2 + r0*(-2*M + r0))) + E_2*(-3*a_2 + r0*(-2*M + r0))*expr4_2 + (72*E_2*M_2*(a_4 + 3*a_2*r0_2)*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/r0_3 - (72*a*E*L*M*(a_2*M + (2*M - r0)*r0_2)*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/r0_3 - (48*a_2*E_2*L_2*M_3*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/(r0_2*(a_2 + r0*(-2*M + r0))) + (144*a*E*L_2*M_2*(2*a*E*M + L*(-2*M + r0))*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/(r0_2*(a_2 + r0*(-2*M + r0))) + (48*a*E_3*L*M_2*(r0_3 + a_2*(2*M + r0))*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/(r0_2*(a_2 + r0*(-2*M + r0))) - (72*E_2*L*M*(2*a*E*M + L*(-2*M + r0))*(r0_3 + a_2*(2*M + r0))*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/(r0_2*(a_2 + r0*(-2*M + r0))) - (12*E_4*M*expr6_2*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/(r0_2*(a_2 + r0*(-2*M + r0))) + (144*a_2*E_2*M*expr1_2)/r0_3 - (144*a*E*L*M*expr1_2)/r0_3 - (144*M*expr7_2*expr1_2)/(r0_3*(a_2 + r0*(-2*M + r0))) - (8*E_2*L_2*M*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/(r0_2*(a_2 + r0*(-2*M + r0))) + (12*E_2*M*expr1_2*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/(r0_3*(a_2 + r0*(-2*M + r0))) + (E_2*(a_6*M_2 - 4*a_5*E*L*M_2 + 12*a*E*L*M*r0_5 + 4*a_3*E*L*M*r0_2*(-3*M + r0) + 4*a_2*M*(M - r0)*r0_2*(2*L_2 + r0_2) + r0_5*(-2*M*r0_2 + L_2*(-8*M + 3*r0)) + a_4*M*(4*L_2*M + r0*(-2*M_2 + M*r0 - 2*r0_2))))/r0_2 + (4*E_2*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(3*a_4*M - 6*a_3*E*L*M + 6*a*E*L*M*r0_2 - (2*M - 3*r0)*r0_2*(2*L_2 + r0_2) + a_2*(6*L_2*M + r0*(2*M_2 + 7*M*r0 + 3*r0_2))))/r0_2))/3.; A00600 = 4*E_2*r0_6; A00620 = (-4*(-6*a_5*E*L*M*(2*(-13 + 6*E_2)*M + (-12 + 5*E_2)*r0) + 3*a_6*E_2*(4*(-13 + 3*E_2)*M_2 + (-23 + 6*E_2)*M*r0 + r0_2) + 2*a*E*L*M*r0*(r0_2*(-216*M_2 + 2*(24 + 19*E_2)*M*r0 + 3*(10 - 7*E_2)*r0_2) - 4*L_2*(42*M_2 - (3 + 4*E_2)*M*r0 + 3*(-3 + E_2)*r0_2)) - 4*a_3*E*L*M*(192*M_3 + (78 - 32*E_2)*M_2*r0 + (-57 + 5*E_2)*M*r0_2 + 3*r0*(2*(-3 + E_2)*L_2 + (-11 + 6*E_2)*r0_2)) + r0*(8*L_4*M*(2*M - r0)*(12*M - (6 + E_2)*r0) + 4*E_2*r0_5*(-2*M_2 + (3 + 2*E_2)*M*r0 - r0_2) + L_2*r0_2*(192*M_3 - 12*(16 + 5*E_2)*M_2*r0 + 4*(12 + 11*E_2 + E_4)*M*r0_2 - 7*E_2*r0_3)) + a_4*E_2*(3*L_2*(12*M_2 + 4*(-5 + E_2)*M*r0 + r0_2) + 2*(192*M_4 - 4*(-63 + 5*E_2)*M_3*r0 + 2*(-13 + 8*E_2)*M_2*r0_2 + 11*(-7 + 2*E_2)*M*r0_3 + r0_4)) + a_2*(12*E_2*L_4*M*r0 + E_2*r0_3*(260*M_3 - 4*(-31 + E_2)*M_2*r0 + (-73 + 34*E_2)*M*r0_2 - 5*r0_3) + 4*L_2*(96*M_4 + 2*(-24 + 7*E_2)*M_3*r0 + (-24 + 39*E_2 - 4*E_4)*M_2*r0_2 + (12 - 9*E_2 + 4*E_4)*M*r0_3 - E_2*r0_4))))/(3.*(a_2 + r0*(-2*M + r0))); A00800 = (r0_3*(48*a_2*E_2*M - 48*a*E*L*M + E_2*r0*(-3*a_2 + r0*(-2*M + r0)) - (24*M*expr7_2)/(a_2 + r0*(-2*M + r0)) + (4*E_2*M*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/(a_2 + r0*(-2*M + r0))))/6.; A01060 = (-128*E*expr1_2*(-(a_4*E*M*(8*M + 5*r0)) + 2*a_3*L*M*(4*M + (2 + E_2)*r0) + 2*a*L*M*r0*(2*L_2 + (2 + 3*E_2)*r0_2) + E*r0_3*(r0_2*(-6*M + r0) + L_2*(-8*M + 2*r0)) + a_2*E*r0*(-6*L_2*M + r0*(-6*M_2 - 9*M*r0 + r0_2))))/(r0_5*(a_2 + r0*(-2*M + r0))); A01080 = (-64*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(a_12*E_2*M_2*(-192*M_3 + 8*(41 - 10*E_2)*M_2*r0 + (509 - 88*E_2)*M*r0_2 + 6*(25 - 4*E_2)*r0_3) - 2*a_11*E*L*M_2*(-192*M_3 + 4*(17 + 36*E_2)*M_2*r0 + (226 + 183*E_2)*M*r0_2 + 12*(6 + 5*E_2)*r0_3) + 2*a_9*E*L*M*r0*(-768*(-5 + 4*E_2)*M_5 + 16*(359 - 236*E_2 + 12*E_4)*M_4*r0 + 4*(372 - 371*E_2 + 72*E_4)*M_3*r0_2 + (-1214 - 647*E_2 + 144*E_4)*M_2*r0_3 + 2*(-206 - 165*E_2 + 12*E_4)*M*r0_4 - 12*(-4 + E_2)*r0_5 - 2*L_2*M*(16*M_2 + (217 + 96*E_2)*M*r0 + 6*(18 + 11*E_2)*r0_2)) + 2*a*E*L*M*r0_4*(-48*L_8*r0_2M_2 - 2*(2*M - r0)*r0_7*(312*M_2 + (-170 + 37*E_2)*M*r0 + 6*(3 - 2*E_2)*r0_2) + 12*L_6*(2*M - r0)*r0*(4*M_2 - 2*(8 + 7*E_2)*M*r0 + (8 + E_2)*r0_2) + L_2*r0_5*(-2592*M_3 - 8*(-353 + 29*E_2)*M_2*r0 + 2*(-472 + 67*E_2 + 30*E_4)*M*r0_2 + 3*(30 + E_2)*r0_3) - 2*L_4*r0_3*(624*M_3 + 4*(-160 + 69*E_2)*M_2*r0 - 2*(-85 + 90*E_2 + 6*E_4)*M*r0_2 + 3*(-1 + 5*E_2)*r0_3)) + r0_5*(24*L_8*M*r0_2M_2*(6*M + (-1 + 4*E_2)*r0) - 2*E_2*M*r0_9*(16*M_2 + 2*(-6 + E_2)*M*r0 + (2 - 5*E_2)*r0_2) + 24*L_6*M*(2*M - r0)*r0_2*(40*M_2 + 4*(-7 + 3*E_2)*M*r0 - (-4 + 8*E_2 + E_4)*r0_2) + 2*L_4*(2*M - r0)*r0_4*(528*M_3 - 8*(48 + E_2)*M_2*r0 - 10*(-6 + 4*E_2 + 3*E_4)*M*r0_2 - 3*E_2*r0_3) + L_2*r0_6*(768*M_4 - 8*(120 + 23*E_2)*M_3*r0 + 4*(96 + 15*E_2 - 13*E_4)*M_2*r0_2 + 2*(-24 + 11*E_2 + 17*E_4)*M*r0_3 - 3*E_2*r0_4)) + 4*a_3*E*L*M*r0_3*(-6*L_6*(32*M_3 + 12*(-5 + 3*E_2)*M_2*r0 + 2*(1 - 7*E_2)*M*r0_2 + (8 + E_2)*r0_3) + 2*r0_5*(-1704*M_4 + 12*(57 - 47*E_2)*M_3*r0 + (702 + 151*E_2)*M_2*r0_2 + 2*(-188 + 19*E_2 + 3*E_4)*M*r0_3 + (39 - 19*E_2)*r0_4) + L_4*r0*(-1104*M_4 - 8*(-23 + 63*E_2)*M_3*r0 + 24*(62 - 11*E_2 + E_4)*M_2*r0_2 + 8*(-74 + 30*E_2 + 3*E_4)*M*r0_3 + 3*(1 - 10*E_2)*r0_4) + L_2*r0_3*(-4704*M_4 - 4*(-478 + 383*E_2)*M_3*r0 + 2*(1272 + 157*E_2 + 60*E_4)*M_2*r0_2 + 3*(-458 + 27*E_2 + 30*E_4)*M*r0_3 - 23*(-6 + E_2)*r0_4)) + a_2*r0_3*(-24*L_8*M*(2*M - r0)*(8*M_2 + (8 - 22*E_2)*M*r0 + (-3 + 4*E_2)*r0_2) + 2*E_2*M*r0_8*(1260*M_3 + 4*(-246 + 101*E_2)*M_2*r0 + (203 - 46*E_2)*M*r0_2 + (-11 + 23*E_2)*r0_3) + 24*L_6*M*r0*(184*M_4 - 4*(41 + 2*E_2)*M_3*r0 + 2*(-29 + 29*E_2 + 4*E_4)*M_2*r0_2 + (73 - 57*E_2 - 4*E_4)*M*r0_3 + (-13 + 14*E_2 + 2*E_4)*r0_4) + L_2*r0_5*(5184*M_5 + 16*(-246 + 349*E_2)*M_4*r0 + 12*(-84 - 499*E_2 + 74*E_4)*M_3*r0_2 - 24*(-53 - 69*E_2 + E_4)*M_2*r0_3 + 9*(-24 - E_2 + 16*E_4)*M*r0_4 - 6*E_2*r0_5) + 2*L_4*r0_3*(4800*M_5 + 8*(-468 + 163*E_2)*M_4*r0 + 12*(-92 - 147*E_2 + 10*E_4)*M_3*r0_2 + 2*(672 + 179*E_2 - 60*E_4)*M_2*r0_3 + (-228 + 83*E_2 + 90*E_4)*M*r0_4 + 3*E_2*r0_5)) + 2*a_5*E*L*M*r0_2*(-72*L_6*M*r0 + 2*L_4*(256*M_4 - 24*(-63 + 41*E_2)*M_3*r0 + 24*(18 - 4*E_2 + E_4)*M_2*r0_2 + 4*(-134 + 6*E_2 + 3*E_4)*M*r0_3 - 15*E_2*r0_4) + L_2*r0*(-9024*M_5 - 8*(197 + 344*E_2)*M_4*r0 + 24*(491 - 189*E_2 + 10*E_4)*M_3*r0_2 + 2*(679 + 360*E_2 + 240*E_4)*M_2*r0_3 + 4*(-714 - 91*E_2 + 45*E_4)*M*r0_4 + (282 - 79*E_2)*r0_5) + r0_3*(-12864*M_5 - 60*(46 + 71*E_2)*M_4*r0 - 92*(-114 + 37*E_2)*M_3*r0_2 + (798 + 1219*E_2 + 144*E_4)*M_2*r0_3 + 24*(-85 - 10*E_2 + 3*E_4)*M*r0_4 + 4*(63 - 23*E_2)*r0_5)) - a_10*M*(2*L_2*M*(96*M_3 + 24*(4 - 13*E_2)*M_2*r0 + (24 - 709*E_2 + 32*E_4)*M*r0_2 + 3*E_2*(-97 + 4*E_2)*r0_3) + E_2*r0*(-1280*(-3 + 2*E_2)*M_5 + 32*(269 - 125*E_2)*M_4*r0 + 2*(2021 - 888*E_2)*M_3*r0_2 + (-1429 + 88*E_2)*M_2*r0_3 + 5*(-183 + 28*E_2)*M*r0_4 - 6*(-1 + E_2)*r0_5)) + a_4*r0_2*(E_2*M*r0_6*(10848*M_4 + 4*(-149 + 984*E_2)*M_3*r0 + 4*(-1475 + 602*E_2)*M_2*r0_2 - 3*(-509 + 96*E_2)*M*r0_3 + 12*(-4 + 7*E_2)*r0_4) - 24*L_6*M*(64*M_4 - 4*(-26 + 43*E_2)*M_3*r0 - 2*(25 - 28*E_2 + 2*E_4)*M_2*r0_2 + (-27 + 21*E_2 + 2*E_4)*M*r0_3 - (-9 + 6*E_2 + E_4)*r0_4) + 2*L_4*M*r0*(5376*M_5 + 16*(-132 + 17*E_2)*M_4*r0 + 8*(-648 + 265*E_2 + 60*E_4)*M_3*r0_2 + 12*(132 - 267*E_2 + 10*E_4)*M_2*r0_3 + 4*(246 + 257*E_2 - 15*E_4)*M*r0_4 + (-276 + 43*E_2 + 90*E_4)*r0_5) + L_2*r0_3*(11520*M_6 + 8*(-384 + 1703*E_2)*M_5*r0 + 16*(-516 - 89*E_2 + 333*E_4)*M_4*r0_2 + 2*(1080 - 5793*E_2 + 1180*E_4)*M_3*r0_3 + 2*(684 + 2227*E_2 + 36*E_4)*M_2*r0_4 + 6*(-60 - 21*E_2 + 38*E_4)*M*r0_5 - 3*E_2*r0_6)) + 2*a_7*E*L*M*r0*(-8*L_4*M*r0*(26*M + 9*(3 + E_2)*r0) + 2*L_2*(512*M_5 + 16*(199 - 126*E_2)*M_4*r0 + 4*(629 - 332*E_2 + 30*E_4)*M_3*r0_2 + 2*(-329 - 83*E_2 + 60*E_4)*M_2*r0_3 + 2*(-317 - 120*E_2 + 15*E_4)*M*r0_4 + 3*(16 - 5*E_2)*r0_5) - r0*(8448*M_6 + 16*(413 + 164*E_2)*M_5*r0 + 4*(-2410 + 1699*E_2)*M_4*r0_2 - 4*(1991 - 658*E_2 + 72*E_4)*M_3*r0_3 + (1694 - 35*E_2 - 288*E_4)*M_2*r0_4 + 4*(322 + 135*E_2 - 18*E_4)*M*r0_5 + 4*(-45 + 13*E_2)*r0_6)) + a_8*M*r0*(-48*L_4*M*(4*M_2 + (2 - 19*E_2)*M*r0 - 15*E_2*r0_2) + 2*L_2*(384*(-5 + 4*E_2)*M_5 + 16*(-90 - 95*E_2 + 76*E_4)*M_4*r0 + 4*(108 - 1013*E_2 + 290*E_4)*M_3*r0_2 + (456 + 537*E_2 + 116*E_4)*M_2*r0_3 + (-12 + 1291*E_2 - 10*E_4)*M*r0_4 + 3*(-12 - 9*E_2 + 7*E_4)*r0_5) + E_2*r0*(8448*M_6 + 32*(353 + 136*E_2)*M_5*r0 + 4*(-2293 + 2744*E_2)*M_4*r0_2 + 12*(-1257 + 644*E_2)*M_3*r0_3 + 21*(-37 + 48*E_2)*M_2*r0_4 + (2167 - 324*E_2)*M*r0_5 + 2*(-14 + 17*E_2)*r0_6)) + a_6*M*r0*(-48*L_6*M*r0*(M - 6*E_2*r0) + E_2*r0_4*(16232*M_5 + 4*(2617 + 1696*E_2)*M_4*r0 + 2*(-6891 + 4840*E_2)*M_3*r0_2 + (-5661 + 2608*E_2)*M_2*r0_3 + 3*(849 - 136*E_2)*M*r0_4 + 4*(-13 + 19*E_2)*r0_5) - 4*L_4*(384*M_5 - 96*(-16 + 15*E_2)*M_4*r0 - 4*(-48 - 71*E_2 + 30*E_4)*M_3*r0_2 + 24*(-24 + 29*E_2)*M_2*r0_3 - 4*(18 + 119*E_2)*M*r0_4 + 3*(18 - 5*E_4)*r0_5) + L_2*r0*(8448*M_6 + 128*(15 + 64*E_2)*M_5*r0 + 8*(-1344 + 1249*E_2 + 620*E_4)*M_4*r0_2 + 8*(-288 - 1841*E_2 + 932*E_4)*M_3*r0_3 + 2*(1584 - 3129*E_2 + 820*E_4)*M_2*r0_4 + 2*(228 + 2435*E_2 + 24*E_4)*M*r0_5 + (-264 - 149*E_2 + 160*E_4)*r0_6))))/(3.*r0_11*expr2_2); A01240 = (-32*E*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(4*a_3*L*M*(6*M + (3 + E_2)*r0) + a_4*E*(-24*M_2 - 12*M*r0 + r0_2) + 12*a*L*M*r0*(L_2 + (1 + E_2)*r0_2) + E*r0_3*(3*r0_2*(-6*M + r0) + L_2*(-22*M + 5*r0)) + a_2*E*r0*(L_2*(-16*M + r0) + 2*r0*(-12*M_2 - 13*M*r0 + 2*r0_2))))/(r0_2*(a_2 + r0*(-2*M + r0))); A01260 = (-16*(-2*a_11*E*L*M*(192*(-7 + 3*E_2)*M_4 + 8*(17 + 132*E_2 + 18*E_4)*M_3*r0 + (1748 + 651*E_2 + 144*E_4)*M_2*r0_2 + 6*(160 + 23*E_2 + 6*E_4)*M*r0_3 + 144*r0_4) + a_12*E_2*M*(192*(-7 + 2*E_2)*M_4 + 80*(25 + 4*E_2)*M_3*r0 + (4279 - 56*E_2)*M_2*r0_2 + 3*(695 - 32*E_2)*M*r0_3 - 18*(-17 + E_2)*r0_4) + 2*a*E*L*M*r0_4*(-168*L_8*r0_2M_2 - 2*L_6*(2*M - r0)*r0*(144*M_2 + 2*(202 + 147*E_2)*M*r0 - 3*(76 + 7*E_2)*r0_2) + 2*L_4*r0_3*(-3024*M_3 - 16*(-125 + 64*E_2)*M_2*r0 + 2*(52 + 265*E_2 + 21*E_4)*M*r0_2 - 3*(58 + E_2)*r0_3) + L_2*r0_5*(-9984*M_3 - 64*(-137 + 21*E_2)*M_2*r0 + 2*(-908 + 321*E_2 + 60*E_4)*M*r0_2 + 3*(-12 + 5*E_2)*r0_3) - 2*r0_7*(2256*M_3 + 2*(-1028 + 151*E_2)*M_2*r0 + (488 - 205*E_2)*M*r0_2 + 3*(-4 + 11*E_2)*r0_3)) + r0_5*(24*L_8*M*r0_2M_2*(26*M + (-5 + 14*E_2)*r0) + 2*E_2*r0_9*(-64*M_3 + (84 - 8*E_2)*M_2*r0 + 4*(-8 + 5*E_2)*M*r0_2 + 3*r0_3) + 4*L_6*(2*M - r0)*r0_2*(1008*M_3 + 4*(-180 + 67*E_2)*M_2*r0 + (108 - 154*E_2 - 21*E_4)*M*r0_2 - 6*E_2*r0_3) + 2*L_2*r0_6*(1536*M_4 - 4*(480 + 61*E_2)*M_3*r0 + 12*(64 + 13*E_2 - 7*E_4)*M_2*r0_2 + (-96 - 29*E_2 + 66*E_4)*M*r0_3 + 6*E_2*r0_4) + L_4*r0_4*(8640*M_4 + 16*(-666 + 23*E_2)*M_3*r0 - 4*(-1044 + 177*E_2 + 86*E_4)*M_2*r0_2 + 4*(-126 + 46*E_2 + 47*E_4)*M*r0_3 + 39*E_2*r0_4)) + 4*a_3*E*L*M*r0_3*(L_6*(-896*M_3 + 12*(104 - 63*E_2)*M_2*r0 + 2*(160 + 147*E_2)*M*r0_2 - 3*(100 + 7*E_2)*r0_3) + r0_5*(-12672*M_4 - 168*(-23 + 20*E_2)*M_3*r0 + 4*(1311 + 68*E_2 + 27*E_4)*M_2*r0_2 + (-1880 + 395*E_2 - 18*E_4)*M*r0_3 - 103*E_2*r0_4) - 2*L_4*r0*(2784*M_4 + 4*(61 + 280*E_2)*M_3*r0 - 2*(1461 - 413*E_2 + 21*E_4)*M_2*r0_2 - 2*(-158 + 227*E_2 + 21*E_4)*M*r0_3 + 3*(93 + 7*E_2)*r0_4) - 2*L_2*r0_3*(9312*M_4 + 18*(-128 + 135*E_2)*M_3*r0 - 6*(822 - 66*E_2 + 29*E_4)*M_2*r0_2 + (1458 - 355*E_2 - 75*E_4)*M*r0_3 + (120 + 11*E_2)*r0_4)) + a_2*r0_3*(-24*L_8*M*(2*M - r0)*(24*M_2 + 7*(4 - 11*E_2)*M*r0 + (-11 + 14*E_2)*r0_2) + 2*E_2*r0_8*(4068*M_4 + 4*(-599 + 320*E_2)*M_3*r0 + (25 - 62*E_2)*M_2*r0_2 + (50 + 79*E_2)*M*r0_3 + 12*r0_4) + 2*L_6*r0*(8928*M_5 + 8*(-954 + 133*E_2)*M_4*r0 + 12*(-222 + 261*E_2 + 28*E_4)*M_3*r0_2 - 6*(-558 + 571*E_2 + 28*E_4)*M_2*r0_3 + 3*(-204 + 251*E_2 + 28*E_4)*M*r0_4 + 12*E_2*r0_5) + 2*L_4*r0_3*(19008*M_5 + 16*(-918 + 359*E_2)*M_4*r0 + 4*(-1044 - 635*E_2 + 143*E_4)*M_3*r0_2 + 2*(2592 - 1001*E_2 + 14*E_4)*M_2*r0_3 + (-900 + 814*E_2 + 265*E_4)*M*r0_4 + 42*E_2*r0_5) + L_2*r0_5*(20160*M_5 + 96*(-159 + 190*E_2)*M_4*r0 + 4*(-948 - 3251*E_2 + 780*E_4)*M_3*r0_2 + 4*(1218 + 57*E_2 + 116*E_4)*M_2*r0_3 + (-840 + 747*E_2 + 464*E_4)*M*r0_4 + 51*E_2*r0_5)) + a_10*M*(L_2*(192*(-7 + 6*E_2)*M_4 + 96*(-18 + 16*E_2 + 13*E_4)*M_3*r0 + 2*(-360 + 3083*E_2 + 416*E_4)*M_2*r0_2 + 3*(-32 + 1571*E_2 + 12*E_4)*M*r0_3 + 18*E_2*(51 - 2*E_2)*r0_4) + E_2*r0*(4352*(-3 + 2*E_2)*M_5 + 32*(-1134 + 439*E_2)*M_4*r0 + 2*(-11145 + 3832*E_2)*M_3*r0_2 + (6651 + 896*E_2)*M_2*r0_3 + (8285 - 412*E_2)*M*r0_4 + 2*(766 - 37*E_2)*r0_5)) - 2*a_9*E*L*M*(2*L_2*(96*M_4 + 8*(-62 + 63*E_2)*M_3*r0 + 2*(421 + 276*E_2 + 18*E_4)*M_2*r0_2 + 3*(332 + 55*E_2 + 6*E_4)*M*r0_3 + 216*r0_4) + r0*(768*(-17 + 14*E_2)*M_5 - 32*(714 - 445*E_2 + 27*E_4)*M_4*r0 - 4*(2520 - 1757*E_2 + 144*E_4)*M_3*r0_2 + (3844 + 2423*E_2 + 216*E_4)*M_2*r0_3 + 2*(1712 + 351*E_2 + 72*E_4)*M*r0_4 + 36*(14 + E_2)*r0_5)) + 2*a_5*E*L*M*r0_2*(-24*L_6*(2*M_2 + 3*M*r0 + 6*r0_2) + 2*L_4*(192*M_4 - 8*(-598 + 471*E_2)*M_3*r0 + 4*(783 - 263*E_2 + 21*E_4)*M_2*r0_2 + 2*(-638 + 105*E_2 + 21*E_4)*M*r0_3 - 3*(200 + 13*E_2)*r0_4) - r0_3*(48384*M_5 + 12*(1148 + 1219*E_2)*M_4*r0 - 4*(9036 - 3125*E_2 + 216*E_4)*M_3*r0_2 - (7716 + 1571*E_2 + 504*E_4)*M_2*r0_3 + 12*(508 - 3*E_2 + 12*E_4)*M*r0_4 + 2*(144 + 125*E_2)*r0_5) - L_2*r0*(35712*M_5 + 48*(239 + 200*E_2)*M_4*r0 - 8*(5006 - 2319*E_2 + 114*E_4)*M_3*r0_2 - 4*(3319 - 528*E_2 + 306*E_4)*M_2*r0_3 - 6*(-1328 + 39*E_2 + 34*E_4)*M*r0_4 + (1284 + 131*E_2)*r0_5)) + a_4*r0_2*(-96*L_8*M_2*r0 - 4*L_6*M*(1152*M_4 - 24*(-90 + 167*E_2)*M_3*r0 - 4*(261 - 212*E_2 + 21*E_4)*M_2*r0_2 + 2*(-243 + 506*E_2 + 21*E_4)*M*r0_3 + (198 - 299*E_2 - 21*E_4)*r0_4) + 2*E_2*r0_6*(19248*M_5 + 24*(61 + 277*E_2)*M_4*r0 + 4*(-2703 + 1021*E_2)*M_3*r0_2 + 4*(163 - 42*E_2)*M_2*r0_3 + (649 + 107*E_2)*M*r0_4 + 18*r0_5) + L_4*r0*(41472*M_6 + 96*(-156 + 85*E_2)*M_5*r0 + 16*(-2376 + 1608*E_2 + 229*E_4)*M_4*r0_2 + 8*(1476 - 2762*E_2 + 441*E_4)*M_3*r0_3 + 4*(1692 - 772*E_2 + 255*E_4)*M_2*r0_4 + 2*(-1044 + 1742*E_2 + 239*E_4)*M*r0_5 + 45*E_2*r0_6) + L_2*r0_3*(43776*M_6 + 120*(-96 + 425*E_2)*M_5*r0 + 4*(-7632 + 2413*E_2 + 3552*E_4)*M_4*r0_2 + 2*(4104 - 20579*E_2 + 5644*E_4)*M_3*r0_3 + (4872 + 3235*E_2 + 2076*E_4)*M_2*r0_4 + 6*(-228 + 585*E_2 + 94*E_4)*M*r0_5 + 66*E_2*r0_6)) + 2*a_7*E*L*M*r0*(-8*L_4*(24*M_3 + (-2 + 45*E_2)*M_2*r0 + 6*(23 + 4*E_2)*M*r0_2 + 54*r0_3) + 2*L_2*(1280*M_5 - 48*(-214 + 153*E_2)*M_4*r0 + 8*(1387 - 795*E_2 + 51*E_4)*M_3*r0_2 + 4*(109 - 414*E_2 + 57*E_4)*M_2*r0_3 - (2972 + 435*E_2 + 6*E_4)*M*r0_4 - 12*(53 + 3*E_2)*r0_5) - r0*(31488*M_6 + 32*(835 + 286*E_2)*M_5*r0 - 4*(7996 - 6067*E_2 + 216*E_4)*M_4*r0_2 - 8*(4217 - 1475*E_2 + 198*E_4)*M_3*r0_3 + (756 + 1237*E_2 - 216*E_4)*M_2*r0_4 + 4*(1444 + 227*E_2 + 54*E_4)*M*r0_5 + 2*(312 + 73*E_2)*r0_6)) + a_8*r0*(6*L_4*M*(48*(-6 + 5*E_2)*M_3 + 8*(-30 + 49*E_2 + 11*E_4)*M_2*r0 + 2*(-24 + 266*E_2 + 11*E_4)*M*r0_2 - 3*E_2*(-51 + E_2)*r0_3) + L_2*M*(768*(-17 + 16*E_2)*M_5 + 32*(-294 - 185*E_2 + 246*E_4)*M_4*r0 + 8*(276 - 4461*E_2 + 1490*E_4)*M_3*r0_2 + 6*(328 - 971*E_2 + 972*E_4)*M_2*r0_3 + (-456 + 13057*E_2 + 748*E_4)*M*r0_4 - 2*(132 - 1809*E_2 + 20*E_4)*r0_5) + E_2*r0*(31488*M_7 + 64*(721 + 233*E_2)*M_6*r0 + 4*(-7347 + 9304*E_2)*M_5*r0_2 + 24*(-2775 + 1126*E_2)*M_4*r0_3 + (-11815 + 5264*E_2)*M_3*r0_4 + (12023 - 672*E_2)*M_2*r0_5 + 4*(763 - 19*E_2)*M*r0_6 + 6*r0_7)) + a_6*r0*(6*L_6*M*r0*(24*(-5 + 3*E_2)*M_2 + 2*(-24 + 47*E_2)*M*r0 + 51*E_2*r0_2) + 2*L_4*M*(-2304*M_5 + 288*(-36 + 41*E_2)*M_4*r0 + 8*(-144 + 117*E_2 + 134*E_4)*M_3*r0_2 + 4*(864 - 1935*E_2 + 308*E_4)*M_2*r0_3 + 8*(18 + 202*E_2 + 47*E_4)*M*r0_4 + (-396 + 1473*E_2 + 59*E_4)*r0_5) + E_2*r0_4*(59816*M_6 + 20*(2283 + 1184*E_2)*M_5*r0 + 2*(-23783 + 16360*E_2)*M_4*r0_2 + (-31147 + 9920*E_2)*M_3*r0_3 + (7245 - 584*E_2)*M_2*r0_4 + 4*(740 + 19*E_2)*M*r0_5 + 24*r0_6) + L_2*r0*(31488*M_7 + 64*(114 + 521*E_2)*M_6*r0 + 8*(-4800 + 6155*E_2 + 1716*E_4)*M_5*r0_2 + 4*(-1920 - 11123*E_2 + 6356*E_4)*M_4*r0_3 + 2*(5424 - 20299*E_2 + 6552*E_4)*M_3*r0_4 + (1176 + 11723*E_2 + 2156*E_4)*M_2*r0_5 + (-984 + 5405*E_2 + 228*E_4)*M*r0_6 + 27*E_2*r0_7))))/(3.*r0_8*expr2_2); A01420 = (-8*E*r0*(2*a_3*L*M*(12*M + (6 + E_2)*r0) + a_4*E*(-24*M_2 - 9*M*r0 + 2*r0_2) + 6*a*L*M*r0*(2*L_2 + (2 + E_2)*r0_2) + E*r0_3*(3*r0_2*(-6*M + r0) + 4*L_2*(-5*M + r0)) + a_2*E*r0*(2*L_2*(-7*M + r0) + 5*r0*(-6*M_2 - 5*M*r0 + r0_2))))/(a_2 + r0*(-2*M + r0)); A01440 = (-4*(a_10*E_2*M*(288*(-5 + 2*E_2)*M_3 + 4*(761 + 80*E_2)*M_2*r0 + 3*(1287 - 40*E_2)*M*r0_2 + 3*(329 - 22*E_2)*r0_3) - 2*a_9*E*L*M*(288*(-5 + 3*E_2)*M_3 + 2*(437 + 360*E_2 + 72*E_4)*M_2*r0 + 12*(144 + 11*E_2 + 6*E_4)*M*r0_2 - 3*(-154 + E_2)*r0_3) + 2*a*E*L*M*r0_3*(-8*L_6*(104*M_2 - 106*M*r0 + 27*r0_2) - 2*L_4*r0*(1104*M_3 + 4*(65 + 158*E_2)*M_2*r0 - 10*(98 + 31*E_2)*M*r0_2 + (287 + 3*E_2)*r0_3) - r0_5*(6048*M_3 + 12*(-376 + 77*E_2)*M_2*r0 + 4*(109 - 147*E_2)*M*r0_2 + 11*(14 + 9*E_2)*r0_3) + L_2*r0_3*(-8448*M_3 + 12*(424 - 129*E_2)*M_2*r0 + 4*(139 + 165*E_2 + 15*E_4)*M*r0_2 + (-494 + 21*E_2)*r0_3)) + r0_4*(8*L_6*M*(2*M - r0)*(252*M_2 + 20*(-9 + 5*E_2)*M*r0 + (27 - 52*E_2)*r0_2) + E_2*r0_7*(-192*M_3 + 12*(25 - 2*E_2)*M_2*r0 + 4*(-32 + 15*E_2)*M*r0_2 + 13*r0_3) + 2*L_2*r0_4*(2304*M_4 - 12*(240 + 7*E_2)*M_3*r0 - 12*(-96 + 7*E_4)*M_2*r0_2 + (-144 + 13*E_2 + 66*E_4)*M*r0_3 + 4*E_2*r0_4) + 2*L_4*r0_2*(4320*M_4 + 4*(-1332 + 173*E_2)*M_3*r0 - 2*(-1044 + 402*E_2 + 43*E_4)*M_2*r0_2 + (-252 + 213*E_2 + 47*E_4)*M*r0_3 + 8*E_2*r0_4)) - 2*a_7*E*L*M*(L_2*(288*M_3 + 112*(-8 + 9*E_2)*M_2*r0 + 12*(132 + 31*E_2 + 3*E_4)*M*r0_2 + 3*(308 + E_2)*r0_3) + 4*r0*(288*(-7 + 6*E_2)*M_4 - 2*(1687 - 822*E_2 + 72*E_4)*M_3*r0 + (-919 + 545*E_2 + 36*E_4)*M_2*r0_2 + (949 + 85*E_2 + 72*E_4)*M*r0_3 + 2*(185 + 3*E_2)*r0_4)) + 2*a_3*E*L*M*r0_2*(-24*L_6*M - 4*L_4*(288*M_3 + 12*(-51 + 37*E_2)*M_2*r0 - 4*(95 + 23*E_2)*M*r0_2 + (259 + 3*E_2)*r0_3) + L_2*r0*(-15840*M_4 - 48*(11 + 82*E_2)*M_3*r0 + 4*(3008 - 881*E_2 + 84*E_4)*M_2*r0_2 + 4*(174 + 217*E_2 + 9*E_4)*M*r0_3 + 5*(-374 + 3*E_2)*r0_4) - 4*r0_3*(5688*M_4 + 6*(-132 + 241*E_2)*M_3*r0 + (-2846 + 229*E_2 - 108*E_4)*M_2*r0_2 + (363 - 214*E_2 + 36*E_4)*M*r0_3 + 4*(54 + 13*E_2)*r0_4)) + a_8*(3*L_2*M*(96*(-5 + 6*E_2)*M_3 + 16*(-27 + 13*E_2 + 26*E_4)*M_2*r0 + 4*(-24 + 344*E_2 + 35*E_4)*M*r0_2 + E_2*(657 - 20*E_2)*r0_3) + E_2*r0*(2688*(-3 + 2*E_2)*M_5 + 16*(-1597 + 422*E_2)*M_4*r0 + 56*(-159 + 49*E_2)*M_3*r0_2 + (9267 - 164*E_2)*M_2*r0_3 + 12*(333 - 20*E_2)*M*r0_4 + 7*r0_5)) + a_2*r0_2*(-2*L_6*M*(576*M_3 - 48*(-12 + 47*E_2)*M_2*r0 + 2*(-396 + 743*E_2)*M*r0_2 + (180 - 199*E_2)*r0_3) + E_2*r0_6*(9672*M_4 + 12*(-269 + 240*E_2)*M_3*r0 + 6*(-403 + 14*E_2)*M_2*r0_2 + 3*(229 + 46*E_2)*M*r0_3 + 46*r0_4) + 2*L_4*r0*(9504*M_5 + 48*(-159 + 35*E_2)*M_4*r0 + 4*(-666 + 791*E_2 + 32*E_4)*M_3*r0_2 + 4*(819 - 962*E_2 + 40*E_4)*M_2*r0_3 + (-612 + 927*E_2 + 73*E_4)*M*r0_4 + 16*E_2*r0_5) + L_2*r0_3*(20160*M_5 + 24*(-636 + 553*E_2)*M_4*r0 + 4*(-1044 - 715*E_2 + 366*E_4)*M_3*r0_2 + 2*(2628 - 3105*E_2 + 614*E_4)*M_2*r0_3 + (-936 + 2087*E_2 + 256*E_4)*M*r0_4 + 51*E_2*r0_5)) + 2*a_5*E*L*M*r0*(-6*L_4*(32*M_2 + 10*(-2 + 3*E_2)*M*r0 + (77 + E_2)*r0_2) + L_2*(768*M_4 + 16*(479 - 396*E_2)*M_3*r0 + 8*(1078 - 417*E_2 + 30*E_4)*M_2*r0_2 - 4*(340 + 53*E_2 + 15*E_4)*M*r0_3 - (2300 + 9*E_2)*r0_4) - 2*r0*(10944*M_5 + 12*(403 + 244*E_2)*M_4*r0 - 4*(2437 - 1219*E_2 + 108*E_4)*M_3*r0_2 + (-5591 + 798*E_2 - 216*E_4)*M_2*r0_3 + 2*(771 - 25*E_2 + 90*E_4)*M*r0_4 + 4*(216 + 17*E_2)*r0_5)) + a_6*r0*(6*L_4*M*(24*(-9 + 10*E_2)*M_2 + 2*(-48 + 43*E_2 + 22*E_4)*M*r0 + E_2*(165 + E_2)*r0_2) + L_2*(1152*(-7 + 8*E_2)*M_5 + 288*(-5 - 5*E_2 + 8*E_4)*M_4*r0 + 8*(270 - 2368*E_2 + 633*E_4)*M_3*r0_2 + 2*(-108 + 1085*E_2 + 994*E_4)*M_2*r0_3 + (-360 + 6049*E_2 - 128*E_4)*M*r0_4 + 23*E_2*r0_5) + E_2*r0*(21888*M_6 + 48*(523 + 188*E_2)*M_5*r0 + 4*(-6059 + 3924*E_2)*M_4*r0_2 + 16*(-1991 + 436*E_2)*M_3*r0_3 + (4005 + 196*E_2)*M_2*r0_4 + 2*(2987 - 132*E_2)*M*r0_5 + 34*r0_6)) + a_4*r0*(6*L_6*M*r0*(12*(-4 + 3*E_2)*M + E_2*r0) + 3*E_2*r0_4*(9776*M_5 + 4*(923 + 828*E_2)*M_4*r0 + 8*(-958 + 307*E_2)*M_3*r0_2 + (-1373 + 116*E_2)*M_2*r0_3 - 4*(-315 + E_2)*M*r0_4 + 20*r0_5) + 2*L_4*(-1152*M_5 + 288*(-13 + 22*E_2)*M_4*r0 + 4*(414 - 231*E_2 + 28*E_4)*M_3*r0_2 + 2*(342 - 1403*E_2 + 165*E_4)*M_2*r0_3 + (-360 + 1209*E_2 + 29*E_4)*M*r0_4 + 8*E_2*r0_5) + L_2*r0*(21888*M_6 + 1920*(-3 + 8*E_2)*M_5*r0 + 32*(-576 + 629*E_2 + 99*E_4)*M_4*r0_2 + 4*(1332 - 5551*E_2 + 1448*E_4)*M_3*r0_3 + 4*(756 - 2051*E_2 + 741*E_4)*M_2*r0_4 + (-1008 + 6163*E_2 + 56*E_4)*M*r0_5 + 66*E_2*r0_6))))/(3.*r0_5*expr2_2); A01600 = (-2*E*r0_4*(4*a*L*M + E*r0_2*(-6*M + r0) + a_2*E*(-4*M + r0)))/(a_2 + r0*(-2*M + r0)); A01620 = (6*a_7*E*L*M*(16*(-13 + 9*E_2)*M_2 + 4*(62 + 6*E_2 + 3*E_4)*M*r0 + (164 - 11*E_2)*r0_2) - 3*a_8*E_2*(16*(-13 + 6*E_2)*M_3 + 592*M_2*r0 + (337 - 26*E_2)*M*r0_2 - 3*r0_3) + 2*a_5*E*L*M*(12*L_2*(12*M_2 + 3*(-6 + 7*E_2)*M*r0 + (41 - 2*E_2)*r0_2) + r0*(192*(-11 + 10*E_2)*M_3 - 8*(503 - 151*E_2 + 15*E_4)*M_2*r0 + 8*(13 + 13*E_2 + 15*E_4)*M*r0_2 + (1196 - 63*E_2)*r0_3)) + 2*a*E*L*M*r0_2*(8*L_4*(52*M_2 - 56*M*r0 + 15*r0_2) + 2*L_2*r0*(1152*M_3 + 4*(-48 + 73*E_2)*M_2*r0 - 4*(137 + 23*E_2)*M*r0_2 + (178 - 15*E_2)*r0_3) + r0_3*(3552*M_3 + 4*(-476 + 157*E_2)*M_2*r0 - 8*(51 + 43*E_2)*M*r0_2 + (236 + 51*E_2)*r0_3)) + a_6*(L_2*((624 - 864*E_2)*M_3 + 24*(12 - 13*E_4)*M_2*r0 + 12*E_2*(-83 + 2*E_2)*M*r0_2 + 9*E_2*r0_3) + E_2*r0*(-704*(-3 + 2*E_2)*M_4 + 8*(1108 - 187*E_2)*M_3*r0 - 2*(229 + 150*E_2)*M_2*r0_2 + (-3107 + 210*E_2)*M*r0_3 + 19*r0_4)) + r0_3*(-8*L_4*M*(2*M - r0)*(180*M_2 + 2*(-66 + 25*E_2)*M*r0 + (21 - 29*E_2)*r0_2) - 8*E_2*r0_5*(-16*M_3 - 2*(-12 + E_2)*M_2*r0 + 5*(-2 + E_2)*M*r0_2 + r0_3) + L_2*r0_2*(-3072*M_4 + 24*(160 - 11*E_2)*M_3*r0 + 4*(-384 + 105*E_2 + 14*E_4)*M_2*r0_2 - 2*(-96 + 79*E_2 + 22*E_4)*M*r0_3 + 7*E_2*r0_4)) + 2*a_3*E*L*M*r0*(48*L_4*M + 2*L_2*(64*M_3 + 12*(-44 + 37*E_2)*M_2*r0 + 8*(-93 + 8*E_2)*M*r0_2 + (424 - 27*E_2)*r0_3) + r0*(6720*M_4 + 16*(29 + 101*E_2)*M_3*r0 - 4*(1094 - 283*E_2 + 54*E_4)*M_2*r0_2 + 4*(-250 - 54*E_2 + 21*E_4)*M*r0_3 + (940 + 21*E_2)*r0_4)) + a_4*r0*(24*L_4*M*(-3*(-4 + 5*E_2)*M + E_2*r0) + L_2*(-192*(-11 + 16*E_2)*M_4 - 8*(102 - 53*E_2 + 14*E_4)*M_3*r0 - 4*(66 - 995*E_2 + 234*E_4)*M_2*r0_2 + 2*(108 - 1081*E_2 + 26*E_4)*M*r0_3 + E_2*r0_4) + E_2*r0*(-6720*M_5 - 16*(376 + 137*E_2)*M_4*r0 + 4*(2119 - 590*E_2)*M_3*r0_2 + 24*(197 - 23*E_2)*M_2*r0_3 + (-3101 + 146*E_2)*M*r0_4 + 3*r0_5)) - a_2*r0*(-8*L_4*M*(48*M_3 + 6*(16 - 47*E_2)*M_2*r0 + (-114 + 167*E_2)*M*r0_2 + (27 - 23*E_2)*r0_3) + E_2*r0_4*(4760*M_4 + 4*(43 + 320*E_2)*M_3*r0 + 2*(-1609 + 118*E_2)*M_2*r0_2 + (925 + 26*E_2)*M*r0_3 + 15*r0_4) + L_2*r0*(6720*M_5 + 16*(-318 + 173*E_2)*M_4*r0 - 16*(111 - 168*E_2 + 4*E_4)*M_3*r0_2 + 8*(267 - 552*E_2 + 83*E_4)*M_2*r0_3 + 4*(-102 + 319*E_2 + 4*E_4)*M*r0_4 + E_2*r0_5)))/(3.*r0_2*expr2_2); A01800 = (r0*(12*a_5*E*L*M*(4*(-4 + 3*E_2)*M + (29 - 5*E_2)*r0) + 3*a_6*E_2*(-16*(-2 + E_2)*M_2 + 2*(-58 + 5*E_2)*M*r0 + 3*r0_2) + 8*a_3*E*L*M*(6*L_2*M + r0*(48*(-1 + E_2)*M_2 + (-134 + 19*E_2)*M*r0 + (67 - 9*E_2)*r0_2)) - r0_2*(8*L_2*M*(2*M - r0)*(48*M_2 + 2*(-18 + 5*E_2)*M*r0 + (6 - 7*E_2)*r0_2) + E_2*r0_3*(-32*M_3 - 4*(-9 + E_2)*M_2*r0 + 2*(-6 + 5*E_2)*M*r0_2 + r0_3)) + a_4*(6*L_2*M*(-8*(-2 + 3*E_2)*M + 5*E_2*r0) + E_2*r0*(-64*(-3 + 2*E_2)*M_3 - 4*(-316 + 39*E_2)*M_2*r0 + 2*(-362 + 25*E_2)*M*r0_2 + 17*r0_3)) + 4*a*E*L*M*r0*(4*L_2*(8*M_2 - 10*M*r0 + 3*r0_2) + r0*(384*M_3 + 20*(-5 + 4*E_2)*M_2*r0 - 2*(70 + 11*E_2)*M*r0_2 + (47 - 3*E_2)*r0_3)) - a_2*r0*(2*L_2*M*(96*(-1 + 2*E_2)*M_2 + (96 - 82*E_2)*M*r0 + (-24 + 13*E_2)*r0_2) + E_2*r0*(768*M_4 + 80*(7 + 2*E_2)*M_3*r0 + 4*(-293 + 26*E_2)*M_2*r0_2 + 2*(182 - 5*E_2)*M*r0_3 - 7*r0_4))))/(12.*expr2_2); A02040 = (192*E_2*expr1_2)/(a_2 + r0*(-2*M + r0)); A02060 = (32*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-4*a_7*E*L*M*(48*M_3 + 12*(4 + 3*E_2)*M_2*r0 + (-12 + 35*E_2)*M*r0_2 + 3*(-4 + E_2)*r0_3) + a_8*E_2*M*(96*M_3 + 24*(4 + E_2)*M_2*r0 + (-73 + 36*E_2)*M*r0_2 + 6*(-9 + 2*E_2)*r0_3) - 4*a*E*L*M*r0_3*(-6*L_4*(20*M_2 - 21*M*r0 + 5*r0_2) + L_2*r0_2*(-384*M_2 + (348 + 139*E_2)*M*r0 - 36*(2 + E_2)*r0_2) + r0_4*(-264*M_2 + (222 + 89*E_2)*M*r0 - 3*(14 + 5*E_2)*r0_2)) + r0_3*(-96*L_6*M*r0_2M_2 + E_2*r0_7*(184*M_2 - 2*(55 + 2*E_2)*M*r0 + 9*r0_2) - 8*L_4*(2*M - r0)*r0_2*(48*M_2 - 2*(12 + 13*E_2)*M*r0 + 3*E_2*r0_2) + 2*L_2*r0_4*(-192*M_3 + 6*(32 + 49*E_2)*M_2*r0 + (-48 - 177*E_2 + 2*E_4)*M*r0_2 + 15*E_2*r0_3)) - 4*a_3*E*L*M*r0_2*(12*L_4*(2*M - r0) + L_2*(-624*M_3 + 56*(3 + E_2)*M_2*r0 + (264 + 157*E_2)*M*r0_2 - 3*(32 + E_2)*r0_3) + r0_2*(-912*M_3 + 4*(54 + 5*E_2)*M_2*r0 + (312 + 173*E_2)*M*r0_2 - (96 + 11*E_2)*r0_3)) + 2*a_2*r0_2*(12*L_6*M_2 + E_2*r0_5*(-250*M_3 + 3*(99 - 26*E_2)*M_2*r0 - 165*M*r0_2 + 6*r0_3) + L_4*(-768*M_4 + 16*(24 + 5*E_2)*M_3*r0 + 6*(36 + 49*E_2)*M_2*r0_2 - 32*(3 + 4*E_2)*M*r0_3 - 6*E_2*r0_4) + L_2*r0_2*(-768*M_4 + (384 - 98*E_2)*M_3*r0 + (204 + 627*E_2 + 104*E_4)*M_2*r0_2 + (-96 - 345*E_2 + 10*E_4)*M*r0_3 + 6*E_2*r0_4)) + 2*a_6*(L_2*M*(48*M_3 + 12*(4 + 13*E_2)*M_2*r0 + 4*(3 + 13*E_2 + 6*E_4)*M*r0_2 + 3*E_2*(-17 + 2*E_2)*r0_3) + E_2*r0*(-768*M_5 - 16*(39 + 4*E_2)*M_4*r0 - 120*(-2 + E_2)*M_3*r0_2 - 6*(-2 + 3*E_2)*M_2*r0_3 + (-139 + 16*E_2)*M*r0_4 - 3*r0_5)) + a_4*r0*(24*L_4*M*(4*M_2 + (2 + 7*E_2)*M*r0 - 2*E_2*r0_2) + E_2*r0_3*(-2108*M_4 + 20*(1 - 18*E_2)*M_3*r0 + 3*(189 - 76*E_2)*M_2*r0_2 + 12*(-37 + 2*E_2)*M*r0_3 - 3*r0_4) - 2*L_2*(768*M_5 + 256*E_2*M_4*r0 + 8*(-54 - 43*E_2 + 2*E_4)*M_3*r0_2 - (24 + 349*E_2 + 80*E_4)*M_2*r0_3 + (48 + 267*E_2 - 14*E_4)*M*r0_4 + 9*E_2*r0_5)) - 4*a_5*E*L*M*r0*(-768*M_4 + 8*(-39 + 10*E_2)*M_3*r0 + 136*(3 + E_2)*M_2*r0_2 + (78 + 151*E_2)*M*r0_3 + (-66 + 7*E_2)*r0_4 + 3*L_2*(24*M_2 + (-8 + E_2)*r0_2 + 4*M*(r0 + 3*E_2*r0)))))/(3.*r0_7*expr2_2); A02220 = (96*E_2*r0_3*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/(a_2 + r0*(-2*M + r0)); A02240 = (-8*(4*a_7*E*L*M*(144*M_3 + 24*(9 + E_2)*M_2*r0 + 5*(12 + E_2)*M*r0_2 - 3*(2 + 3*E_2)*r0_3) + a_8*E_2*(-288*M_4 + 48*(-12 + E_2)*M_3*r0 + (-119 + 24*E_2)*M_2*r0_2 + 66*M*r0_3 + 6*r0_4) + 4*a*E*L*M*r0_3*(L_4*(-432*M_2 + 2*(165 + 2*E_2)*M*r0 - 48*r0_2) - 6*r0_4*(120*M_2 - 3*(29 + 11*E_2)*M*r0 + (12 + 7*E_2)*r0_2) - 3*L_2*r0_2*(384*M_2 - 4*(71 + 21*E_2)*M*r0 + (40 + 21*E_2)*r0_2)) + r0_3*(4*L_6*M*(2*M - r0)*(144*M - (72 + E_2)*r0) + 3*E_2*r0_7*(-184*M_2 + 2*(59 + 2*E_2)*M*r0 - 13*r0_2) + 36*L_2*(2*M - r0)*r0_4*(16*M_2 - 2*(4 + 11*E_2)*M*r0 + 3*E_2*r0_2) + 2*L_4*r0_2*(1152*M_3 - 2*(576 + 263*E_2)*M_2*r0 + (288 + 335*E_2 - 2*E_4)*M*r0_2 - 36*E_2*r0_3)) + 4*a_3*E*L*M*r0_2*(L_4*(60*M - 6*r0) - 6*L_2*(336*M_3 - 4*(11 + 6*E_2)*M_2*r0 - (126 + 37*E_2)*M*r0_2 + 2*(11 + 4*E_2)*r0_3) + r0_2*(-2592*M_3 + 6*(60 + 53*E_2)*M_2*r0 + (840 + 289*E_2)*M*r0_2 - (150 + 83*E_2)*r0_3)) - 2*a_2*r0_2*(36*L_6*M_2 - 3*E_2*r0_5*(108*M_3 + 2*(-77 + 24*E_2)*M_2*r0 + (143 + 6*E_2)*M*r0_2 - 15*r0_3) + L_4*(-2304*M_4 + 1152*M_3*r0 + 4*(162 + 123*E_2 + E_4)*M_2*r0_2 + (-288 - 287*E_2 + 2*E_4)*M*r0_3 + 15*E_2*r0_4) + 3*L_2*r0_2*(-768*M_4 + 384*M_3*r0 + 6*(34 + 53*E_2 + 3*E_4)*M_2*r0_2 - (96 + 277*E_2)*M*r0_3 + 25*E_2*r0_4)) - 2*a_6*(L_2*(144*M_4 + 24*(6 + 13*E_2)*M_3*r0 + 2*(18 + 95*E_2 + 3*E_4)*M_2*r0_2 - 63*E_2*M*r0_3 - 6*E_2*r0_4) - E_2*M*r0*(2304*M_4 + 48*(45 + E_2)*M_3*r0 + 2*(-149 + 108*E_2)*M_2*r0_2 + (-193 + 120*E_2)*M*r0_3 + 3*(61 + 2*E_2)*r0_4)) + 4*a_5*E*L*M*r0*(3*L_2*(64*M_2 + 10*(4 + E_2)*M*r0 - (4 + 3*E_2)*r0_2) + 2*(-1152*M_4 + 60*(-9 + 2*E_2)*M_3*r0 + (516 + 169*E_2)*M_2*r0_2 + (189 + 58*E_2)*M*r0_3 - (42 + 25*E_2)*r0_4)) + a_4*r0*(-6*L_4*(48*M_3 + 2*(12 + 23*E_2)*M_2*r0 - 10*E_2*M*r0_2 - E_2*r0_3) + 3*E_2*r0_3*(1804*M_4 + 4*(61 + 48*E_2)*M_3*r0 + (-241 + 168*E_2)*M_2*r0_2 + 4*(67 + 3*E_2)*M*r0_3 - 19*r0_4) + 2*L_2*(2304*M_5 + 1200*E_2*M_4*r0 - 4*(324 + 67*E_2)*M_3*r0_2 - 4*(18 + 121*E_2 + 9*E_4)*M_2*r0_3 + 12*(12 + 37*E_2)*M*r0_4 - 15*E_2*r0_5))))/(3.*r0_4*expr2_2); A02400 = (12*E_2*r0_6)/(a_2 + r0*(-2*M + r0)); A02420 = (-2*(-24*a_5*E*L*M*(-12*M_2 + (-18 + 5*E_2)*M*r0 + 4*(-1 + E_2)*r0_2) + 3*a_6*E_2*(-48*M_3 + 4*(-30 + 7*E_2)*M_2*r0 + 2*(-11 + 6*E_2)*M*r0_2 + 3*r0_3) - 12*a_3*E*L*M*r0*(384*M_3 + 4*(3 - 10*E_2)*M_2*r0 - (134 + 19*E_2)*M*r0_2 + (-2 + 23*E_2)*r0_3 - 4*L_2*(4*M - (-2 + E_2)*r0)) + r0_2*(24*L_4*M*(2*M - r0)*(24*M - (12 + E_2)*r0) + E_2*r0_5*(-552*M_2 + 2*(179 + 6*E_2)*M*r0 - 41*r0_2) + L_2*(2*M - r0)*r0_2*(576*M_2 - 6*(48 + 71*E_2)*M*r0 + 59*E_2*r0_2)) + 12*a*E*L*M*r0_2*(-2*L_2*(84*M_2 - (47 + 4*E_2)*M*r0 + (1 + 2*E_2)*r0_2) + r0_2*(-216*M_2 + (126 + 43*E_2)*M*r0 - (6 + 13*E_2)*r0_2)) + a_4*(-3*L_2*(48*M_3 + 4*(6 + 7*E_2)*M_2*r0 + 4*E_2*(3 - 2*E_2)*M*r0_2 - 3*E_2*r0_3) + E_2*r0*(2304*M_4 - 48*(-27 + 2*E_2)*M_3*r0 + 6*(-53 + 20*E_2)*M_2*r0_2 + 2*(19 + 42*E_2)*M*r0_3 - 17*r0_4)) + a_2*r0*(24*L_4*M*(-3*M + E_2*r0) + E_2*r0_3*(900*M_3 + 2*(-167 + 42*E_2)*M_2*r0 + 30*(15 + 2*E_2)*M*r0_2 - 67*r0_3) + 2*L_2*(1152*M_4 + 48*(-12 + 5*E_2)*M_3*r0 - 6*(54 + 27*E_2 + 4*E_4)*M_2*r0_2 + 6*(24 + 31*E_2 + 2*E_4)*M*r0_3 - 25*E_2*r0_4))))/(3.*r0*expr2_2); A02600 = (r0_2*(24*a_3*E*L*M*(-2*M + (-3 + 2*E_2)*r0) - 3*a_4*E_2*(-8*M_2 + 8*(-3 + E_2)*M*r0 + r0_2) - 8*a*E*L*M*r0*(-96*M_2 + (39 + 10*E_2)*M*r0 - 6*(-1 + E_2)*r0_2) + r0*(-4*L_2*M*(2*M - r0)*(48*M - (24 + 5*E_2)*r0) + E_2*r0_3*(184*M_2 - 2*(57 + 2*E_2)*M*r0 + 11*r0_2)) + 2*a_2*(12*L_2*M*(M - E_2*r0) - E_2*r0*(192*M_3 - 4*(-9 + 5*E_2)*M_2*r0 + 7*(1 + 2*E_2)*M*r0_2 - 4*r0_3))))/(6.*expr2_2); A03040 = (-32*E*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(4*a_3*L*M*(6*M + (3 + E_2)*r0) + a_4*E*(-24*M_2 - 12*M*r0 + r0_2) + 12*a*L*M*r0*(L_2 + (1 + E_2)*r0_2) + E*r0_3*(r0_2*(-17*M + 2*r0) + L_2*(-21*M + 4*r0)) + a_2*E*r0*(L_2*(-16*M + r0) + r0*(-22*M_2 - 27*M*r0 + 3*r0_2))))/(r0_2*expr2_2); A03060 = (-16*(4*a_11*E*L*M*(48*(-1 + 4*E_2)*M_4 + 2*(-265 + 18*E_2 + 18*E_4)*M_3*r0 + (-421 - 189*E_2 + 54*E_4)*M_2*r0_2 + 3*(-12 - 31*E_2 + 6*E_4)*M*r0_3 + 24*r0_4) + a_12*E_2*M*(-96*(-1 + 2*E_2)*M_4 - 8*(-205 + 83*E_2)*M_3*r0 + 4*(325 - 137*E_2)*M_2*r0_2 + 3*(19 - 40*E_2)*M*r0_3 + 6*(-17 + E_2)*r0_4) + 2*a*E*L*M*r0_4*(-168*L_8*r0_2M_2 + r0_7*(-4560*M_3 - 8*(-664 + 33*E_2)*M_2*r0 + 4*(-505 + 67*E_2 + 27*E_4)*M*r0_2 + 3*(82 - 19*E_2)*r0_3) + L_2*r0_5*(-10224*M_3 + 4*(3194 - 127*E_2)*M_2*r0 + 4*(-1318 + 91*E_2 + 57*E_4)*M*r0_2 - 3*(-234 + E_2)*r0_3) - 2*L_6*r0*(360*M_3 + 4*(-44 + 147*E_2)*M_2*r0 - 28*(5 + 12*E_2)*M*r0_2 + 3*(24 + 7*E_2)*r0_3) + 2*L_4*r0_3*(-3192*M_3 + (4244 - 506*E_2)*M_2*r0 + 2*(-911 + 96*E_2 + 21*E_4)*M*r0_2 + 3*(80 + 17*E_2)*r0_3)) + r0_5*(24*L_8*M*r0_2M_2*(27*M + 2*(-3 + 7*E_2)*r0) + 3*E_2*r0_9*(-284*M_3 + (298 - 24*E_2)*M_2*r0 + 2*(-44 + 9*E_2)*M*r0_2 + 5*r0_3) + 2*L_6*(2*M - r0)*r0_2*(2088*M_3 + 2*(-774 + 143*E_2)*M_2*r0 + (252 - 169*E_2 - 42*E_4)*M*r0_2 - 24*E_2*r0_3) + L_2*r0_6*(3168*M_4 - 4*(1008 + 695*E_2)*M_3*r0 - 4*(-414 - 651*E_2 + 85*E_4)*M_2*r0_2 + (-216 - 685*E_2 + 184*E_4)*M*r0_3 + 39*E_2*r0_4) + L_4*r0_4*(8928*M_4 - 416*(27 + 5*E_2)*M_3*r0 + 2*(2268 + 867*E_2 - 230*E_4)*M_2*r0_2 + (-576 - 479*E_2 + 226*E_4)*M*r0_3 + 66*E_2*r0_4)) + 2*a_3*E*L*M*r0_3*(-2*L_6*(944*M_3 + 108*(-17 + 7*E_2)*M_2*r0 + 2*(194 - 147*E_2)*M*r0_2 + 3*(36 + 7*E_2)*r0_3) + r0_5*(-25728*M_4 + 12*(1146 - 695*E_2)*M_3*r0 + 2*(4542 + 1529*E_2 - 270*E_4)*M_2*r0_2 + 4*(-1696 + 46*E_2 + 135*E_4)*M*r0_3 + (1026 - 257*E_2)*r0_4) + 2*L_2*r0_3*(-19200*M_4 - 22*(-504 + 353*E_2)*M_3*r0 + (8880 + 3397*E_2 + 672*E_4)*M_2*r0_2 + 3*(-2270 + 69*E_2 + 128*E_4)*M*r0_3 + 2*(525 - 107*E_2)*r0_4) - 4*L_4*r0*(2976*M_4 + 2*(-751 + 718*E_2)*M_3*r0 - (3057 + 373*E_2 + 42*E_4)*M_2*r0_2 - 2*(-935 + 129*E_2 + 21*E_4)*M*r0_3 + 42*(-5 + 2*E_2)*r0_4)) - a_2*r0_3*(24*L_8*M*(48*M_3 + 2*(27 - 77*E_2)*M_2*r0 + (-62 + 105*E_2)*M*r0_2 + (11 - 14*E_2)*r0_3) - E_2*r0_8*(5880*M_4 + 4*(-1795 + 846*E_2)*M_3*r0 + 4*(1102 - 233*E_2)*M_2*r0_2 + (-1141 + 268*E_2)*M*r0_3 + 15*r0_4) + L_2*r0_5*(-20736*M_5 - 8*(-2016 + 1919*E_2)*M_4*r0 + 12*(344 + 2065*E_2 - 374*E_4)*M_3*r0_2 + 2*(-2676 - 6891*E_2 + 1052*E_4)*M_2*r0_3 + (912 + 2511*E_2 - 800*E_4)*M*r0_4 + 27*E_2*r0_5) + 2*L_6*r0*(-9216*M_5 - 64*(-126 + 25*E_2)*M_4*r0 + 4*(840 + 197*E_2 - 84*E_4)*M_3*r0_2 + 2*(-1938 + 385*E_2 + 84*E_4)*M_2*r0_3 + (648 - 419*E_2 - 84*E_4)*M*r0_4 + 36*E_2*r0_5) + L_4*r0_3*(-39168*M_5 - 24*(-1296 + 539*E_2)*M_4*r0 + 4*(2388 + 5793*E_2 + 358*E_4)*M_3*r0_2 + 4*(-2904 - 2653*E_2 + 18*E_4)*M_2*r0_3 + (1944 + 1021*E_2 - 732*E_4)*M*r0_4 + 81*E_2*r0_5)) + 4*a_9*E*L*M*(L_2*(192*M_4 + 4*(-110 + 129*E_2)*M_3*r0 + (-1037 + 114*E_2 + 48*E_4)*M_2*r0_2 + 3*(-84 - 59*E_2 + 6*E_4)*M*r0_3 + 72*r0_4) + r0*(-96*(-85 + 62*E_2)*M_5 + 8*(1302 - 899*E_2 + 36*E_4)*M_4*r0 + 2*(348 - 1145*E_2 + 234*E_4)*M_3*r0_2 + (-3053 - 736*E_2 + 468*E_4)*M_2*r0_3 + (-488 - 585*E_2 + 162*E_4)*M*r0_4 + 6*(36 - 5*E_2)*r0_5)) + a_10*M*(L_2*(-96*(-1 + 12*E_2)*M_4 - 24*(-20 - 83*E_2 + 38*E_4)*M_3*r0 + 4*(102 + 1171*E_2 - 326*E_4)*M_2*r0_2 + 3*(32 + 407*E_2 - 108*E_4)*M*r0_3 + 6*E_2*(-51 + 2*E_2)*r0_4) + E_2*r0*(64*(-255 + 148*E_2)*M_5 + 16*(-1818 + 935*E_2)*M_4*r0 + 2*(-4311 + 3016*E_2)*M_3*r0_2 + 11*(543 - 104*E_2)*M_2*r0_3 + (1397 - 676*E_2)*M*r0_4 + 2*(-329 + 38*E_2)*r0_5)) + a_4*r0_2*(-48*L_8*M_2*(M - 2*r0) - 2*L_6*M*(2304*M_4 + 24*(241 - 352*E_2)*M_3*r0 - 4*(525 - 1111*E_2 + 42*E_4)*M_2*r0_2 + 4*(-420 + 47*E_2 + 21*E_4)*M*r0_3 + (396 - 139*E_2 - 42*E_4)*r0_4) + E_2*r0_6*(34140*M_5 + 12*(-817 + 1278*E_2)*M_4*r0 + (-13965 + 8684*E_2)*M_3*r0_2 + 8*(1168 - 297*E_2)*M_2*r0_3 + (-2461 + 538*E_2)*M*r0_4 - 45*r0_5) + L_2*r0_3*(44928*M_6 + 4*(-3168 + 11983*E_2)*M_5*r0 + 4*(-8460 - 4609*E_2 + 6984*E_4)*M_4*r0_2 + (8904 - 34221*E_2 + 6296*E_4)*M_3*r0_3 + 4*(1482 + 6265*E_2 - 927*E_4)*M_2*r0_4 + 3*(-480 - 1561*E_2 + 436*E_4)*M*r0_5 - 171*E_2*r0_6) + L_4*r0*(42624*M_6 + 32*(-504 + 347*E_2)*M_5*r0 + 8*(-5532 + 1145*E_2 + 772*E_4)*M_4*r0_2 - 24*(-524 + 1207*E_2 + 148*E_4)*M_3*r0_3 + 4*(2262 + 3755*E_2 - 222*E_4)*M_2*r0_4 + 2*(-1080 - 907*E_2 + 396*E_4)*M*r0_5 - 147*E_2*r0_6)) + 2*a_7*E*L*M*r0*(8*L_4*(66*M_3 + (-133 + 75*E_2)*M_2*r0 - 3*(33 + 7*E_2)*M*r0_2 + 18*r0_3) + 2*L_2*(1088*M_5 - 96*(-139 + 87*E_2)*M_4*r0 + 4*(2231 - 1059*E_2 + 84*E_4)*M_3*r0_2 + (-4418 + 1167*E_2 + 624*E_4)*M_2*r0_3 + 2*(-1171 - 387*E_2 + 96*E_4)*M*r0_4 + 12*(41 - 8*E_2)*r0_5) - r0*(32256*M_6 + 16*(1307 + 588*E_2)*M_5*r0 + 8*(-5255 + 3282*E_2)*M_4*r0_2 + 4*(-6409 + 2653*E_2 + 18*E_4)*M_3*r0_3 - 6*(-1859 + 162*E_2 + 216*E_4)*M_2*r0_4 + 2*(2240 + 1119*E_2 - 432*E_4)*M*r0_5 + (-1254 + 263*E_2)*r0_6)) + a_8*(-6*L_4*M*(32*M_4 + 24*(-2 + 15*E_2)*M_3*r0 + 8*(-16 - 51*E_2 + 16*E_4)*M_2*r0_2 + 2*(-24 - 188*E_2 + 17*E_4)*M*r0_3 - E_2*(-51 + E_2)*r0_4) + L_2*M*r0*(192*(-85 + 76*E_2)*M_5 + 16*(-786 - 841*E_2 + 648*E_4)*M_4*r0 + 8*(594 - 3447*E_2 + 1034*E_4)*M_3*r0_2 + 3*(1768 + 2685*E_2 - 1160*E_4)*M_2*r0_3 + 2*(192 + 3881*E_2 - 664*E_4)*M*r0_4 + 4*(-66 - 438*E_2 + 71*E_4)*r0_5) + E_2*r0_2*(32256*M_7 + 32*(1091 + 468*E_2)*M_6*r0 + 8*(-4993 + 5068*E_2)*M_5*r0_2 + 20*(-2189 + 1460*E_2)*M_4*r0_3 + (5057 + 2488*E_2)*M_3*r0_4 + (5293 - 1720*E_2)*M_2*r0_5 + (-1981 + 298*E_2)*M*r0_6 - 30*r0_7)) + a_6*r0*(-6*L_6*M*(32*M_3 + 4*(-13 + 38*E_2)*M_2*r0 - 2*(24 + 91*E_2)*M*r0_2 + 17*E_2*r0_3) - 4*L_4*M*(1152*M_5 - 96*(-68 + 69*E_2)*M_4*r0 - 32*(-39 - 78*E_2 + 25*E_4)*M_3*r0_2 + (-2700 + 2937*E_2 + 770*E_4)*M_2*r0_3 + 2*(-282 - 1070*E_2 + 89*E_4)*M*r0_4 + (198 + 288*E_2 - 73*E_4)*r0_5) + E_2*r0_4*(57960*M_6 + 12*(2009 + 2004*E_2)*M_5*r0 + 14*(-3451 + 2616*E_2)*M_4*r0_2 + (-6893 + 8384*E_2)*M_3*r0_3 + (9783 - 2680*E_2)*M_2*r0_4 + 3*(-1003 + 184*E_2)*M*r0_5 - 75*r0_6) + L_2*r0*(32256*M_7 + 768*(9 + 46*E_2)*M_6*r0 + 16*(-2772 + 1921*E_2 + 1174*E_4)*M_5*r0_2 + 16*(-618 - 3587*E_2 + 2098*E_4)*M_4*r0_3 - 6*(-2316 + 1679*E_2 + 8*E_4)*M_3*r0_4 + (2520 + 19847*E_2 - 2948*E_4)*M_2*r0_5 + (-1008 - 4303*E_2 + 964*E_4)*M*r0_6 - 105*E_2*r0_7)) + 2*a_5*E*L*M*r0_2*(24*L_6*(7*M_2 - 15*M*r0 + 2*r0_2) + 2*L_4*r0*((7088 - 4128*E_2)*M_3 + 2*(561 + 428*E_2 + 42*E_4)*M_2*r0 + 2*(-1289 + 48*E_2 + 21*E_4)*M*r0_2 + 3*(84 - 29*E_2)*r0_3) - L_2*r0*(37056*M_5 + 8*(165 + 1532*E_2)*M_4*r0 - 4*(12514 - 4809*E_2 + 120*E_4)*M_3*r0_2 - 2*(-589 + 4152*E_2 + 1152*E_4)*M_2*r0_3 + 4*(3132 + 401*E_2 - 222*E_4)*M*r0_4 + (-2238 + 617*E_2)*r0_5) - r0_3*(49344*M_5 + 4*(-10362 + 3239*E_2 + 378*E_4)*M_3*r0_2 + 2*(1059 - 2746*E_2 + 36*E_4)*M_2*r0_3 + 6*(1390 + 223*E_2 - 168*E_4)*M*r0_4 + (-1650 + 403*E_2)*r0_5 + 3624*M_4*(r0 + 4*E_2*r0)))))/(3.*r0_8*expr2_3); A03220 = (-16*E*r0*(2*a_3*L*M*(12*M + (6 + E_2)*r0) + a_4*E*(-24*M_2 - 9*M*r0 + 2*r0_2) + 6*a*L*M*r0*(2*L_2 + (2 + E_2)*r0_2) + E*r0_3*(r0_2*(-17*M + 2*r0) + L_2*(-19*M + 3*r0)) + 2*a_2*E*r0*(L_2*(-7*M + r0) + r0*(-14*M_2 - 13*M*r0 + 2*r0_2))))/expr2_2; A03240 = (-4*(a_10*E_2*M*(192*(-3 + E_2)*M_3 + 4*(1033 - 89*E_2)*M_2*r0 + 3*(1201 - 108*E_2)*M*r0_2 + 6*(107 - 6*E_2)*r0_3) - 4*a_9*E*L*M*(96*(-3 + E_2)*M_3 + (973 + 258*E_2 + 18*E_4)*M_2*r0 + 15*(58 + 13*E_2)*M*r0_2 + 3*(50 + E_2)*r0_3) + 4*a*E*L*M*r0_3*(-4*L_6*(214*M_2 - 215*M*r0 + 54*r0_2) + 3*r0_5*(-2048*M_3 - 4*(-532 + 53*E_2)*M_2*r0 + 4*(-173 + 43*E_2 + 9*E_4)*M*r0_2 + (67 - 33*E_2)*r0_3) + L_2*r0_3*(-8736*M_3 + 2*(4608 - 695*E_2)*M_2*r0 + (-3036 + 817*E_2 + 114*E_4)*M*r0_2 + 6*(48 - 7*E_2)*r0_3) - L_4*r0*(2400*M_3 + 92*(-19 + 16*E_2)*M_2*r0 + 2*(8 - 423*E_2)*M*r0_2 + 3*(46 + 17*E_2)*r0_3)) + r0_4*(2*L_6*M*(2*M - r0)*(2088*M_2 + 2*(-774 + 425*E_2)*M*r0 + 7*(36 - 61*E_2)*r0_2) + 3*E_2*r0_7*(-852*M_3 + (930 - 72*E_2)*M_2*r0 + 2*(-139 + 27*E_2)*M*r0_2 + 13*r0_3) + 2*L_4*r0_2*(8928*M_4 + 312*(-36 + E_2)*M_3*r0 - 2*(-2268 + 237*E_2 + 115*E_4)*M_2*r0_2 + (-576 + 111*E_2 + 113*E_4)*M*r0_3 + 24*E_2*r0_4) + L_2*r0_4*(9504*M_4 - 112*(108 + 43*E_2)*M_3*r0 + 2*(2484 + 2283*E_2 - 340*E_4)*M_2*r0_2 + (-648 - 1169*E_2 + 368*E_4)*M*r0_3 + 45*E_2*r0_4)) + 4*a_3*E*L*M*r0_2*(-(L_4*(1344*M_3 + 12*(-316 + 163*E_2)*M_2*r0 - 8*(-62 + 97*E_2)*M*r0_2 + 3*(128 + 15*E_2)*r0_3)) + r0_3*(-23232*M_4 + (9432 - 6834*E_2)*M_3*r0 + (10068 + 815*E_2 - 54*E_4)*M_2*r0_2 + (-5208 + 505*E_2 + 324*E_4)*M*r0_3 + (456 - 211*E_2)*r0_4) + L_2*r0*(-16512*M_4 + 32*(189 - 160*E_2)*M_3*r0 + 2*(5946 - 653*E_2 + 114*E_4)*M_2*r0_2 + 2*(-2631 + 505*E_2 + 108*E_4)*M*r0_3 + 3*(58 - 15*E_2)*r0_4)) + 4*a_7*E*L*M*(L_2*(96*M_3 + 2*(-134 + 3*E_2)*M_2*r0 - 6*(189 + 38*E_2)*M*r0_2 + 3*(-100 + E_2)*r0_3) - r0*(288*(-37 + 27*E_2)*M_4 - 4*(2567 - 1443*E_2 + 108*E_4)*M_3*r0 + (1222 + 719*E_2 - 270*E_4)*M_2*r0_2 + (2784 + 811*E_2 - 108*E_4)*M*r0_3 + 3*(82 + 23*E_2)*r0_4)) + a_8*(-6*L_2*M*(96*M_3 - 2*(-20 + 233*E_2 + 14*E_4)*M_2*r0 + 4*(-1 - 233*E_2 + 2*E_4)*M*r0_2 + E_2*(-215 + 8*E_2)*r0_3) + E_2*r0*(192*(-111 + 62*E_2)*M_5 + 8*(-4474 + 1649*E_2)*M_4*r0 + (-3949 + 1972*E_2)*M_3*r0_2 - 2*(-5145 + 662*E_2)*M_2*r0_3 - 6*(-309 + E_2)*M*r0_4 - 30*r0_5)) + a_2*r0_2*(-2*L_6*M*(1152*M_3 - 24*(-80 + 197*E_2)*M_2*r0 + 2*(-1002 + 1627*E_2)*M*r0_2 + (360 - 437*E_2)*r0_3) + 3*E_2*r0_6*(4976*M_4 + 4*(-1155 + 626*E_2)*M_3*r0 - 40*(-61 + 15*E_2)*M_2*r0_2 + 2*(-353 + 98*E_2)*M*r0_3 + 15*r0_4) + 8*L_4*M*r0*(4896*M_4 + 4*(-1008 + 275*E_2)*M_3*r0 + (-1668 - 277*E_2 + 197*E_4)*M_2*r0_2 + (1896 - 454*E_2 - 105*E_4)*M*r0_3 + (-324 + 148*E_2 + 51*E_4)*r0_4) + L_2*r0_3*(41472*M_5 + 8*(-4032 + 3071*E_2)*M_4*r0 + 8*(-1188 - 3480*E_2 + 683*E_4)*M_3*r0_2 - 6*(-1956 - 1967*E_2 + 324*E_4)*M_2*r0_3 + 3*(-672 - 655*E_2 + 352*E_4)*M*r0_4 - 15*E_2*r0_5)) + 4*a_5*E*L*M*r0*(6*L_4*(14*M_2 - 44*M*r0 + (-25 + E_2)*r0_2) + L_2*(480*M_4 - 8*(-1393 + 918*E_2)*M_3*r0 + 2*(1960 - 375*E_2 + 102*E_4)*M_2*r0_2 + (-3564 - 143*E_2 + 102*E_4)*M*r0_3 - 6*(69 + 10*E_2)*r0_4) + r0*(-22464*M_5 - 12*(367 + 516*E_2)*M_4*r0 + 2*(11742 - 5065*E_2 + 216*E_4)*M_3*r0_2 + 3*(1141 + 346*E_2 + 126*E_4)*M_2*r0_3 + (-5046 - 527*E_2 + 324*E_4)*M*r0_4 + (159 - 178*E_2)*r0_5)) + a_6*(-12*L_4*M*(16*M_3 + 2*(14 + 15*E_2)*M_2*r0 - 2*(2 + 83*E_2)*M*r0_2 + E_2*(-53 + E_2)*r0_3) + 2*L_2*r0*(288*(-37 + 38*E_2)*M_5 + 12*(-220 - 585*E_2 + 296*E_4)*M_4*r0 + 4*(1044 - 2693*E_2 + 453*E_4)*M_3*r0_2 + (780 + 5621*E_2 + 140*E_4)*M_2*r0_3 + (-360 + 1217*E_2 + 112*E_4)*M*r0_4 - 39*E_2*r0_5) + E_2*r0_2*(44928*M_6 + 48*(631 + 386*E_2)*M_5*r0 + 16*(-3290 + 2187*E_2)*M_4*r0_2 + 2*(-14365 + 5518*E_2)*M_3*r0_3 + (12111 - 2644*E_2)*M_2*r0_4 + 12*(97 + 30*E_2)*M*r0_5 - 93*r0_6)) + a_4*r0*(-12*L_6*M*(8*M_2 - 2*M*r0 + E_2*r0_2) + 3*E_2*r0_4*(18292*M_5 + 4*(-253 + 1862*E_2)*M_4*r0 + (-10739 + 5140*E_2)*M_3*r0_2 + 2*(1687 - 538*E_2)*M_2*r0_3 + 12*(-37 + 21*E_2)*M*r0_4 - 19*r0_5) - 2*L_4*(2304*M_5 - 48*(-215 + 294*E_2)*M_4*r0 - 4*(846 - 1629*E_2 + 122*E_4)*M_3*r0_2 + 2*(-1392 + 541*E_2 + 111*E_4)*M_2*r0_3 + (720 - 703*E_2 - 85*E_4)*M*r0_4 + 24*E_2*r0_5) + 2*L_2*r0*(22464*M_6 + 144*(-44 + 115*E_2)*M_5*r0 + 4*(-5364 + 1699*E_2 + 1400*E_4)*M_4*r0_2 + 2*(2868 - 10673*E_2 + 2326*E_4)*M_3*r0_3 + 2*(2076 + 3331*E_2 - 42*E_4)*M_2*r0_4 + 3*(-348 + 49*E_2 + 160*E_4)*M*r0_5 - 69*E_2*r0_6))))/(3.*r0_5*expr2_3); A03400 = (-2*E*r0_4*(12*a*L*M + 3*a_2*E*(-4*M + r0) + E*r0_2*(-17*M + 2*r0)))/expr2_2; A03420 = (12*a_7*E*L*M*(4*(-27 + 20*E_2)*M_2 + 2*(132 + 11*E_2 + 3*E_4)*M*r0 + (131 - 14*E_2)*r0_2) - 3*a_8*E_2*(8*(-27 + 14*E_2)*M_3 + 4*(284 - 13*E_2)*M_2*r0 + 2*(258 - 19*E_2)*M*r0_2 - 9*r0_3) - 4*a*E*L*M*r0_2*(-12*L_4*(56*M_2 - 58*M*r0 + 15*r0_2) + r0_3*(-5448*M_3 + 12*(400 - 73*E_2)*M_2*r0 + (-1102 + 621*E_2 + 54*E_4)*M*r0_2 + (23 - 108*E_2)*r0_3) - L_2*r0*(3624*M_3 + 4*(-669 + 284*E_2)*M_2*r0 + 16*(13 - 38*E_2)*M*r0_2 + (121 + 27*E_2)*r0_3)) - 4*a_5*E*L*M*(-3*L_2*(16*M_2 + 2*(4 + 21*E_2)*M*r0 + (131 - 8*E_2)*r0_2) + r0*(-72*(-63 + 46*E_2)*M_3 + 18*(185 - 56*E_2 + 8*E_4)*M_2*r0 - (1118 + 63*E_2 + 18*E_4)*M*r0_2 + (-769 + 60*E_2)*r0_3)) + a_6*(-3*L_2*(72*(-3 + 4*E_2)*M_3 + 4*(-20 + 63*E_2 + 26*E_4)*M_2*r0 + 2*E_2*(253 - 8*E_2)*M*r0_2 - 9*E_2*r0_3) + E_2*r0*((9072 - 4800*E_2)*M_4 - 24*(-662 + 141*E_2)*M_3*r0 + 4*(-800 + 63*E_2)*M_2*r0_2 + (-4169 + 180*E_2)*M*r0_3 + 61*r0_4)) + r0_3*(-8*L_4*M*(2*M - r0)*(558*M_2 + (-423 + 169*E_2)*M*r0 + (72 - 91*E_2)*r0_2) + E_2*r0_5*(2556*M_3 + 216*(-13 + E_2)*M_2*r0 + (841 - 162*E_2)*M*r0_2 - 38*r0_3) + L_2*r0_2*(-9504*M_4 + 4*(3024 + 323*E_2)*M_3*r0 + 4*(-1242 - 243*E_2 + 85*E_4)*M_2*r0_2 + (648 + 155*E_2 - 184*E_4)*M*r0_3 + 4*E_2*r0_4)) - 4*a_3*E*L*M*r0*(-24*L_4*M + L_2*(-336*M_3 + 12*(215 - 132*E_2)*M_2*r0 + 12*(21 + 34*E_2)*M*r0_2 - (562 + 3*E_2)*r0_3) + r0*(-10368*M_4 - 36*(-71 + 74*E_2)*M_3*r0 + 2*(3095 - 612*E_2 + 108*E_4)*M_2*r0_2 + 6*(-236 + 78*E_2 + 9*E_4)*M*r0_3 - (353 + 78*E_2)*r0_4)) + a_4*(24*L_4*M*(2*M_2 - 5*(-2 + 3*E_2)*M*r0 + 2*E_2*r0_2) - L_2*r0*(144*(-63 + 76*E_2)*M_4 + 24*(107 - 245*E_2 + 40*E_4)*M_3*r0 + 12*(184 - 338*E_2 + 57*E_4)*M_2*r0_2 + (-648 + 2809*E_2 + 24*E_4)*M*r0_3 + 2*E_2*r0_4) - E_2*r0_2*(20736*M_5 + 48*(123 + 146*E_2)*M_4*r0 + 4*(-5005 + 1836*E_2)*M_3*r0_2 - 4*(422 + 147*E_2)*M_2*r0_3 + 3*(971 + 48*E_2)*M*r0_4 - 15*r0_5)) - a_2*r0*(-12*L_4*M*(96*M_3 + 4*(79 - 156*E_2)*M_2*r0 + (-296 + 419*E_2)*M*r0_2 + (54 - 59*E_2)*r0_3) + E_2*r0_4*(12216*M_4 + 24*(-289 + 203*E_2)*M_3*r0 + 4*(320 - 201*E_2)*M_2*r0_2 + 3*(-175 + 124*E_2)*M*r0_3 + 57*r0_4) + L_2*r0*(20736*M_5 + 2304*(-7 + 4*E_2)*M_4*r0 + 16*(-414 - 120*E_2 + 61*E_4)*M_3*r0_2 + 4*(1854 - 817*E_2 + 40*E_4)*M_2*r0_3 + 8*(-162 + 127*E_2 + 32*E_4)*M*r0_4 + 25*E_2*r0_5)))/(3.*r0_2*expr2_3); A03600 = (r0*(12*a_5*E*L*M*(4*(-7 + 6*E_2)*M + (73 - 12*E_2)*r0) + 3*a_6*E_2*(-8*(-7 + 4*E_2)*M_2 + 4*(-73 + 6*E_2)*M*r0 + 7*r0_2) + 4*a_3*E*L*M*(24*L_2*M - r0*((624 - 456*E_2)*M_2 + 40*(10 + E_2)*M*r0 + (-286 + 21*E_2)*r0_2)) + r0_2*(-6*L_2*M*(2*M - r0)*(264*M_2 + 2*(-102 + 31*E_2)*M*r0 + 3*(12 - 13*E_2)*r0_2) + E_2*r0_3*(852*M_3 + 24*(-38 + 3*E_2)*M_2*r0 + (271 - 54*E_2)*M*r0_2 - 14*r0_3)) + a_4*(-24*L_2*M*((-7 + 12*E_2)*M - 3*E_2*r0) + E_2*r0*(-32*(-39 + 19*E_2)*M_3 - 8*(-329 + 33*E_2)*M_2*r0 + (-1569 + 74*E_2)*M*r0_2 + 28*r0_3)) + 4*a*E*L*M*r0*(4*L_2*(38*M_2 - 43*M*r0 + 12*r0_2) + r0*(1584*M_3 + 4*(-268 + 93*E_2)*M_2*r0 + 2*(18 - 97*E_2)*M*r0_2 + 5*(11 + 3*E_2)*r0_3)) - a_2*r0*(2*L_2*M*(48*(-13 + 19*E_2)*M_2 + (516 - 556*E_2)*M*r0 + (-96 + 91*E_2)*r0_2) + E_2*r0*(3168*M_4 + 8*(-32 + 93*E_2)*M_3*r0 + 4*(-373 + 16*E_2)*M_2*r0_2 + 2*(211 + 26*E_2)*M*r0_3 + 7*r0_4))))/(12.*expr2_3); A04020 = (48*E_2*r0_3*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/expr2_2; A04040 = (8*(-4*a_7*E*L*M*(144*M_3 + 12*(3 + 8*E_2)*M_2*r0 + 2*(-51 + 32*E_2)*M*r0_2 + 3*(-14 + E_2)*r0_3) + a_8*E_2*(288*M_4 + 48*(-3 + 2*E_2)*M_3*r0 + 2*(-271 + 60*E_2)*M_2*r0_2 + 6*(-35 + 6*E_2)*M*r0_3 - 3*r0_4) + 4*a*E*L*M*r0_3*(L_4*(216*M_2 + 4*(-72 + E_2)*M*r0 - 6*(-13 + E_2)*r0_2) - 3*r0_4*(-120*M_2 + (124 + 35*E_2)*M*r0 + 4*(-7 + E_2)*r0_2) + 3*L_2*r0_2*(192*M_2 - (220 + 51*E_2)*M*r0 + 2*(27 + E_2)*r0_2)) - 4*a_5*E*L*M*r0*(-1152*M_4 + 24*(-7 + 2*E_2)*M_3*r0 + 2*(408 + 113*E_2)*M_2*r0_2 + 229*E_2*M*r0_3 + 8*(-21 + E_2)*r0_4 + 3*L_2*(64*M_2 + 2*(-7 + 13*E_2)*M*r0 + (-28 + 3*E_2)*r0_2)) + r0_3*(-4*L_6*M*(2*M - r0)*(72*M + (-36 + E_2)*r0) + 3*E_2*r0_7*(159*M_2 + 4*(-21 + E_2)*M*r0 + 3*r0_2) + 3*L_2*r0_4*(-192*M_3 + 2*(96 + 197*E_2)*M_2*r0 + 4*(-12 - 51*E_2 + 2*E_4)*M*r0_2 + 5*E_2*r0_3) + L_4*r0_2*(-1152*M_3 + (1152 + 721*E_2)*M_2*r0 + 4*(-72 - 95*E_2 + 2*E_4)*M*r0_2 + 12*E_2*r0_3)) - 4*a_3*E*L*M*r0_2*(6*L_4*(10*M + (-7 + E_2)*r0) + 3*L_2*(-336*M_3 + 4*(47 + 2*E_2)*M_2*r0 + (154 + 71*E_2)*M*r0_2 + (-82 + 3*E_2)*r0_3) + r0_2*(-1296*M_3 + 6*(98 + 9*E_2)*M_2*r0 + 2*(237 + 145*E_2)*M*r0_2 + (-210 + 17*E_2)*r0_3)) + a_2*r0_2*(12*L_6*M*(6*M + E_2*r0) + 6*E_2*r0_5*(40*M_3 + 2*(91 - 18*E_2)*M_2*r0 + (-149 + 12*E_2)*M*r0_2 + 6*r0_3) - 2*L_4*(1152*M_4 + 48*(-12 + E_2)*M_3*r0 + 2*(-180 - 315*E_2 + 2*E_4)*M_2*r0_2 + (144 + 265*E_2 - 10*E_4)*M*r0_3 - 12*E_2*r0_4) + 3*L_2*r0_2*(-768*M_4 + 24*(16 + 5*E_2)*M_3*r0 + 4*(54 + 205*E_2 + 9*E_4)*M_2*r0_2 + 2*(-48 - 257*E_2 + 16*E_4)*M*r0_3 + 19*E_2*r0_4)) + 2*a_6*(L_2*(144*M_4 + 48*(3 + 8*E_2)*M_3*r0 + 2*(18 - 44*E_2 + 27*E_4)*M_2*r0_2 + 3*E_2*(-67 + 8*E_2)*M*r0_3 - 3*E_2*r0_4) + E_2*r0*(-1152*M_5 - 48*(7 + 2*E_2)*M_4*r0 + 2*(313 - 72*E_2)*M_3*r0_2 + (-403 + 60*E_2)*M_2*r0_3 + 3*(-127 + 20*E_2)*M*r0_4 + 6*r0_5)) + a_4*r0*(3*L_4*(96*M_3 + 4*(12 + 31*E_2)*M_2*r0 + 4*E_2*(-15 + E_2)*M*r0_2 - E_2*r0_3) + 3*E_2*r0_3*(-740*M_4 + 4*(137 - 48*E_2)*M_3*r0 + (101 - 72*E_2)*M_2*r0_2 + 2*(-199 + 24*E_2)*M*r0_3 + 14*r0_4) - 2*L_2*(1152*M_5 + 672*E_2*M_4*r0 + 4*(-180 - 287*E_2 + 12*E_4)*M_3*r0_2 - (72 + 527*E_2 + 84*E_4)*M_2*r0_3 + 3*(24 + 211*E_2 - 20*E_4)*M*r0_4 - 18*E_2*r0_5))))/(3.*r0_4*expr2_3); A04200 = (12*E_2*r0_6)/expr2_2; A04220 = (4*(2*a_5*E*L*M*(-48*M_2 + 2*(3 - 8*E_2)*M*r0 + (20 + E_2)*r0_2) + a_6*E_2*M*(48*M_2 + 4*(-9 + 2*E_2)*M*r0 + (-47 + 6*E_2)*r0_2) - 2*a_3*E*L*M*r0*(-384*M_3 + 4*(31 + 4*E_2)*M_2*r0 + (158 + 45*E_2)*M*r0_2 - (58 + 7*E_2)*r0_3 + 4*L_2*(8*M + (-5 + E_2)*r0)) - 2*a*E*L*M*r0_2*(-4*L_2*(42*M_2 - 43*M*r0 - (-9 + E_2)*r0_2) + r0_2*(-216*M_2 + (200 + 39*E_2)*M*r0 + 2*(-19 + 2*E_2)*r0_2)) + r0_2*(-48*L_4*M*r0_2M_2 + E_2*r0_5*(159*M_2 + 2*(-43 + 2*E_2)*M*r0 + 4*r0_2) + L_2*r0_2*(-192*M_3 + 3*(64 + 67*E_2)*M_2*r0 + (-48 - 107*E_2 + 4*E_4)*M*r0_2 + 4*E_2*r0_3)) + a_4*(4*L_2*M*(12*M_2 + 2*(3 + 8*E_2)*M*r0 + E_2*(-12 + E_2)*r0_2) + E_2*r0*(-384*M_4 - 8*(-7 + E_2)*M_3*r0 + (57 - 8*E_2)*M_2*r0_2 + 8*(-19 + 2*E_2)*M*r0_3 + 10*r0_4)) + a_2*r0*(4*L_4*M*(6*M + E_2*r0) + E_2*r0_3*(-56*M_3 - 8*(-29 + 4*E_2)*M_2*r0 + 7*(-29 + 2*E_2)*M*r0_2 + 14*r0_3) + L_2*(-384*M_4 - 8*(-24 + 13*E_2)*M_3*r0 + 10*(12 + 25*E_2)*M_2*r0_2 + (-48 - 147*E_2 + 8*E_4)*M*r0_3 + 15*E_2*r0_4))))/(r0*expr2_3); A04400 = (r0_2*(-72*a_3*E*L*M*(2*M - r0) - 24*a*E*L*M*r0*(-48*M_2 + 2*(19 + E_2)*M*r0 - 5*r0_2) + 9*a_4*E_2*(8*M_2 - 8*M*r0 + r0_2) + r0*(-12*L_2*M*(2*M - r0)*(24*M - (12 + E_2)*r0) + E_2*r0_3*(477*M_2 + 2*(-127 + 6*E_2)*M*r0 + 10*r0_2)) + 2*a_2*(36*L_2*M_2 + E_2*r0*(-288*M_3 + 12*(14 + E_2)*M_2*r0 + 6*(-27 + E_2)*M*r0_2 + 17*r0_3))))/(6.*expr2_3); A05020 = (-8*E*r0*(2*a_3*L*M*(12*M + (6 + E_2)*r0) + a_4*E*(-24*M_2 - 9*M*r0 + 2*r0_2) + 6*a*L*M*r0*(2*L_2 + (2 + E_2)*r0_2) + E*r0_3*(r0_2*(-16*M + r0) + 2*L_2*(-9*M + r0)) + a_2*E*r0*(2*L_2*(-7*M + r0) + r0*(-26*M_2 - 27*M*r0 + 3*r0_2))))/expr2_3; A05040 = (-4*(-(a_10*E_2*M*(96*(-9 + 4*E_2)*M_3 + 4*(-272 + 169*E_2)*M_2*r0 + 6*(43 + 34*E_2)*M*r0_2 + 15*(23 - 2*E_2)*r0_3)) + 2*a_9*E*L*M*(96*(-9 + 7*E_2)*M_3 + 4*(-268 + 51*E_2 + 27*E_4)*M_2*r0 + 6*(-2 - 43*E_2 + 12*E_4)*M*r0_2 - 9*(-18 + E_2)*r0_3) + 2*a*E*L*M*r0_3*(-8*L_6*(110*M_2 - 109*M*r0 + 27*r0_2) + L_2*r0_3*(-9024*M_3 + (12900 - 2237*E_2)*M_2*r0 + 8*(-747 + 301*E_2 + 21*E_4)*M*r0_2 + 6*(141 - 95*E_2)*r0_3) + 3*r0_5*(-2080*M_3 - 5*(-538 + 51*E_2)*M_2*r0 + 4*(-287 + 81*E_2 + 18*E_4)*M*r0_2 + 2*(77 - 41*E_2)*r0_3) - 2*L_4*r0*(1296*M_3 + (-1879 + 864*E_2)*M_2*r0 + 2*(403 - 292*E_2)*M*r0_2 + 12*(-7 + 6*E_2)*r0_3)) + r0_4*(6*L_6*M*r0_2M_2*(180*M + (-48 + 77*E_2)*r0) - 3*E_2*M*r0_7*(688*M_2 + (-673 + 60*E_2)*M*r0 + (163 - 30*E_2)*r0_2) + 2*L_4*r0_2*(4608*M_4 + (-5904 + 7*E_2)*M_3*r0 - 3*(-816 + 109*E_2 + 52*E_4)*M_2*r0_2 + 2*(-162 + 118*E_2 + 39*E_4)*M*r0_3 - 36*E_2*r0_4) - L_2*r0_4*(-4896*M_4 + 2*(3168 + 1901*E_2)*M_3*r0 + (-2664 - 3213*E_2 + 524*E_4)*M_2*r0_2 + (360 + 551*E_2 - 248*E_4)*M*r0_3 + 48*E_2*r0_4)) + 2*a_3*E*L*M*r0_2*(24*L_6*M - 2*L_4*(768*M_3 + 12*(-210 + 89*E_2)*M_2*r0 + 4*(299 - 154*E_2)*M*r0_2 + 63*(-2 + E_2)*r0_3) + 2*r0_3*(-11856*M_4 + (7584 - 3525*E_2)*M_3*r0 + 2*(2298 + 218*E_2 - 135*E_4)*M_2*r0_2 + (-4356 + 467*E_2 + 396*E_4)*M*r0_3 + (786 - 119*E_2)*r0_4) + L_2*r0*(-17184*M_4 - 16*(-747 + 397*E_2)*M_3*r0 + 3*(4080 - 29*E_2 + 40*E_4)*M_2*r0_2 + 6*(-1802 + 381*E_2 + 66*E_4)*M*r0_3 + 6*(327 - 28*E_2)*r0_4)) + 2*a_7*E*L*M*(L_2*(480*M_3 + 4*(-358 + 255*E_2)*M_2*r0 + 12*(-57 - 7*E_2 + 3*E_4)*M*r0_2 + 9*(36 + E_2)*r0_3) + 2*r0*(-48*(-137 + 90*E_2)*M_4 + 4*(883 - 642*E_2 + 36*E_4)*M_3*r0 + 2*(-1495 + 172*E_2 + 171*E_4)*M_2*r0_2 + 2*(-438 - 265*E_2 + 126*E_4)*M*r0_3 + 3*(162 - 13*E_2)*r0_4)) + a_8*(-3*L_2*M*(288*(-1 + 2*E_2)*M_3 + 4*(-88 - 181*E_2 + 90*E_4)*M_2*r0 + 4*(-26 - 122*E_2 + 39*E_4)*M*r0_2 + E_2*(227 - 4*E_2)*r0_3) + E_2*r0*(96*(-137 + 68*E_2)*M_5 + 16*(-643 + 404*E_2)*M_4*r0 - 8*(-599 + 92*E_2)*M_3*r0_2 + 2*(453 - 598*E_2)*M_2*r0_3 + 6*(-359 + 35*E_2)*M*r0_4 - 45*r0_5)) + a_2*r0_2*(-4*L_6*M*(288*M_3 + 6*(111 - 206*E_2)*M_2*r0 + 8*(-75 + 112*E_2)*M*r0_2 + (90 - 131*E_2)*r0_3) + 3*E_2*r0_6*(1714*M_4 + (-3143 + 1444*E_2)*M_3*r0 + 4*(689 - 127*E_2)*M_2*r0_2 + 2*(-404 + 65*E_2)*M*r0_3 + 21*r0_4) + 2*L_4*r0*(10080*M_5 + 8*(-1062 + 343*E_2)*M_4*r0 + 3*(-1328 - 1133*E_2 + 228*E_4)*M_3*r0_2 + (4284 + 941*E_2 - 640*E_4)*M_2*r0_3 + (-684 - 233*E_2 + 167*E_4)*M*r0_4 + 84*E_2*r0_5) + L_2*r0_3*(21312*M_5 + 2*(-8496 + 5273*E_2)*M_4*r0 + (-5304 - 21071*E_2 + 5296*E_4)*M_3*r0_2 + (6456 + 14171*E_2 - 4516*E_4)*M_2*r0_3 + (-1080 - 3485*E_2 + 848*E_4)*M*r0_4 + 165*E_2*r0_5)) + 2*a_5*E*L*M*r0*(18*L_4*(20*M_2 + 2*(-18 + 5*E_2)*M*r0 + (9 + E_2)*r0_2) + L_2*(192*M_4 - 464*(-31 + 18*E_2)*M_3*r0 + 4*(-151 + 417*E_2 + 42*E_4)*M_2*r0_2 + 2*(-2814 + 59*E_2 + 132*E_4)*M*r0_3 + 3*(480 - 41*E_2)*r0_4) + r0*(-23040*M_5 + 24*(23 - 268*E_2)*M_4*r0 + 2*(13716 - 5383*E_2)*M_3*r0_2 + 3*(-1294 + 939*E_2 + 108*E_4)*M_2*r0_3 + 4*(-1752 - 53*E_2 + 252*E_4)*M*r0_4 + (1920 - 61*E_2)*r0_5)) + a_6*(-6*L_4*M*(32*M_3 + 20*(-8 + 15*E_2)*M_2*r0 + 2*(-52 - 123*E_2 + 22*E_4)*M*r0_2 + E_2*(59 + 3*E_2)*r0_3) - L_2*r0*(-96*(-137 + 132*E_2)*M_5 - 192*(-20 - 62*E_2 + 25*E_4)*M_4*r0 + 8*(-765 + 355*E_2 + 168*E_4)*M_3*r0_2 + 4*(-438 - 2108*E_2 + 457*E_4)*M_2*r0_3 + (360 + 3643*E_2 - 376*E_4)*M*r0_4 + 117*E_2*r0_5) + E_2*r0_2*(23040*M_6 + 48*(121 + 196*E_2)*M_5*r0 + 2*(-14153 + 9504*E_2)*M_4*r0_2 + (2243 + 4408*E_2)*M_3*r0_3 + 20*(387 - 136*E_2)*M_2*r0_4 + 3*(-1429 + 180*E_2)*M*r0_5 - 27*r0_6)) + a_4*r0*(-6*L_6*M*(16*M_2 + 4*(-13 + 9*E_2)*M*r0 + 3*E_2*r0_2) + 3*E_2*r0_4*(8580*M_5 + 8*(-541 + 488*E_2)*M_4*r0 + 6*(-529 + 464*E_2)*M_3*r0_2 + (4131 - 1024*E_2)*M_2*r0_3 + (-1471 + 220*E_2)*M*r0_4 + 27*r0_5) - 4*L_4*(576*M_5 - 48*(-68 + 81*E_2)*M_4*r0 - 2*(426 - 1347*E_2 + 94*E_4)*M_3*r0_2 + 2*(-519 - 371*E_2 + 144*E_4)*M_2*r0_3 - 5*(-36 - 49*E_2 + 8*E_4)*M*r0_4 + 18*E_2*r0_5) + L_2*r0*(23040*M_6 + 768*(-9 + 23*E_2)*M_5*r0 + 4*(-6096 - 1097*E_2 + 2020*E_4)*M_4*r0_2 + (6096 - 20243*E_2 + 4280*E_4)*M_3*r0_3 + 2*(2616 + 9131*E_2 - 2004*E_4)*M_2*r0_4 + 4*(-270 - 1285*E_2 + 241*E_4)*M*r0_5 + 96*E_2*r0_6))))/(3.*r0_5*expr2_4); A05200 = (-2*E*r0_4*(12*a*L*M + E*r0_2*(-16*M + r0) + 3*a_2*E*(-4*M + r0)))/expr2_3; A05220 = (-6*a_7*E*L*M*(16*(-12 + 7*E_2)*M_2 + 4*(-78 - 4*E_2 + 3*E_4)*M*r0 + (-32 + 23*E_2)*r0_2) + 3*a_8*E_2*(64*(-3 + E_2)*M_3 + 8*(-62 + 13*E_2)*M_2*r0 - (21 + 2*E_2)*M*r0_2 + 9*r0_3) - 6*a_5*E*L*M*(4*L_2*(20*M_2 + (-62 + 21*E_2)*M*r0 + 2*(-4 + E_2)*r0_2) + r0*(-64*(-61 + 39*E_2)*M_3 + 4*(119 - 45*E_2 + 18*E_4)*M_2*r0 + 2*(-688 + 39*E_2 + 48*E_4)*M*r0_2 + (148 + 7*E_2)*r0_3)) - 2*a*E*L*M*r0_2*(-360*L_4*r0_2M_2 - 2*L_2*r0*(3792*M_3 + 22*(-207 + 64*E_2)*M_2*r0 + 2*(867 - 482*E_2)*M*r0_2 + 3*(-60 + 37*E_2)*r0_3) - 3*r0_3*(3712*M_3 + (-4372 + 671*E_2)*M_2*r0 - 4*(-424 + 161*E_2 + 18*E_4)*M*r0_2 + 2*(-102 + 67*E_2)*r0_3)) + 3*a_6*(L_2*(96*(-2 + 3*E_2)*M_3 + 8*(-16 - 63*E_2 + 13*E_4)*M_2*r0 + 8*E_2*(-2 + E_2)*M*r0_2 + 9*E_2*r0_3) + E_2*r0*(-64*(-61 + 28*E_2)*M_4 + 4*(458 - 195*E_2)*M_3*r0 + 8*(-202 + 59*E_2)*M_2*r0_2 + (247 - 74*E_2)*M*r0_3 + 11*r0_4)) + r0_3*(-4*L_4*M*(2*M - r0)*(1152*M_2 + (-900 + 379*E_2)*M*r0 + (162 - 193*E_2)*r0_2) + 6*E_2*r0_5*(688*M_3 + (-679 + 60*E_2)*M_2*r0 - 6*(-27 + 5*E_2)*M*r0_2 + 2*r0_3) + L_2*r0_2*(-9792*M_4 + 2*(6336 + 1277*E_2)*M_3*r0 + (-5328 - 1863*E_2 + 524*E_4)*M_2*r0_2 + 4*(180 + 29*E_2 - 62*E_4)*M*r0_3 + 84*E_2*r0_4)) - 6*a_3*E*L*M*r0*(16*L_4*M - 2*L_2*(160*M_3 + 4*(-293 + 153*E_2)*M_2*r0 + 2*(271 - 170*E_2)*M*r0_2 + (-38 + 33*E_2)*r0_3) + r0*(-7104*M_4 - 112*(-33 + 17*E_2)*M_3*r0 + (4016 - 665*E_2 + 72*E_4)*M_2*r0_2 + 2*(-1388 + 291*E_2 + 78*E_4)*M*r0_3 + 4*(96 - 29*E_2)*r0_4)) + 3*a_4*(8*L_4*M*(4*M_2 + (-16 + 15*E_2)*M*r0 + E_2*r0_2) - L_2*r0*(64*(-61 + 66*E_2)*M_4 + 4*(220 - 841*E_2 + 132*E_4)*M_3*r0 + 4*(298 + 261*E_2 - 122*E_4)*M_2*r0_2 + 4*(-54 - 55*E_2 + 19*E_4)*M*r0_3 + 13*E_2*r0_4) - E_2*r0_2*(7104*M_5 + 144*(-12 + 17*E_2)*M_4*r0 + (-4937 + 2528*E_2)*M_3*r0_2 + (3037 - 864*E_2)*M_2*r0_3 + 2*(-460 + 101*E_2)*M*r0_4 + 42*r0_5)) - a_2*r0*(-24*L_4*M*(48*M_3 + (218 - 342*E_2)*M_2*r0 + (-180 + 253*E_2)*M*r0_2 + (27 - 37*E_2)*r0_3) + 3*E_2*r0_4*(3346*M_4 + 3*(-1429 + 620*E_2)*M_3*r0 + (3385 - 632*E_2)*M_2*r0_2 + 2*(-529 + 95*E_2)*M*r0_3 + 40*r0_4) + L_2*r0*(21312*M_5 + 48*(-354 + 209*E_2)*M_4*r0 + 2*(-3936 - 5001*E_2 + 1084*E_4)*M_3*r0_2 + (8376 + 4361*E_2 - 1732*E_4)*M_2*r0_3 + 4*(-342 - 338*E_2 + 125*E_4)*M*r0_4 + 156*E_2*r0_5)))/(3.*r0_2*expr2_4); A05400 = (r0*(-36*a_5*E*L*M*(-4*M + (-15 + 2*E_2)*r0) + 9*a_6*E_2*(-8*M_2 + 4*(-15 + E_2)*M*r0 + r0_2) + 4*a_3*E*L*M*r0*(12*(-107 + 66*E_2)*M_2 - 6*(-61 + 56*E_2)*M*r0 + (80 + 33*E_2)*r0_2) + a_4*(36*L_2*M*(-2*M + E_2*r0) + E_2*r0*(-24*(-107 + 44*E_2)*M_3 + 24*(19 + 5*E_2)*M_2*r0 - 2*(238 + 27*E_2)*M*r0_2 - 13*r0_3)) + r0_2*(-6*L_2*M*(2*M - r0)*(408*M_2 + 4*(-81 + 26*E_2)*M*r0 + (60 - 59*E_2)*r0_2) + E_2*r0_3*(2064*M_3 + 45*(-45 + 4*E_2)*M_2*r0 + 2*(244 - 45*E_2)*M*r0_2 + 2*r0_3)) + 4*a*E*L*M*r0*(12*L_2*(22*M_2 - 23*M*r0 + 6*r0_2) + r0*(2448*M_3 + 3*(-841 + 208*E_2)*M_2*r0 + 2*(406 - 213*E_2)*M*r0_2 + (-70 + 51*E_2)*r0_3)) - a_2*r0*(6*L_2*M*((-428 + 528*E_2)*M_2 - 4*(-80 + 97*E_2)*M*r0 + (-48 + 61*E_2)*r0_2) + E_2*r0*(4896*M_4 + 12*(-313 + 104*E_2)*M_3*r0 + (1919 - 372*E_2)*M_2*r0_2 + 60*(-11 + 3*E_2)*M*r0_3 + 62*r0_4))))/(12.*expr2_4); A06000 = (4*E_2*r0_6)/expr2_3; A06020 = (2*(-24*a_5*E*L*M*(12*M_2 + (-8 + 7*E_2)*M*r0 + (-8 + E_2)*r0_2) + 3*a_6*E_2*(48*M_3 + 4*(-22 + 5*E_2)*M_2*r0 + 2*(-35 + 6*E_2)*M*r0_2 + r0_3) - 8*a_3*E*L*M*r0*(-192*M_3 + 2*(63 - 2*E_2)*M_2*r0 + (93 + 34*E_2)*M*r0_2 + 3*(-19 + 2*E_2)*r0_3 + 6*L_2*(4*M + (-4 + E_2)*r0)) + 8*a*E*L*M*r0_2*(r0_2*(108*M_2 - (135 + 13*E_2)*M*r0 + 3*(11 - 5*E_2)*r0_2) + L_2*(84*M_2 + (-123 + 4*E_2)*M*r0 + 3*(11 - 2*E_2)*r0_2)) + r0_2*(-8*L_4*M*(2*M - r0)*(24*M + (-12 + E_2)*r0) + E_2*M*r0_5*(427*M + 20*(-10 + E_2)*r0) + L_2*r0_2*(-384*M_3 + 3*(128 + 161*E_2)*M_2*r0 + 4*(-24 - 51*E_2 + 4*E_4)*M*r0_2 - 12*E_2*r0_3)) + a_4*(3*L_2*(48*M_3 + 4*(6 + 19*E_2)*M_2*r0 + 4*E_2*(-17 + 2*E_2)*M*r0_2 + E_2*r0_3) + E_2*r0*(-768*M_4 + 16*(39 - 4*E_2)*M_3*r0 + 8*(16 + E_2)*M_2*r0_2 + 2*(-283 + 46*E_2)*M*r0_3 + 39*r0_4)) + a_2*r0*(24*L_4*M*(3*M + E_2*r0) + E_2*r0_3*(62*M_3 + (783 - 100*E_2)*M_2*r0 + 2*(-311 + 38*E_2)*M*r0_2 + 36*r0_3) + L_2*(-768*M_4 - 128*(-3 + 2*E_2)*M_3*r0 + 8*(33 + 108*E_2 - 2*E_4)*M_2*r0_2 + 2*(-48 - 219*E_2 + 20*E_4)*M*r0_3 + 48*E_2*r0_4))))/(3.*r0*expr2_4); A06200 = (r0_2*(-24*a_3*E*L*M*(6*M + (-7 + 2*E_2)*r0) + 3*a_4*E_2*(24*M_2 + 8*(-7 + E_2)*M*r0 + 5*r0_2) + 8*a*E*L*M*r0*(96*M_2 + (-111 + 2*E_2)*M*r0 - 6*(-4 + E_2)*r0_2) + M*r0*(-4*L_2*(2*M - r0)*(48*M + (-24 + E_2)*r0) + E_2*r0_3*(427*M + 20*(-10 + E_2)*r0)) + a_2*(24*L_2*M*(3*M + E_2*r0) + 2*E_2*r0*(-192*M_3 - 4*(-63 + E_2)*M_2*r0 + (-199 + 22*E_2)*M*r0_2 + 18*r0_3))))/(6.*expr2_4); A07000 = (2*E*r0_4*(-4*a*L*M + a_2*E*(4*M - r0) + 5*E*M*r0_2))/expr2_4; A07020 = (-12*a_7*E*L*M*(4*(-25 + 16*E_2)*M_2 + 2*(-8 + E_2 + 3*E_4)*M*r0 + 3*(11 + E_2)*r0_2) + 3*a_8*E_2*(40*(-5 + 2*E_2)*M_3 + 4*(12 + 13*E_2)*M_2*r0 - 2*(-79 + 7*E_2)*M*r0_2 + 3*r0_3) - 4*a*E*L*M*r0_2*(-4*L_4*(64*M_2 - 62*M*r0 + 15*r0_2) + L_2*r0*(-1320*M_3 + 3*(693 - 188*E_2)*M_2*r0 + 4*(-249 + 112*E_2)*M*r0_2 + 3*(44 - 23*E_2)*r0_3) + r0_3*(-1896*M_3 + (2719 - 377*E_2)*M_2*r0 + 2*(-628 + 191*E_2 + 27*E_4)*M*r0_2 + 3*(58 - 17*E_2)*r0_3)) - 4*a_5*E*L*M*(3*L_2*(32*M_2 + 2*(-40 + 21*E_2)*M*r0 + 33*r0_2) + r0*(-24*(-99 + 58*E_2)*M_3 + 2*(-302 + 67*E_2 + 12*E_4)*M_2*r0 + 2*(-499 + 64*E_2 + 51*E_4)*M*r0_2 + 3*(131 - 6*E_2)*r0_3)) + M*r0_3*(E_2*r0_5*(1799*M_2 + 2*(-843 + 80*E_2)*M*r0 + 2*(191 - 29*E_2)*r0_2) - 12*L_4*(2*M - r0)*(132*M_2 + (-106 + 47*E_2)*M*r0 + (20 - 23*E_2)*r0_2) + L_2*r0_2*(-3360*M_3 + (4416 + 1187*E_2)*M_2*r0 + 12*(-158 - 77*E_2 + 20*E_4)*M*r0_2 + 2*(132 + 77*E_2 - 54*E_4)*r0_3)) + a_6*(L_2*(24*(-25 + 36*E_2)*M_3 + 12*(-28 - 63*E_2 + 26*E_4)*M_2*r0 + 474*E_2*M*r0_2 + 9*E_2*r0_3) - E_2*r0*(16*(-297 + 124*E_2)*M_4 + 4*(382 + 113*E_2)*M_3*r0 - 54*(-39 + 16*E_2)*M_2*r0_2 + 3*(-601 + 64*E_2)*M*r0_3 + 9*r0_4)) - 4*a_3*E*L*M*r0*(24*L_4*M + L_2*(-208*M_3 - 24*(-61 + 29*E_2)*M_2*r0 + 2*(-567 + 274*E_2)*M*r0_2 + 3*(84 - 23*E_2)*r0_3) + r0*(-3648*M_4 + 2*(1387 - 500*E_2)*M_3*r0 + (1995 - 317*E_2)*M_2*r0_2 + 2*(-1124 + 234*E_2 + 69*E_4)*M*r0_3 + 12*(39 - 7*E_2)*r0_4)) + a_4*(24*L_4*M_2*(2*M + (-14 + 15*E_2)*r0) - L_2*r0*(48*(-99 + 100*E_2)*M_4 + 4*(222 - 1159*E_2 + 184*E_4)*M_3*r0 - 4*(-408 - 802*E_2 + 303*E_4)*M_2*r0_2 + (-216 - 1307*E_2 + 152*E_4)*M*r0_3 + 36*E_2*r0_4) - E_2*r0_2*(7296*M_5 + 8*(-643 + 316*E_2)*M_4*r0 + 52*(-63 + 50*E_2)*M_3*r0_2 + (6293 - 1452*E_2)*M_2*r0_3 + (-2665 + 316*E_2)*M*r0_4 + 90*r0_5)) - a_2*r0*(-4*L_4*M*(96*M_3 + 24*(23 - 31*E_2)*M_2*r0 + 35*(-12 + 17*E_2)*M*r0_2 + (54 - 91*E_2)*r0_3) + E_2*r0_4*(2654*M_4 + (-6017 + 1988*E_2)*M_3*r0 + (5939 - 856*E_2)*M_2*r0_2 + 16*(-113 + 14*E_2)*M*r0_3 + 72*r0_4) + L_2*r0*(7296*M_5 + 64*(-93 + 56*E_2)*M_4*r0 + 24*(-126 - 230*E_2 + 47*E_4)*M_3*r0_2 + (3096 + 3429*E_2 - 1228*E_4)*M_2*r0_3 + 2*(-240 - 567*E_2 + 130*E_4)*M*r0_4 + 84*E_2*r0_5)))/(3.*r0_2*expr2_5); A07200 = -(r0*(12*a_5*E*L*M*(4*(-11 + 6*E_2)*M + (13 - 4*E_2)*r0) - 3*a_6*E_2*(8*(-11 + 4*E_2)*M_2 + (52 - 8*E_2)*M*r0 - 3*r0_2) - 4*a_3*E*L*M*(-24*L_2*M + r0*(120*(-9 + 5*E_2)*M_2 + 20*(43 - 20*E_2)*M*r0 + 3*(-54 + 19*E_2)*r0_2)) + M*r0_2*(2*L_2*(2*M - r0)*(840*M_2 + 2*(-342 + 113*E_2)*M*r0 + (132 - 115*E_2)*r0_2) + E_2*r0_3*(-1799*M_2 - 2*(-843 + 80*E_2)*M*r0 + 2*(-191 + 29*E_2)*r0_2)) + a_4*(24*L_2*M*((11 - 12*E_2)*M + E_2*r0) + E_2*r0*(80*(-27 + 10*E_2)*M_3 - 8*(-241 + 51*E_2)*M_2*r0 + (-859 + 130*E_2)*M*r0_2 + 42*r0_3)) - 4*a*E*L*M*r0*(4*L_2*(50*M_2 - 49*M*r0 + 12*r0_2) + r0*(1680*M_3 + (-2239 + 452*E_2)*M_2*r0 + 2*(487 - 179*E_2)*M*r0_2 + 9*(-14 + 5*E_2)*r0_3)) + a_2*r0*(2*L_2*M*(120*(-9 + 10*E_2)*M_2 + (756 - 988*E_2)*M*r0 + (-96 + 145*E_2)*r0_2) + E_2*r0*(3360*M_4 + 4*(-1135 + 226*E_2)*M_3*r0 + (3707 - 520*E_2)*M_2*r0_2 + 4*(-293 + 41*E_2)*M*r0_3 + 72*r0_4))))/(12.*expr2_5); A08000 = (r0_2*(-12*a_3*E*L*M*(2*M + (-3 + E_2)*r0) + 3*a_4*E_2*(4*M_2 + 2*(-6 + E_2)*M*r0 + r0_2) + 4*a*E*L*M*r0*(24*M_2 + 2*(-18 + E_2)*M*r0 - 3*(-3 + E_2)*r0_2) + M*r0*(E_2*r0_3*(65*M + 4*(-7 + E_2)*r0) - 2*L_2*(2*M - r0)*(12*M + (-6 + E_2)*r0)) + 2*a_2*(3*L_2*M*(2*M + E_2*r0) + E_2*r0*(-24*M_3 - 2*(-24 + E_2)*M_2*r0 + 5*(-7 + E_2)*M*r0_2 + 3*r0_3))))/(3.*expr2_5); A09000 = -(r0*(6*a_5*E*L*M*(4*(-5 + 3*E_2)*M + (14 - 3*E_2)*r0) + 3*a_6*E_2*((20 - 8*E_2)*M_2 + (-28 + 3*E_2)*M*r0 + r0_2) + 2*a_3*E*L*M*(12*L_2*M + r0*((324 - 168*E_2)*M_2 + 2*(-181 + 71*E_2)*M*r0 + 3*(30 - 7*E_2)*r0_2)) + 3*M*r0_2*(L_2*(2*M - r0)*(72*M_2 + 20*(-3 + E_2)*M*r0 + 3*(4 - 3*E_2)*r0_2) + 2*E_2*r0_3*(-45*M_2 + (41 - 4*E_2)*M*r0 + (-9 + E_2)*r0_2)) + a_4*(3*L_2*M*(-4*(-5 + 6*E_2)*M + 3*E_2*r0) + E_2*r0*(4*(-81 + 28*E_2)*M_3 + (508 - 90*E_2)*M_2*r0 + (-245 + 26*E_2)*M*r0_2 + 9*r0_3)) - 4*a*E*L*M*r0*(L_2*(28*M_2 - 26*M*r0 + 6*r0_2) + r0*(216*M_3 + 4*(-86 + 15*E_2)*M_2*r0 + 13*(13 - 4*E_2)*M*r0_2 + 6*(-4 + E_2)*r0_3)) + a_2*r0*(2*L_2*M*(6*(-27 + 28*E_2)*M_2 + (108 - 149*E_2)*M*r0 + 4*(-3 + 5*E_2)*r0_2) + E_2*r0*(432*M_4 + 40*(-20 + 3*E_2)*M_3*r0 + 2*(367 - 47*E_2)*M_2*r0_2 + (-227 + 23*E_2)*M*r0_3 + 12*r0_4))))/(6.*expr2_6); } /* A_{t,r} */ { A10061 = (-256*E*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0))*expr1_3)/(r0_5*(a_2 + r0*(-2*M + r0))); A10081 = (-128*expr1_2*(a_11*E_2*M_2*(312*M_2 + 289*M*r0 + 66*r0_2) + a_10*E*L*M_2*(-624*M_2 + (-589 + 32*E_2)*M*r0 + 6*(-23 + 3*E_2)*r0_2) + a_8*E*L*M*r0*(1248*M_4 + 4*(-193 + 18*E_2)*M_3*r0 + 4*(-479 + 45*E_2)*M_2*r0_2 + (-525 + 74*E_2)*M*r0_3 + 6*(5 - 3*E_2)*r0_4 - 2*L_2*M*(284*M + 3*(44 - 3*E_2)*r0)) + E*L*(2*M - r0)*r0_5*(36*L_6*M*(-2*M + r0) + 6*L_4*M*r0_2*(-26*M + (13 + 4*E_2)*r0) + 4*M*r0_6*(8*M + (-4 + 7*E_2)*r0) + L_2*r0_4*(-64*M_2 + 2*(19 + 24*E_2)*M*r0 - 3*r0_2)) + a_2*E*L*r0_3*(-12*L_6*M*(28*M_2 - 20*M*r0 + 3*r0_2) + 2*M*r0_5*(284*M_3 - 6*(-7 + 2*E_2)*M_2*r0 + 10*(-17 + 8*E_2)*M*r0_2 + 3*(13 - 17*E_2)*r0_3) - 6*L_4*M*r0*(156*M_3 - 8*(4 + E_2)*M_2*r0 - (67 + 16*E_2)*M*r0_2 + 2*(11 + 4*E_2)*r0_3) + L_2*r0_3*(-512*M_4 + 648*M_3*r0 + 2*(-43 + 108*E_2)*M_2*r0_2 - (61 + 138*E_2)*M*r0_3 + 3*r0_4)) + a_9*M*(2*L_2*M*(156*M_2 + 2*(75 + 59*E_2)*M*r0 + 3*(12 + 17*E_2)*r0_2) + E_2*r0*(-16*(39 + 14*E_2)*M_4 + 4*(169 - 84*E_2)*M_3*r0 - 7*(-187 + 24*E_2)*M_2*r0_2 + 2*(201 - 14*E_2)*M*r0_3 + 6*r0_4)) + a_6*E*L*M*r0*(-126*L_4*M*r0 + r0_2*(-68*(-39 + 4*E_2)*M_4 - 4*(-369 + 58*E_2)*M_3*r0 + (-2101 + 168*E_2)*M_2*r0_2 + 6*(-142 + 21*E_2)*M*r0_3 + 2*(53 - 41*E_2)*r0_4) + 2*L_2*(-896*M_4 + 60*(5 + 2*E_2)*M_3*r0 + 60*(-5 + 2*E_2)*M_2*r0_2 + 42*(-9 + E_2)*M*r0_3 + 3*(2 - 7*E_2)*r0_4)) - 2*a_3*M*r0_2*(E_2*r0_6*(456*M_3 + 12*(11 + 9*E_2)*M_2*r0 + (-201 + 68*E_2)*M*r0_2 - 12*r0_3) - 6*L_6*(52*M_3 + 2*(-19 + 6*E_2)*M_2*r0 - 8*E_2*M*r0_2 + (3 + 2*E_2)*r0_3) + L_2*r0_3*(96*M_4 - 4*(-60 + 83*E_2)*M_3*r0 + 48*(-3 + 2*E_2 + 3*E_4)*M_2*r0_2 + 4*(-21 + 16*E_2 + 27*E_4)*M*r0_3 + 7*(6 - 11*E_2)*r0_4) - 6*L_4*r0*(16*M_4 + 12*(-1 + 9*E_2)*M_3*r0 - 2*(9 - 5*E_2 + 4*E_4)*M_2*r0_2 + (20 - 35*E_2 - 8*E_4)*M*r0_3 + 5*(-1 + 2*E_2)*r0_4)) - a_5*M*r0*(-72*L_6*M*r0 + 3*E_2*r0_4*(364*M_4 + 4*(173 + 36*E_2)*M_3*r0 + (-221 + 200*E_2)*M_2*r0_2 + 4*(-73 + 16*E_2)*M*r0_3 - 12*r0_4) + L_2*r0_2*(-64*(-12 + 25*E_2)*M_4 + 8*(51 - 70*E_2 + 36*E_4)*M_3*r0 + 12*(-53 + 5*E_2 + 48*E_4)*M_2*r0_2 + 6*(-24 - 67*E_2 + 36*E_4)*M*r0_3 + (96 - 133*E_2)*r0_4) - 12*L_4*(56*M_4 + 2*(-25 + 42*E_2)*M_3*r0 + (3 - 6*E_2 - 8*E_4)*M_2*r0_2 - 2*(-11 + E_2 + 2*E_4)*M*r0_3 + (-3 + 5*E_2)*r0_4)) + a_7*M*r0*(12*L_4*M*(25*M + 3*(4 + E_2)*r0) - 3*E_2*r0_2*((628 + 96*E_2)*M_4 + 16*(17 + 16*E_2)*M_3*r0 + (-597 + 184*E_2)*M_2*r0_2 + 4*(-73 + 10*E_2)*M*r0_3 - 8*r0_4) + 2*L_2*(24*(-13 + 28*E_2)*M_4 + 12*(4 + 11*E_2 - 12*E_4)*M_3*r0 + 12*(25 + 23*E_2 - 12*E_4)*M_2*r0_2 + (60 + 221*E_2 - 36*E_4)*M*r0_3 + 3*(-6 + 7*E_2)*r0_4)) + a_4*E*L*M*r0_2*(-6*L_4*(264*M_3 - 24*(4 + E_2)*M_2*r0 - 2*(1 + 4*E_2)*M*r0_2 + (9 + 4*E_2)*r0_3) + r0_3*(808*M_4 - 4*(-535 + 48*E_2)*M_3*r0 + 2*(-373 + 14*E_2)*M_2*r0_2 + 3*(-247 + 58*E_2)*M*r0_3 - 138*(-1 + E_2)*r0_4) + L_2*r0*(-1232*M_4 - 8*(-73 + 21*E_2)*M_3*r0 + 8*(85 + 27*E_2)*M_2*r0_2 + 2*(-356 + 93*E_2)*M*r0_3 - 11*(1 + 12*E_2)*r0_4)) + a*M*r0_3*(36*L_8*r0_2M_2 + 6*E_2*r0_8*(-26*M_2 + (11 - 6*E_2)*M*r0 + r0_2) + 12*L_4*r0_4*(8*(-1 + 5*E_2)*M_2 - 2*(-4 + 15*E_2 + 2*E_4)*M*r0 + (-2 + 5*E_2)*r0_2) + L_2*r0_5*(-96*M_3 + 184*E_2*M_2*r0 - 2*(-36 + 109*E_2 + 36*E_4)*M*r0_2 + 3*(-8 + 21*E_2)*r0_3) + 12*L_6*(2*M - r0)*r0*(4*M_2 - (3 + 2*E_2)*r0_2 + 4*M*(r0 + 2*E_2*r0)))))/(3.*r0_11*expr2_2); A10241 = (-192*E*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0))*expr1_2)/(r0_2*(a_2 + r0*(-2*M + r0))); A10261 = (64*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(a_11*E_2*M*(12*(-55 + 2*E_2)*M_3 + (-619 + 24*E_2)*M_2*r0 + 6*(-23 + E_2)*M*r0_2 + 3*r0_3) - a_10*E*L*M*(24*(-55 + 3*E_2)*M_3 + (-1261 + 122*E_2)*M_2*r0 + 3*(-98 + 17*E_2)*M*r0_2 + 3*(1 + E_2)*r0_3) - E*L*(2*M - r0)*r0_5*(-81*L_6*M*(2*M - r0) + 2*L_4*M*r0_2*(-170*M + 85*r0 + 24*E_2*r0) + L_2*M*r0_4*(-126*M + 63*r0 + 100*E_2*r0) + r0_6*(64*M_2 - 38*M*r0 + 56*E_2*M*r0 + 3*r0_2)) + a*M*r0_3*(-72*L_8*r0_2M_2 + 3*E_2*r0_8*(104*M_2 + 2*(-25 + 12*E_2)*M*r0 - r0_2) + L_4*r0_4*(-4*(-78 + 277*E_2)*M_2 + 4*(-78 + 212*E_2 + 21*E_4)*M*r0 + 3*(26 - 49*E_2)*r0_2) - 6*L_6*(2*M - r0)*r0*(12*M_2 + 2*(7 + 20*E_2)*M*r0 - (10 + 9*E_2)*r0_2) + L_2*r0_5*(144*M_3 - 8*(-15 + 46*E_2)*M_2*r0 + 2*(-114 + 209*E_2 + 72*E_4)*M*r0_2 + 3*(22 - 39*E_2)*r0_3)) + a_9*M*(2*L_2*(6*(-55 + 6*E_2)*M_3 + (-321 - 235*E_2 + 6*E_4)*M_2*r0 + 3*(-26 - 35*E_2 + E_4)*M*r0_2 + 6*E_2*r0_3) + E_2*r0*(40*(33 + 10*E_2)*M_4 + 48*(-28 + 15*E_2)*M_3*r0 + 111*(-25 + 4*E_2)*M_2*r0_2 + 4*(-215 + 23*E_2)*M*r0_3 + 3*r0_4)) + a_2*E*L*r0_3*(6*L_6*M*(116*M_2 - 84*M*r0 + 13*r0_2) + L_4*M*r0*(1852*M_3 - 4*(127 + 3*E_2)*M_2*r0 - 3*(253 + 64*E_2)*M*r0_2 + (275 + 93*E_2)*r0_3) + L_2*r0_3*(1160*M_4 + 4*(-433 + 19*E_2)*M_3*r0 + 2*(207 - 251*E_2)*M_2*r0_2 + (75 + 287*E_2)*M*r0_3 + 3*r0_4) + r0_5*(-980*M_4 + 12*(-33 + 4*E_2)*M_3*r0 + 5*(157 - 70*E_2)*M_2*r0_2 + 21*(-9 + 10*E_2)*M*r0_3 + 9*r0_4)) + a_3*M*r0_2*(E_2*r0_6*(1680*M_3 + 44*(14 + 9*E_2)*M_2*r0 + 10*(-86 + 29*E_2)*M*r0_2 - 15*r0_3) - 12*L_6*(102*M_3 + (-77 + 30*E_2)*M_2*r0 + (3 - 19*E_2)*M*r0_2 + (5 + 4*E_2)*r0_3) + 2*L_2*r0_3*(144*M_4 + (600 - 892*E_2)*M_3*r0 + 2*(-144 + 250*E_2 + 135*E_4)*M_2*r0_2 + (-240 + 57*E_2 + 221*E_4)*M*r0_3 + (108 - 149*E_2)*r0_4) + L_4*r0*(-288*M_4 - 8*(-51 + 346*E_2)*M_3*r0 + 84*(5 + 2*E_4)*M_2*r0_2 + 4*(-156 + 223*E_2 + 42*E_4)*M*r0_3 + 3*(58 - 89*E_2)*r0_4)) + a_5*M*r0*(6*L_6*r0*(-26*M + E_2*r0) + E_2*r0_4*(2004*M_4 + 80*(53 + 9*E_2)*M_3*r0 + 27*(-43 + 44*E_2)*M_2*r0_2 + 6*(-309 + 74*E_2)*M*r0_3 - 24*r0_4) + L_4*(-1296*M_4 + 12*(107 - 176*E_2)*M_3*r0 + 2*(-75 + 188*E_2 + 84*E_4)*M_2*r0_2 + 4*(-147 - E_2 + 21*E_4)*M*r0_3 + 3*(32 - 35*E_2)*r0_4) + L_2*r0_2*(-32*(-51 + 106*E_2)*M_4 + 4*(249 - 179*E_2 + 126*E_4)*M_3*r0 + 2*(-717 + 411*E_2 + 554*E_4)*M_2*r0_2 + 2*(-180 - 557*E_2 + 229*E_4)*M*r0_3 + 13*(18 - 19*E_2)*r0_4)) - a_8*E*L*M*(L_2*(24*M_3 + 2*(-605 + 18*E_2)*M_2*r0 + 3*(-189 + 17*E_2)*M*r0_2 + 3*(3 + 2*E_2)*r0_3) + r0*(-48*(-55 + 2*E_2)*M_4 + 16*(-96 + 25*E_2)*M_3*r0 + 4*(-1028 + 157*E_2)*M_2*r0_2 + (-1144 + 177*E_2)*M*r0_3 + 3*(28 - 11*E_2)*r0_4)) + a_7*M*r0*(3*L_4*(2*(-107 + 6*E_2)*M_2 - 8*(13 + 3*E_2)*M*r0 + 5*E_2*r0_2) + E_2*r0_2*(4*(961 + 108*E_2)*M_4 + 4*(485 + 354*E_2)*M_3*r0 + 3*(-1207 + 404*E_2)*M_2*r0_2 + 6*(-311 + 52*E_2)*M*r0_3 - 12*r0_4) - 2*L_2*(12*(-55 + 112*E_2)*M_4 + 2*(48 + 19*E_2 - 130*E_4)*M_3*r0 + 2*(327 + 248*E_2 - 145*E_4)*M_2*r0_2 + (132 + 524*E_2 - 83*E_4)*M*r0_3 + 3*(-14 + 9*E_2)*r0_4)) - a_6*E*L*r0*(3*L_4*M*(4*M_2 - 91*M*r0 + (3 + E_2)*r0_2) + L_2*M*(-3488*M_4 + 8*(191 + 42*E_2)*M_3*r0 + 2*(-663 + 298*E_2)*M_2*r0_2 + 4*(-437 + 52*E_2)*M*r0_3 + 3*(22 - 25*E_2)*r0_4) + r0_2*((5476 - 904*E_2)*M_5 + 4*(863 - 119*E_2)*M_4*r0 + (-4413 + 854*E_2)*M_3*r0_2 + (-1951 + 311*E_2)*M_2*r0_3 + (260 - 173*E_2)*M*r0_4 - 3*r0_5)) + a_4*E*L*r0_2*(-3*L_6*M*r0 + 2*L_4*M*(1576*M_3 - 6*(107 + 18*E_2)*M_2*r0 + (41 - 48*E_2)*M*r0_2 + 3*(16 + 7*E_2)*r0_3) + L_2*r0*(2344*M_5 + 4*(-396 + 139*E_2)*M_4*r0 - 72*(23 + 7*E_2)*M_3*r0_2 + 17*(109 - 27*E_2)*M_2*r0_3 + (-39 + 268*E_2)*M*r0_4 + 3*r0_5) + r0_3*(-1376*M_5 + 4*(-1159 + 195*E_2)*M_4*r0 + 2*(631 - 166*E_2)*M_3*r0_2 - 9*(-194 + 47*E_2)*M_2*r0_3 + 3*(-108 + 97*E_2)*M*r0_4 + 9*r0_5))))/(3.*r0_8*expr2_2); A10421 = (-48*E*r0*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0))*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/(a_2 + r0*(-2*M + r0)); A10441 = (8*(a_11*E_2*M*(72*(-29 + 2*E_2)*M_3 + (-1957 + 144*E_2)*M_2*r0 + 18*(-23 + 2*E_2)*M*r0_2 + 21*r0_3) - a_10*E*L*M*(144*(-29 + 3*E_2)*M_3 + (-4009 + 560*E_2)*M_2*r0 + 6*(-153 + 35*E_2)*M*r0_2 + 3*(7 + 6*E_2)*r0_3) - E*L*(2*M - r0)*r0_5*(-278*L_6*M*(2*M - r0) + L_4*r0_2*(-1108*M_2 + 4*(133 + 37*E_2)*M*r0 + 11*r0_2) + r0_6*(192*M_2 + 2*(-71 + 84*E_2)*M*r0 + 23*r0_2) + L_2*r0_4*(-372*M_2 + 4*(31 + 78*E_2)*M*r0 + 31*r0_2)) + a*M*r0_3*(-216*L_8*r0_2M_2 + 3*E_2*r0_8*(312*M_2 + 2*(-89 + 36*E_2)*M*r0 + 11*r0_2) - 4*L_6*(2*M - r0)*r0*(36*M_2 + 2*(27 + 115*E_2)*M*r0 - 3*(12 + 17*E_2)*r0_2) - 3*L_4*r0_4*(4*(-108 + 319*E_2)*M_2 - 4*(-108 + 243*E_2 + 19*E_4)*M*r0 + (-108 + 167*E_2)*r0_2) + 3*L_2*r0_5*(96*M_3 + 16*(15 - 23*E_2)*M_2*r0 + 2*(-156 + 187*E_2 + 72*E_4)*M*r0_2 + (84 - 95*E_2)*r0_3)) + a_2*E*L*r0_3*(8*L_6*M*(272*M_2 - 202*M*r0 + 33*r0_2) + L_4*r0*(5592*M_4 + 172*(-11 + 2*E_2)*M_3*r0 - 2*(1093 + 350*E_2)*M_2*r0_2 + (839 + 286*E_2)*M*r0_3 + 14*r0_4) + L_2*r0_3*(3840*M_4 + 16*(-391 + 36*E_2)*M_3*r0 + 10*(187 - 180*E_2)*M_2*r0_2 + (7 + 906*E_2)*M*r0_3 + 71*r0_4) + r0_5*(-2472*M_4 + 8*(-221 + 18*E_2)*M_3*r0 - 12*(-219 + 95*E_2)*M_2*r0_2 + (-707 + 648*E_2)*M*r0_3 + 72*r0_4)) + a_9*M*(2*L_2*(36*(-29 + 6*E_2)*M_3 + 2*(-513 - 341*E_2 + 24*E_4)*M_2*r0 + 3*(-84 - 101*E_2 + 8*E_4)*M*r0_2 + 39*E_2*r0_3) + E_2*r0*(48*(87 + 22*E_2)*M_4 + 4*(-1009 + 576*E_2)*M_3*r0 + (-8705 + 1656*E_2)*M_2*r0_2 + 2*(-1319 + 192*E_2)*M*r0_3 + 77*r0_4)) + a_5*M*r0*(36*L_6*r0*((-14 + E_2)*M + E_2*r0) + E_2*r0_4*(5364*M_4 + 12*(1069 + 144*E_2)*M_3*r0 + 7*(-457 + 504*E_2)*M_2*r0_2 + 108*(-53 + 14*E_2)*M*r0_3 + 162*r0_4) + L_2*r0_2*(-192*(-27 + 56*E_2)*M_4 + 8*(441 - 130*E_2 + 144*E_4)*M_3*r0 + 4*(-1197 + 1055*E_2 + 792*E_4)*M_2*r0_2 + 2*(-648 - 1993*E_2 + 768*E_4)*M*r0_3 + (828 - 581*E_2)*r0_4) + L_4*(-3744*M_4 - 72*(-57 + 94*E_2)*M_3*r0 + 4*(-171 + 486*E_2 + 104*E_4)*M_2*r0_2 + 4*(-486 - E_2 + 67*E_4)*M*r0_3 + (360 - 283*E_2)*r0_4)) + a_3*M*r0_2*(E_2*r0_6*(4608*M_3 + 12*(163 + 90*E_2)*M_2*r0 + 14*(-197 + 66*E_2)*M*r0_2 + 113*r0_3) - 4*L_6*(900*M_3 + 6*(-117 + 56*E_2)*M_2*r0 + (54 - 227*E_2)*M*r0_2 + 6*(6 + 7*E_2)*r0_3) + L_4*r0*(-576*M_4 - 48*(-33 + 191*E_2)*M_3*r0 + 4*(306 + 167*E_2 + 96*E_4)*M_2*r0_2 + 4*(-576 + 751*E_2 + 121*E_4)*M*r0_3 + (684 - 877*E_2)*r0_4) + 2*L_2*r0_3*(288*M_4 + 12*(180 - 271*E_2)*M_3*r0 + 16*(-54 + 136*E_2 + 45*E_4)*M_2*r0_2 + 4*(-234 - 5*E_2 + 174*E_4)*M*r0_3 + 3*(132 - 125*E_2)*r0_4)) + a_7*M*r0*(3*L_4*(12*(-57 + 8*E_2)*M_2 + 4*(-84 - 13*E_2 + E_4)*M*r0 + 31*E_2*r0_2) + E_2*r0_2*(12*(977 + 72*E_2)*M_4 + 16*(413 + 243*E_2)*M_3*r0 + 11*(-997 + 360*E_2)*M_2*r0_2 + 36*(-159 + 32*E_2)*M*r0_3 + 138*r0_4) - 2*L_2*(72*(-29 + 56*E_2)*M_4 - 4*(-72 + 131*E_2 + 168*E_4)*M_3*r0 + 4*(531 + 329*E_2 - 228*E_4)*M_2*r0_2 + (432 + 1729*E_2 - 312*E_4)*M*r0_3 + (-144 + 19*E_2)*r0_4)) - a_6*E*L*r0*(3*L_4*M*(32*M_2 + 2*(-143 + 6*E_2)*M*r0 + (19 + 6*E_2)*r0_2) + r0_2*((16908 - 3792*E_2)*M_5 - 12*(-979 + 126*E_2)*M_4*r0 + (-13853 + 3952*E_2)*M_3*r0_2 + 2*(-3228 + 581*E_2)*M_2*r0_3 + 2*(460 - 273*E_2)*M*r0_4 - 32*r0_5) + 2*L_2*(-5088*M_5 + 4*(691 + 54*E_2)*M_4*r0 + 24*(-91 + 48*E_2)*M_3*r0_2 + 6*(-487 + 77*E_2)*M_2*r0_3 + (167 - 105*E_2)*M*r0_4 - 3*r0_5)) - a_8*E*L*(2*L_2*M*(72*M_3 + 4*(-479 + 36*E_2)*M_2*r0 + 3*(-298 + 41*E_2)*M*r0_2 + 6*(5 + 3*E_2)*r0_3) + r0*(-288*(-29 + 2*E_2)*M_5 + 4*(-1153 + 482*E_2)*M_4*r0 + 4*(-3277 + 677*E_2)*M_3*r0_2 + 5*(-729 + 134*E_2)*M_2*r0_3 + 2*(163 - 45*E_2)*M*r0_4 - 3*r0_5)) + a_4*E*L*r0_2*(-6*L_6*M*(2*M + 3*r0) + L_4*(9456*M_4 - 48*(89 + 8*E_2)*M_3*r0 - 8*(-65 + 53*E_2)*M_2*r0_2 + 8*(32 + 15*E_2)*M*r0_3 + 3*r0_4) + L_2*r0*(6672*M_5 + 8*(-743 + 339*E_2)*M_4*r0 - 8*(710 + 207*E_2)*M_3*r0_2 + 2*(3326 - 927*E_2)*M_2*r0_3 + (-323 + 840*E_2)*M*r0_4 + 46*r0_5) + r0_3*(-3336*M_5 + 4*(-3727 + 828*E_2)*M_4*r0 + 2*(1601 - 846*E_2)*M_3*r0_2 + (5881 - 1506*E_2)*M_2*r0_3 + 54*(-21 + 17*E_2)*M*r0_4 + 78*r0_5))))/(3.*r0_5*expr2_2); A10601 = (-4*E*r0_4*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0)))/(a_2 + r0*(-2*M + r0)); A10621 = (4*(6*a_9*E_2*M*((-61 + 6*E_2)*M_2 + (-26 + 3*E_2)*M*r0 + 2*r0_2) - 3*a_8*E*L*M*(4*(-61 + 9*E_2)*M_2 + (-112 + 25*E_2)*M*r0 + (4 + 3*E_2)*r0_2) - E*L*(2*M - r0)*r0_4*(-107*L_4*M*(2*M - r0) + 2*r0_4*(32*M_2 + 2*(-15 + 14*E_2)*M*r0 + 7*r0_2) + L_2*r0_2*(-186*M_2 + (71 + 52*E_2)*M*r0 + 11*r0_2)) + 2*a_7*M*(3*L_2*((-61 + 18*E_2)*M_2 + 2*(-15 - 7*E_2 + E_4)*M*r0 + 5*E_2*r0_2) + E_2*r0*((366 + 76*E_2)*M_3 + 2*(-261 + 83*E_2)*M_2*r0 + (-397 + 73*E_2)*M*r0_2 + 22*r0_3)) + 2*a_5*M*r0*(9*L_4*(2*(-5 + E_2)*M + E_2*r0) + E_2*r0_2*(18*(55 + 2*E_2)*M_3 + (-73 + 238*E_2)*M_2*r0 + (-624 + 155*E_2)*M*r0_2 + 41*r0_3) + L_2*((366 - 672*E_2)*M_3 + (-231 + 340*E_2 + 52*E_4)*M_2*r0 + 2*(-87 - 63*E_2 + 28*E_4)*M*r0_2 + (54 - 17*E_2)*r0_3)) + 2*a*M*r0_2*(-36*L_6*r0_2M_2 + 3*E_2*r0_6*(52*M_2 + 12*(-3 + E_2)*M*r0 + 5*r0_2) - L_4*(2*M - r0)*r0*(12*M_2 + 14*(-3 + 14*E_2)*M*r0 + 9*(2 - 5*E_2)*r0_2) + L_2*r0_3*(24*M_3 - 20*(-9 + 17*E_2)*M_2*r0 + 2*(-99 + 130*E_2 + 18*E_4)*M*r0_2 + 3*(17 - 15*E_2)*r0_3)) + 2*a_3*M*r0*(E_2*r0_4*(384*M_3 + 18*(21 + 5*E_2)*M_2*r0 + (-413 + 127*E_2)*M*r0_2 + 40*r0_3) + L_2*r0_2*((456 - 944*E_2)*M_3 + 2*(-36 + 155*E_2 + 18*E_4)*M_2*r0 + 2*(-144 + 90*E_2 + 43*E_4)*M*r0_2 + 7*(15 - 11*E_2)*r0_3) - 2*L_4*(150*M_3 + 3*(-55 + 46*E_2)*M_2*r0 + (63 - 104*E_2)*M*r0_2 + 9*(-1 + 2*E_2)*r0_3)) - a_6*E*L*(3*L_2*M*(12*M_2 + (-107 + 12*E_2)*M*r0 + (7 + 3*E_2)*r0_2) + r0*(-24*(-61 + 6*E_2)*M_4 + 2*(-753 + 254*E_2)*M_3*r0 + (-1183 + 284*E_2)*M_2*r0_2 - 4*(-32 + 9*E_2)*M*r0_3 - 3*r0_4)) + a_4*E*L*r0*(-3*L_4*M*(4*M + 3*r0) + L_2*(1648*M_4 - 12*(97 + 2*E_2)*M_3*r0 + 2*(321 - 116*E_2)*M_2*r0_2 + (-17 + 42*E_2)*M*r0_3 + 3*r0_4) + r0_2*(4*(-723 + 203*E_2)*M_4 + 6*(1 - 34*E_2)*M_3*r0 + (1652 - 507*E_2)*M_2*r0_2 + (-264 + 155*E_2)*M*r0_3 + 20*r0_4)) + a_2*E*L*r0_2*(2*L_4*M*(380*M_2 - 292*M*r0 + 51*r0_2) + L_2*r0*(1052*M_4 + 4*(-271 + 71*E_2)*M_3*r0 + (85 - 316*E_2)*M_2*r0_2 + (69 + 103*E_2)*M*r0_3 + 14*r0_4) + r0_3*(-412*M_4 + 4*(-247 + 68*E_2)*M_3*r0 + 5*(189 - 82*E_2)*M_2*r0_2 + 2*(-118 + 83*E_2)*M*r0_3 + 31*r0_4))))/(3.*r0_2*expr2_2); A10801 = (r0*(3*a_7*E_2*M*(4*(-8 + E_2)*M + 3*r0) - 3*a_6*E*L*M*(4*(-16 + 3*E_2)*M + (3 + 2*E_2)*r0) + a*M*r0*(-36*L_4*r0_2M_2 - 4*L_2*(2*M - r0)*r0_2*((-30 + 62*E_2)*M - 15*(-1 + E_2)*r0) + 3*E_2*r0_4*(52*M_2 + 4*(-11 + 3*E_2)*M*r0 + 9*r0_2)) - E*L*(2*M - r0)*r0_3*(-62*L_2*M*(2*M - r0) + r0_2*(32*M_2 - 38*M*r0 + 28*E_2*M*r0 + 11*r0_2)) + a_5*M*(12*L_2*((-8 + 3*E_2)*M + E_2*r0) + E_2*r0*(32*(6 + E_2)*M_2 + 4*(-91 + 19*E_2)*M*r0 + 29*r0_2)) + a_3*M*r0*(E_2*r0_2*(500*M_2 + 4*(-92 + 25*E_2)*M*r0 + 47*r0_2) - 4*L_2*(12*(-4 + 7*E_2)*M_2 + (54 - 71*E_2)*M*r0 + 3*(-5 + 4*E_2)*r0_2)) + a_4*E*L*(-6*L_2*M*(2*M + r0) + r0*(48*(-8 + E_2)*M_3 + 4*(145 - 46*E_2)*M_2*r0 + 2*(-37 + 12*E_2)*M*r0_2 + 3*r0_3)) + a_2*E*L*r0*(20*L_2*M*(20*M_2 - 16*M*r0 + 3*r0_2) + r0_2*(4*(-185 + 62*E_2)*M_3 + 4*(133 - 55*E_2)*M_2*r0 + (-109 + 58*E_2)*M*r0_2 + 14*r0_3))))/(6.*expr2_2); A11061 = (-128*expr1_2*(a_7*E_2*M*(4*M_2 + M*r0 - r0_2) + a_6*E*L*M*(-8*M_2 + (-3 + 4*E_2)*M*r0 + (1 + 3*E_2)*r0_2) + a_4*E*L*r0_2*((4 + 3*E_2)*L_2*M - 2*(15 + 2*E_2)*M_3 - (19 + 4*E_2)*M_2*r0 + (9 + 8*E_2)*M*r0_2 + 2*r0_3) + E*L*r0_3*(L_4*M*(-2*M + r0) - 2*L_2*r0_2*(6*M_2 - (5 + E_2)*M*r0 + r0_2) - r0_4*(6*M_2 - (5 + 2*E_2)*M*r0 + r0_2)) + a_5*M*(-2*E_2*r0_2*(-11*M_2 - 9*M*r0 + r0_2) + L_2*(4*M_2 + (2 - 6*E_2)*M*r0 - 7*E_2*r0_2)) + a_2*E*L*r0_2*(3*L_4*M + r0_3*(-2*(11 + 8*E_2)*M_2 + 7*(1 + E_2)*M*r0 + r0_2) + L_2*(-4*M_3 - 2*(12 + E_2)*M_2*r0 + 5*(2 + E_2)*M*r0_2 + 2*r0_3)) + a*M*r0_3*(6*E_2*(2*M - r0)*r0_4 + L_2*r0_2*((4 + 34*E_2)*M - (2 + 21*E_2)*r0) + L_4*(4*(1 + E_2)*M - 2*(r0 + 3*E_2*r0))) + a_3*M*r0*(2*L_4*(M - 3*E_2*r0) + E_2*r0_3*(6*M_2 + 17*M*r0 - 7*r0_2) + 2*L_2*r0*(4*(1 + E_2)*M_2 - (1 + 8*E_2)*r0_2 + M*(r0 + 12*E_2*r0)))))/(r0_7*expr2_2); A11241 = (-32*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(4*a_7*E_2*M*(3*M_2 - r0_2) + a_6*E*L*M*(-24*M_2 + 2*(-3 + 7*E_2)*M*r0 + (4 + 9*E_2)*r0_2) + 6*a*M*r0_3*(3*E_2*(2*M - r0)*r0_4 - L_2*r0_2*(-2*(1 + 7*E_2)*M + r0 + 9*E_2*r0) + L_4*(2*(1 + E_2)*M - (1 + 3*E_2)*r0)) + E*L*r0_3*(3*L_4*M*(-2*M + r0) + L_2*r0_2*(-32*M_2 + 2*(13 + 3*E_2)*M*r0 - 5*r0_2) - 3*r0_4*(6*M_2 - (5 + 2*E_2)*M*r0 + r0_2)) + 2*a_5*M*(E_2*r0_2*(36*M_2 + 22*M*r0 - 5*r0_2) + L_2*(6*M_2 + (3 - 11*E_2)*M*r0 - 11*E_2*r0_2)) + a_4*E*L*r0*(L_2*M*(2*M + (13 + 9*E_2)*r0) + r0*(-12*(8 + E_2)*M_3 - 50*M_2*r0 + 3*(9 + 8*E_2)*M*r0_2 + 5*r0_3)) + a_2*E*L*r0_2*(9*L_4*M + r0_2*(-12*M_3 - 2*(29 + 15*E_2)*M_2*r0 + (22 + 21*E_2)*M*r0_2 + 2*r0_3) + L_2*(-12*M_3 - 6*(11 + E_2)*M_2*r0 + (29 + 15*E_2)*M*r0_2 + 5*r0_3)) + 6*a_3*M*r0*(L_4*(M - 3*E_2*r0) + 2*E_2*r0_3*(3*M_2 + 4*M*r0 - 2*r0_2) + L_2*r0*(4*(1 + E_2)*M_2 - (1 + 8*E_2)*r0_2 + M*(r0 + 9*E_2*r0)))))/(r0_4*expr2_2); A11421 = (-8*(a_7*E_2*M*(12*M_2 - 3*M*r0 - 5*r0_2) + a_6*E*L*M*(-24*M_2 + (-3 + 16*E_2)*M*r0 + (5 + 9*E_2)*r0_2) + E*L*r0_3*(3*L_4*M*(-2*M + r0) + 2*L_2*r0_2*(-14*M_2 + (11 + 3*E_2)*M*r0 - 2*r0_2) - 3*r0_4*(6*M_2 - (5 + 2*E_2)*M*r0 + r0_2)) + a_5*M*(2*E_2*r0_2*(39*M_2 + 17*M*r0 - 7*r0_2) + L_2*(12*M_2 + (6 - 26*E_2)*M*r0 - 23*E_2*r0_2)) + a_4*E*L*r0*(L_2*M*(4*M + (14 + 9*E_2)*r0) + r0*(-6*(17 + 2*E_2)*M_3 + (-43 + 12*E_2)*M_2*r0 + 3*(9 + 8*E_2)*M*r0_2 + 4*r0_3)) + a_2*E*L*r0_2*(9*L_4*M + r0_2*(-24*M_3 - 2*(25 + 6*E_2)*M_2*r0 + (23 + 21*E_2)*M*r0_2 + r0_3) + L_2*(-12*M_3 - 6*(10 + E_2)*M_2*r0 + (28 + 15*E_2)*M*r0_2 + 4*r0_3)) + 3*a*M*r0_3*(6*E_2*(2*M - r0)*r0_4 + L_2*r0_2*((4 + 22*E_2)*M - (2 + 15*E_2)*r0) + L_4*(4*(1 + E_2)*M - 2*(r0 + 3*E_2*r0))) + 3*a_3*M*r0*(2*L_4*(M - 3*E_2*r0) + 3*E_2*r0_3*(6*M_2 + 5*M*r0 - 3*r0_2) + 2*L_2*r0*(4*(1 + E_2)*M_2 - (1 + 8*E_2)*r0_2 + M*(r0 + 6*E_2*r0)))))/(r0*expr2_2); A11601 = (2*r0_2*(2*a_5*E_2*M*(-M + r0) + a_4*E*L*M*(4*M - (2 + 3*E_2)*r0) - 2*a_3*M*(E_2*(7*M - 2*r0)*r0_2 + L_2*(M - 3*E_2*r0)) + 2*a*M*r0_2*(3*E_2*r0_2*(-2*M + r0) + L_2*(-2*(1 + E_2)*M + r0 + 3*E_2*r0)) - a_2*E*L*r0*(3*L_2*M + r0*(-2*(9 + E_2)*M_2 + 5*(1 + E_2)*M*r0 + r0_2)) + E*L*r0_2*(L_2*M*(2*M - r0) + r0_2*(6*M_2 - (5 + 2*E_2)*M*r0 + r0_2))))/expr2_2; A12041 = (-192*E*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0))*expr1_2)/(r0_2*expr2_2); A12061 = (-32*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(a_11*E_2*M*(24*(46 + 7*E_2)*M_3 + (1031 + 180*E_2)*M_2*r0 + 6*(41 + 8*E_2)*M*r0_2 + 6*r0_3) - a_10*E*L*M*(24*(92 + 17*E_2)*M_3 + (2087 + 296*E_2)*M_2*r0 + 6*(83 + 6*E_2)*M*r0_2 + 6*(1 + E_2)*r0_3) + E*L*r0_5*(-6*L_6*M*(102*M_2 - 103*M*r0 + 26*r0_2) + r0_6*(124*M_3 + 2*(-41 + 94*E_2)*M_2*r0 - 4*(2 + 25*E_2)*M*r0_2 + 9*r0_3) + 2*L_4*r0_2*(-734*M_3 + (791 + 102*E_2)*M_2*r0 - 2*(118 + 27*E_2)*M*r0_2 + 12*r0_3) + 2*L_2*r0_4*(-354*M_3 + 47*(9 + 4*E_2)*M_2*r0 - (153 + 100*E_2)*M*r0_2 + 15*r0_3)) + a*M*r0_3*(-3*E_2*r0_8*(116*M_2 + 4*(4 + 3*E_2)*M*r0 - 37*r0_2) + 12*L_8*(50*M_2 - 49*M*r0 + 12*r0_2) + 2*L_4*r0_4*(2*(-18 + 725*E_2)*M_2 + (18 - 1385*E_2 - 84*E_4)*M*r0 + 330*E_2*r0_2) + 12*L_6*(2*M - r0)*r0*(12*M_2 + (28 + 37*E_2)*M*r0 - (17 + 15*E_2)*r0_2) + 2*L_2*r0_5*(-144*M_3 + 614*E_2*M_2*r0 + (96 - 805*E_2 - 90*E_4)*M*r0_2 + 3*(-10 + 83*E_2)*r0_3)) - a_2*E*L*r0_3*(6*L_6*M*(244*M_2 - 193*M*r0 + 33*r0_2) + 2*L_4*r0*(1672*M_4 + (416 - 30*E_2)*M_3*r0 - 3*(478 + 87*E_2)*M_2*r0_2 + 5*(61 + 24*E_2)*M*r0_3 + 36*r0_4) + r0_5*(-1912*M_4 + 24*(7 + 4*E_2)*M_3*r0 + 14*(44 - 29*E_2)*M_2*r0_2 + 3*(-69 + 128*E_2)*M*r0_3 + 36*r0_4) + 2*L_2*r0_3*(764*M_4 + 2*(-95 + 329*E_2)*M_3*r0 - (657 + 748*E_2)*M_2*r0_2 + (153 + 308*E_2)*M*r0_3 + 48*r0_4)) + a_9*M*(2*L_2*(12*(46 + 9*E_2)*M_3 + 2*(264 + 247*E_2 + 30*E_4)*M_2*r0 + 3*(42 + 65*E_2 + 8*E_4)*M*r0_2 + 12*E_2*r0_3) + E_2*r0*(-16*(129 + 62*E_2)*M_4 + 24*(103 - 31*E_2)*M_3*r0 + 3*(1531 + 96*E_2)*M_2*r0_2 + 2*(707 + 106*E_2)*M*r0_3 + 54*r0_4)) - a_8*E*L*M*(2*L_2*(-60*M_3 + 8*(113 + 15*E_2)*M_2*r0 + 435*M*r0_2 + 3*(3 + 2*E_2)*r0_3) + r0*(-96*(43 + 3*E_2)*M_4 + 8*(363 + 125*E_2)*M_3*r0 + 2*(3311 + 734*E_2)*M_2*r0_2 + (1733 + 342*E_2)*M*r0_3 + 6*(-16 + 17*E_2)*r0_4)) - a_3*M*r0_2*(36*L_8*M + E_2*r0_6*(3084*M_3 + 2*(373 + 414*E_2)*M_2*r0 + 4*(-223 + 10*E_2)*M*r0_2 - 243*r0_3) - 12*L_6*(212*M_3 + (-133 + 66*E_2)*M_2*r0 - (19 + 60*E_2)*M*r0_2 + 4*(3 + 4*E_2)*r0_3) + 2*L_2*r0_3*(288*M_4 + (792 - 458*E_2)*M_3*r0 + (-426 - 785*E_2 + 180*E_4)*M_2*r0_2 + 2*(-135 + 414*E_2 + 113*E_4)*M*r0_3 + (132 - 391*E_2)*r0_4) - 2*L_4*r0*(288*M_4 + 8*(12 + 283*E_2)*M_3*r0 - 12*(39 - 118*E_2 + 14*E_4)*M_2*r0_2 - 2*(-135 + 773*E_2 + 84*E_4)*M*r0_3 + 9*(-8 + 37*E_2)*r0_4)) + a_7*M*(6*L_4*(-16*M_3 + 156*M_2*r0 + 6*(13 + E_2)*M*r0_2 + 5*E_2*r0_3) + E_2*r0_3*(-20*(307 + 72*E_2)*M_4 - 4*(667 + 738*E_2)*M_3*r0 + 3*(1901 - 232*E_2)*M_2*r0_2 + 78*(33 + 4*E_2)*M*r0_3 + 111*r0_4) + 2*L_2*r0*(24*(-43 + 106*E_2)*M_4 + 4*(54 + 313*E_2 - 142*E_4)*M_3*r0 + (1002 + 1583*E_2 - 220*E_4)*M_2*r0_2 + 2*(81 + 380*E_2 + E_4)*M*r0_3 + 3*(-24 + 43*E_2)*r0_4)) + a_5*M*r0*(-12*L_6*(10*M_2 + 3*(-5 + 3*E_2)*M*r0 - E_2*r0_2) + E_2*r0_4*(-3588*M_4 - 8*(832 + 279*E_2)*M_3*r0 - 3*(-749 + 544*E_2)*M_2*r0_2 + 6*(391 + 24*E_2)*M*r0_3 + 195*r0_4) + 2*L_4*(1344*M_4 + 96*(-9 + 22*E_2)*M_3*r0 - 2*(30 - 181*E_2 + 84*E_4)*M_2*r0_2 + (342 - 287*E_2 - 84*E_4)*M*r0_3 + 18*(-4 + 11*E_2)*r0_4) + 2*L_2*r0_2*(16*(-81 + 158*E_2)*M_4 - 2*(348 - 775*E_2 + 324*E_4)*M_3*r0 + 4*(267 + 261*E_2 - 139*E_4)*M_2*r0_2 + 2*(105 + 59*E_2 - 79*E_4)*M*r0_3 + (-174 + 259*E_2)*r0_4)) - a_6*E*L*r0*(-6*L_4*M*(40*M_2 + 2*(-22 + 3*E_2)*M*r0 - (3 + E_2)*r0_2) + 2*L_2*M*(3536*M_4 - 4*(121 + 108*E_2)*M_3*r0 + (933 + 250*E_2)*M_2*r0_2 + 2*(523 - 2*E_2)*M*r0_3 + 3*(1 + 40*E_2)*r0_4) + r0_2*((-8732 + 80*E_2)*M_5 + 4*(-1267 + 76*E_2)*M_4*r0 + (6519 + 2456*E_2)*M_3*r0_2 + 2*(1234 + 361*E_2)*M_2*r0_3 + (-181 + 370*E_2)*M*r0_4 + 54*r0_5)) - a_4*E*L*r0_2*(6*L_6*M*(-18*M + r0) + 2*L_4*M*(3248*M_3 - 6*(151 + 34*E_2)*M_2*r0 - (395 + 159*E_2)*M*r0_2 + 3*(50 + 23*E_2)*r0_3) + 2*L_2*r0*(2056*M_5 + 2*(9 + 44*E_2)*M_4*r0 + 3*(-359 + 236*E_2)*M_3*r0_2 + (281 - 348*E_2)*M_2*r0_3 + 2*(75 + 161*E_2)*M*r0_4 + 63*r0_5) + r0_3*(-2536*M_5 - 8*(829 + 174*E_2)*M_4*r0 + 4*(574 + 257*E_2)*M_3*r0_2 + 3*(505 + 66*E_2)*M_2*r0_3 + 6*(-49 + 93*E_2)*M*r0_4 + 99*r0_5))))/(3.*r0_8*expr2_3); A12221 = (-96*E*r0*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0))*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/expr2_2; A12241 = (-8*(a_11*E_2*M_2*(384*(9 + E_2)*M_2 + (3239 + 408*E_2)*M*r0 + 6*(125 + 18*E_2)*r0_2) - a_10*E*L*M*(48*(144 + 17*E_2)*M_3 + (6599 + 548*E_2)*M_2*r0 + 6*(261 + 14*E_2)*M*r0_2 + 18*E_2*r0_3) + E*L*r0_5*(-2*L_6*M*(1022*M_2 - 1031*M*r0 + 260*r0_2) + 3*r0_6*(124*M_3 + 2*(-57 + 94*E_2)*M_2*r0 - 4*(-6 + 25*E_2)*M*r0_2 + r0_3) + 6*L_2*r0_4*(-342*M_3 + (375 + 188*E_2)*M_2*r0 - 2*(57 + 50*E_2)*M*r0_2 + 6*r0_3) + 2*L_4*r0_2*(-2246*M_3 + 5*(469 + 58*E_2)*M_2*r0 - (647 + 154*E_2)*M*r0_2 + 18*r0_3)) + a*M*r0_3*(-9*E_2*r0_8*(116*M_2 + 12*E_2*M*r0 - 29*r0_2) + 36*L_8*(50*M_2 - 49*M*r0 + 12*r0_2) + 4*L_6*(2*M - r0)*r0*(72*M_2 + (228 + 397*E_2)*M*r0 - 3*(44 + 45*E_2)*r0_2) + 12*L_4*r0_4*((-82 + 670*E_2)*M_2 + (73 - 617*E_2 - 29*E_4)*M*r0 + (-16 + 141*E_2)*r0_2) - 12*L_2*r0_5*(48*M_3 + 6*(10 - 47*E_2)*M_2*r0 + (-90 + 361*E_2 + 36*E_4)*M*r0_2 + 2*(12 - 55*E_2)*r0_3)) + a_9*M*(2*L_2*(72*(24 + E_2)*M_3 + 2*(840 + 712*E_2 + 75*E_4)*M_2*r0 + 3*(136 + 217*E_2 + 24*E_4)*M*r0_2 + 18*E_2*r0_3) + E_2*r0*(-48*(135 + 56*E_2)*M_4 + 4*(1787 - 576*E_2)*M_3*r0 + (14027 + 336*E_2)*M_2*r0_2 + 6*(729 + 70*E_2)*M*r0_3 + 66*r0_4)) - a_2*E*L*r0_3*(2*L_6*M*(2260*M_2 - 1793*M*r0 + 309*r0_2) + 6*L_2*r0_3*(1104*M_4 + 4*(-229 + 64*E_2)*M_3*r0 - 3*(107 + 170*E_2)*M_2*r0_2 + 2*(59 + 156*E_2)*M*r0_3 + 51*r0_4) + 3*r0_5*(-1440*M_4 + 4*(-112 + 3*E_2)*M_3*r0 + 2*(431 - 207*E_2)*M_2*r0_2 + (-271 + 400*E_2)*M*r0_3 + 54*r0_4) + 2*L_4*r0*(5016*M_4 + 22*(19 + 5*E_2)*M_3*r0 - (3873 + 625*E_2)*M_2*r0_2 + 10*(95 + 34*E_2)*M*r0_3 + 87*r0_4)) + a_7*M*(-12*L_4*(28*M_3 + (-248 + 21*E_2)*M_2*r0 - (127 + 28*E_2 + 3*E_4)*M*r0_2 - 6*E_2*r0_3) + 3*E_2*r0_3*(-12*(505 + 96*E_2)*M_4 - 16*(185 + 156*E_2)*M_3*r0 + (5539 - 768*E_2)*M_2*r0_2 + 6*(459 + 28*E_2)*M*r0_3 + 51*r0_4) + 2*L_2*r0*(72*(-45 + 106*E_2)*M_4 - 8*(-75 - 268*E_2 + 192*E_4)*M_3*r0 + 2*(1635 + 1685*E_2 - 381*E_4)*M_2*r0_2 + (564 + 2791*E_2 + 48*E_4)*M*r0_3 + 3*(-82 + 127*E_2)*r0_4)) - a_3*M*r0_2*(108*L_8*M + 3*E_2*r0_6*(2520*M_3 + 4*(271 + 162*E_2)*M_2*r0 + 4*(-249 + 19*E_2)*M*r0_2 - 181*r0_3) - 4*L_6*(1872*M_3 + 3*(-411 + 230*E_2)*M_2*r0 - (114 + 535*E_2)*M*r0_2 + 3*(31 + 48*E_2)*r0_3) + 2*L_2*r0_3*(576*M_4 - 48*(-63 + 97*E_2)*M_3*r0 + 2*(-615 + 631*E_2 + 567*E_4)*M_2*r0_2 + (-1236 + 1921*E_2 + 528*E_4)*M*r0_3 + (534 - 1255*E_2)*r0_4) - 4*L_4*r0*(288*M_4 + 24*(-1 + 155*E_2)*M_3*r0 + (-714 + 965*E_2 - 228*E_4)*M_2*r0_2 + (627 - 2041*E_2 - 161*E_4)*M*r0_3 + 3*(-62 + 193*E_2)*r0_4)) - a_5*M*r0*(12*L_6*(32*M_2 + 2*(-25 + 9*E_2)*M*r0 - 3*E_2*r0_2) + 3*E_2*r0_4*(3252*M_4 + 4*(1631 + 432*E_2)*M_3*r0 + (-1615 + 1392*E_2)*M_2*r0_2 - 2*(1271 + 12*E_2)*M*r0_3 - 123*r0_4) + 4*L_4*(-1944*M_4 - 144*(-10 + 23*E_2)*M_3*r0 + 2*(6 + 87*E_2 + 110*E_4)*M_2*r0_2 + (-609 + 244*E_2 + 65*E_4)*M*r0_3 + 6*(23 - 53*E_2)*r0_4) - 2*L_2*r0_2*(48*(-84 + 173*E_2)*M_4 - 8*(327 - 559*E_2 + 216*E_4)*M_3*r0 - 6*(-598 + 164*E_2 + 349*E_4)*M_2*r0_2 + (852 + 1565*E_2 - 336*E_4)*M*r0_3 + 2*(-318 + 479*E_2)*r0_4)) - a_8*E*L*(2*L_2*M*(-312*M_3 + 2*(1421 + 129*E_2)*M_2*r0 + 3*(475 + 14*E_2)*M*r0_2 + 9*(1 + 2*E_2)*r0_3) + r0*(-288*(45 + E_2)*M_5 + 4*(2087 + 392*E_2)*M_4*r0 + 4*(5202 + 515*E_2)*M_3*r0_2 + (5761 + 898*E_2)*M_2*r0_3 + 6*(-53 + 59*E_2)*M*r0_4 + 18*r0_5)) - a_4*E*L*r0_2*(18*L_6*M*(-16*M + r0) + 2*L_4*(9696*M_4 - 12*(291 + 35*E_2)*M_3*r0 - (830 + 289*E_2)*M_2*r0_2 + 3*(157 + 65*E_2)*M*r0_3 + 9*r0_4) + 3*r0_3*(-2120*M_5 + 4*(-1739 + 102*E_2)*M_4*r0 + 2*(787 + 94*E_2)*M_3*r0_2 + (2045 + 38*E_2)*M_2*r0_3 + 6*(-62 + 101*E_2)*M*r0_4 + 117*r0_5) + 2*L_2*r0*(5880*M_5 + 4*(-163 + 246*E_2)*M_4*r0 + 2*(-2530 + 93*E_2)*M_3*r0_2 + 14*(163 - 45*E_2)*M_2*r0_3 + 6*(58 + 165*E_2)*M*r0_4 + 189*r0_5)) - a_6*E*L*r0*(6*L_4*M*(-142*M_2 + 166*M*r0 + 3*(2 + E_2)*r0_2) + 2*L_2*(10320*M_5 - 16*(167 + 54*E_2)*M_4*r0 + 12*(207 - 7*E_2)*M_3*r0_2 + (3875 + 162*E_2)*M_2*r0_3 + 3*(1 + 124*E_2)*M*r0_4 + 18*r0_5) + r0_2*(12*(-2187 + 212*E_2)*M_5 + 4*(-4325 + 666*E_2)*M_4*r0 + (19571 + 2392*E_2)*M_3*r0_2 + 2*(4349 + 803*E_2)*M_2*r0_3 + 33*(-21 + 38*E_2)*M*r0_4 + 204*r0_5))))/(3.*r0_5*expr2_3); A12401 = (-12*E*r0_4*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0)))/expr2_2; A12421 = (2*(-3*a_9*E_2*M*((600 + 44*E_2)*M_2 + 6*(45 + 4*E_2)*M*r0 - 5*r0_2) + 3*a_8*E*L*M*(4*(300 + 17*E_2)*M_2 + 2*(281 + 6*E_2)*M*r0 + (-5 + 6*E_2)*r0_2) + a_7*M*(3*L_2*(60*(-10 + E_2)*M_2 - 4*(73 + 52*E_2 + 4*E_4)*M*r0 - 7*E_2*r0_2) + 2*E_2*r0*(12*(141 + 50*E_2)*M_3 + 147*(-17 + 2*E_2)*M_2*r0 - (1871 + 66*E_2)*M*r0_2 + 8*r0_3)) + E*L*r0_4*(6*L_4*M*(386*M_2 - 389*M*r0 + 98*r0_2) + L_2*r0_2*(2352*M_3 - 4*(584 + 141*E_2)*M_2*r0 + 2*(277 + 150*E_2)*M*r0_2 + 13*r0_3) + r0_4*(-372*M_3 + (478 - 564*E_2)*M_2*r0 + 4*(-52 + 75*E_2)*M*r0_2 + 31*r0_3)) + a_5*M*(12*L_4*(16*M_2 + (-64 + 15*E_2)*M*r0 - 3*E_2*r0_2) + 2*E_2*r0_3*(6*(731 + 108*E_2)*M_3 + 2*(-199 + 453*E_2)*M_2*r0 + 3*(-837 + 10*E_2)*M*r0_2 + 40*r0_3) + L_2*r0*(-72*(-47 + 106*E_2)*M_3 + 12*(-187 + 144*E_2 + 60*E_4)*M_2*r0 + 6*(-252 - 151*E_2 + 20*E_4)*M*r0_2 + (552 - 695*E_2)*r0_3)) + a_3*M*r0*(108*L_6*M + 2*E_2*r0_4*(1890*M_3 + 3*(553 + 198*E_2)*M_2*r0 + (-1399 + 114*E_2)*M*r0_2 - 40*r0_3) + L_2*r0_2*(-48*(-87 + 188*E_2)*M_3 + 12*(-53 + 43*E_2 + 60*E_4)*M_2*r0 + 4*(-633 + 844*E_2 + 96*E_4)*M*r0_2 + (948 - 1295*E_2)*r0_3) - 12*L_4*(312*M_3 + 9*(-31 + 30*E_2)*M_2*r0 + (65 - 196*E_2)*M*r0_2 + 2*(-5 + 26*E_2)*r0_3)) - 3*a*M*r0_2*(12*L_6*(50*M_2 - 49*M*r0 + 12*r0_2) + E_2*r0_6*(-348*M_2 + 4*(17 - 9*E_2)*M*r0 + 53*r0_2) + 4*L_4*(2*M - r0)*r0*(12*M_2 + (-7 + 163*E_2)*M*r0 - (1 + 49*E_2)*r0_2) + L_2*r0_3*(-96*M_3 + 32*(-15 + 43*E_2)*M_2*r0 - 2*(-264 + 647*E_2 + 36*E_4)*M*r0_2 + 3*(-44 + 101*E_2)*r0_3)) + a_6*E*L*(3*L_2*M*(-148*M_2 + 4*(119 + 3*E_2)*M*r0 + (1 + 6*E_2)*r0_2) + r0*(144*(-47 + E_2)*M_4 + (7242 - 72*E_2)*M_3*r0 + 2*(2720 + 57*E_2)*M_2*r0_2 + (-421 + 384*E_2)*M*r0_3 + 33*r0_4)) + a_2*E*L*r0_2*(18*L_4*M*(260*M_2 - 209*M*r0 + 37*r0_2) + L_2*r0*(5592*M_4 + 12*(-247 + 73*E_2)*M_3*r0 - 2*(1082 + 591*E_2)*M_2*r0_2 + 21*(31 + 32*E_2)*M*r0_3 + 178*r0_4) + r0_3*(-2160*M_4 + 16*(-223 + 57*E_2)*M_3*r0 - 14*(-227 + 93*E_2)*M_2*r0_2 + (-941 + 948*E_2)*M*r0_3 + 221*r0_4)) + a_4*E*L*r0*(-6*L_4*M*(46*M - 3*r0) + L_2*(10032*M_4 - 24*(233 + 15*E_2)*M_3*r0 - 6*(-284 + 79*E_2)*M_2*r0_2 + 2*(136 + 195*E_2)*M*r0_3 + 33*r0_4) + r0_2*(12*(-1079 + 202*E_2)*M_4 + 2*(-55 + 162*E_2)*M_3*r0 + 2*(3133 - 330*E_2)*M_2*r0_2 + (-887 + 1014*E_2)*M*r0_3 + 223*r0_4))))/(3.*r0_2*expr2_3); A12601 = (r0*(-3*a_7*E_2*M*(4*(26 + E_2)*M - 3*r0) + 3*a_6*E*L*M*(208*M + (-3 + 2*E_2)*r0) + a*M*r0*(-4*L_2*(2*M - r0)*r0_2*((-90 + 203*E_2)*M + 42*r0 - 57*E_2*r0) + 3*E_2*r0_4*(116*M_2 + 4*(-13 + 3*E_2)*M*r0 - 3*r0_2) - 12*L_4*(50*M_2 - 49*M*r0 + 12*r0_2)) + a_5*M*(12*L_2*((-26 + 6*E_2)*M - E_2*r0) + E_2*r0*(4*(147 + 44*E_2)*M_2 + 4*(-268 + 7*E_2)*M*r0 + 25*r0_2)) + a_3*M*(36*L_4*M + E_2*r0_3*(16*(86 + 9*E_2)*M_2 + 4*(-219 + 19*E_2)*M*r0 + 79*r0_2) - 4*L_2*r0*(3*(-49 + 106*E_2)*M_2 + (168 - 233*E_2)*M*r0 + 3*(-17 + 20*E_2)*r0_2)) + a_4*E*L*(6*L_2*M*(-16*M + r0) + r0*(24*(-49 + 3*E_2)*M_3 + 2*(872 - 107*E_2)*M_2*r0 + 2*(-95 + 69*E_2)*M*r0_2 + 15*r0_3)) + E*L*r0_3*(2*L_2*M*(442*M_2 - 445*M*r0 + 112*r0_2) + r0_2*(-124*M_3 + 2*(109 - 94*E_2)*M_2*r0 + 4*(-32 + 25*E_2)*M*r0_2 + 25*r0_3)) + a_2*E*L*r0*(2*L_2*M*(812*M_2 - 667*M*r0 + 123*r0_2) + r0_2*(4*(-524 + 149*E_2)*M_3 + 2*(673 - 227*E_2)*M_2*r0 + (-325 + 232*E_2)*M*r0_2 + 76*r0_3))))/(6.*expr2_3); A13041 = (-32*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(4*a_7*E_2*M*(3*M_2 - r0_2) + a_6*E*L*M*(-24*M_2 + 2*(-3 + 7*E_2)*M*r0 + (4 + 9*E_2)*r0_2) + E*L*r0_3*(3*L_4*M*(-2*M + r0) + L_2*r0_2*(-30*M_2 + (23 + 6*E_2)*M*r0 - 4*r0_2) - 2*r0_4*(8*M_2 - 3*(2 + E_2)*M*r0 + r0_2)) + a_5*M*(E_2*r0_2*(70*M_2 + 45*M*r0 - 9*r0_2) + 2*L_2*(6*M_2 + (3 - 11*E_2)*M*r0 - 11*E_2*r0_2)) + a_3*M*r0*(6*L_4*(M - 3*E_2*r0) + 10*E_2*r0_3*(3*M_2 + 5*M*r0 - 2*r0_2) + L_2*r0*(24*(1 + E_2)*M_2 + (6 + 53*E_2)*M*r0 - (6 + 47*E_2)*r0_2)) + a_4*E*L*r0*(L_2*M*(2*M + (13 + 9*E_2)*r0) + r0*(-2*(47 + 6*E_2)*M_3 - 51*M_2*r0 + 2*(13 + 12*E_2)*M*r0_2 + 5*r0_3)) + a_2*E*L*r0_2*(9*L_4*M + r0_2*(-8*M_3 - (61 + 30*E_2)*M_2*r0 + (20 + 21*E_2)*M*r0_2 + 3*r0_3) + L_2*(-12*M_3 - (65 + 6*E_2)*M_2*r0 + (28 + 15*E_2)*M*r0_2 + 5*r0_3)) + 3*a*M*r0_3*(E_2*(11*M - 5*r0)*r0_4 + L_2*r0_2*((4 + 27*E_2)*M - (2 + 17*E_2)*r0) + L_4*(4*(1 + E_2)*M - 2*(r0 + 3*E_2*r0)))))/(r0_4*expr2_3); A13221 = (-16*(a_7*E_2*M*(12*M_2 - 3*M*r0 - 5*r0_2) + a_6*E*L*M*(-24*M_2 + (-3 + 16*E_2)*M*r0 + (5 + 9*E_2)*r0_2) + E*L*r0_3*(3*L_4*M*(-2*M + r0) + L_2*r0_2*(-26*M_2 + (19 + 6*E_2)*M*r0 - 3*r0_2) - 2*r0_4*(8*M_2 - 3*(2 + E_2)*M*r0 + r0_2)) + a_5*M*(E_2*r0_2*(76*M_2 + 35*M*r0 - 13*r0_2) + L_2*(12*M_2 + (6 - 26*E_2)*M*r0 - 23*E_2*r0_2)) + a_3*M*r0*(6*L_4*(M - 3*E_2*r0) + E_2*r0_3*(48*M_2 + 47*M*r0 - 23*r0_2) + L_2*r0*(24*(1 + E_2)*M_2 + (6 + 35*E_2)*M*r0 - (6 + 47*E_2)*r0_2)) + a_4*E*L*r0*(L_2*M*(4*M + (14 + 9*E_2)*r0) + 2*r0*(-2*(25 + 3*E_2)*M_3 + 2*(-11 + 3*E_2)*M_2*r0 + (13 + 12*E_2)*M*r0_2 + 2*r0_3)) + a_2*E*L*r0_2*(9*L_4*M + r0_2*(-20*M_3 - (53 + 12*E_2)*M_2*r0 + 21*(1 + E_2)*M*r0_2 + 2*r0_3) + L_2*(-12*M_3 - (59 + 6*E_2)*M_2*r0 + 3*(9 + 5*E_2)*M*r0_2 + 4*r0_3)) + 3*a*M*r0_3*(E_2*(11*M - 5*r0)*r0_4 + L_4*(4*(1 + E_2)*M - 2*(r0 + 3*E_2*r0)) + L_2*r0_2*((4 + 21*E_2)*M - 2*(r0 + 7*E_2*r0)))))/(r0*expr2_3); A13401 = (-2*r0_2*(6*a_5*E_2*M*(M - r0) + 3*a_4*E*L*M*(-4*M + (2 + 3*E_2)*r0) + a_3*M*(E_2*(41*M - 11*r0)*r0_2 + 6*L_2*(M - 3*E_2*r0)) + E*L*r0_2*(3*L_2*M*(-2*M + r0) - 2*r0_2*(8*M_2 - 3*(2 + E_2)*M*r0 + r0_2)) + a_2*E*L*r0*(9*L_2*M + r0*(-((53 + 6*E_2)*M_2) + (14 + 15*E_2)*M*r0 + 3*r0_2)) + 3*a*M*r0_2*(E_2*(11*M - 5*r0)*r0_2 + L_2*(4*(1 + E_2)*M - 2*(r0 + 3*E_2*r0)))))/expr2_3; A14021 = (-48*E*r0*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0))*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/expr2_3; A14041 = (-8*(a_11*E_2*M*(24*(57 + 22*E_2)*M_3 + 2*(641 + 276*E_2)*M_2*r0 + 48*(7 + 3*E_2)*M*r0_2 + 21*r0_3) - a_10*E*L*M*(48*(57 + 26*E_2)*M_3 + 2*(1295 + 554*E_2)*M_2*r0 + 6*(108 + 49*E_2)*M*r0_2 + 3*(7 + 12*E_2)*r0_3) + a*M*r0_3*(36*L_8*(26*M_2 - 25*M*r0 + 6*r0_2) + 9*E_2*r0_8*(-25*M_2 + 4*(-10 + 3*E_2)*M*r0 + 25*r0_2) + 3*L_4*r0_4*((88 + 1241*E_2)*M_2 - 4*(29 + 309*E_2 + 10*E_4)*M*r0 + 4*(9 + 74*E_2)*r0_2) - 3*L_2*r0_5*(96*M_3 + (8 - 566*E_2)*M_2*r0 + 4*(-15 + 193*E_2)*M*r0_2 + (16 - 233*E_2)*r0_3) + 4*L_6*r0*(72*M_3 + 2*(153 + 164*E_2)*M_2*r0 - (357 + 320*E_2)*M*r0_2 + 3*(31 + 25*E_2)*r0_3)) - a_2*E*L*r0_3*(8*L_6*M*(293*M_2 - 244*M*r0 + 42*r0_2) + 3*r0_5*(-632*M_4 + (103 - 132*E_2)*M_3*r0 + 2*(29 + 40*E_2)*M_2*r0_2 + (-63 + 166*E_2)*M*r0_3 + 32*r0_4) + 3*L_2*r0_3*(848*M_4 + 2*(113 + 110*E_2)*M_3*r0 - 4*(275 + 73*E_2)*M_2*r0_2 + (169 + 294*E_2)*M*r0_3 + 77*r0_4) + L_4*r0*(4392*M_4 + (2545 - 136*E_2)*M_3*r0 - 2*(2613 + 254*E_2)*M_2*r0_2 + 2*(493 + 182*E_2)*M*r0_3 + 132*r0_4)) + a_9*M*(2*L_2*(36*(19 + 8*E_2)*M_3 + 2*(327 + 371*E_2 + 99*E_4)*M_2*r0 + 12*(13 + 29*E_2 + 8*E_4)*M*r0_2 + 57*E_2*r0_3) + E_2*r0*(-48*(49 + 34*E_2)*M_4 + 3052*M_3*r0 + 8*(674 + 249*E_2)*M_2*r0_2 + 12*(150 + 67*E_2)*M*r0_3 + 153*r0_4)) + a_7*M*(3*L_4*(-112*M_3 + 4*(77 + 3*E_2)*M_2*r0 + 4*(43 + 15*E_2 + 4*E_4)*M*r0_2 + 55*E_2*r0_3) + 3*E_2*r0_3*(-4*(553 + 216*E_2)*M_4 - 24*(37 + 50*E_2)*M_3*r0 + (1975 + 552*E_2)*M_2*r0_2 + 24*(40 + 23*E_2)*M*r0_3 + 114*r0_4) + 2*L_2*r0*(24*(-49 + 150*E_2)*M_4 + 4*(78 + 661*E_2 - 216*E_4)*M_3*r0 + (1164 + 2081*E_2 + 150*E_4)*M_2*r0_2 + (138 + 1079*E_2 + 360*E_4)*M*r0_3 + 6*(-17 + 59*E_2)*r0_4)) + a_3*M*r0_2*(-108*L_8*M + 3*E_2*r0_6*(-1032*M_3 - (437 + 288*E_2)*M_2*r0 + 8*(18 + 29*E_2)*M*r0_2 + 183*r0_3) + 4*L_6*(972*M_3 + 6*(-89 + 59*E_2)*M_2*r0 - (165 + 299*E_2)*M*r0_2 + 3*(19 + 31*E_2)*r0_3) + 2*L_2*r0_3*(-288*M_4 + 48*(-19 + 20*E_2)*M_3*r0 + (408 + 1115*E_2 - 414*E_4)*M_2*r0_2 + 2*(159 - 763*E_2 + 84*E_4)*M*r0_3 + 10*(-15 + 68*E_2)*r0_4) + L_4*r0*(576*M_4 + 48*(29 + 117*E_2)*M_3*r0 + (-1560 + 4297*E_2 - 528*E_4)*M_2*r0_2 - 2*(-126 + 2329*E_2 + 80*E_4)*M*r0_3 + 12*(-7 + 106*E_2)*r0_4)) + a_5*M*r0*(-12*L_6*(32*M_2 + (-8 + 15*E_2)*M*r0 - 6*E_2*r0_2) + 3*E_2*r0_4*(-1404*M_4 - 36*(67 + 32*E_2)*M_3*r0 - 9*(-59 + 24*E_2)*M_2*r0_2 + 16*(46 + 33*E_2)*M*r0_3 + 178*r0_4) + L_4*(4032*M_4 + 24*(-71 + 270*E_2)*M_3*r0 - 4*(177 - 327*E_2 + 116*E_4)*M_2*r0_2 + 2*(258 - 487*E_2 + 4*E_4)*M*r0_3 + 3*(-64 + 309*E_2)*r0_4) + L_2*r0_2*(96*(-31 + 60*E_2)*M_4 - 8*(213 - 889*E_2 + 288*E_4)*M_3*r0 - 6*(-414 - 455*E_2 + 170*E_4)*M_2*r0_2 + 2*(210 - 155*E_2 + 432*E_4)*M*r0_3 + (-456 + 1255*E_2)*r0_4)) - a_8*E*L*(2*L_2*M*(-240*M_3 + 2*(463 + 201*E_2)*M_2*r0 + 3*(177 + 55*E_2)*M*r0_2 + 3*(13 + 12*E_2)*r0_3) + r0*(-96*(49 + 9*E_2)*M_5 + 4*(919 + 874*E_2)*M_4*r0 + 2*(3903 + 2402*E_2)*M_3*r0_2 + 2*(1096 + 775*E_2)*M_2*r0_3 + 6*(3 + 41*E_2)*M*r0_4 + 15*r0_5)) - a_6*E*L*r0*(3*L_4*M*(-252*M_2 + 2*(23 + 6*E_2)*M*r0 + (31 + 12*E_2)*r0_2) + 2*L_2*(5232*M_5 + (44 - 648*E_2)*M_4*r0 + 3*(107 + 362*E_2)*M_3*r0_2 + (991 + 624*E_2)*M_2*r0_3 + 3*(57 + 83*E_2)*M*r0_4 + 15*r0_5) + r0_2*(-108*(89 + 12*E_2)*M_5 + 20*(-293 + 42*E_2)*M_4*r0 + (6187 + 6632*E_2)*M_3*r0_2 + 2*(1246 + 1453*E_2)*M_2*r0_3 + 6*(24 + 107*E_2)*M*r0_4 + 144*r0_5)) - a_4*E*L*r0_2*(12*L_6*M*(-23*M + 3*r0) + L_4*(9936*M_4 - 12*(225 + 38*E_2)*M_3*r0 - 2*(1081 + 68*E_2)*M_2*r0_2 + 12*(55 + 21*E_2)*M*r0_3 + 15*r0_4) + 3*r0_3*(-952*M_5 - 76*(29 + 12*E_2)*M_4*r0 + 2*(277 + 418*E_2)*M_3*r0_2 + (233 + 702*E_2)*M_2*r0_3 + 2*(-13 + 135*E_2)*M*r0_4 + 78*r0_5) + L_2*r0*(5040*M_5 - 8*(-508 + 99*E_2)*M_4*r0 + 4*(-1028 + 489*E_2)*M_3*r0_2 + 2*(-788 + 405*E_2)*M_2*r0_3 + 3*(289 + 348*E_2)*M*r0_4 + 276*r0_5)) + E*L*r0_5*(-4*L_6*M*(230*M_2 - 233*M*r0 + 59*r0_2) + 3*L_2*r0_4*(-364*M_3 + 2*(203 + 80*E_2)*M_2*r0 - 2*(61 + 44*E_2)*M*r0_2 + 5*r0_3) + L_4*r0_2*(-2114*M_3 + (2213 + 272*E_2)*M_2*r0 - 2*(301 + 74*E_2)*M*r0_2 + 12*r0_3) + 3*r0_6*(18*M_3 - 4*(3 + 10*E_2)*M*r0_2 + 3*r0_3 + 3*M_2*(r0 + 24*E_2*r0)))))/(3.*r0_5*expr2_4); A14201 = (-12*E*r0_4*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0)))/expr2_3; A14221 = (-4*(a_9*E_2*M*((234 + 80*E_2)*M_2 + 6*(19 + 7*E_2)*M*r0 + 7*r0_2) - a_8*E*L*M*(4*(117 + 44*E_2)*M_2 + (226 + 87*E_2)*M*r0 + (7 + 15*E_2)*r0_2) - E*L*r0_4*(L_4*M*(340*M_2 - 344*M*r0 + 87*r0_2) + r0_4*(-18*M_3 + (17 - 72*E_2)*M_2*r0 + 8*(-1 + 5*E_2)*M*r0_2 + 2*r0_3) + L_2*r0_2*(374*M_3 - (379 + 80*E_2)*M_2*r0 + 4*(23 + 11*E_2)*M*r0_2 + 2*r0_3)) + a_7*M*(L_2*(6*(39 + 8*E_2)*M_2 + 4*(28 + 31*E_2 + 7*E_4)*M*r0 + 37*E_2*r0_2) + E_2*r0*(-4*(101 + 62*E_2)*M_3 + (625 + 136*E_2)*M_2*r0 + 2*(231 + 95*E_2)*M*r0_2 + 39*r0_3)) + a_5*M*(L_4*(-64*M_2 + 4*(19 - 6*E_2)*M*r0 + 30*E_2*r0_2) + E_2*r0_3*(-8*(124 + 45*E_2)*M_3 + (121 - 128*E_2)*M_2*r0 + 10*(48 + 29*E_2)*M*r0_2 + 57*r0_3) + L_2*r0*(4*(-101 + 300*E_2)*M_3 + 2*(145 + 56*E_2 - 68*E_4)*M_2*r0 + (160 + 55*E_2 + 72*E_4)*M*r0_2 + 2*(-38 + 93*E_2)*r0_3)) + a_3*M*r0*(-36*L_6*M + E_2*r0_4*(-516*M_3 - 9*(41 + 24*E_2)*M_2*r0 + 2*(81 + 89*E_2)*M*r0_2 + 85*r0_3) + 4*L_4*(162*M_3 + (-115 + 132*E_2)*M_2*r0 + (3 - 89*E_2)*M*r0_2 + (-1 + 31*E_2)*r0_3) + L_2*r0_2*(16*(-31 + 69*E_2)*M_3 + (80 + 393*E_2 - 168*E_4)*M_2*r0 + 4*(69 - 165*E_2 + 11*E_4)*M*r0_2 + 2*(-55 + 123*E_2)*r0_3)) + a*M*r0_2*(12*L_6*(26*M_2 - 25*M*r0 + 6*r0_2) + 3*E_2*r0_6*(-25*M_2 + 6*(-5 + 2*E_2)*M*r0 + 20*r0_2) + 2*L_4*r0*(24*M_3 + 8*(5 + 32*E_2)*M_2*r0 - 2*(31 + 113*E_2)*M*r0_2 + (18 + 47*E_2)*r0_3) + L_2*r0_3*(-48*M_3 + (-128 + 595*E_2)*M_2*r0 + 3*(48 - 205*E_2)*M*r0_2 + (-34 + 151*E_2)*r0_3)) - a_6*E*L*(L_2*M*(-112*M_2 + (155 + 48*E_2)*M*r0 + (22 + 15*E_2)*r0_2) + r0*(-8*(101 + 12*E_2)*M_4 + 5*(183 + 98*E_2)*M_3*r0 + (643 + 322*E_2)*M_2*r0_2 + 2*(-6 + 43*E_2)*M*r0_3 + 8*r0_4)) - a_2*E*L*r0_2*(2*L_4*M*(400*M_2 - 332*M*r0 + 57*r0_2) + L_2*r0*(804*M_4 + (45 + 4*E_2)*M_3*r0 - 4*(181 + 16*E_2)*M_2*r0_2 + (131 + 111*E_2)*M*r0_3 + 39*r0_4) + r0_3*(-316*M_4 - (241 + 18*E_2)*M_3*r0 + (177 + 40*E_2)*M_2*r0_2 + 8*(-12 + 17*E_2)*M*r0_3 + 42*r0_4)) - a_4*E*L*r0*(5*L_4*M*(-16*M + 3*r0) + L_2*(1696*M_4 - 6*(117 + 16*E_2)*M_3*r0 + 5*(-13 + 16*E_2)*M_2*r0_2 + 2*(51 + 41*E_2)*M*r0_3 + 8*r0_4) + r0_2*(-12*(124 + E_2)*M_4 + 12*(-2 + 25*E_2)*M_3*r0 + (505 + 323*E_2)*M_2*r0_2 + (-47 + 167*E_2)*M*r0_3 + 48*r0_4))))/(r0_2*expr2_4); A14401 = (r0*(-9*a_7*E_2*M*(4*(10 + 3*E_2)*M + 3*r0) + 9*a_6*E*L*M*(80*M + 24*E_2*M + 3*r0 + 6*E_2*r0) - a_5*M*(36*L_2*(10*M + 3*E_2*r0) + E_2*r0*(-48*(13 + 7*E_2)*M_2 + 12*(88 + 31*E_2)*M*r0 + 91*r0_2)) + a_3*M*(108*L_4*M + E_2*r0_3*(3*(409 + 144*E_2)*M_2 - 2*(275 + 186*E_2)*M*r0 - 22*r0_2) - 12*L_2*r0*(2*(-26 + 75*E_2)*M_2 + (61 - 88*E_2)*M*r0 + 3*(-7 + 11*E_2)*r0_2)) - 3*a*M*r0*(12*L_4*(26*M_2 - 25*M*r0 + 6*r0_2) + E_2*r0_4*(-75*M_2 + 2*(-25 + 18*E_2)*M*r0 + 40*r0_2) + 4*L_2*r0_2*(2*(-31 + 78*E_2)*M_2 + (57 - 128*E_2)*M*r0 + (-13 + 24*E_2)*r0_2)) + E*L*r0_3*(6*L_2*M*(192*M_2 - 194*M*r0 + 49*r0_2) + r0_2*(-54*M_3 + (131 - 216*E_2)*M_2*r0 + 8*(-13 + 15*E_2)*M*r0_2 + 26*r0_3)) + a_4*E*L*(-54*L_2*M*(4*M - r0) + r0*(-24*(52 + 3*E_2)*M_3 + 12*(149 + 40*E_2)*M_2*r0 + 2*(-67 + 126*E_2)*M*r0_2 + 27*r0_3)) + a_2*E*L*r0*(24*L_2*M*(103*M_2 - 86*M*r0 + 15*r0_2) + r0_2*(9*(-219 + 32*E_2)*M_3 + 1006*M_2*r0 + 6*(-58 + 53*E_2)*M*r0_2 + 134*r0_3))))/(6.*expr2_4); A15021 = (-8*(a_7*E_2*M*(12*M_2 - 3*M*r0 - 5*r0_2) + a_6*E*L*M*(-24*M_2 + (-3 + 16*E_2)*M*r0 + (5 + 9*E_2)*r0_2) + E*L*r0_3*(3*L_4*M*(-2*M + r0) - r0_4*(14*M_2 - 3*(3 + 2*E_2)*M*r0 + r0_2) - 2*L_2*r0_2*(12*M_2 - (8 + 3*E_2)*M*r0 + r0_2)) + a_5*M*(2*E_2*r0_2*(37*M_2 + 18*M*r0 - 6*r0_2) + L_2*(12*M_2 + (6 - 26*E_2)*M*r0 - 23*E_2*r0_2)) + a_3*M*r0*(6*L_4*(M - 3*E_2*r0) + E_2*r0_3*(42*M_2 + 49*M*r0 - 19*r0_2) + 2*L_2*r0*(12*(1 + E_2)*M_2 + (3 + 17*E_2)*M*r0 - (3 + 23*E_2)*r0_2)) + a_2*E*L*r0_2*(9*L_4*M + r0_2*(-16*M_3 - 4*(14 + 3*E_2)*M_2*r0 + (19 + 21*E_2)*M*r0_2 + 3*r0_3) + L_2*(-12*M_3 - 2*(29 + 3*E_2)*M_2*r0 + (26 + 15*E_2)*M*r0_2 + 4*r0_3)) + a_4*E*L*r0*(L_2*M*(4*M + (14 + 9*E_2)*r0) + r0*(-2*(49 + 6*E_2)*M_3 + 3*(-15 + 4*E_2)*M_2*r0 + (25 + 24*E_2)*M*r0_2 + 4*r0_3)) + 3*a*M*r0_3*(2*E_2*(5*M - 2*r0)*r0_4 + L_2*r0_2*(4*(1 + 5*E_2)*M - (2 + 13*E_2)*r0) + L_4*(4*(1 + E_2)*M - 2*(r0 + 3*E_2*r0)))))/(r0*expr2_4); A15201 = (-2*r0_2*(6*a_5*E_2*M*(M - r0) + 3*a_4*E*L*M*(-4*M + (2 + 3*E_2)*r0) + 2*a_3*M*(5*E_2*(4*M - r0)*r0_2 + 3*L_2*(M - 3*E_2*r0)) + 6*a*M*r0_2*(E_2*(5*M - 2*r0)*r0_2 + L_2*(2*(1 + E_2)*M - (1 + 3*E_2)*r0)) + E*L*r0_2*(3*L_2*M*(-2*M + r0) - r0_2*(14*M_2 - 3*(3 + 2*E_2)*M*r0 + r0_2)) + a_2*E*L*r0*(9*L_2*M + r0*(-2*(26 + 3*E_2)*M_2 + (13 + 15*E_2)*M*r0 + 3*r0_2))))/expr2_4; A16001 = (-4*E*r0_4*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0)))/expr2_4; A16021 = (-2*(3*a_9*E_2*M*(4*(28 + 23*E_2)*M_2 + 2*(31 + 24*E_2)*M*r0 + 11*r0_2) - 3*a_8*E*L*M*(4*(56 + 53*E_2)*M_2 + 2*(57 + 56*E_2)*M*r0 + (11 + 18*E_2)*r0_2) - E*L*r0_4*(2*L_4*M*(290*M_2 - 293*M*r0 + 74*r0_2) + M*r0_4*(26*M_2 - (53 + 92*E_2)*M*r0 + 4*(5 + 13*E_2)*r0_2) + L_2*r0_2*(654*M_3 - (639 + 124*E_2)*M_2*r0 + 4*(33 + 17*E_2)*M*r0_2 + 12*r0_3)) + a_7*M*(3*L_2*(28*(4 + 3*E_2)*M_2 + 4*(13 + 24*E_2 + 8*E_4)*M*r0 + 47*E_2*r0_2) + 2*E_2*r0*(-4*(63 + 74*E_2)*M_3 + 10*(42 + 37*E_2)*M_2*r0 + (309 + 358*E_2)*M*r0_2 + 81*r0_3)) + a*M*r0_2*(36*L_6*(18*M_2 - 17*M*r0 + 4*r0_2) + 3*E_2*r0_6*(-M_2 + 2*(-61 + 30*E_2)*M*r0 + 56*r0_2) + 4*L_4*r0*(24*M_3 + 2*(51 + 91*E_2)*M_2*r0 - (123 + 181*E_2)*M*r0_2 + 3*(11 + 13*E_2)*r0_3) + L_2*r0_3*(-96*M_3 + (-48 + 829*E_2)*M_2*r0 + 2*(36 - 451*E_2 + 36*E_4)*M*r0_2 + 12*(-1 + 17*E_2)*r0_3)) + a_3*M*r0*(-108*L_6*M + 2*E_2*r0_4*(-399*M_3 - 6*(40 + 39*E_2)*M_2*r0 + 2*(-48 + 197*E_2)*M*r0_2 + 153*r0_3) + 4*L_4*(336*M_3 + 3*(-61 + 86*E_2)*M_2*r0 - (51 + 154*E_2)*M*r0_2 + 6*(1 + 11*E_2)*r0_3) + L_2*r0_2*(16*(-39 + 86*E_2)*M_3 + (132 + 1643*E_2 - 432*E_4)*M_2*r0 + 2*(138 - 661*E_2 + 152*E_4)*M*r0_2 + 6*(-22 + 83*E_2)*r0_3)) + a_5*M*(-12*L_4*(16*M_2 + (-4 + 3*E_2)*M*r0 - 9*E_2*r0_2) + E_2*r0_3*(-6*(187 + 168*E_2)*M_3 + (195 + 92*E_2)*M_2*r0 + 118*(3 + 10*E_2)*M*r0_2 + 267*r0_3) + L_2*r0*(24*(-21 + 94*E_2)*M_3 + 4*(105 + 260*E_2 - 76*E_4)*M_2*r0 + 8*(18 - 9*E_2 + 41*E_4)*M*r0_2 + 3*(-40 + 163*E_2)*r0_3)) - a_6*E*L*(3*L_2*M*(-100*M_2 + 12*(4 + 5*E_2)*M*r0 + (29 + 18*E_2)*r0_2) + r0*(-144*(7 + 3*E_2)*M_4 + 4*(315 + 499*E_2)*M_3*r0 + 2*(392 + 625*E_2)*M_2*r0_2 + 3*(31 + 68*E_2)*M*r0_3 + 21*r0_4)) - a_2*E*L*r0_2*(2*L_4*M*(820*M_2 - 695*M*r0 + 111*r0_2) + r0_3*(-524*M_4 + (83 - 476*E_2)*M_3*r0 + (-217 + 722*E_2)*M_2*r0_2 + 40*(-2 + 5*E_2)*M*r0_3 + 84*r0_4) + L_2*r0*(1336*M_4 + (1075 - 284*E_2)*M_3*r0 + 2*(-1014 + 83*E_2)*M_2*r0_2 + 2*(141 + 100*E_2)*M*r0_3 + 84*r0_4)) - a_4*E*L*r0*(-6*L_4*M*(38*M - 9*r0) + L_2*(3440*M_4 - 12*(79 + 22*E_2)*M_3*r0 + 10*(-81 + 49*E_2)*M_2*r0_2 + 6*(51 + 31*E_2)*M*r0_3 + 21*r0_4) + r0_2*(-2*(873 + 436*E_2)*M_4 + (-49 + 1068*E_2)*M_3*r0 + 4*(17 + 396*E_2)*M_2*r0_2 + 2*(43 + 149*E_2)*M*r0_3 + 105*r0_4))))/(3.*r0_2*expr2_5); A16201 = (r0*(-3*a_7*E_2*M*((56 + 44*E_2)*M + 15*r0) + 3*a_6*E*L*M*(16*(7 + 6*E_2)*M + (15 + 22*E_2)*r0) - a_5*M*(12*L_2*(2*(7 + 3*E_2)*M + 11*E_2*r0) + E_2*r0*(-4*(63 + 68*E_2)*M_2 + 4*(88 + 131*E_2)*M*r0 + 141*r0_2)) + a_3*M*(108*L_4*M + E_2*r0_3*((317 + 432*E_2)*M_2 + (74 - 572*E_2)*M*r0 - 102*r0_2) - 4*L_2*r0*(3*(-21 + 94*E_2)*M_2 + (78 - 113*E_2)*M*r0 + 33*(-1 + 2*E_2)*r0_2)) + a*M*r0*(3*E_2*r0_4*(M_2 + (98 - 60*E_2)*M*r0 - 44*r0_2) - 36*L_4*(18*M_2 - 17*M*r0 + 4*r0_2) - 4*L_2*r0_2*((-72 + 214*E_2)*M_2 + 5*(12 - 37*E_2)*M*r0 + 3*(-4 + 11*E_2)*r0_2)) + E*L*r0_3*(2*L_2*M*(322*M_2 - 325*M*r0 + 82*r0_2) + r0_2*(26*M_3 - (5 + 92*E_2)*M_2*r0 + 4*(-7 + 13*E_2)*M*r0_2 + 12*r0_3)) + a_4*E*L*(6*L_2*M*(-32*M + 11*r0) + r0*(-168*(3 + E_2)*M_3 + 2*(332 + 433*E_2)*M_2*r0 + 6*(1 + 31*E_2)*M*r0_2 + 21*r0_3)) + a_2*E*L*r0*(2*L_2*M*(836*M_2 - 703*M*r0 + 111*r0_2) + r0_2*(-55*(11 + 4*E_2)*M_3 + 2*(42 + 241*E_2)*M_2*r0 + 4*(-37 + 43*E_2)*M*r0_2 + 96*r0_3))))/(6.*expr2_5); A17001 = (-2*r0_2*(2*a_5*E_2*M*(M - r0) + a_4*E*L*M*(-4*M + (2 + 3*E_2)*r0) + a_3*M*(E_2*(13*M - 3*r0)*r0_2 + 2*L_2*(M - 3*E_2*r0)) + E*L*M*r0_2*(L_2*(-2*M + r0) + 2*r0_2*(-2*M + r0 + E_2*r0)) + a_2*E*L*r0*(3*L_2*M + r0*(-((17 + 2*E_2)*M_2) + (4 + 5*E_2)*M*r0 + r0_2)) + a*M*r0_2*(3*E_2*(3*M - r0)*r0_2 + L_2*(4*(1 + E_2)*M - 2*(r0 + 3*E_2*r0)))))/expr2_5; A18001 = (r0*(-3*a_7*E_2*M*((4 + 8*E_2)*M + 3*r0) + 3*a_6*E*L*M*(2*(4 + 9*E_2)*M + (3 + 4*E_2)*r0) + E*L*M*(2*M - r0)*r0_3*(16*L_2*(2*M - r0) + r0_2*(5*M - 2*(2 + E_2)*r0)) - a*M*r0*(6*L_4*(14*M_2 - 13*M*r0 + 3*r0_2) + 3*E_2*r0_4*(5*M_2 + 4*(-5 + 3*E_2)*M*r0 + 8*r0_2) + 2*L_2*r0_2*((-6 + 28*E_2)*M_2 + (3 - 26*E_2)*M*r0 + 3*E_2*r0_2)) + a_3*M*(18*L_4*M + E_2*r0_3*((-17 + 72*E_2)*M_2 + 2*(29 - 56*E_2)*M*r0 - 24*r0_2) - 2*L_2*r0*((-6 + 66*E_2)*M_2 + (9 - 11*E_2)*M*r0 + 3*(-2 + 5*E_2)*r0_2)) + a_4*E*L*(-6*L_2*M*(5*M - 2*r0) + r0*(-12*(2 + 3*E_2)*M_3 + 2*(10 + 89*E_2)*M_2*r0 + 12*(1 + 2*E_2)*M*r0_2 + 3*r0_3)) + a_2*E*L*r0*(2*L_2*M*(106*M_2 - 89*M*r0 + 12*r0_2) + r0_2*((5 - 80*E_2)*M_3 + 2*(-27 + 62*E_2)*M_2*r0 + 2*(-4 + 7*E_2)*M*r0_2 + 12*r0_3)) - a_5*M*(6*L_2*((2 + 3*E_2)*M + 4*E_2*r0) + E_2*r0*(-4*(3 + 10*E_2)*M_2 + 27*r0_2 + 2*M*(r0 + 50*E_2*r0)))))/(3.*expr2_6); } /* A_{t,theta} */ { A20161 = (128*E*expr1_3*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/(r0_6*(a_2 + r0*(-2*M + r0))); A20341 = (96*E*expr1_2*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/(r0_3*(a_2 + r0*(-2*M + r0))); A20521 = (24*E*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/(a_2 + r0*(-2*M + r0)); A20701 = 2*E*r0_3*(-(E*M*(a_3 - 3*a*r0_2)) + L*(a_2*M + 2*r0_2*(-M + r0)) - (L*M*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/(a_2 + r0*(-2*M + r0))); A21161 = (64*expr1_2*(a_8*E*L*M*((8 - 24*E_2)*M_2 - 2*(1 + E_2)*r0_2 + M*(r0 - 11*E_2*r0)) + a_9*E_2*M*(4*(-1 + 3*E_2)*M_2 + 2*r0_2 + M*(r0 + 6*E_2*r0)) + a_6*E*L*M*(L_2*(24*M_2 + (17 + 6*E_2)*M*r0 - 2*(2 + E_2)*r0_2) + r0*(16*(-1 + 2*E_2)*M_3 - 2*(4 + 57*E_2)*M_2*r0 + (6 - 49*E_2)*M*r0_2 + (-1 + E_2)*r0_3)) - a_5*M*(2*L_4*(6*M_2 + (4 + 9*E_2)*M*r0 - 2*E_2*r0_2) + E_2*r0_3*(12*(1 + 4*E_2)*M_3 + 4*(1 - 5*E_2)*M_2*r0 - (19 + 52*E_2)*M*r0_2 - 13*r0_3) + 2*L_2*r0*(-4*M_3 - 2*(2 + 25*E_2)*M_2*r0 + (4 + 7*E_2)*M*r0_2 + (2 + E_2)*r0_3)) + a_4*E*L*r0*(2*L_4*M*(9*M - r0) + L_2*M*(-32*M_3 - 2*(17 + 4*E_2)*M_2*r0 + (39 + 10*E_2)*M*r0_2 + 5*r0_3) + r0_2*(4*(7 + 38*E_2)*M_4 - 4*(3 + 13*E_2)*M_3*r0 - (23 + 97*E_2)*M_2*r0_2 + (8 + 13*E_2)*M*r0_3 + 2*r0_4)) + a_2*E*L*r0_2*(2*L_4*M*(-12*M_2 + 9*M*r0 + r0_2) + L_2*M*r0*(56*M_3 + 4*(-11 + 2*E_2)*M_2*r0 - 2*(10 + E_2)*M*r0_2 + 3*(7 + 2*E_2)*r0_3) + r0_3*(-8*M_4 + 6*(8 + 13*E_2)*M_3*r0 - (40 + 67*E_2)*M_2*r0_2 + 3*(1 + 5*E_2)*M*r0_3 + 4*r0_4)) + a_7*M*(E_2*r0*((8 - 16*E_2)*M_3 + 44*E_2*M_2*r0 + (3 + 32*E_2)*M*r0_2 + 7*r0_3) - 2*L_2*(2*M_2 - 3*E_2*r0_2 + M*(r0 + 2*E_2*r0))) + E*L*r0_4*(4*L_4*M*(2*M_2 - 3*M*r0 + r0_2) + 2*L_2*M*r0_2*(16*M_2 - (20 + 3*E_2)*M*r0 + 2*(3 + E_2)*r0_2) + r0_4*(8*M_3 + (-4 + 5*E_2)*M*r0_2 + 2*r0_3 - 4*M_2*(r0 + 2*E_2*r0))) - a_3*M*r0*(6*L_6*M + E_2*r0_4*(4*M_3 + 4*(11 + 3*E_2)*M_2*r0 - (17 + 32*E_2)*M*r0_2 - 13*r0_3) + 2*L_2*r0_2*((8 + 80*E_2)*M_3 - 2*(5 + 19*E_2)*M_2*r0 - (3 + 34*E_2)*M*r0_2 + (4 + 15*E_2)*r0_3) + L_4*(-16*M_3 + 8*(1 + 3*E_2)*M*r0_2 + 2*(2 + E_2)*r0_3 - 4*M_2*(r0 + 6*E_2*r0))) - a*M*r0_2*(4*L_6*M*(-2*M + r0) + E_2*r0_6*(20*M_2 - 6*E_2*M*r0 - 5*r0_2) + 2*L_2*r0_4*((4 + 56*E_2)*M_2 - (6 + 47*E_2)*M*r0 + (2 + 11*E_2)*r0_2) + 2*L_4*r0_2*(2*r0*(-2*M + r0) + E_2*(8*M_2 - 7*M*r0 + 3*r0_2)))))/(r0_8*expr2_2); A21341 = (16*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-(a_8*E*L*M*(24*(-1 + 3*E_2)*M_2 + 44*E_2*M*r0 + (7 + 9*E_2)*r0_2)) + a_9*E_2*M*(12*(-1 + 3*E_2)*M_2 + 7*r0_2 + 6*M*(r0 + 3*E_2*r0)) + a_7*M*(L_2*(-12*M_2 + 2*(-3 + 5*E_2 + 3*E_4)*M*r0 + 25*E_2*r0_2) + 2*E_2*r0*((12 - 24*E_2)*M_3 + 6*(-1 + 11*E_2)*M_2*r0 + (1 + 48*E_2)*M*r0_2 + 10*r0_3)) + a_5*M*(-6*L_4*(6*M_2 + 2*(2 + 3*E_2)*M*r0 - 3*E_2*r0_2) + 2*E_2*r0_3*(-12*(1 + 6*E_2)*M_3 + 2*(4 + 15*E_2)*M_2*r0 + (25 + 78*E_2)*M*r0_2 + 17*r0_3) + L_2*r0*(24*M_3 - 8*(-3 - 29*E_2 + E_4)*M_2*r0 + 2*(-12 - 13*E_2 + 13*E_4)*M*r0_2 + (-12 + 7*E_2)*r0_3)) + a_2*E*L*r0_2*(L_4*M*(-64*M_2 + 48*M*r0 + 7*r0_2) + r0_4*(4*(26 + 51*E_2)*M_3 - 2*(53 + 92*E_2)*M_2*r0 + (13 + 44*E_2)*M*r0_2 + 10*r0_3) + L_2*M*r0*(144*M_3 + 40*(-3 + 2*E_2)*M_2*r0 - 2*(25 + 28*E_2)*M*r0_2 + (58 + 21*E_2)*r0_3)) - a_4*E*L*r0*(L_4*(-48*M_2 + 9*M*r0) + r0_2*(-72*(1 + 6*E_2)*M_4 + 4*(13 + 32*E_2)*M_3*r0 + 4*(10 + 69*E_2)*M_2*r0_2 - (23 + 34*E_2)*M*r0_3 - 2*r0_4) + L_2*(96*M_4 + 68*M_3*r0 + 2*(-57 + 14*E_2)*M_2*r0_2 + (-8 + E_2)*M*r0_3 + 2*r0_4)) - a_6*E*L*(L_2*M*(-72*M_2 - 40*M*r0 + (16 + 9*E_2)*r0_2) + r0*((48 - 96*E_2)*M_4 + 4*(3 + 77*E_2)*M_3*r0 + 2*(-11 + 80*E_2)*M_2*r0_2 + (9 + 4*E_2)*M*r0_3 + 2*r0_4)) + E*L*r0_4*(2*L_4*M*(16*M_2 - 22*M*r0 + 7*r0_2) + L_2*r0_2*(88*M_3 - 4*(26 + 5*E_2)*M_2*r0 + 13*(2 + E_2)*M*r0_2 + 2*r0_3) + 3*r0_4*(8*M_3 + (-4 + 5*E_2)*M*r0_2 + 2*r0_3 - 4*M_2*(r0 + 2*E_2*r0))) - a_3*M*r0*(18*L_6*M + 6*E_2*r0_4*(8*M_3 + 6*(3 + E_2)*M_2*r0 - (9 + 16*E_2)*M*r0_2 - 6*r0_3) + L_2*r0_2*(48*(1 + 9*E_2)*M_3 + 4*(-15 - 47*E_2 + 6*E_4)*M_2*r0 - 2*(9 + 91*E_2 + 13*E_4)*M*r0_2 + 3*(8 + 23*E_2)*r0_3) + L_4*(-48*M_3 + 2*(12 + 17*E_2)*M*r0_2 + 6*(2 + E_2)*r0_3 - 12*M_2*(r0 + 4*E_2*r0))) + a*M*r0_2*(12*L_6*M*(2*M - r0) + 3*E_2*r0_6*(-20*M_2 + 6*E_2*M*r0 + 5*r0_2) - 3*L_2*r0_4*(4*(2 + 25*E_2)*M_2 - 2*(6 + 39*E_2 + E_4)*M*r0 + (4 + 17*E_2)*r0_2) - 2*L_4*r0_2*(6*r0*(-2*M + r0) + E_2*(44*M_2 - 37*M*r0 + 12*r0_2)))))/(r0_5*expr2_2); A21521 = (4*(-(a_8*E*L*M*(24*(-1 + 3*E_2)*M_2 + (3 + 55*E_2)*M*r0 + 4*(2 + 3*E_2)*r0_2)) + a_9*E_2*M*(12*(-1 + 3*E_2)*M_2 + 8*r0_2 + 9*M*(r0 + 2*E_2*r0)) + a_7*M*(L_2*(-12*M_2 + 2*(-3 + 16*E_2 + 6*E_4)*M*r0 + 32*E_2*r0_2) + E_2*r0*((24 - 48*E_2)*M_3 + 12*(-2 + 11*E_2)*M_2*r0 + (-5 + 96*E_2)*M*r0_2 + 19*r0_3)) + a_5*M*(-6*L_4*(6*M_2 + (4 + 3*E_2)*M*r0 - 4*E_2*r0_2) + E_2*r0_3*(-12*(1 + 12*E_2)*M_3 + 4*(11 + 15*E_2)*M_2*r0 + (43 + 156*E_2)*M*r0_2 + 29*r0_3) + 2*L_2*r0*(12*M_3 + 2*(6 + 41*E_2 - 4*E_4)*M_2*r0 + (-12 - 5*E_2 + 26*E_4)*M*r0_2 + 2*(-3 + 5*E_2)*r0_3)) - a_4*E*L*r0*(-6*L_4*M*(7*M - 2*r0) + r0_2*(-12*(5 + 34*E_2)*M_4 + 4*(17 + 25*E_2)*M_3*r0 + (11 + 261*E_2)*M_2*r0_2 - (22 + 29*E_2)*M*r0_3 + 2*r0_4) + L_2*(96*M_4 + (34 - 24*E_2)*M_3*r0 + (-111 + 86*E_2)*M_2*r0_2 + (-1 + 2*E_2)*M*r0_3 + 4*r0_4)) - a_6*E*L*(L_2*M*(-72*M_2 + (-29 + 18*E_2)*M*r0 + 4*(5 + 3*E_2)*r0_2) + r0*((48 - 96*E_2)*M_4 + 274*E_2*M_3*r0 + (-26 + 173*E_2)*M_2*r0_2 + (15 + 11*E_2)*M*r0_3 + 4*r0_4)) + a_2*E*L*r0_2*(L_4*(-56*M_3 + 42*M_2*r0 + 8*M*r0_2) + L_2*M*r0*(120*M_3 + 4*(-27 + 34*E_2)*M_2*r0 - 2*(20 + 53*E_2)*M*r0_2 + (53 + 24*E_2)*r0_3) + r0_3*(24*M_4 + 2*(32 + 87*E_2)*M_3*r0 - (92 + 167*E_2)*M_2*r0_2 + (17 + 43*E_2)*M*r0_3 + 8*r0_4)) + E*L*r0_4*(4*L_4*M*(10*M_2 - 13*M*r0 + 4*r0_2) + 2*L_2*r0_2*(40*M_3 - 11*(4 + E_2)*M_2*r0 + (8 + 7*E_2)*M*r0_2 + 2*r0_3) + 3*r0_4*(8*M_3 + (-4 + 5*E_2)*M*r0_2 + 2*r0_3 - 4*M_2*(r0 + 2*E_2*r0))) + a_3*M*r0*(-18*L_6*M + 3*E_2*r0_4*(-28*M_3 - 4*(7 + 3*E_2)*M_2*r0 + (19 + 32*E_2)*M*r0_2 + 11*r0_3) - 2*L_2*r0_2*(24*(1 + 8*E_2)*M_3 + 2*(-15 - 37*E_2 + 12*E_4)*M_2*r0 - (9 + 80*E_2 + 26*E_4)*M*r0_2 + 12*(1 + 2*E_2)*r0_3) + 2*L_4*(24*M_3 + 2*(-6 + E_2)*M*r0_2 - 3*(2 + E_2)*r0_3 + 6*M_2*(r0 + 2*E_2*r0))) + a*M*r0_2*(12*L_6*M*(2*M - r0) + 3*E_2*r0_6*(-20*M_2 + 6*E_2*M*r0 + 5*r0_2) - 6*L_2*r0_4*((4 + 44*E_2)*M_2 - (6 + 31*E_2 + 2*E_4)*M*r0 + 2*(1 + 3*E_2)*r0_2) - 2*L_4*r0_2*(6*r0*(-2*M + r0) + E_2*(64*M_2 - 53*M*r0 + 15*r0_2)))))/(r0_2*expr2_2); A21701 = (r0*(a_7*E_2*M*((-2 + 6*E_2)*M + 3*r0) - a_6*E*L*M*(4*(-1 + 3*E_2)*M + (3 + 5*E_2)*r0) + a_5*M*(-2*L_2*(M - 5*E_2*r0) + E_2*r0*((4 - 8*E_2)*M_2 + 2*(-4 + 13*E_2)*M*r0 + 3*r0_2)) + a*M*r0*(4*L_4*M*(2*M - r0) + E_2*r0_4*(-20*M_2 + 6*E_2*M*r0 + 5*r0_2) - 2*L_2*r0_2*(4*(1 + 7*E_2)*M_2 - (6 + 23*E_2)*M*r0 + 2*(1 + 3*E_2)*r0_2)) + a_2*E*L*M*r0*(L_2*(-16*M_2 + 12*M*r0 + 3*r0_2) + r0_2*(8*(1 + 8*E_2)*M_2 - 2*(7 + 26*E_2)*M*r0 + (7 + 9*E_2)*r0_2)) + a_4*E*L*(L_2*M*(12*M - 5*r0) - r0*((8 - 16*E_2)*M_3 + 6*(-1 + 8*E_2)*M_2*r0 + E_2*M*r0_2 + 2*r0_3)) + E*L*r0_3*(2*L_2*M*(8*M_2 - 10*M*r0 + 3*r0_2) + r0_2*(8*M_3 + (-4 + 5*E_2)*M*r0_2 + 2*r0_3 - 4*M_2*(r0 + 2*E_2*r0))) + a_3*M*(-6*L_4*M + 2*L_2*r0*(2*M_2 - (2 + E_2)*r0_2 + M*(r0 + 7*E_2*r0)) + E_2*r0_3*(5*r0*(2*M + r0) + E_2*(-24*M_2 + 26*M*r0)))))/expr2_2; A22141 = (96*E*expr1_2*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/(r0_3*expr2_2); A22321 = (48*E*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/expr2_2; A22501 = (6*E*r0_3*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/expr2_2; A23141 = (16*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-(a_8*E*L*M*(24*(-1 + 3*E_2)*M_2 + 44*E_2*M*r0 + (7 + 9*E_2)*r0_2)) + a_9*E_2*M*(12*(-1 + 3*E_2)*M_2 + 7*r0_2 + 6*M*(r0 + 3*E_2*r0)) + E*L*r0_4*(2*L_4*M*(18*M_2 - 25*M*r0 + 8*r0_2) + L_2*r0_2*(88*M_3 - (100 + 21*E_2)*M_2*r0 + 2*(10 + 7*E_2)*M*r0_2 + 4*r0_3) + r0_4*(20*M_3 - (2 + 25*E_2)*M_2*r0 + 4*(-5 + 4*E_2)*M*r0_2 + 8*r0_3)) + a_7*M*(L_2*(-12*M_2 + 2*(-3 + 5*E_2 + 3*E_4)*M*r0 + 25*E_2*r0_2) + E_2*r0*((24 - 48*E_2)*M_3 + 2*(-5 + 66*E_2)*M_2*r0 + (1 + 96*E_2)*M*r0_2 + 19*r0_3)) + a_5*M*(-6*L_4*(6*M_2 + 2*(2 + 3*E_2)*M*r0 - 3*E_2*r0_2) + L_2*r0*(24*M_3 + 4*(6 + 61*E_2 - 2*E_4)*M_2*r0 + (-24 - 31*E_2 + 26*E_4)*M*r0_2 - 12*r0_3) + E_2*r0_3*(-4*(7 + 36*E_2)*M_3 + 2*(7 + 30*E_2)*M_2*r0 + (55 + 156*E_2)*M*r0_2 + 35*r0_3)) - a_6*E*L*(L_2*M*(-72*M_2 - 40*M*r0 + (16 + 9*E_2)*r0_2) + r0*((48 - 96*E_2)*M_4 + 2*(7 + 157*E_2)*M_3*r0 + (-23 + 157*E_2)*M_2*r0_2 + (8 + E_2)*M*r0_3 + 2*r0_4)) + a_4*E*L*r0*(3*L_4*M*(16*M - 3*r0) + L_2*(-96*M_4 - 74*M_3*r0 + (116 - 31*E_2)*M_2*r0_2 + 2*(6 + E_2)*M*r0_3 - 2*r0_4) + r0_2*((76 + 440*E_2)*M_4 - 4*(13 + 35*E_2)*M_3*r0 - 3*(16 + 93*E_2)*M_2*r0_2 + (25 + 41*E_2)*M*r0_3 + 4*r0_4)) + a_2*E*L*r0_2*(L_4*M*(-64*M_2 + 45*M*r0 + 10*r0_2) + L_2*r0*(152*M_4 + 42*(-3 + 2*E_2)*M_3*r0 - 8*(7 + 8*E_2)*M_2*r0_2 + 5*(12 + 5*E_2)*M*r0_3 + 2*r0_4) + r0_3*(-8*M_4 + 2*(61 + 103*E_2)*M_3*r0 - (113 + 191*E_2)*M_2*r0_2 + (6 + 49*E_2)*M*r0_3 + 14*r0_4)) - a_3*M*r0*(18*L_6*M + E_2*r0_4*(36*M_3 + 2*(61 + 18*E_2)*M_2*r0 - 3*(17 + 32*E_2)*M*r0_2 - 41*r0_3) + L_2*r0_2*(16*(3 + 28*E_2)*M_3 + 2*(-30 - 103*E_2 + 12*E_4)*M_2*r0 - 2*(9 + 95*E_2 + 13*E_4)*M*r0_2 + (24 + 79*E_2)*r0_3) - 4*L_4*(12*M_3 - (6 + 7*E_2)*M*r0_2 - 3*(1 + E_2)*r0_3 + 3*M_2*(r0 + 4*E_2*r0))) - a*M*r0_2*(12*L_6*M*(-2*M + r0) + L_2*r0_4*((24 + 302*E_2)*M_2 - (36 + 239*E_2 + 6*E_4)*M*r0 + 6*(2 + 9*E_2)*r0_2) + 9*E_2*r0_6*(6*M_2 - 2*r0_2 + M*(r0 - 2*E_2*r0)) + 2*L_4*r0_2*(6*r0*(-2*M + r0) + E_2*(48*M_2 - 44*M*r0 + 15*r0_2)))))/(r0_5*expr2_3); A23321 = (8*(-(a_8*E*L*M*(24*(-1 + 3*E_2)*M_2 + (3 + 55*E_2)*M*r0 + 4*(2 + 3*E_2)*r0_2)) + a_9*E_2*M*(12*(-1 + 3*E_2)*M_2 + 8*r0_2 + 9*M*(r0 + 2*E_2*r0)) - 2*a_7*M*(L_2*(6*M_2 + (3 - 16*E_2 - 6*E_4)*M*r0 - 16*E_2*r0_2) + E_2*r0*(12*(-1 + 2*E_2)*M_3 + 11*(1 - 6*E_2)*M_2*r0 + 3*(1 - 16*E_2)*M*r0_2 - 9*r0_3)) + E*L*r0_4*(2*L_4*M*(22*M_2 - 29*M*r0 + 9*r0_2) + L_2*r0_2*(80*M_3 - (84 + 23*E_2)*M_2*r0 + 5*(2 + 3*E_2)*M*r0_2 + 6*r0_3) + r0_4*(20*M_3 - (2 + 25*E_2)*M_2*r0 + 4*(-5 + 4*E_2)*M*r0_2 + 8*r0_3)) + a_5*M*(-6*L_4*(6*M_2 + (4 + 3*E_2)*M*r0 - 4*E_2*r0_2) + 2*E_2*r0_3*(-8*(1 + 9*E_2)*M_3 + 3*(7 + 10*E_2)*M_2*r0 + 6*(4 + 13*E_2)*M*r0_2 + 15*r0_3) + L_2*r0*(24*M_3 - 8*(-3 - 22*E_2 + 2*E_4)*M_2*r0 + (-24 - 15*E_2 + 52*E_4)*M*r0_2 + (-12 + 13*E_2)*r0_3)) + a_4*E*L*r0*(6*L_4*M*(7*M - 2*r0) + M*r0_2*(32*(2 + 13*E_2)*M_3 - 4*(17 + 28*E_2)*M_2*r0 - (19 + 264*E_2)*M*r0_2 + 12*(2 + 3*E_2)*r0_3) + L_2*(-96*M_4 + 8*(-5 + 3*E_2)*M_3*r0 + (113 - 89*E_2)*M_2*r0_2 + (5 + E_2)*M*r0_3 - 4*r0_4)) + a_2*E*L*r0_2*(L_4*M*(-56*M_2 + 39*M*r0 + 11*r0_2) + L_2*r0*(128*M_4 + 2*(-57 + 70*E_2)*M_3*r0 - 2*(23 + 57*E_2)*M_2*r0_2 + (55 + 28*E_2)*M*r0_3 + 2*r0_4) + r0_3*(16*M_4 + 2*(41 + 88*E_2)*M_3*r0 - 3*(33 + 58*E_2)*M_2*r0_2 + 2*(5 + 24*E_2)*M*r0_3 + 12*r0_4)) - 2*a_3*M*r0*(9*L_6*M + E_2*r0_4*(36*M_3 + (49 + 18*E_2)*M_2*r0 - 3*(9 + 16*E_2)*M*r0_2 - 19*r0_3) + L_2*r0_2*(8*(3 + 25*E_2)*M_3 + (-30 - 83*E_2 + 24*E_4)*M_2*r0 - (9 + 84*E_2 + 26*E_4)*M*r0_2 + (12 + 29*E_2)*r0_3) + L_4*(-24*M_3 + (12 - 5*E_2)*M*r0_2 + 6*(1 + E_2)*r0_3 - 6*M_2*(r0 + 2*E_2*r0))) - a_6*E*L*(L_2*M*(-72*M_2 + (-29 + 18*E_2)*M*r0 + 4*(5 + 3*E_2)*r0_2) + r0*((48 - 96*E_2)*M_4 + (-27 + 170*E_2)*M_2*r0_2 + 2*(7 + 4*E_2)*M*r0_3 + 4*r0_4 + 2*M_3*(r0 + 140*E_2*r0))) - a*M*r0_2*(12*L_6*M*(-2*M + r0) + L_2*r0_4*((24 + 266*E_2)*M_2 - (36 + 191*E_2 + 12*E_4)*M*r0 + 3*(4 + 13*E_2)*r0_2) + 9*E_2*r0_6*(6*M_2 - 2*r0_2 + M*(r0 - 2*E_2*r0)) + 4*L_4*r0_2*(3*r0*(-2*M + r0) + E_2*(34*M_2 - 30*M*r0 + 9*r0_2)))))/(r0_2*expr2_3); A23501 = (r0*(3*a_7*E_2*M*((-2 + 6*E_2)*M + 3*r0) - 3*a_6*E*L*M*(4*(-1 + 3*E_2)*M + (3 + 5*E_2)*r0) + a_5*M*(-6*L_2*(M - 5*E_2*r0) + E_2*r0*((12 - 24*E_2)*M_2 + (-23 + 78*E_2)*M*r0 + 8*r0_2)) + a_4*E*L*(3*L_2*M*(12*M - 5*r0) + r0*(24*(-1 + 2*E_2)*M_3 + (17 - 147*E_2)*M_2*r0 + M*r0_2 - 6*r0_3)) + a_2*E*L*r0*(3*L_2*M*(-16*M_2 + 11*M*r0 + 4*r0_2) + r0_2*(2*(13 + 98*E_2)*M_3 - (43 + 164*E_2)*M_2*r0 + (18 + 31*E_2)*M*r0_2 + 2*r0_3)) + E*L*r0_3*(2*L_2*M*(26*M_2 - 33*M*r0 + 10*r0_2) + r0_2*(20*M_3 - (2 + 25*E_2)*M_2*r0 + 4*(-5 + 4*E_2)*M*r0_2 + 8*r0_3)) - a*M*r0*(12*L_4*M*(-2*M + r0) + 2*L_2*r0_2*(4*(3 + 22*E_2)*M_2 - 2*(9 + 38*E_2)*M*r0 + 3*(2 + 7*E_2)*r0_2) + 9*E_2*r0_4*(6*M_2 - 2*r0_2 + M*(r0 - 2*E_2*r0))) + a_3*M*(-18*L_4*M + E_2*r0_3*(-2*(1 + 36*E_2)*M_2 + 6*(5 + 13*E_2)*M*r0 + 17*r0_2) + 6*L_2*r0*(2*M_2 - 2*(1 + E_2)*r0_2 + M*(r0 + 8*E_2*r0)))))/expr2_3; A24121 = (24*E*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/expr2_3; A24301 = (6*E*r0_3*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/expr2_3; A25121 = (4*(-(a_8*E*L*M*(24*(-1 + 3*E_2)*M_2 + (3 + 55*E_2)*M*r0 + 4*(2 + 3*E_2)*r0_2)) + a_9*E_2*M*(12*(-1 + 3*E_2)*M_2 + 8*r0_2 + 9*M*(r0 + 2*E_2*r0)) + E*L*r0_4*(4*L_4*M*(12*M_2 - 16*M*r0 + 5*r0_2) + 4*L_2*r0_2*(20*M_3 - 2*(10 + 3*E_2)*M_2*r0 + (1 + 4*E_2)*M*r0_2 + 2*r0_3) + r0_4*(16*M_3 + (8 - 26*E_2)*M_2*r0 + (-28 + 17*E_2)*M*r0_2 + 10*r0_3)) + a_7*M*(L_2*(-12*M_2 + 2*(-3 + 16*E_2 + 6*E_4)*M*r0 + 32*E_2*r0_2) + E_2*r0*((24 - 48*E_2)*M_3 + 4*(-5 + 33*E_2)*M_2*r0 + (-7 + 96*E_2)*M*r0_2 + 17*r0_3)) + a_5*M*(-6*L_4*(6*M_2 + (4 + 3*E_2)*M*r0 - 4*E_2*r0_2) + E_2*r0_3*(-4*(5 + 36*E_2)*M_3 + 20*(2 + 3*E_2)*M_2*r0 + (53 + 156*E_2)*M*r0_2 + 31*r0_3) + 2*L_2*r0*(12*M_3 + 2*(6 + 47*E_2 - 4*E_4)*M_2*r0 + 2*(-6 - 5*E_2 + 13*E_4)*M*r0_2 + 3*(-2 + E_2)*r0_3)) + a_4*E*L*r0*(6*L_4*M*(7*M - 2*r0) + L_2*(-96*M_4 + 2*(-23 + 12*E_2)*M_3*r0 - 23*(-5 + 4*E_2)*M_2*r0_2 + (9 + 4*E_2)*M*r0_3 - 4*r0_4) + r0_2*((68 + 424*E_2)*M_4 - 4*(17 + 31*E_2)*M_3*r0 - 3*(9 + 89*E_2)*M_2*r0_2 + (26 + 43*E_2)*M*r0_3 + 2*r0_4)) - a_6*E*L*(L_2*M*(-72*M_2 + (-29 + 18*E_2)*M*r0 + 4*(5 + 3*E_2)*r0_2) + r0*((48 - 96*E_2)*M_4 + 2*(2 + 143*E_2)*M_3*r0 + (-28 + 167*E_2)*M_2*r0_2 + (13 + 5*E_2)*M*r0_3 + 4*r0_4)) + a_2*E*L*r0_2*(2*L_4*M*(-28*M_2 + 18*M*r0 + 7*r0_2) + L_2*r0*(136*M_4 + 24*(-5 + 6*E_2)*M_3*r0 - 2*(26 + 61*E_2)*M_2*r0_2 + (57 + 32*E_2)*M*r0_3 + 4*r0_4) + r0_3*(8*M_4 + 2*(50 + 89*E_2)*M_3*r0 - (106 + 181*E_2)*M_2*r0_2 + (3 + 53*E_2)*M*r0_3 + 16*r0_4)) + a_3*M*r0*(-18*L_6*M + E_2*r0_4*(-60*M_3 - 4*(28 + 9*E_2)*M_2*r0 + 3*(17 + 32*E_2)*M*r0_2 + 43*r0_3) - 2*L_2*r0_2*(8*(3 + 26*E_2)*M_3 + 2*(-15 - 46*E_2 + 12*E_4)*M_2*r0 - (9 + 88*E_2 + 26*E_4)*M*r0_2 + 2*(6 + 17*E_2)*r0_3) + 2*L_4*(24*M_3 + 4*(-3 + 2*E_2)*M*r0_2 - 3*(2 + 3*E_2)*r0_3 + 6*M_2*(r0 + 2*E_2*r0))) - a*M*r0_2*(12*L_6*M*(-2*M + r0) + 3*E_2*r0_6*(16*M_2 - 6*(-1 + E_2)*M*r0 - 7*r0_2) + 2*L_2*r0_4*(2*(6 + 67*E_2)*M_2 - 2*(9 + 49*E_2 + 3*E_4)*M*r0 + 3*(2 + 7*E_2)*r0_2) + 2*L_4*r0_2*(6*r0*(-2*M + r0) + E_2*(72*M_2 - 67*M*r0 + 21*r0_2)))))/(r0_2*expr2_4); A25301 = (r0*(3*a_7*E_2*M*((-2 + 6*E_2)*M + 3*r0) - 3*a_6*E*L*M*(4*(-1 + 3*E_2)*M + (3 + 5*E_2)*r0) + a_5*M*(-6*L_2*(M - 5*E_2*r0) + E_2*r0*((12 - 24*E_2)*M_2 + 2*(-11 + 39*E_2)*M*r0 + 7*r0_2)) - a*M*r0*(12*L_4*M*(-2*M + r0) + 3*E_2*r0_4*(16*M_2 - 6*(-1 + E_2)*M*r0 - 7*r0_2) + 2*L_2*r0_2*(4*(3 + 23*E_2)*M_2 - (18 + 83*E_2)*M*r0 + 6*(1 + 4*E_2)*r0_2)) + a_4*E*L*(3*L_2*M*(12*M - 5*r0) + r0*(24*(-1 + 2*E_2)*M_3 - 2*(-8 + 75*E_2)*M_2*r0 + (2 + 3*E_2)*M*r0_2 - 6*r0_3)) + a_2*E*L*r0*(3*L_2*M*(-16*M_2 + 10*M*r0 + 5*r0_2) + r0_2*(4*(7 + 50*E_2)*M_3 - 4*(11 + 43*E_2)*M_2*r0 + 5*(3 + 7*E_2)*M*r0_2 + 4*r0_3)) + E*L*r0_3*(2*L_2*M*(28*M_2 - 36*M*r0 + 11*r0_2) + r0_2*(16*M_3 + (8 - 26*E_2)*M_2*r0 + (-28 + 17*E_2)*M*r0_2 + 10*r0_3)) + a_3*M*(-18*L_4*M + E_2*r0_3*(-4*(1 + 18*E_2)*M_2 + 6*(5 + 13*E_2)*M*r0 + 19*r0_2) + 6*L_2*r0*(2*M_2 - (2 + 3*E_2)*r0_2 + M*(r0 + 9*E_2*r0)))))/expr2_4; A26101 = (2*E*r0_3*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/expr2_4; A27101 = (r0*(a_7*E_2*M*((-2 + 6*E_2)*M + 3*r0) - a_6*E*L*M*(4*(-1 + 3*E_2)*M + (3 + 5*E_2)*r0) + a_5*M*(-2*L_2*(M - 5*E_2*r0) + E_2*r0*((4 - 8*E_2)*M_2 + (-7 + 26*E_2)*M*r0 + 2*r0_2)) + a_4*E*L*(L_2*M*(12*M - 5*r0) + r0*(8*(-1 + 2*E_2)*M_3 + (5 - 51*E_2)*M_2*r0 + (1 + 2*E_2)*M*r0_2 - 2*r0_3)) + E*L*r0_3*(2*L_2*M*(10*M_2 - 13*M*r0 + 4*r0_2) + r0_2*(4*M_3 + (6 - 9*E_2)*M_2*r0 + 6*(-2 + E_2)*M*r0_2 + 4*r0_3)) + a_2*E*L*r0*(L_2*M*(-16*M_2 + 9*M*r0 + 6*r0_2) + r0_2*(2*(5 + 34*E_2)*M_3 + (4 + 13*E_2)*M*r0_2 + 2*r0_3 - 15*M_2*(r0 + 4*E_2*r0))) - a*M*r0*(4*L_4*M*(-2*M + r0) + E_2*r0_4*(14*M_2 + (9 - 6*E_2)*M*r0 - 8*r0_2) + 2*L_2*r0_2*(4*(1 + 8*E_2)*M_2 + (2 + 9*E_2)*r0_2 - 6*M*(r0 + 5*E_2*r0))) + a_3*M*(-6*L_4*M + E_2*r0_3*(-2*(1 + 12*E_2)*M_2 + 2*(5 + 13*E_2)*M*r0 + 7*r0_2) + 2*L_2*r0*(2*M_2 - 2*(1 + 2*E_2)*r0_2 + M*(r0 + 10*E_2*r0)))))/expr2_5; } /* A_{t,phi} */ { A30060 = -256*E*L*expr4_3; A30080 = (128*expr1_2*(-(a_8*E*L*M_2*r0) - 12*a_9*E_2*M_2*(2*M + r0) + E*L*r0_5*(36*L_4*M*(-2*M + r0) + 2*r0_4*(-2*M_2 + (-11 + 8*E_2)*M*r0 + 6*r0_2) + L_2*r0_2*(-88*M_2 + 2*(13 + 6*E_2)*M*r0 + 9*r0_2)) + 4*a*M*r0_2*(18*L_6*M*(2*M - r0) + 3*E_2*r0_7*(-2*M + 3*r0) - 3*L_4*r0_2*(-16*M_2 - 2*(-3 + E_2)*M*r0 + r0_2) + L_2*r0_4*(12*M_2 + 2*E_2*M*r0 + 3*(-1 + 2*E_2)*r0_2)) + 4*a_3*M*r0*(3*E_2*r0_5*(18*M_2 + 7*M*r0 + 7*r0_2) + 3*L_4*(40*M_3 + 2*(-1 + 2*E_2)*M_2*r0 + (-7 + 2*E_2)*M*r0_2 - r0_3) + L_2*r0_2*(72*M_3 + 2*(3 + 34*E_2)*M_2*r0 + 9*(-1 + 2*E_2)*M*r0_2 + 2*(-3 + 4*E_2)*r0_3)) + 2*a_6*E*L*M*(-384*M_4 + 64*(-6 + E_2)*M_3*r0 + 2*(-29 + 48*E_2)*M_2*r0_2 + (1 + 8*E_2)*r0_4 + M*(-2*L_2*r0 + (17 + 48*E_2)*r0_3)) + 4*a_7*M*(L_2*M*(6*M + 3*r0 - 2*E_2*r0) + 3*E_2*(32*M_4 + 52*M_3*r0 + 18*M_2*r0_2 + M*r0_3 + r0_4)) + a_4*E*L*r0*(4*L_2*M*(-208*M_3 + 6*(-17 + 2*E_2)*M_2*r0 + 12*(2 + E_2)*M*r0_2 + (11 + 3*E_2)*r0_3) + r0_2*(-916*M_4 + 4*(-95 + 48*E_2)*M_3*r0 + 3*(21 + 64*E_2)*M_2*r0_2 + 6*(5 + 8*E_2)*M*r0_3 + 12*r0_4)) + 4*a_5*M*(3*L_4*M*r0 + 3*E_2*r0_3*(60*M_3 + 46*M_2*r0 + 11*M*r0_2 + 5*r0_3) + L_2*(96*M_4 + 4*(9 + 14*E_2)*M_3*r0 + 12*(-1 + 5*E_2)*M_2*r0_2 + 6*(-1 + E_2)*M*r0_3 + (-3 + 2*E_2)*r0_4)) + a_2*E*L*r0_2*(L_4*(-240*M_3 + 36*M*r0_2) + 2*r0_4*(-128*M_3 + 12*(-1 + 4*E_2)*M_2*r0 + 3*(1 + 8*E_2)*M*r0_2 + 12*r0_3) + L_2*r0_2*(-616*M_3 + 8*(11 + 3*E_2)*M*r0_2 + 9*r0_3 + 12*M_2*(r0 + 4*E_2*r0)))))/(3.*r0_9*(a_2 + r0*(-2*M + r0))); A30240 = -192*E*L*expr1_2; A30260 = (64*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-6*a_9*E_2*M*(14*M_2 + 11*M*r0 + 2*r0_2) + a_8*E*L*M*(6*E_2*r0_p_2M_2 - r0*(7*M + 3*r0)) + E*L*r0_5*(-74*L_4*M*(2*M - r0) + 2*L_2*r0_2*(-96*M_2 + (30 + 11*E_2)*M*r0 + 9*r0_2) + r0_4*(-32*M_2 + 26*(-1 + E_2)*M*r0 + 21*r0_2)) + a_6*E*L*(-1536*M_5 + 32*(-48 + 5*E_2)*M_4*r0 + 72*(-3 + 4*E_2)*M_3*r0_2 + 12*(9 + 16*E_2)*M_2*r0_3 + (19 + 44*E_2)*M*r0_4 + 3*r0_5 + L_2*M*(24*M_2 + 4*(2 + 3*E_2)*M*r0 + 3*(-1 + 2*E_2)*r0_2)) + 2*a*M*r0_2*(3*E_2*r0_7*(-2*M + 9*r0) + 6*L_6*(22*M_2 - 13*M*r0 + r0_2) + L_4*r0_2*(192*M_2 + 2*(-51 + 20*E_2)*M*r0 + 3*(1 - 3*E_2)*r0_2) + L_2*r0_4*(60*M_2 + 2*(-12 + 19*E_2)*M*r0 + 3*(-1 + 4*E_2)*r0_2)) + a_2*E*L*r0_2*(2*L_4*M*(-232*M_2 + 6*M*r0 + 37*r0_2) + L_2*r0_2*(-1264*M_3 + 2*(15 + 38*E_2)*M_2*r0 + (189 + 50*E_2)*M*r0_2 + 21*r0_3) + r0_4*(-584*M_3 + 18*(-3 + 8*E_2)*M_2*r0 + 3*(15 + 28*E_2)*M*r0_2 + 45*r0_3)) + 2*a_3*M*r0*(6*L_6*r0 + 3*E_2*r0_5*(78*M_2 + 37*M*r0 + 19*r0_2) + L_2*r0_2*(312*M_3 + 10*(-3 + 35*E_2)*M_2*r0 + (-51 + 107*E_2)*M*r0_2 - 5*E_2*r0_3) + L_4*(456*M_3 + 2*(-33 + 34*E_2)*M_2*r0 + (-87 + 28*E_2)*M*r0_2 + 3*(5 - 6*E_2)*r0_3)) - 2*a_7*M*(L_2*(6*(-7 + 4*E_2)*M_2 + (-33 + 49*E_2)*M*r0 + 3*(-2 + 5*E_2)*r0_2) - 3*E_2*(128*M_4 + 220*M_3*r0 + 86*M_2*r0_2 - 5*M*r0_3 - 3*r0_4)) + a_4*E*L*r0*(12*L_4*M_2 + L_2*(-1664*M_4 + 32*(-25 + 2*E_2)*M_3*r0 + 22*(11 + 4*E_2)*M_2*r0_2 + 2*(48 + 17*E_2)*M*r0_3 + 3*r0_4) + r0_2*(-1844*M_4 + 8*(-104 + 33*E_2)*M_3*r0 + 3*(55 + 104*E_2)*M_2*r0_2 + 3*(31 + 32*E_2)*M*r0_3 + 27*r0_4)) + 2*a_5*M*(-3*L_4*r0*((-11 + 4*E_2)*M + (-4 + 3*E_2)*r0) + 3*E_2*r0_3*(228*M_3 + 202*M_2*r0 + 45*M*r0_2 + 9*r0_3) + L_2*(384*M_4 + 4*(27 + 74*E_2)*M_3*r0 + 14*(-6 + 23*E_2)*M_2*r0_2 + 2*(3 - 4*E_2)*M*r0_3 + (9 - 32*E_2)*r0_4))))/(3.*r0_6*(a_2 + r0*(-2*M + r0))); A30420 = -48*E*L*r0_3*(a_2*(2*M + r0) + r0*(L_2 + r0_2)); A30440 = (8*(-36*a_9*E_2*M*(10*M_2 + 9*M*r0 + 2*r0_2) + a_8*E*L*(-13*M_2*r0 + 3*r0_3 + 36*E_2*M*r0_p_2M_2) + E*L*r0_3*(8*L_6*M*(-2*M + r0) + L_4*r0_2*(-460*M_2 + 4*(52 + E_2)*M*r0 + 11*r0_2) + r0_6*(-168*M_2 + 2*(-17 + 30*E_2)*M*r0 + 59*r0_2) + L_2*r0_4*(-624*M_2 + 2*(89 + 30*E_2)*M*r0 + 67*r0_2)) + 4*a*M*r0_2*(9*E_2*r0_7*(2*M + 3*r0) + 3*L_2*r0_4*(36*M_2 + 2*(-12 + 17*E_2)*M*r0 + 3*r0_2) + 3*L_4*r0_2*(96*M_2 + 6*(-11 + 5*E_2)*M*r0 + (9 - 10*E_2)*r0_2) + 2*L_6*(90*M_2 + (-63 + 4*E_2)*M*r0 - 3*(-3 + E_2)*r0_2)) + 2*a_6*E*L*(-2304*M_5 + 96*(-24 + E_2)*M_4*r0 + 2*(-157 + 144*E_2)*M_3*r0_2 + (233 + 288*E_2)*M_2*r0_3 + (79 + 84*E_2)*M*r0_4 + 16*r0_5 + L_2*(72*M_3 + 2*(23 + 24*E_2)*M_2*r0 + 6*(1 + 4*E_2)*M*r0_2 + 3*r0_3)) + a_2*E*L*r0_2*(12*L_6*M - 2*L_4*(696*M_3 + 8*(-3 + E_2)*M_2*r0 - 4*(31 + 2*E_2)*M*r0_2 - 7*r0_3) + 2*r0_4*(-984*M_3 + 4*(-29 + 36*E_2)*M_2*r0 + 9*(13 + 12*E_2)*M*r0_2 + 72*r0_3) + L_2*r0_2*(-3864*M_3 + 4*(-1 + 36*E_2)*M_2*r0 + 12*(51 + 14*E_2)*M*r0_2 + 107*r0_3)) + 4*a_3*M*r0*(-6*(-3 + E_2)*L_6*r0 + 9*E_2*r0_5*(42*M_2 + 23*M*r0 + 5*r0_2) + 3*L_4*(216*M_3 + 2*(-27 + 26*E_2)*M_2*r0 + 9*(-5 + 2*E_2)*M*r0_2 + (21 - 22*E_2)*r0_3) + L_2*r0_2*(504*M_3 + 6*(-21 + 104*E_2)*M_2*r0 + (-99 + 224*E_2)*M*r0_2 + 4*(9 - 16*E_2)*r0_3)) - 4*a_7*M*(L_2*(18*(-5 + 4*E_2)*M_2 + (-81 + 140*E_2)*M*r0 + 6*(-3 + 8*E_2)*r0_2) - 9*E_2*(64*M_4 + 116*M_3*r0 + 50*M_2*r0_2 - 7*M*r0_3 - 5*r0_4)) + a_4*E*L*r0*(3*L_4*(32*M_2 + 4*(2 + E_2)*M*r0 + r0_2) + L_2*(-4992*M_4 + 8*(-299 + 6*E_2)*M_3*r0 + 8*(103 + 30*E_2)*M_2*r0_2 + 4*(95 + 39*E_2)*M*r0_3 + 46*r0_4) + r0_2*(-5604*M_4 + 4*(-691 + 108*E_2)*M_3*r0 + (559 + 720*E_2)*M_2*r0_2 + 6*(71 + 48*E_2)*M*r0_3 + 114*r0_4)) + 4*a_5*M*(3*L_4*r0*((27 - 16*E_2)*M - 12*(-1 + E_2)*r0) + 9*E_2*r0_3*(108*M_3 + 110*M_2*r0 + 23*M*r0_2 - r0_3) + L_2*(576*M_4 + 12*(9 + 46*E_2)*M_3*r0 + 4*(-45 + 154*E_2)*M_2*r0_2 + 2*(27 - 25*E_2)*M*r0_3 + (45 - 112*E_2)*r0_4))))/(3.*r0_3*(a_2 + r0*(-2*M + r0))); A30600 = -4*E*L*r0_6; A30620 = (-4*(6*a_7*E_2*M*(13*M + 6*r0) - 3*a_6*E*L*(r0*(M + r0) + 6*E_2*M*(2*M + r0)) - E*L*r0_2*(8*L_4*M*(-2*M + r0) + 2*r0_4*(-40*M_2 + 7*E_2*M*r0 + 10*r0_2) + L_2*r0_2*(-144*M_2 + 2*(25 + 2*E_2)*M*r0 + 11*r0_2)) - 2*a*M*r0*(3*E_2*r0_5*(10*M + 3*r0) + L_2*r0_2*(84*M_2 + 4*(-18 + 17*E_2)*M*r0 + 3*(5 - 7*E_2)*r0_2) + 2*L_4*(54*M_2 + (-45 + 8*E_2)*M*r0 + 3*(3 - 2*E_2)*r0_2)) - 6*a_5*M*(L_2*((13 - 12*E_2)*M + (6 - 11*E_2)*r0) + E_2*(64*M_3 + 90*M_2*r0 + 12*M*r0_2 - 11*r0_3)) - a_2*E*L*r0*(12*L_4*M - 2*L_2*(224*M_3 + 2*(-3 + 4*E_2)*M_2*r0 - (39 + 8*E_2)*M*r0_2 - 7*r0_3) + r0_2*(-568*M_3 + 2*(-19 + 10*E_2)*M_2*r0 + (71 + 46*E_2)*M*r0_2 + 37*r0_3)) - 2*a_3*M*(-6*(-3 + 2*E_2)*L_4*r0 + 3*E_2*r0_3*(70*M_2 + 39*M*r0 - 2*r0_2) + L_2*(192*M_3 + 2*(-39 + 62*E_2)*M_2*r0 + (-39 + 56*E_2)*M*r0_2 + 3*(11 - 18*E_2)*r0_3)) - a_4*E*L*(3*L_2*(12*M_2 + 4*(1 + E_2)*M*r0 + r0_2) + 2*(-384*M_4 - 8*(24 + E_2)*M_3*r0 + (43 + 28*E_2)*M_2*r0_2 + (31 + 25*E_2)*M*r0_3 + 10*r0_4))))/(3.*(a_2 + r0*(-2*M + r0))); A30800 = (r0_3*(-24*a_5*E_2*M + 3*a_4*E*L*(4*E_2*M + r0) - 2*a_2*E*L*(-6*L_2*M + 96*M_3 + 8*E_2*M_2*r0 - 2*(5 + 4*E_2)*M*r0_2 - 7*r0_3) - 24*a_3*M*((-1 + E_2)*L_2 + E_2*(-4*M_2 - 4*M*r0 + r0_2)) + E*L*r0*(8*L_2*M*(-2*M + r0) + r0_2*(-52*M_2 + 4*(1 + E_2)*M*r0 + 11*r0_2)) + 8*a*M*(6*E_2*M*r0_3 + L_2*(12*M_2 + 4*(-3 + E_2)*M*r0 - 3*(-1 + E_2)*r0_2))))/(6.*(a_2 + r0*(-2*M + r0))); A31060 = (-128*expr1_2*(a_4*E*L*M*r0 + 2*a_5*E_2*M*(2*M + r0) + E*L*r0_3*(2*L_2*M + r0_3) - 2*a*M*r0*(L_4 + L_2*r0_2 - 3*E_2*r0_4) - 2*a_3*M*(L_2*(2*M + r0) - 2*E_2*r0_2*(3*M + 2*r0)) + a_2*E*L*r0*(2*L_2*M + r0*(-6*M_2 + 3*M*r0 + r0_2))))/(r0_5*(a_2 + r0*(-2*M + r0))); A31080 = (64*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(2*a_13*E_2*M_2*(-96*M_3 + 34*M_2*r0 + 113*M*r0_2 + 36*r0_3) + a_12*E*L*M_2*(384*M_3 + 16*(24 - 19*E_2)*M_2*r0 + (105 - 344*E_2)*M*r0_2 + 6*(1 - 16*E_2)*r0_3) + a_10*E*L*M*r0*(-512*(-15 + 2*E_2)*M_5 - 1920*(-7 + E_2)*M_4*r0 + 2*(3565 - 1248*E_2)*M_3*r0_2 + (695 - 2096*E_2)*M_2*r0_3 - (223 + 512*E_2)*M*r0_4 + 6*(-1 + 9*E_2)*r0_5 + 2*L_2*M*(264*M_2 - 5*(-39 + 32*E_2)*M*r0 + 3*(13 - 28*E_2)*r0_2)) + E*L*r0_6*(48*L_8*M*r0_2M_2 + 24*L_6*M*(2*M - r0)*r0_2*(11*M - (7 + 3*E_2)*r0) + 2*L_4*M*r0_4*(296*M_2 - 2*(197 + 108*E_2)*M*r0 + 3*(41 + 38*E_2)*r0_2) + L_2*r0_6*(320*M_3 - 4*(121 + 109*E_2)*M_2*r0 + 6*(26 + 41*E_2)*M*r0_2 + 3*r0_3) + 2*r0_8*(-4*M_3 + (2 - 86*E_2)*M_2*r0 + 3*(-4 + 17*E_2)*M*r0_2 + 6*r0_3)) - 2*a*M*r0_4*(24*L_10*r0_2M_2 - 6*E_2*r0_10*(-14*M_2 + (5 + 12*E_2)*M*r0 + r0_2) - 12*L_8*(2*M - r0)*r0*(14*M_2 - 2*(6 + E_2)*M*r0 + (4 + 3*E_2)*r0_2) + L_6*r0_3*(-864*M_3 + 8*(94 + 63*E_2)*M_2*r0 - 2*(101 + 258*E_2 + 36*E_4)*M*r0_2 + 3*(7 + 50*E_2)*r0_3) + L_2*r0_7*(-288*M_3 + 4*(65 + 244*E_2)*M_2*r0 - 2*(35 + 379*E_2 + 72*E_4)*M*r0_2 + 3*(2 + 53*E_2)*r0_3) + L_4*r0_5*(-816*M_3 + 4*(163 + 304*E_2)*M_2*r0 - 4*(32 + 248*E_2 + 45*E_4)*M*r0_2 + 3*(1 + 78*E_2)*r0_3)) + a_2*E*L*r0_4*(48*L_8*M*(6*M_2 - 5*M*r0 + r0_2) + 48*L_6*M*r0*(18*M_3 + (5 - 8*E_2)*M_2*r0 - 2*(7 + 3*E_2)*M*r0_2 + (5 + 3*E_2)*r0_3) + 4*L_4*M*r0_3*(124*M_3 - 48*(-3 + 4*E_2)*M_2*r0 - 6*(43 + 41*E_2)*M*r0_2 + 3*(41 + 55*E_2)*r0_3) + L_2*r0_5*(-2432*M_4 + 4*(583 + 48*E_2)*M_3*r0 - 1228*(1 + E_2)*M_2*r0_2 + 3*(153 + 308*E_2)*M*r0_3 + 6*r0_4) + 2*r0_7*(-1284*M_4 + 56*(19 + 4*E_2)*M_3*r0 - (263 + 376*E_2)*M_2*r0_2 + 3*(1 + 77*E_2)*M*r0_3 + 18*r0_4)) - 2*a_11*M*(L_2*M*(96*M_3 + (226 - 96*E_2)*M_2*r0 + (161 - 290*E_2)*M*r0_2 + 12*(3 - 10*E_2)*r0_3) - 2*E_2*r0*(320*(-3 + E_2)*M_5 + 4*(-599 + 160*E_2)*M_4*r0 + 3*(-551 + 160*E_2)*M_3*r0_2 + (-229 + 160*E_2)*M_2*r0_3 + (49 + 20*E_2)*M*r0_4 - 6*r0_5)) + a_4*E*L*r0_3*(24*L_6*M*(108*M_3 + 2*(9 - 14*E_2)*M_2*r0 - 2*(4 + 3*E_2)*M*r0_2 + 3*(1 + E_2)*r0_3) - 2*L_4*M*r0*(736*M_4 + 112*(-23 + 3*E_2)*M_3*r0 + 24*(-58 + 59*E_2)*M_2*r0_2 + 28*(7 + 15*E_2)*M*r0_3 - 3*(41 + 106*E_2)*r0_4) + L_2*r0_3*(-14144*M_5 + 48*(108 + 53*E_2)*M_4*r0 - 8*(-818 + 171*E_2)*M_3*r0_2 - 4*(356 + 351*E_2)*M_2*r0_3 + 24*(17 + 54*E_2)*M*r0_4 + 3*r0_5) + r0_5*(-14616*M_5 + 4*(691 + 516*E_2)*M_4*r0 + 2*(2735 - 4*E_2)*M_3*r0_2 - (1487 + 1288*E_2)*M_2*r0_3 + 12*(7 + 69*E_2)*M*r0_4 + 36*r0_5)) + 2*a_9*M*r0*(L_4*M*(-208*M_2 + (-313 + 168*E_2)*M*r0 + 12*(-9 + 10*E_2)*r0_2) + L_2*(-384*(5 + 6*E_2)*M_5 + 8*(-241 - 706*E_2 + 136*E_4)*M_4*r0 + 8*(-45 - 698*E_2 + 204*E_4)*M_3*r0_2 + (65 - 1270*E_2 + 816*E_4)*M_2*r0_3 + 2*(23 + 34*E_2 + 68*E_4)*M*r0_4 + 12*(2 - 9*E_2)*r0_5) + 2*E_2*r0*(2112*M_6 + 4*(893 + 144*E_2)*M_5*r0 + 2*(-695 + 896*E_2)*M_4*r0_2 + (-4079 + 1824*E_2)*M_3*r0_3 + 2*(-617 + 384*E_2)*M_2*r0_4 + (61 + 116*E_2)*M*r0_5 - 27*r0_6)) + a_6*E*L*r0_2*(72*L_6*M_2*r0 + 4*L_4*M*(1952*M_4 - 8*(-272 + 93*E_2)*M_3*r0 - 60*(-10 + 9*E_2)*M_2*r0_2 - (1 + 90*E_2)*M*r0_3 + 51*E_2*r0_4) + L_2*M*r0*(-14272*M_5 + 40*(-13 + 64*E_2)*M_4*r0 - 304*(-70 + 3*E_2)*M_3*r0_2 + 2*(3499 - 1952*E_2)*M_2*r0_3 - 2*(533 + 550*E_2)*M*r0_4 + 3*(25 + 268*E_2)*r0_5) + r0_3*(-26824*M_6 + 4*(-3273 + 424*E_2)*M_5*r0 + 2*(8659 + 1248*E_2)*M_4*r0_2 + (5521 - 2128*E_2)*M_3*r0_3 - (1759 + 1328*E_2)*M_2*r0_4 + 12*(4 + 61*E_2)*M*r0_5 + 12*r0_6)) + 2*a_7*M*r0*(-4*L_6*M*r0*(38*M - 9*(-3 + E_2)*r0) + 6*E_2*r0_4*(1460*M_5 + 12*(107 + 32*E_2)*M_4*r0 + (-893 + 736*E_2)*M_3*r0_2 + (-615 + 448*E_2)*M_2*r0_3 + 8*(5 + 11*E_2)*M*r0_4 - 14*r0_5) - 2*L_4*(704*M_5 + 8*(233 + 108*E_2)*M_4*r0 + 2*(307 + 598*E_2 - 180*E_4)*M_3*r0_2 + (-127 + 502*E_2 - 360*E_4)*M_2*r0_3 + (-31 + 84*E_2 - 90*E_4)*M*r0_4 + 3*(-8 + 35*E_2)*r0_5) + L_2*r0*(4224*M_6 + 8*(307 + 20*E_2)*M_5*r0 + 4*(-1051 - 734*E_2 + 288*E_4)*M_4*r0_2 + 2*(-1129 - 4344*E_2 + 1680*E_4)*M_3*r0_3 + (305 - 3082*E_2 + 2496*E_4)*M_2*r0_4 + 2*(122 + 53*E_2 + 276*E_4)*M*r0_5 + (66 - 449*E_2)*r0_6)) + a_8*E*L*M*r0*(72*L_4*M*r0*(4*M - (-2 + E_2)*r0) + 2*L_2*(3584*M_5 - 32*(-283 + 50*E_2)*M_4*r0 + 4*(1775 - 508*E_2)*M_3*r0_2 - 2*(-713 + 698*E_2)*M_2*r0_3 - 4*(37 + 82*E_2)*M*r0_4 + 3*(-5 + 31*E_2)*r0_5) + r0*(-16896*M_6 + 64*(-300 + 23*E_2)*M_5*r0 + 4*(3331 + 296*E_2)*M_4*r0_2 - 4*(-4751 + 280*E_2)*M_3*r0_3 + (2681 - 3424*E_2)*M_2*r0_4 - (1031 + 1036*E_2)*M*r0_5 + 6*(-2 + 53*E_2)*r0_6)) + 2*a_3*M*r0_3*(2*E_2*M*r0_8*(588*M_2 + 2*(-223 + 144*E_2)*M*r0 + (103 + 164*E_2)*r0_2) + L_2*r0_5*(2352*M_4 - 24*(47 + 68*E_2)*M_3*r0 + 36*(-13 - 39*E_2 + 24*E_4)*M_2*r0_2 + 2*(92 + 855*E_2 + 284*E_4)*M*r0_3 + (6 - 551*E_2)*r0_4) + 2*L_4*r0_3*(2160*M_4 - 4*(265 + 437*E_2)*M_3*r0 + 2*(-264 - 137*E_2 + 180*E_4)*M_2*r0_2 + (165 + 748*E_2 + 270*E_4)*M*r0_3 + (21 - 331*E_2)*r0_4) + L_6*r0*(2160*M_4 - 8*(229 + 144*E_2)*M_3*r0 + 24*(-22 + 13*E_2 + 6*E_4)*M_2*r0_2 + 4*(92 + 99*E_2 + 36*E_4)*M*r0_3 - 3*(7 + 100*E_2)*r0_4) - 12*L_8*(56*M_3 - (15 + 2*E_2)*M*r0_2 + (4 + 3*E_2)*r0_3 - 6*M_2*(r0 + 2*E_2*r0))) + 2*a_5*M*r0_2*(-36*L_8*M*r0 + E_2*r0_6*(6012*M_4 + 108*(5 + 16*E_2)*M_3*r0 + (-2601 + 2048*E_2)*M_2*r0_2 + 4*(89 + 148*E_2)*M*r0_3 - 48*r0_4) - 2*L_6*(832*M_4 + 12*(65 - 6*E_2)*M_3*r0 - 12*(16 + 3*E_2 + 6*E_4)*M_2*r0_2 - 2*(25 - 21*E_2 + 18*E_4)*M*r0_3 + 75*E_2*r0_4) + L_4*r0*(5088*M_5 - 4*(245 + 964*E_2)*M_4*r0 + 12*(-381 - 304*E_2 + 60*E_4)*M_3*r0_2 + (-41 - 504*E_2 + 1440*E_4)*M_2*r0_3 + 4*(93 + 62*E_2 + 135*E_4)*M*r0_4 + (93 - 638*E_2)*r0_5) + L_2*r0_3*(5664*M_5 + 12*(-275 - 384*E_2 + 144*E_4)*M_3*r0_2 + (-129 - 2086*E_2 + 2544*E_4)*M_2*r0_3 + 6*(46 + 185*E_2 + 140*E_4)*M*r0_4 + (54 - 733*E_2)*r0_5 + 156*M_4*(r0 + 6*E_2*r0)))))/(3.*r0_11*expr2_2); A31240 = (-32*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-(a_4*E*L*r0_2) + 6*a_5*E_2*M*(2*M + r0) - 6*a*M*r0*(L_4 - (-1 + E_2)*L_2*r0_2 - 3*E_2*r0_4) + E*L*r0_3*(3*r0_3 + L_2*(4*M + r0)) + 2*a_3*M*(6*E_2*r0_2*(3*M + 2*r0) + L_2*(-6*M + (-3 + E_2)*r0)) + a_2*E*L*r0*(L_2*(4*M - r0) + 2*r0*(-6*M_2 + 4*M*r0 + r0_2))))/(r0_2*(a_2 + r0*(-2*M + r0))); A31260 = (16*(4*a_13*E_2*M*(2*M + r0)*(24*(-7 + E_2)*M_3 + (101 + 24*E_2)*M_2*r0 + 6*(28 + E_2)*M*r0_2 + 36*r0_3) + a_12*E*L*M*(-384*(-7 + E_2)*M_4 - 128*(-27 + 10*E_2)*M_3*r0 + (1503 - 1144*E_2)*M_2*r0_2 + 3*(87 - 112*E_2)*M*r0_3 - 18*(-1 + E_2)*r0_4) + E*L*r0_6*(168*L_8*M*r0_2M_2 + 4*L_6*M*(2*M - r0)*r0_2*(220*M - 21*(7 + 3*E_2)*r0) + L_4*r0_4*(1856*M_3 - 4*(679 + 374*E_2)*M_2*r0 + 24*(38 + 33*E_2)*M*r0_2 - 9*r0_3) + 2*L_2*r0_6*(356*M_3 - 4*(172 + 195*E_2)*M_2*r0 + 3*(77 + 146*E_2)*M*r0_2 + 12*r0_3) + 2*r0_8*(-64*M_3 - 8*(-4 + 37*E_2)*M_2*r0 + 6*(-7 + 29*E_2)*M*r0_2 + 21*r0_3)) + a_2*E*L*r0_4*(168*L_8*M*(6*M_2 - 5*M*r0 + r0_2) + 2*L_6*M*r0*(968*M_3 + (676 - 672*E_2)*M_2*r0 - 2*(571 + 252*E_2)*M*r0_2 + (421 + 252*E_2)*r0_3) - 2*L_4*r0_3*(1192*M_4 + 4*(-352 + 421*E_2)*M_3*r0 + 2*(729 + 722*E_2)*M_2*r0_2 - (900 + 1127*E_2)*M*r0_3 + 12*r0_4) + L_2*r0_5*(-12672*M_4 - 12*(-647 + 88*E_2)*M_3*r0 - 4*(671 + 994*E_2)*M_2*r0_2 + (1467 + 3224*E_2)*M*r0_3 + 27*r0_4) + 2*r0_7*(-4788*M_4 + 8*(399 + 43*E_2)*M_3*r0 - (543 + 1154*E_2)*M_2*r0_2 + 5*(2 + 157*E_2)*M*r0_3 + 60*r0_4)) + 4*a_3*M*r0_3*(2*E_2*r0_8*(978*M_3 + (-631 + 486*E_2)*M_2*r0 + 2*(10 + 149*E_2)*M*r0_2 + 51*r0_3) + L_8*(-1168*M_3 + 12*(8 + 21*E_2)*M_2*r0 + 2*(218 + 21*E_2)*M*r0_2 - 9*(16 + 7*E_2)*r0_3) + L_6*r0*(4416*M_4 - 4*(925 + 404*E_2)*M_3*r0 + 2*(-519 + 290*E_2 + 126*E_4)*M_2*r0_2 + 4*(299 + 86*E_2 + 63*E_4)*M*r0_3 - 3*(93 + 142*E_2)*r0_4) + L_2*r0_5*(4608*M_4 - 12*(187 + 166*E_2)*M_3*r0 + 2*(-465 - 722*E_2 + 882*E_4)*M_2*r0_2 + (560 + 1717*E_2 + 1098*E_4)*M*r0_3 - 2*(42 + 313*E_2)*r0_4) - 2*L_4*r0_3*(-4416*M_4 + 24*(96 + 95*E_2)*M_3*r0 + (1026 + 173*E_2 - 648*E_4)*M_2*r0_2 - (639 + 801*E_2 + 443*E_4)*M*r0_3 + (105 + 457*E_2)*r0_4)) + a_4*E*L*r0_3*(4*L_6*M*(2216*M_3 + 12*(43 - 49*E_2)*M_2*r0 - 2*(76 + 63*E_2)*M*r0_2 + (68 + 63*E_2)*r0_3) + L_2*r0_3*(-59256*M_5 + 4*(1885 + 672*E_2)*M_4*r0 + 2*(13743 - 4196*E_2)*M_3*r0_2 - (1537 + 3516*E_2)*M_2*r0_3 + 438*(3 + 10*E_2)*M*r0_4 - 18*r0_5) - L_4*r0*(12576*M_5 + 16*(-886 + 227*E_2)*M_4*r0 + 8*(-1641 + 1225*E_2)*M_3*r0_2 + 4*(58 + 453*E_2)*M_2*r0_3 - 2*(468 + 1057*E_2)*M*r0_4 + 15*r0_5) + 2*r0_5*(-26472*M_5 + 24*(81 + 151*E_2)*M_4*r0 + 2*(4917 - 758*E_2)*M_3*r0_2 - 2*(723 + 904*E_2)*M_2*r0_3 + (133 + 1391*E_2)*M*r0_4 + 54*r0_5)) - 2*a_11*M*(L_2*(672*M_4 + 4*(449 + 96*E_2 + 12*E_4)*M_3*r0 + (1594 - 1063*E_2 + 48*E_4)*M_2*r0_2 + 6*(96 - 177*E_2 + 2*E_4)*M*r0_3 + 72*(1 - 3*E_2)*r0_4) - 4*E_2*r0*(544*(-3 + E_2)*M_5 + 8*(-591 + 151*E_2)*M_4*r0 + 3*(-1239 + 344*E_2)*M_3*r0_2 + 2*(-236 + 199*E_2)*M_2*r0_3 + 2*(190 + 29*E_2)*M*r0_4 + 87*r0_5)) + a_10*E*L*M*(L_2*(384*M_4 + 96*(44 + 5*E_2)*M_3*r0 + 2*(1719 - 224*E_2)*M_2*r0_2 + 3*(275 - 148*E_2)*M*r0_3 + 18*(3 - 2*E_2)*r0_4) + r0*(-512*(-51 + 8*E_2)*M_5 - 32*(-1524 + 329*E_2)*M_4*r0 - 50*(-627 + 248*E_2)*M_3*r0_2 + (7199 - 7568*E_2)*M_2*r0_3 + (329 - 1572*E_2)*M*r0_4 + 2*(22 + 53*E_2)*r0_5)) - 2*a_5*M*r0_2*(12*L_8*(2*M_2 + 11*M*r0 + 6*r0_2) - 2*E_2*r0_6*(10332*M_4 + 24*(85 + 117*E_2)*M_3*r0 + (-4857 + 3604*E_2)*M_2*r0_2 + 10*(-2 + 113*E_2)*M*r0_3 + 228*r0_4) + L_6*(5568*M_4 + 16*(349 - 45*E_2)*M_3*r0 - 4*(567 - 76*E_2 + 126*E_4)*M_2*r0_2 - 4*(86 - 201*E_2 + 63*E_4)*M*r0_3 + 6*(94 + 53*E_2)*r0_4) - L_2*r0_3*(21312*M_5 + 60*(10 + 67*E_2)*M_4*r0 + 4*(-3042 - 1595*E_2 + 1800*E_4)*M_3*r0_2 + (690 - 9047*E_2 + 9960*E_4)*M_2*r0_3 + 24*(43 + 130*E_4)*M*r0_4 - 4*(72 + 281*E_2)*r0_5) + L_4*r0*(-20160*M_5 + 24*(143 + 376*E_2)*M_4*r0 - 8*(-2141 - 830*E_2 + 342*E_4)*M_3*r0_2 - 2*(1087 - 2004*E_2 + 2488*E_4)*M_2*r0_3 - 2*(708 - 779*E_2 + 842*E_4)*M*r0_4 + (678 + 1249*E_2)*r0_5)) + a_6*E*L*r0_2*(6*L_6*M*(40*M_2 + 54*M*r0 + 3*r0_2) + 2*L_4*M*(12576*M_4 - 8*(-1887 + 674*E_2)*M_3*r0 + 4*(1433 - 814*E_2)*M_2*r0_2 + 4*(113 - 66*E_2)*M*r0_3 + (57 + 317*E_2)*r0_4) - L_2*r0*(59968*M_6 - 72*(-217 + 44*E_2)*M_5*r0 + 4*(-17777 + 3124*E_2)*M_4*r0_2 + 2*(-17037 + 7136*E_2)*M_3*r0_3 + (221 + 2012*E_2)*M_2*r0_4 - 3*(103 + 852*E_2)*M*r0_5 + 21*r0_6) + r0_3*(-99448*M_6 + 4*(-13813 + 2608*E_2)*M_5*r0 + 2*(27917 + 1752*E_2)*M_4*r0_2 + (25417 - 12128*E_2)*M_3*r0_3 - 3*(1013 + 1192*E_2)*M_2*r0_4 + 12*(12 + 199*E_2)*M*r0_5 + 24*r0_6)) - 2*a_9*M*(2*L_4*(48*M_4 + 8*(77 + 27*E_2)*M_3*r0 + (1141 + 60*E_2 + 24*E_4)*M_2*r0_2 + 3*(214 - 105*E_2 + 4*E_4)*M*r0_3 - 108*(-1 + E_2)*r0_4) + L_2*r0*(384*(17 + 18*E_2)*M_5 - 32*(-171 - 523*E_2 + 129*E_4)*M_4*r0 + 4*(192 + 5491*E_2 - 1488*E_4)*M_3*r0_2 + (1250 + 8149*E_2 - 2808*E_4)*M_2*r0_3 - 2*(-598 + 627*E_2 + 216*E_4)*M*r0_4 + 12*(20 - 49*E_2)*r0_5) - 4*E_2*r0_2*(3936*M_6 + 4*(1771 + 216*E_2)*M_5*r0 + 2*(-955 + 1492*E_2)*M_4*r0_2 + (-8261 + 3360*E_2)*M_3*r0_3 + 12*(-256 + 131*E_2)*M_2*r0_4 + (359 + 265*E_2)*M*r0_5 + 168*r0_6)) - 2*a_7*M*r0*(8*L_6*(12*M_3 + (89 + 27*E_2)*M_2*r0 + 3*(35 - 2*E_2)*M*r0_2 - 9*(-3 + E_2)*r0_3) - 12*E_2*r0_4*(2652*M_5 + 8*(323 + 75*E_2)*M_4*r0 + (-1463 + 1256*E_2)*M_3*r0_2 + (-1411 + 836*E_2)*M_2*r0_3 + 12*(2 + 15*E_2)*M*r0_4 + 58*r0_5) + 2*L_4*(2240*M_5 + 48*(133 + 45*E_2)*M_4*r0 - 4*(-341 - 936*E_2 + 322*E_4)*M_3*r0_2 - 2*(325 - 1723*E_2 + 584*E_4)*M_2*r0_3 + (694 + 577*E_2 - 250*E_4)*M*r0_4 + 12*(25 - 2*E_2)*r0_5) + L_2*r0*(-15744*M_6 - 16*(557 + 184*E_2)*M_5*r0 + 4*(3682 + 385*E_2 - 1224*E_4)*M_4*r0_2 + 4*(1543 + 6142*E_2 - 3300*E_4)*M_3*r0_3 + (-1686 + 18007*E_2 - 9288*E_4)*M_2*r0_4 - 8*(-40 - 150*E_2 + 243*E_4)*M*r0_5 + 4*(84 - 23*E_2)*r0_6)) + a_8*E*L*r0*(6*L_4*M*(112*M_3 + 8*(46 + 7*E_2)*M_2*r0 - 2*(-74 + 9*E_2)*M*r0_2 - 3*(-3 + E_2)*r0_3) + L_2*M*(22528*M_5 - 32*(-1871 + 426*E_2)*M_4*r0 - 8*(-6691 + 1994*E_2)*M_3*r0_2 - 22*(-771 + 356*E_2)*M_2*r0_3 + (1013 - 1356*E_2)*M*r0_4 + 2*(27 + 244*E_2)*r0_5) + r0*(-62976*M_7 + 64*(-1164 + 107*E_2)*M_6*r0 + 212*(193 + 8*E_2)*M_5*r0_2 - 8*(-8869 + 1698*E_2)*M_4*r0_3 + (17573 - 14832*E_2)*M_3*r0_4 - (1229 + 2912*E_2)*M_2*r0_5 + 8*(1 + 119*E_2)*M*r0_6 - 6*r0_7)) - 2*a*M*r0_4*(84*L_10*r0_2M_2 - 2*L_8*(2*M - r0)*r0*(336*M_2 - 2*(155 + 21*E_2)*M*r0 + 9*(12 + 7*E_2)*r0_2) + 2*L_6*r0_3*(-1872*M_3 + 4*(470 + 187*E_2)*M_2*r0 - 2*(341 + 385*E_2 + 63*E_4)*M*r0_2 + 21*(5 + 11*E_2)*r0_3) + 2*L_2*r0_7*(-624*M_3 + 2*(302 + 691*E_2)*M_2*r0 - (194 + 1021*E_2 + 288*E_4)*M*r0_2 + 12*(2 + 17*E_2)*r0_3) + L_4*r0_5*(-3648*M_3 + 32*(106 + 117*E_2)*M_2*r0 - 2*(518 + 1539*E_2 + 306*E_4)*M*r0_2 + 9*(14 + 83*E_2)*r0_3) - 12*E_2*r0_10*(-18*M_2 + 4*r0_2 + M*(r0 + 21*E_2*r0)))))/(3.*r0_8*expr2_2); A31420 = (-8*r0*(6*a_5*E_2*M*(2*M + r0) - a_4*E*L*r0*(3*M + 2*r0) - 6*a*M*r0*(L_4 + (1 - 2*E_2)*L_2*r0_2 - 3*E_2*r0_4) + E*L*r0_3*(3*r0_3 + 2*L_2*(M + r0)) + 2*a_3*M*(6*E_2*r0_2*(3*M + 2*r0) + L_2*(-6*M - 3*r0 + 2*E_2*r0)) + a_2*E*L*r0*(2*L_2*(M - r0) + r0*(-6*M_2 + 7*M*r0 + r0_2))))/(a_2 + r0*(-2*M + r0)); A31440 = (4*(2*a_11*E_2*M*(144*(-5 + E_2)*M_3 + (437 + 144*E_2)*M_2*r0 + 36*(24 + E_2)*M*r0_2 + 231*r0_3) + a_10*E*L*M*(-576*(-5 + E_2)*M_3 + 16*(162 - 59*E_2)*M_2*r0 + 3*(231 - 160*E_2)*M*r0_2 + 3*(21 - 22*E_2)*r0_3) + E*L*r0_5*(8*L_6*M*(104*M_2 - 106*M*r0 + 27*r0_2) + 2*L_4*r0_2*(728*M_3 - 2*(512 + 157*E_2)*M_2*r0 + (352 + 159*E_2)*M*r0_2 - 11*r0_3) - 2*L_2*r0_4*(-324*M_3 + 18*(43 + 36*E_2)*M_2*r0 - 2*(154 + 177*E_2)*M*r0_2 + r0_3) + r0_6*(-336*M_3 - 24*(-7 + 31*E_2)*M_2*r0 + 2*(-59 + 216*E_2)*M*r0_2 + 59*r0_3)) - 2*a*M*r0_3*(3*E_2*r0_8*(48*M_2 + 2*(29 - 54*E_2)*M*r0 - 41*r0_2) + 4*L_8*(104*M_2 - 106*M*r0 + 27*r0_2) + L_6*r0*(-2064*M_3 + 4*(641 + 28*E_2)*M_2*r0 - 4*(317 + 80*E_2)*M*r0_2 + (251 + 138*E_2)*r0_3) + L_2*r0_5*(-2016*M_3 + 12*(172 + 209*E_2)*M_2*r0 - 2*(377 + 939*E_2 + 252*E_4)*M*r0_2 + (113 + 402*E_2)*r0_3) + L_4*r0_3*(-3984*M_3 + 24*(170 + 71*E_2)*M_2*r0 - 2*(769 + 798*E_2 + 144*E_4)*M*r0_2 + (247 + 462*E_2)*r0_3)) - a_2*E*L*r0_3*(-2*L_6*M*(592*M_2 - 482*M*r0 + 103*r0_2) + r0_5*(12936*M_4 - 12*(563 + 102*E_2)*M_3*r0 + 2*(101 + 1368*E_2)*M_2*r0_2 + (5 - 1518*E_2)*M*r0_3 - 118*r0_4) + 2*L_4*r0*(480*M_4 + 4*(-181 + 256*E_2)*M_3*r0 + 16*(37 + 26*E_2)*M_2*r0_2 - (403 + 305*E_2)*M*r0_3 + 6*r0_4) + L_2*r0_3*(11304*M_4 + 4*(-1127 + 438*E_2)*M_3*r0 + 26*(15 + 94*E_2)*M_2*r0_2 - (1153 + 1912*E_2)*M*r0_3 + 23*r0_4)) - 2*a_9*M*(L_2*(720*M_3 + (1733 + 336*E_2 + 48*E_4)*M_2*r0 + 24*(48 - 38*E_2 + E_4)*M*r0_2 + 3*(77 - 155*E_2)*r0_3) - E_2*r0*(1344*(-3 + E_2)*M_4 + 4*(-3055 + 684*E_2)*M_3*r0 + (-6107 + 1872*E_2)*M_2*r0_2 + 2*(793 + 210*E_2)*M*r0_3 + 965*r0_4)) - 2*a_3*M*r0_2*(12*L_8*M - E_2*r0_6*(5184*M_3 + 72*(-29 + 24*E_2)*M_2*r0 + 4*(-274 + 321*E_2)*M*r0_2 + 581*r0_3) + 2*L_6*(1008*M_3 - 36*(-3 + 10*E_2)*M_2*r0 + 2*(-316 + 25*E_2)*M*r0_2 + (241 + 72*E_2)*r0_3) + 2*L_2*r0_3*(-4824*M_4 + 12*(204 + 109*E_2)*M_3*r0 + 2*(503 + 13*E_2 - 540*E_4)*M_2*r0_2 - (879 + 191*E_2 + 708*E_4)*M*r0_3 + 2*(117 + 136*E_2)*r0_4) + L_4*r0*(-9360*M_4 + 24*(251 + 122*E_2)*M_3*r0 - 16*(-155 + 78*E_2 + 45*E_4)*M_2*r0_2 - 4*(699 - 64*E_2 + 130*E_4)*M*r0_3 + (863 + 592*E_2)*r0_4)) + a_8*E*L*(3*L_2*M*(192*M_3 + 16*(63 + 10*E_2)*M_2*r0 + 4*(110 - 3*E_2)*M*r0_2 + (41 - 20*E_2)*r0_3) + r0*(-768*(-21 + 4*E_2)*M_5 + 16*(1548 - 485*E_2)*M_4*r0 + 2*(5797 - 3244*E_2)*M_3*r0_2 + (1553 - 1912*E_2)*M_2*r0_3 + 2*(65 + 12*E_2)*M*r0_4 + r0_5)) + a_4*E*L*r0_2*(6*L_6*M*(20*M + r0) + 2*L_4*(4032*M_4 - 4*(-423 + 388*E_2)*M_3*r0 + 2*(131 - 25*E_2)*M_2*r0_2 + (116 + 149*E_2)*M*r0_3 + 5*r0_4) + L_2*r0*(-25248*M_5 + 16*(61 - 120*E_2)*M_4*r0 + 4*(4271 - 1696*E_2)*M_3*r0_2 + 12*(187 - 113*E_2)*M_2*r0_3 + (543 + 1640*E_2)*M*r0_4 - 10*r0_5) + r0_3*(-46632*M_5 + 12*(-353 + 492*E_2)*M_4*r0 + 2*(9973 - 1764*E_2)*M_3*r0_2 + (11 - 4032*E_2)*M_2*r0_3 + 12*(9 + 158*E_2)*M*r0_4 + 60*r0_5)) - 2*a_7*M*(2*L_4*(72*M_3 + 8*(53 + 27*E_2)*M_2*r0 + 12*(57 + 5*E_2 + E_4)*M*r0_2 + 3*(77 - 38*E_2)*r0_3) + 2*L_2*r0*(288*(7 + 6*E_2)*M_4 + 2*(41 + 1242*E_2 - 504*E_4)*M_3*r0 + (-307 + 4030*E_2 - 888*E_4)*M_2*r0_2 + (823 + 406*E_2 - 180*E_4)*M*r0_3 + 2*(176 - 295*E_2)*r0_4) - E_2*r0_2*(10944*M_5 + 12*(1315 + 144*E_2)*M_4*r0 + 8*(-1103 + 702*E_2)*M_3*r0_2 + 5*(-3001 + 1008*E_2)*M_2*r0_3 + 24*(-17 + 57*E_2)*M*r0_4 + 1572*r0_5)) + 2*a_5*M*r0*(-3*L_6*(32*M_2 + 4*(19 + 9*E_2)*M*r0 + (77 + 2*E_2)*r0_2) + E_2*r0_4*(15660*M_4 + 252*(31 + 12*E_2)*M_3*r0 + 5*(-2033 + 1008*E_2)*M_2*r0_2 + 108*(-19 + 18*E_2)*M*r0_3 + 1296*r0_4) - 2*L_4*(1248*M_4 + 2260*M_3*r0 - 4*(305 - 120*E_2 + 82*E_4)*M_2*r0_2 - 2*(19 - 441*E_2 + 52*E_4)*M*r0_3 - 49*(-11 + E_2)*r0_4) + L_2*r0*(10944*M_5 - 12*(-29 + 92*E_2)*M_4*r0 + 4*(-1955 + 244*E_2 + 576*E_4)*M_3*r0_2 + (1991 - 5956*E_2 + 3984*E_4)*M_2*r0_3 + 2*(255 - 1600*E_2 + 648*E_4)*M*r0_4 + 3*(-276 + 191*E_2)*r0_5)) + a_6*E*L*r0*(6*L_4*M*(112*M_2 + 2*(65 + 14*E_2)*M*r0 + (11 + E_2)*r0_2) + L_2*(12288*M_5 - 48*(-443 + 168*E_2)*M_4*r0 - 8*(-1748 + 573*E_2)*M_3*r0_2 + 2*(1259 - 122*E_2)*M_2*r0_3 + (189 + 376*E_2)*M*r0_4 + 11*r0_5) + r0*(-43776*M_6 + 96*(-336 + 55*E_2)*M_5*r0 - 44*(-673 + 48*E_2)*M_4*r0_2 + 8*(2774 - 1247*E_2)*M_3*r0_3 - 7*(-143 + 496*E_2)*M_2*r0_4 + 2*(31 + 450*E_2)*M*r0_5 + 2*r0_6))))/(3.*r0_5*expr2_2); A31600 = (-2*r0_4*(2*a_3*E_2*M - a_2*E*L*r0 + E*L*r0_3 - 2*a*M*(L_2 - 3*E_2*r0_2)))/(a_2 + r0*(-2*M + r0)); A31620 = (12*a_9*E_2*M*(4*(-13 + 3*E_2)*M_2 + 2*(31 + 3*E_2)*M*r0 + 41*r0_2) - 3*a_8*E*L*(32*(-13 + 3*E_2)*M_3 + 96*(-2 + E_2)*M_2*r0 + (-9 + 26*E_2)*M*r0_2 + 3*r0_3) + E*L*r0_4*(16*L_4*M*(32*M_2 - 34*M*r0 + 9*r0_2) + L_2*r0_2*(408*M_3 - 4*(207 + 86*E_2)*M_2*r0 + 2*(167 + 90*E_2)*M*r0_2 - 11*r0_3) + 4*r0_4*(-80*M_3 - 20*(-2 + 5*E_2)*M_2*r0 + (-20 + 57*E_2)*M*r0_2 + 10*r0_3)) - 2*a_7*M*(3*L_2*(104*M_2 + 4*(55 + E_4)*M*r0 + (82 - 93*E_2)*r0_2) - 4*E_2*r0*(88*(-3 + E_2)*M_3 + (-947 + 178*E_2)*M_2*r0 + 4*(-23 + 19*E_2)*M*r0_2 + 202*r0_3)) - 2*a*M*r0_2*(4*L_6*(52*M_2 - 56*M*r0 + 15*r0_2) - 6*E_2*r0_6*(4*M_2 + 2*(-22 + 15*E_2)*M*r0 + 21*r0_2) + 2*L_4*r0*(-720*M_3 + 4*(204 + 19*E_2)*M_2*r0 - 2*(185 + 52*E_2)*M*r0_2 + (71 + 39*E_2)*r0_3) + L_2*r0_3*(-1440*M_3 + 4*(386 + 241*E_2)*M_2*r0 - 16*(39 + 47*E_2 + 9*E_4)*M*r0_2 + (106 + 177*E_2)*r0_3)) + a_6*E*L*(3*L_2*(96*M_3 + 8*(24 + 5*E_2)*M_2*r0 + 4*(1 - 2*E_2)*M*r0_2 - 3*r0_3) - r0*(128*(-33 + 8*E_2)*M_4 + 8*(-684 + 287*E_2)*M_3*r0 + 46*(-31 + 22*E_2)*M_2*r0_2 + (17 + 30*E_2)*M*r0_3 + 31*r0_4)) + a_2*E*L*r0_2*(8*L_4*M*(74*M_2 - 55*M*r0 + 14*r0_2) + L_2*r0*(-2992*M_4 + 16*(39 - 58*E_2)*M_3*r0 - 392*(-1 + E_2)*M_2*r0_2 + 4*(81 + 80*E_2)*M*r0_3 - 15*r0_4) + r0_3*(-7480*M_4 + 4*(673 + 200*E_2)*M_3*r0 + 2*(367 - 714*E_2)*M_2*r0_2 + (-31 + 582*E_2)*M*r0_3 + 43*r0_4)) - 2*a_5*M*(6*L_4*(12*M_2 + 6*(5 + 3*E_2)*M*r0 + (41 - 4*E_2)*r0_2) + L_2*r0*(96*(11 + 6*E_2)*M_3 - 4*(263 - 44*E_2 + 82*E_4)*M_2*r0 + 8*(11 + 155*E_2 - 13*E_4)*M*r0_2 + (562 - 469*E_2)*r0_3) - 4*E_2*r0_2*(840*M_4 + 2*(473 + 36*E_2)*M_3*r0 + 2*(-446 + 143*E_2)*M_2*r0_2 + (-491 + 170*E_2)*M*r0_3 + 245*r0_4)) - 2*a_3*M*r0*(24*L_6*M - 4*E_2*r0_4*(666*M_3 + (-37 + 126*E_2)*M_2*r0 + 4*(-90 + 37*E_2)*M*r0_2 + 136*r0_3) + 2*L_4*(272*M_3 + 12*(14 - 15*E_2)*M_2*r0 + 16*(-27 + 4*E_2)*M*r0_2 + (194 + 27*E_2)*r0_3) + L_2*r0*(-3360*M_4 + 104*(17 + 10*E_2)*M_3*r0 - 4*(-209 + 255*E_2 + 90*E_4)*M_2*r0_2 - 4*(281 - 166*E_2 + 65*E_4)*M*r0_3 + (422 - 13*E_2)*r0_4)) + a_4*E*L*r0*(24*L_4*M*(7*M - r0) + L_2*(2560*M_4 - 8*(-237 + 194*E_2)*M_3*r0 + 4*(289 + 10*E_2)*M_2*r0_2 + 2*(17 + 58*E_2)*M*r0_3 - 13*r0_4) - r0*(13440*M_5 + 16*(252 - 101*E_2)*M_4*r0 + 4*(-1827 + 422*E_2)*M_3*r0_2 + 8*(-194 + 219*E_2)*M_2*r0_3 + (43 - 402*E_2)*M*r0_4 + 19*r0_5)))/(3.*r0_2*expr2_2); A31800 = (r0*(6*a_7*E_2*M*(4*(-4 + E_2)*M + 29*r0) - 3*a_6*E*L*(16*(-4 + E_2)*M_2 + 10*E_2*M*r0 + 3*r0_2) - 2*a_5*M*(L_2*(48*M + 87*r0 - 30*E_2*r0) + E_2*r0*(-32*(-3 + E_2)*M_2 + (484 - 76*E_2)*M*r0 - 203*r0_2)) + E*L*r0_3*(16*L_2*M*(10*M_2 - 11*M*r0 + 3*r0_2) + r0_2*(-104*M_3 + (52 - 76*E_2)*M_2*r0 + 2*(-11 + 21*E_2)*M*r0_2 + 11*r0_3)) - a_4*E*L*(-6*L_2*M*(8*M - 5*r0) + r0*(128*(-3 + E_2)*M_3 + 20*(-24 + 11*E_2)*M_2*r0 + 2*(11 + E_2)*M*r0_2 + 23*r0_3)) + 2*a_3*M*(-12*L_4*M + 2*L_2*r0*(-48*M_2 + 2*(61 + 8*E_2)*M*r0 - 61*r0_2) + E_2*r0_2*(384*M_3 + 332*M_2*r0 + 4*(-128 + 25*E_2)*M*r0_2 + 161*r0_3)) + 2*a*M*r0*(-4*L_4*(8*M_2 - 10*M*r0 + 3*r0_2) + 9*E_2*r0_4*(4*M_2 + 4*(-3 + E_2)*M*r0 + 5*r0_2) + L_2*r0*(384*M_3 - 4*(107 + 40*E_2)*M_2*r0 + 4*(47 + 32*E_2)*M*r0_2 - 5*(7 + 6*E_2)*r0_3)) + a_2*E*L*r0*(2*L_2*M*(64*M_2 - 38*M*r0 + 13*r0_2) + r0*(-1536*M_4 + 32*(6 + 5*E_2)*M_3*r0 - 140*(-3 + 2*E_2)*M_2*r0_2 + 2*(-6 + 35*E_2)*M*r0_3 - 3*r0_4))))/(12.*expr2_2); A32040 = (-192*E*L*expr1_2)/(a_2 + r0*(-2*M + r0)); A32060 = (32*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-24*a_9*E_2*M*(4*M_3 + 4*M_2*r0 - M*r0_2 - r0_3) + a_8*E*L*M*(192*M_3 + 24*(8 + E_2)*M_2*r0 + (49 - 12*E_2)*M*r0_2 + 6*(1 - 2*E_2)*r0_3) + E*L*r0_6*(-4*L_4*M*(71*M - 37*r0) + 2*L_2*r0_2*(-162*M_2 + (45 + 16*E_2)*M*r0 + 21*r0_2) + r0_4*(-52*M_2 + 2*(-23 + 20*E_2)*M*r0 + 39*r0_2)) + 2*a_6*E*L*r0*(-1536*M_5 + 208*(-6 + E_2)*M_4*r0 + 24*(7 + 20*E_2)*M_3*r0_2 + 6*(32 + 35*E_2)*M_2*r0_3 + (13 + 2*E_2)*M*r0_4 - 3*r0_5 + L_2*M*(60*M_2 + 4*(2 - 3*E_2)*M*r0 + 3*(1 - 2*E_2)*r0_2)) + 4*a*M*r0_3*(3*E_2*r0_7*(-17*M + 15*r0) + 3*L_6*(44*M_2 - 17*M*r0 - 3*r0_2) + L_4*r0_2*(192*M_2 + 2*(-27 + 8*E_2)*M*r0 + 3*(-8 + 3*E_2)*r0_2) + L_2*r0_4*(60*M_2 - (3 + 85*E_2)*M*r0 + 15*(-1 + 5*E_2)*r0_2)) + 2*a_2*E*L*r0_3*(-2*L_4*M*(220*M_2 + 9*M*r0 - 37*r0_2) + L_2*r0_2*(-1006*M_3 + (-15 + 76*E_2)*M_2*r0 + (177 + 26*E_2)*M*r0_2 + 18*r0_3) + r0_4*(-494*M_3 + 3*(-3 + 98*E_2)*M_2*r0 + 3*(17 + 18*E_2)*M*r0_2 + 36*r0_3)) + 4*a_3*M*r0_2*(-6*L_6*r0 + 3*E_2*r0_5*(36*M_2 + 9*M*r0 + 37*r0_2) + 2*L_4*(228*M_3 + 2*(3 + 11*E_2)*M_2*r0 + 2*(-24 + 7*E_2)*M*r0_2 + 9*(-2 + E_2)*r0_3) + L_2*r0_2*(312*M_3 - 4*(-9 + 7*E_2)*M_2*r0 - (60 + E_2)*M*r0_2 + (-36 + 121*E_2)*r0_3)) + 4*a_7*M*(-(L_2*(24*M_3 + 24*(1 + E_2)*M_2*r0 + (18 - 17*E_2)*M*r0_2 + 3*(2 - 5*E_2)*r0_3)) + 3*E_2*r0*(128*M_4 + 156*M_3*r0 + 24*M_2*r0_2 + 7*M*r0_3 + 11*r0_4)) + a_4*E*L*r0_2*(-24*L_4*M_2 - 2*L_2*(1616*M_4 + 8*(64 - 11*E_2)*M_3*r0 - (239 + 64*E_2)*M_2*r0_2 - (87 + 4*E_2)*M*r0_3 + 3*r0_4) + r0_2*(-3700*M_4 + 4*(-245 + 306*E_2)*M_3*r0 + 3*(183 + 340*E_2)*M_2*r0_2 + 84*(2 + E_2)*M*r0_3 + 27*r0_4)) + 4*a_5*M*r0*(-3*L_4*(4*M_2 + (6 - 4*E_2)*M*r0 + (4 - 3*E_2)*r0_2) + 3*E_2*r0_3*(204*M_3 + 108*M_2*r0 + 31*M*r0_2 + 31*r0_3) + L_2*(384*M_4 + 4*(39 + 62*E_2)*M_3*r0 + 4*(-21 + E_2)*M_2*r0_2 + (-75 + 13*E_2)*M*r0_3 + (-27 + 61*E_2)*r0_4))))/(3.*r0_7*expr2_2); A32220 = (-96*E*L*r0_3*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/(a_2 + r0*(-2*M + r0)); A32240 = (8*(-12*a_9*E_2*M*(24*M_3 + 36*M_2*r0 + 10*M*r0_2 - r0_3) + a_8*E*L*(576*M_4 + 144*(4 + E_2)*M_3*r0 + (193 + 72*E_2)*M_2*r0_2 + 42*M*r0_3 + 6*r0_4) + E*L*r0_4*(4*L_6*M*(-2*M + r0) + 12*L_2*r0_4*(-90*M_2 + 2*(13 + 3*E_2)*M*r0 + 11*r0_2) + 2*L_4*r0_2*(-400*M_2 + (185 - 2*E_2)*M*r0 + 12*r0_2) + 3*r0_6*(-100*M_2 + 14*(-1 + 2*E_2)*M*r0 + 35*r0_2)) + 4*a*M*r0_3*(9*E_2*r0_7*(-11*M + 12*r0) + L_6*(360*M_2 + (-177 + 4*E_2)*M*r0 - 6*r0_2) + 3*L_4*r0_2*(192*M_2 + (-86 + 3*E_2)*M*r0 + (-8 + 15*E_2)*r0_2) + 3*L_2*r0_4*(72*M_2 - 3*(9 + 16*E_2)*M*r0 + 2*(-3 + 29*E_2)*r0_2)) + 2*a_6*E*L*r0*(-4608*M_5 + 48*(-78 + 7*E_2)*M_4*r0 + 2*(199 + 468*E_2)*M_3*r0_2 + 7*(101 + 72*E_2)*M_2*r0_3 + 3*(39 + 14*E_2)*M*r0_4 + 6*r0_5 + L_2*(264*M_3 + 2*(73 + 9*E_2)*M_2*r0 + 39*M*r0_2 + 6*r0_3)) - 2*a_2*E*L*r0_3*(L_4*(1296*M_3 + 4*(-24 + E_2)*M_2*r0 + (-221 + 2*E_2)*M*r0_2 + 9*r0_3) - 3*L_2*r0_2*(-1128*M_3 + 6*(9 + 17*E_2)*M_2*r0 + (197 + 24*E_2)*M*r0_2 + 19*r0_3) - 3*r0_4*(-588*M_3 + 2*(-5 + 96*E_2)*M_2*r0 + (85 + 42*E_2)*M*r0_2 + 35*r0_3)) - 4*a_3*M*r0_2*(3*L_6*(2*M + r0) - 9*E_2*r0_5*(36*M_2 + 19*M*r0 + 29*r0_2) + L_2*r0_2*(-1008*M_3 - 6*(-6 + 71*E_2)*M_2*r0 + (228 - 97*E_2)*M*r0_2 + (39 - 223*E_2)*r0_3) - 3*L_4*(432*M_3 + 4*(-7 + 18*E_2)*M_2*r0 + (-102 + E_2)*M*r0_2 - (10 + E_2)*r0_3)) - 4*a_7*M*(L_2*(72*M_3 + 12*(3 + 10*E_2)*M_2*r0 + (6 + 79*E_2)*M*r0_2 + 3*(1 + E_2)*r0_3) - 3*E_2*r0*(384*M_4 + 492*M_3*r0 + 128*M_2*r0_2 + 15*M*r0_3 + 17*r0_4)) + a_4*E*L*r0_2*(6*L_4*(14*M_2 + 6*M*r0 + r0_2) + L_2*(-9696*M_4 + 8*(-403 + 36*E_2)*M_3*r0 + 8*(251 + 63*E_2)*M_2*r0_2 + 24*(26 + 3*E_2)*M*r0_3 - 6*r0_4) + 3*r0_2*(-3620*M_4 + 4*(-299 + 192*E_2)*M_3*r0 + (635 + 696*E_2)*M_2*r0_2 + 4*(62 + 21*E_2)*M*r0_3 + 37*r0_4)) - 4*a_5*M*r0*(-3*E_2*r0_3*(540*M_3 + 360*M_2*r0 + 115*M*r0_2 + 67*r0_3) + L_2*(-1152*M_4 - 12*(33 + 80*E_2)*M_3*r0 + 2*(174 - 211*E_2)*M_2*r0_2 + (153 + 82*E_2)*M*r0_3 + 2*(12 - 23*E_2)*r0_4) + 6*L_4*(8*M_2 + (1 + E_2)*r0_2 + 2*M*(r0 + 2*E_2*r0)))))/(3.*r0_4*expr2_2); A32400 = (-12*E*L*r0_6)/(a_2 + r0*(-2*M + r0)); A32420 = (2*(-24*a_7*E_2*M*(6*M_2 + 9*M*r0 + 2*r0_2) + 3*a_6*E*L*(96*M_3 + 12*(4 + 3*E_2)*M_2*r0 + 2*(5 + 6*E_2)*M*r0_2 + 3*r0_3) + a_4*E*L*r0*(-4608*M_4 + 48*(-30 + E_2)*M_3*r0 + 6*(167 + 68*E_2)*M_2*r0_2 + 2*(157 + 60*E_2)*M*r0_3 + 43*r0_4 + 3*L_2*(68*M_2 + 4*(5 + 2*E_2)*M*r0 + 3*r0_2)) + E*L*r0_3*(24*L_4*M*(-2*M + r0) + L_2*r0_2*(-744*M_2 + 268*M*r0 + 61*r0_2) + r0_4*(-444*M_2 + 2*(17 + 24*E_2)*M*r0 + 103*r0_2)) + 12*a*M*r0_2*(3*E_2*r0_5*(-5*M + 9*r0) + L_4*(108*M_2 + (-67 + 8*E_2)*M*r0 + (5 - 4*E_2)*r0_2) + L_2*r0_2*(84*M_2 + (-51 + 4*E_2)*M*r0 + (3 + 14*E_2)*r0_2)) + 12*a_5*M*(-2*L_2*(6*M_2 + (-3 + 11*E_2)*M*r0 + 2*(-1 + 3*E_2)*r0_2) + E_2*r0*(192*M_3 + 162*M_2*r0 + 17*M*r0_2 + 5*r0_3)) + a_2*E*L*r0_2*(24*L_4*M + L_2*(-2544*M_3 + 12*(31 - 4*E_2)*M_2*r0 + 24*(18 + E_2)*M*r0_2 + 10*r0_3) + r0_2*(-3204*M_3 + 2*(103 + 222*E_2)*M_2*r0 + 6*(79 + 22*E_2)*M*r0_2 + 137*r0_3)) + 12*a_3*M*r0*(-4*L_4*(M + (-1 + E_2)*r0) + 6*E_2*r0_3*(23*M_2 + 8*M*r0 + 6*r0_2) + L_2*(192*M_3 + 2*(-21 + 50*E_2)*M_2*r0 + (-47 + 2*E_2)*M*r0_2 + 7*(1 - 2*E_2)*r0_3))))/(3.*r0*expr2_2); A32600 = (r0_2*(-12*a_5*E_2*M*(2*M + 3*r0) + 3*a_4*E*L*(16*M_2 + 8*E_2*M*r0 + r0_2) + 2*a_2*E*L*r0*(12*L_2*M - 384*M_3 + 4*(18 - 5*E_2)*M_2*r0 + 7*(7 + 2*E_2)*M*r0_2 + 14*r0_3) + 12*a_3*M*(L_2*(-2*M + (3 - 4*E_2)*r0) + E_2*r0*(32*M_2 + 13*M*r0 + r0_2)) + E*L*r0_2*(20*L_2*M*(-2*M + r0) + r0_2*(-196*M_2 + 2*(15 + 2*E_2)*M*r0 + 37*r0_2)) + 4*a*M*r0*(3*E_2*r0_3*(M + 6*r0) + L_2*(96*M_2 + 5*(-15 + 4*E_2)*M*r0 - 12*(-1 + E_2)*r0_2))))/(6.*expr2_2); A33040 = (-32*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-(a_4*E*L*r0_2) + 6*a_5*E_2*M*(2*M + r0) - 6*a*M*r0*(L_4 - (-1 + E_2)*L_2*r0_2 - 3*E_2*r0_4) + E*L*r0_3*(L_2*(3*M + 2*r0) + r0_2*(-M + 4*r0)) + 2*a_3*M*(6*E_2*r0_2*(3*M + 2*r0) + L_2*(-6*M + (-3 + E_2)*r0)) + a_2*E*L*r0*(L_2*(4*M - r0) + r0*(-14*M_2 + 9*M*r0 + 3*r0_2))))/(r0_2*expr2_2); A33060 = (16*(-2*a_13*E_2*M*(2*M + r0)*(24*(-1 + E_2)*M_3 + (-253 + 36*E_2)*M_2*r0 + 12*(-7 + E_2)*M*r0_2 + 24*r0_3) + a_12*E*L*M*(192*(-1 + 2*E_2)*M_4 - 8*(120 + 73*E_2)*M_3*r0 - 4*(198 + 259*E_2)*M_2*r0_2 - 3*(61 + 104*E_2)*M*r0_3 + 6*(-1 + E_2)*r0_4) + E*L*r0_6*(168*L_8*M*r0_2M_2 + 2*L_6*M*r0_2*(908*M_2 - 14*(73 + 18*E_2)*M*r0 + (281 + 126*E_2)*r0_2) + L_4*r0_4*(1976*M_3 - 2*(1337 + 776*E_2)*M_2*r0 + (861 + 818*E_2)*M*r0_2 - 18*r0_3) + L_2*r0_6*(604*M_3 - 52*(20 + 31*E_2)*M_2*r0 + (285 + 904*E_2)*M*r0_2 + 33*r0_3) + r0_8*(-180*M_3 + 2*(95 - 294*E_2)*M_2*r0 + 2*(-73 + 175*E_2)*M*r0_2 + 45*r0_3)) + 2*a*M*r0_4*(-84*L_10*r0_2M_2 + 3*E_2*r0_10*(-180*M_2 + 2*(61 + 36*E_2)*M*r0 - 15*r0_2) + 2*L_6*r0_3*(1932*M_3 - 2*(847 + 493*E_2)*M_2*r0 + (373 + 1014*E_2 + 126*E_4)*M*r0_2 - 291*E_2*r0_3) + L_4*r0_5*(3816*M_3 - 4*(797 + 1375*E_2)*M_2*r0 + 2*(278 + 2417*E_2 + 342*E_4)*M*r0_2 + 3*(17 - 393*E_2)*r0_3) + L_2*r0_7*(1320*M_3 - 4*(296 + 957*E_2)*M_2*r0 + 2*(131 + 1562*E_2 + 306*E_4)*M*r0_2 + 3*(1 - 226*E_2)*r0_3) + 2*L_8*r0*(684*M_3 - 4*(215 + 21*E_2)*M_2*r0 + 2*(197 + 84*E_2)*M*r0_2 - 3*(22 + 21*E_2)*r0_3)) + a_2*E*L*r0_4*(168*L_8*M*(6*M_2 - 5*M*r0 + r0_2) + 2*L_6*M*r0*(1144*M_3 + (908 - 672*E_2)*M_2*r0 - 8*(167 + 63*E_2)*M*r0_2 + 3*(139 + 84*E_2)*r0_3) + L_4*r0_3*(-480*M_4 - 8*(-639 + 335*E_2)*M_3*r0 - 16*(282 + 247*E_2)*M_2*r0_2 + (1539 + 2384*E_2)*M*r0_3 + 15*r0_4) + L_2*r0_5*(-12728*M_4 + 4*(3143 + 960*E_2)*M_3*r0 - 2*(2269 + 3524*E_2)*M_2*r0_2 + (825 + 3392*E_2)*M*r0_3 + 105*r0_4) + r0_7*(-9744*M_4 + 24*(339 + 74*E_2)*M_3*r0 - 4*(415 + 671*E_2)*M_2*r0_2 + 9*(-27 + 176*E_2)*M*r0_3 + 141*r0_4)) + 2*a_3*M*r0_3*(2*E_2*r0_8*(1422*M_3 + (-1493 + 1062*E_2)*M_2*r0 + (793 + 482*E_2)*M*r0_2 - 135*r0_3) - 2*L_8*(1192*M_3 - 36*(2 + 7*E_2)*M_2*r0 - 2*(155 + 21*E_2)*M*r0_2 + 3*(20 + 21*E_2)*r0_3) + L_2*r0_5*(9600*M_4 - 12*(369 + 527*E_2)*M_3*r0 + 2*(-1251 - 3031*E_2 + 1152*E_4)*M_2*r0_2 + 2*(428 + 3823*E_2 + 1194*E_4)*M*r0_3 + (141 - 2290*E_2)*r0_4) + 2*L_4*r0_3*(9120*M_4 - 4*(1116 + 1943*E_2)*M_3*r0 + 18*(-153 - 56*E_2 + 72*E_4)*M_2*r0_2 + (843 + 3982*E_2 + 1042*E_4)*M*r0_3 + 23*(9 - 64*E_2)*r0_4) + 2*L_6*r0*(4512*M_4 - 2*(1787 + 986*E_2)*M_3*r0 + (-1461 + 470*E_2 + 252*E_4)*M_2*r0_2 + 2*(379 + 495*E_2 + 126*E_4)*M*r0_3 + 18*(4 - 33*E_2)*r0_4)) + 2*a_11*M*(L_2*(-48*(-1 + 6*E_2)*M_4 - 2*(25 - 336*E_2 + 24*E_4)*M_3*r0 + (-13 + 1315*E_2)*M_2*r0_2 + 6*(10 + 49*E_2 + 2*E_4)*M*r0_3 + 24*(1 - 3*E_2)*r0_4) + 2*E_2*r0*(16*(-255 + 74*E_2)*M_5 + 8*(-1056 + 293*E_2)*M_4*r0 + 3*(-1571 + 528*E_2)*M_3*r0_2 + 2*(-169 + 203*E_2)*M_2*r0_3 + 2*(11 + 13*E_2)*M*r0_4 - 96*r0_5)) + a_4*E*L*r0_3*(2*L_6*M*(4672*M_3 - 12*(-65 + 98*E_2)*M_2*r0 - 4*(151 + 63*E_2)*M*r0_2 + 7*(19 + 18*E_2)*r0_3) + L_4*r0*(-13088*M_5 - 8*(-3535 + 254*E_2)*M_4*r0 - 4*(-2965 + 2696*E_2)*M_3*r0_2 - 4*(1228 + 987*E_2)*M_2*r0_3 + 2*(351 + 1160*E_2)*M*r0_4 + 33*r0_5) + L_2*r0_3*(-66044*M_5 + 4*(8387 + 4320*E_2)*M_4*r0 + (28813 - 3160*E_2)*M_3*r0_2 - 2*(4883 + 4878*E_2)*M_2*r0_3 + 3*(193 + 1588*E_2)*M*r0_4 + 111*r0_5) + r0_5*(-55644*M_5 + 36*(413 + 134*E_2)*M_4*r0 + (20481 + 1156*E_2)*M_3*r0_2 - 2*(3279 + 2288*E_2)*M_2*r0_3 + (-151 + 2842*E_2)*M*r0_4 + 153*r0_5)) + 2*a_5*M*r0_2*(12*L_8*(2*M_2 - 7*M*r0 + 2*r0_2) + E_2*r0_6*(19404*M_4 + 1152*(-1 + 6*E_2)*M_3*r0 + (-6861 + 7268*E_2)*M_2*r0_2 + 2*(1267 + 842*E_2)*M*r0_3 - 660*r0_4) + 2*L_6*(-2880*M_4 + 8*(-415 + 18*E_2)*M_3*r0 + 7*(69 + 52*E_2 + 36*E_4)*M_2*r0_2 + (403 + 96*E_2 + 126*E_4)*M*r0_3 + 9*(12 - 35*E_2)*r0_4) + L_2*r0_3*(21984*M_5 + 12*(65 + 721*E_2)*M_4*r0 + 4*(-3531 - 5738*E_2 + 1116*E_4)*M_3*r0_2 + (-1143 - 7025*E_2 + 7824*E_4)*M_2*r0_3 + 6*(281 + 1112*E_2 + 584*E_4)*M*r0_4 + (429 - 3134*E_2)*r0_5) + L_4*r0*(20640*M_5 - 4*(885 + 2344*E_2)*M_4*r0 + 4*(-5035 - 5092*E_2 + 612*E_4)*M_3*r0_2 + (-1081 - 624*E_2 + 5264*E_4)*M_2*r0_3 + 2*(1248 + 1821*E_2 + 1070*E_4)*M*r0_4 + (747 - 2737*E_2)*r0_5)) + a_10*E*L*M*(L_2*(384*M_4 + 24*(-7 + 10*E_2)*M_3*r0 - 16*(57 + 85*E_2)*M_2*r0_2 - 3*(105 + 236*E_2)*M*r0_3 + 6*(-3 + 2*E_2)*r0_4) + r0*(-128*(-255 + 38*E_2)*M_5 + 16*(3192 - 445*E_2)*M_4*r0 + 2*(10011 - 3416*E_2)*M_3*r0_2 - (2713 + 6368*E_2)*M_2*r0_3 - (2041 + 1740*E_2)*M*r0_4 + 2*(-41 + 104*E_2)*r0_5)) + 2*a_9*M*(L_4*(-48*M_4 - 8*(25 + 9*E_2)*M_3*r0 + (-281 + 1116*E_2 + 48*E_4)*M_2*r0_2 + 6*(6 + 83*E_2 + 4*E_4)*M*r0_3 - 72*(-1 + E_2)*r0_4) + L_2*r0*(-96*(85 + 72*E_2)*M_5 + 16*(-540 - 1403*E_2 + 252*E_4)*M_4*r0 + 8*(-141 - 2558*E_2 + 678*E_4)*M_3*r0_2 + (1543 - 2299*E_2 + 2832*E_4)*M_2*r0_3 + 4*(220 + 75*E_2 + 147*E_4)*M*r0_4 + 12*(17 - 61*E_2)*r0_5) + E_2*r0_2*(16128*M_6 + 8*(2903 + 504*E_2)*M_5*r0 + 4*(-3431 + 3356*E_2)*M_4*r0_2 + 2*(-12925 + 6576*E_2)*M_3*r0_3 + 12*(-421 + 402*E_2)*M_2*r0_4 + 8*(55 + 68*E_2)*M*r0_5 - 567*r0_6)) - a_6*E*L*r0_2*(6*L_6*M*(40*M_2 - 6*M*r0 + r0_2) - 4*L_4*M*(6624*M_4 + 4*(2283 - 632*E_2)*M_3*r0 + (1591 - 2186*E_2)*M_2*r0_2 - 2*(304 + 243*E_2)*M*r0_3 + 2*(-12 + 95*E_2)*r0_4) + r0_3*(102120*M_6 + 4*(9595 + 132*E_2)*M_5*r0 - 2*(36117 + 3464*E_2)*M_4*r0_2 + (-15573 + 4304*E_2)*M_3*r0_3 + (9519 + 4568*E_2)*M_2*r0_4 + (227 - 2528*E_2)*M*r0_5 - 63*r0_6) - L_2*r0*(-63168*M_6 + 32*(138 + 143*E_2)*M_5*r0 + 8*(12187 + 668*E_2)*M_4*r0_2 - 2*(-9847 + 6776*E_2)*M_3*r0_3 - 5*(2017 + 1380*E_2)*M_2*r0_4 + (-219 + 2980*E_2)*M*r0_5 + 39*r0_6)) + 2*a_7*M*r0*(4*L_6*(6*M_3 + (-61 + 54*E_2)*M_2*r0 + 3*(-9 + 20*E_2)*M*r0_2 - 6*(-3 + E_2)*r0_3) + 6*E_2*r0_4*(5196*M_5 + 8*(452 + 189*E_2)*M_4*r0 + (-3323 + 2800*E_2)*M_3*r0_2 + (-1395 + 1516*E_2)*M_2*r0_3 + (291 + 236*E_2)*M*r0_4 - 139*r0_5) - 2*L_4*(2336*M_5 + 24*(323 + 108*E_2)*M_4*r0 + 2*(1597 + 2796*E_2 - 620*E_4)*M_3*r0_2 + (-857 + 824*E_2 - 1360*E_4)*M_2*r0_3 - (701 + 191*E_2 + 382*E_4)*M*r0_4 + 6*(-38 + 87*E_2)*r0_5) + L_2*r0*(16128*M_6 + 8*(1153 + 660*E_2)*M_5*r0 + 4*(-4405 - 3027*E_2 + 1152*E_4)*M_4*r0_2 + 2*(-5147 - 18986*E_2 + 5352*E_4)*M_3*r0_3 + 3*(577 - 2455*E_2 + 2784*E_4)*M_2*r0_4 + 4*(478 + 539*E_2 + 576*E_4)*M*r0_5 + (471 - 2182*E_2)*r0_6)) - a_8*E*L*r0*(6*L_4*M*(8*M_3 + 8*(8 + 7*E_2)*M_2*r0 + 2*(8 + 33*E_2)*M*r0_2 - (-3 + E_2)*r0_3) + L_2*M*(-23296*M_5 + 16*(-4603 + 792*E_2)*M_4*r0 + 8*(-6775 + 1466*E_2)*M_3*r0_2 + (-3009 + 10664*E_2)*M_2*r0_3 + 4*(1039 + 822*E_2)*M*r0_4 + 4*(69 - 179*E_2)*r0_5) + r0*(64512*M_7 - 192*(-338 + 17*E_2)*M_6*r0 - 8*(7809 + 4*E_2)*M_5*r0_2 + 4*(-17149 + 284*E_2)*M_4*r0_3 + (-1175 + 9016*E_2)*M_3*r0_4 + 3*(2223 + 1172*E_2)*M_2*r0_5 - 3*(-83 + 374*E_2)*M*r0_6 - 6*r0_7))))/(3.*r0_8*expr2_3); A33220 = (-16*r0*(6*a_5*E_2*M*(2*M + r0) - a_4*E*L*r0*(3*M + 2*r0) - 6*a*M*r0*(L_4 + (1 - 2*E_2)*L_2*r0_2 - 3*E_2*r0_4) + E*L*r0_3*(L_2*(M + 3*r0) + r0_2*(-M + 4*r0)) + 2*a_3*M*(6*E_2*r0_2*(3*M + 2*r0) + L_2*(-6*M - 3*r0 + 2*E_2*r0)) + 2*a_2*E*L*r0*(L_2*(M - r0) + r0*(-4*M_2 + 4*M*r0 + r0_2))))/expr2_2; A33240 = (4*(2*a_11*E_2*M*(48*(-6 + E_2)*M_3 + (973 + 24*E_2)*M_2*r0 + 870*M*r0_2 + 150*r0_3) + a_10*E*L*M*(1152*M_3 + 4*(120 - 331*E_2)*M_2*r0 + 9*(11 - 92*E_2)*M*r0_2 + 6*(7 - 6*E_2)*r0_3) + E*L*r0_5*(430*L_6*M*r0_2M_2 + 2*L_4*r0_2*(1548*M_3 - 26*(79 + 25*E_2)*M_2*r0 + (703 + 325*E_2)*M*r0_2 - 36*r0_3) + L_2*r0_4*(1136*M_3 - 2*(1281 + 1336*E_2)*M_2*r0 + (1015 + 1448*E_2)*M*r0_2 - 27*r0_3) + 3*r0_6*(-260*M_3 + (202 - 488*E_2)*M_2*r0 + 2*(-56 + 143*E_2)*M*r0_2 + 35*r0_3)) - 2*a*M*r0_3*(-9*E_2*r0_8*(-144*M_2 + 4*(22 + 15*E_2)*M*r0 - 7*r0_2) + 4*L_8*(214*M_2 - 215*M*r0 + 54*r0_2) + 2*L_6*r0*(-2112*M_3 + 2*(1183 + 106*E_2)*M_2*r0 - 2*(467 + 213*E_2)*M*r0_2 + 3*(45 + 53*E_2)*r0_3) + 2*L_4*r0_3*(-4128*M_3 + 4*(954 + 661*E_2)*M_2*r0 - (990 + 2569*E_2 + 324*E_4)*M*r0_2 + 3*(16 + 233*E_2)*r0_3) + 3*L_2*r0_5*(-1408*M_3 + 16*(83 + 148*E_2)*M_2*r0 - 8*(44 + 249*E_2 + 45*E_4)*M*r0_2 + (17 + 458*E_2)*r0_3)) + a_2*E*L*r0_3*(2*L_6*M*(1304*M_2 - 1102*M*r0 + 221*r0_2) + 4*L_4*r0*(-536*M_4 + 2*(981 - 433*E_2)*M_3*r0 - 6*(205 + 106*E_2)*M_2*r0_2 + (307 + 316*E_2)*M*r0_3 + 21*r0_4) + L_2*r0_3*(-23432*M_4 + 8*(2403 + 218*E_2)*M_3*r0 - 6*(831 + 1436*E_2)*M_2*r0_2 + 3*(433 + 1344*E_2)*M*r0_3 + 69*r0_4) + 3*r0_5*(-8736*M_4 + 4*(1535 + 362*E_2)*M_3*r0 - 8*(93 + 250*E_2)*M_2*r0_2 + 6*(-31 + 170*E_2)*M*r0_3 + 83*r0_4)) - 2*a_9*M*(L_2*(288*(1 + E_2)*M_3 + (1213 - 624*E_2 + 48*E_4)*M_2*r0 + 6*(141 - 208*E_2)*M*r0_2 + 6*(25 - 49*E_2)*r0_3) - E_2*r0*(96*(-111 + 31*E_2)*M_4 + 4*(-4871 + 1224*E_2)*M_3*r0 + (-6155 + 2472*E_2)*M_2*r0_2 + 6*(315 + 62*E_2)*M*r0_3 + 480*r0_4)) - 2*a_3*M*r0_2*(-3*E_2*r0_6*(2712*M_3 + 4*(-493 + 324*E_2)*M_2*r0 + 664*(1 + E_2)*M*r0_2 - 55*r0_3) + 2*L_6*(2112*M_3 + 12*(35 - 51*E_2)*M_2*r0 - 2*(467 + 64*E_2)*M*r0_2 + 9*(22 + 17*E_2)*r0_3) + 2*L_4*r0*(-9600*M_4 + 8*(729 + 388*E_2)*M_3*r0 + 2*(1779 + 631*E_2 - 324*E_4)*M_2*r0_2 - (2001 + 1864*E_2 + 640*E_4)*M*r0_3 + 39*(3 + 22*E_2)*r0_4) + 2*L_2*r0_3*(-9984*M_4 + 6*(786 + 557*E_2)*M_3*r0 + (2850 + 3865*E_2 - 1512*E_4)*M_2*r0_2 - 6*(225 + 691*E_2 + 262*E_4)*M*r0_3 + 2*(15 + 709*E_2)*r0_4)) + a_8*E*L*(6*L_2*M*(128*M_3 + 2*(107 + 30*E_2)*M_2*r0 + 4*(21 - 23*E_2)*M*r0_2 + (15 - 8*E_2)*r0_3) - r0*(384*(-111 + 19*E_2)*M_5 + 8*(-5928 + 1277*E_2)*M_4*r0 + (-8077 + 9892*E_2)*M_3*r0_2 + 4*(676 + 1043*E_2)*M_2*r0_3 - 42*(-5 + 9*E_2)*M*r0_4 + 18*r0_5)) + a_4*E*L*r0_2*(-12*L_6*M*r0 + 2*L_4*(8736*M_4 - 8*(-534 + 367*E_2)*M_3*r0 - 2*(407 + 323*E_2)*M_2*r0_2 + (61 + 301*E_2)*M*r0_3 - 18*r0_4) + 2*L_2*r0*(-26928*M_5 - 4*(-3163 + 316*E_2)*M_4*r0 + 2*(9509 - 1814*E_2)*M_3*r0_2 - 2*(1483 + 1698*E_2)*M_2*r0_3 + 3*(11 + 612*E_2)*M*r0_4 + 21*r0_5) + 3*r0_3*(-32308*M_5 + 4*(999 + 602*E_2)*M_4*r0 + (13939 - 4*E_2)*M_3*r0_2 - 4*(656 + 781*E_2)*M_2*r0_3 + 18*(-11 + 74*E_2)*M*r0_4 + 55*r0_5)) + 2*a_7*M*(-2*L_4*(72*M_3 + 2*(157 + 63*E_2)*M_2*r0 + 3*(181 - 52*E_2)*M*r0_2 + 6*(25 - 13*E_2)*r0_3) + 2*L_2*r0*(-144*(37 + 24*E_2)*M_4 + 2*(-1057 - 4032*E_2 + 984*E_4)*M_3*r0 + (937 - 4811*E_2 + 1752*E_4)*M_2*r0_2 + 2*(-33 + 151*E_2 + 246*E_4)*M*r0_3 + 3*(-43 + 10*E_2)*r0_4) + 3*E_2*r0_2*(7488*M_5 + 4*(1879 + 360*E_2)*M_4*r0 + 16*(-457 + 255*E_2)*M_3*r0_2 + 3*(-2005 + 952*E_2)*M_2*r0_3 + 2*(259 + 276*E_2)*M*r0_4 + 157*r0_5)) + 2*a_5*M*r0*(-6*L_6*(6*M_2 + 40*M*r0 + (25 - 2*E_2)*r0_2) + 3*E_2*r0_4*(10068*M_4 + 12*(145 + 216*E_2)*M_3*r0 + (-5171 + 3336*E_2)*M_2*r0_2 + 2*(289 + 456*E_2)*M*r0_3 + 13*r0_4) - 2*L_4*(2640*M_4 + 4*(1457 + 108*E_2)*M_3*r0 - 4*(247 - 315*E_2 + 158*E_4)*M_2*r0_2 + (-726 + 309*E_2 - 316*E_4)*M*r0_3 + 3*(73 + 103*E_2)*r0_4) + L_2*r0*(22464*M_5 + 12*(89 + 48*E_2)*M_4*r0 + 4*(-4749 - 3241*E_2 + 1080*E_4)*M_3*r0_2 + 3*(133 - 3800*E_2 + 2320*E_4)*M_2*r0_3 + 2*(1179 + 1276*E_2 + 1524*E_4)*M*r0_4 - (117 + 1696*E_2)*r0_5)) - a_6*E*L*r0*(-12*L_4*M*(26*M_2 + 34*M*r0 - (-3 + E_2)*r0_2) + L_2*(-25728*M_5 + 24*(-2333 + 632*E_2)*M_4*r0 + 368*(-55 + 24*E_2)*M_3*r0_2 + 142*(19 + 20*E_2)*M_2*r0_3 + 2*(241 - 520*E_2)*M*r0_4 + 54*r0_5) + r0*(89856*M_6 - 96*(-492 + 59*E_2)*M_5*r0 + 8*(-10031 + 66*E_2)*M_4*r0_2 + 2*(-15339 + 5710*E_2)*M_3*r0_3 + (8029 + 8180*E_2)*M_2*r0_4 - 48*(-13 + 46*E_2)*M*r0_5 - 3*r0_6))))/(3.*r0_5*expr2_3); A33400 = (2*r0_4*(-6*a_3*E_2*M + 3*a_2*E*L*r0 + E*L*(M - 4*r0)*r0_2 + 6*a*M*(L_2 - 3*E_2*r0_2)))/expr2_2; A33420 = (6*a_9*E_2*M*(4*(-27 + 7*E_2)*M_2 + 12*(22 + E_2)*M*r0 + 131*r0_2) - 3*a_8*E*L*(48*(-9 + 2*E_2)*M_3 + 20*(-8 + 11*E_2)*M_2*r0 + 2*(4 + 19*E_2)*M*r0_2 + 9*r0_3) + E*L*r0_4*(8*L_4*M*(194*M_2 - 201*M*r0 + 52*r0_2) + L_2*r0_2*(1132*M_3 - 4*(552 + 265*E_2)*M_2*r0 + (903 + 544*E_2)*M*r0_2 - 50*r0_3) + r0_4*(-1020*M_3 - 12*(-56 + 97*E_2)*M_2*r0 + (-299 + 666*E_2)*M*r0_2 + 100*r0_3)) - 2*a_7*M*(3*L_2*(12*(9 + 2*E_2)*M_2 + 4*(86 - 24*E_2 + E_4)*M*r0 + (131 - 159*E_2)*r0_2) - 2*E_2*r0*(12*(-189 + 50*E_2)*M_3 + 3*(-1281 + 278*E_2)*M_2*r0 + (-17 + 258*E_2)*M*r0_2 + 578*r0_3)) - 2*a*M*r0_2*(-3*E_2*r0_6*(-324*M_2 + 2*(71 + 72*E_2)*M*r0 + 13*r0_2) + 12*L_6*(56*M_2 - 58*M*r0 + 15*r0_2) + L_4*r0*(-4440*M_3 + 4*(1149 + 136*E_2)*M_2*r0 - 808*(2 + E_2)*M*r0_2 + (205 + 282*E_2)*r0_3) + L_2*r0_3*(-4488*M_3 + 12*(368 + 317*E_2)*M_2*r0 - 2*(673 + 1683*E_2 + 234*E_4)*M*r0_2 + (121 + 837*E_2)*r0_3)) + a_6*E*L*(3*L_2*(160*M_3 + 20*(9 + 2*E_2)*M_2*r0 - 2*(9 + 8*E_2)*M*r0_2 - 9*r0_3) - r0*(96*(-189 + 38*E_2)*M_4 + 48*(-256 + 93*E_2)*M_3*r0 + 12*(2 + 241*E_2)*M_2*r0_2 + (329 - 216*E_2)*M*r0_3 + 67*r0_4)) + a_2*E*L*r0_2*(12*L_4*M*(176*M_2 - 147*M*r0 + 33*r0_2) + L_2*r0*(-9936*M_4 + 16*(489 - 155*E_2)*M_3*r0 - 8*(199 + 226*E_2)*M_2*r0_2 + 4*(133 + 256*E_2)*M*r0_3 + 69*r0_4) + r0_3*(-22800*M_4 + 36*(367 + 80*E_2)*M_3*r0 - 4*(13 + 1047*E_2)*M_2*r0_2 + (-535 + 1776*E_2)*M*r0_3 + 187*r0_4)) - 2*a_5*M*(3*L_4*(36*M_2 + 4*(22 + 9*E_2)*M*r0 + (131 - 16*E_2)*r0_2) + L_2*r0*(216*(21 + 8*E_2)*M_3 - 6*(257 - 358*E_2 + 160*E_4)*M_2*r0 - 2*(257 - 567*E_2 + 210*E_4)*M*r0_2 + (757 - 493*E_2)*r0_3) - 2*E_2*r0_2*(5184*M_4 + 18*(167 + 36*E_2)*M_3*r0 + 2*(-2284 + 831*E_2)*M_2*r0_2 + 3*(-289 + 226*E_2)*M*r0_3 + 592*r0_4)) - 2*a_3*M*r0*(24*L_6*M - 2*E_2*r0_4*(3438*M_3 + 3*(-463 + 306*E_2)*M_2*r0 + (-253 + 654*E_2)*M*r0_2 + 230*r0_3) + 2*L_4*(888*M_3 + 12*(67 - 36*E_2)*M_2*r0 - 6*(163 + 8*E_2)*M*r0_2 + (275 + 117*E_2)*r0_3) + L_2*r0*(-10368*M_4 + 36*(139 + 58*E_2)*M_3*r0 + 2*(1891 + 744*E_2 - 504*E_4)*M_2*r0_2 - 4*(648 + 328*E_2 + 225*E_4)*M*r0_3 + (485 + 701*E_2)*r0_4)) - a_4*E*L*r0*(-24*L_4*M*(7*M - 2*r0) + L_2*(-8256*M_4 + 192*(-45 + 23*E_2)*M_3*r0 + 12*(-18 + 55*E_2)*M_2*r0_2 + 3*(43 - 144*E_2)*M*r0_3 + 4*r0_4) + r0*(41472*M_5 - 48*(-42 + 55*E_2)*M_4*r0 + 48*(-499 + 48*E_2)*M_3*r0_2 + 4*(293 + 1314*E_2)*M_2*r0_3 + (541 - 1440*E_2)*M*r0_4 - 47*r0_5)))/(3.*r0_2*expr2_3); A33600 = (r0*(6*a_7*E_2*M*(4*(-7 + 2*E_2)*M + 73*r0) - 3*a_6*E*L*(16*(-7 + 2*E_2)*M_2 + 24*E_2*M*r0 + 7*r0_2) - 2*a_5*M*(3*L_2*(28*M + (73 - 24*E_2)*r0) + E_2*r0*(-8*(-78 + 19*E_2)*M_2 - 4*(-271 + 49*E_2)*M*r0 - 463*r0_2)) + a_4*E*L*(24*L_2*M*(4*M - 3*r0) + r0*(-32*(-78 + 19*E_2)*M_3 - 8*(-84 + 71*E_2)*M_2*r0 + 5*(-29 + 14*E_2)*M*r0_2 - 46*r0_3)) + E*L*r0_3*(2*L_2*M*(300*M_2 - 328*M*r0 + 89*r0_2) + r0_2*(-420*M_3 - 32*(-8 + 9*E_2)*M_2*r0 + (-109 + 158*E_2)*M*r0_2 + 40*r0_3)) + 2*a_3*M*(-24*L_4*M - 2*L_2*r0*(312*M_2 - 2*(187 + 38*E_2)*M*r0 + (137 + 27*E_2)*r0_2) + E_2*r0_2*(1584*M_3 + 8*(34 + 9*E_2)*M_2*r0 + 8*(-114 + 35*E_2)*M*r0_2 + 325*r0_3)) - 2*a*M*r0*(4*L_4*(38*M_2 - 43*M*r0 + 12*r0_2) - 3*E_2*r0_4*(-72*M_2 + 36*E_2*M*r0 + 19*r0_2) + L_2*r0*(-1584*M_3 + 16*(101 + 33*E_2)*M_2*r0 - 4*(138 + 121*E_2)*M*r0_2 + (67 + 126*E_2)*r0_3)) + a_2*E*L*r0*(2*L_2*M*(304*M_2 - 236*M*r0 + 67*r0_2) + r0*(-6336*M_4 + 24*(112 + 13*E_2)*M_3*r0 + 4*(185 - 218*E_2)*M_2*r0_2 + 10*(-19 + 30*E_2)*M*r0_3 + 39*r0_4))))/(12.*expr2_3); A34020 = (-48*E*L*r0_3*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/expr2_2; A34040 = (8*(-12*a_9*E_2*M*(24*M_3 + 6*M_2*r0 - 17*M*r0_2 - 7*r0_3) + a_8*E*L*(576*M_4 + 576*M_3*r0 + 2*(103 - 36*E_2)*M_2*r0_2 - 6*(-7 + 6*E_2)*M*r0_3 + 3*r0_4) + E*L*r0_4*(4*L_6*M*(2*M - r0) + 3*r0_6*(-39*M_2 + 8*(-1 + E_2)*M*r0 + 17*r0_2) + 3*L_2*r0_4*(-130*M_2 + 4*(4 + E_2)*M*r0 + 31*r0_2) + L_4*r0_2*(-289*M_2 + (92 - 8*E_2)*M*r0 + 36*r0_2)) + 4*a*M*r0_3*(36*E_2*r0_7*(-3*M + 2*r0) + L_6*(180*M_2 - 2*(27 + 2*E_2)*M*r0 + 3*(-7 + 2*E_2)*r0_2) + 3*L_4*r0_2*(96*M_2 - 11*(2 + 3*E_2)*M*r0 + (-15 + 31*E_2)*r0_2) + 3*L_2*r0_4*(36*M_2 - (4 + 85*E_2)*M*r0 + (-8 + 61*E_2)*r0_2)) + 2*a_6*E*L*r0*(-2304*M_5 + 240*(-6 + E_2)*M_4*r0 + 2*(377 + 324*E_2)*M_3*r0_2 + (457 + 216*E_2)*M_2*r0_3 + 3*(1 - 14*E_2)*M*r0_4 - 18*r0_5 + L_2*(192*M_3 + 10*(10 - 3*E_2)*M_2*r0 + 3*(11 - 8*E_2)*M*r0_2 + 3*r0_3)) + a_2*E*L*r0_3*(-12*L_6*M + 3*L_2*r0_2*(-960*M_3 + 4*(32 + 39*E_2)*M_2*r0 + 2*(85 - 4*E_2)*M*r0_2 + r0_3) + 6*r0_4*(-268*M_3 + 4*(11 + 36*E_2)*M_2*r0 + (43 + 6*E_2)*M*r0_2 + 10*r0_3) - 2*L_4*(600*M_3 - 2*(45 + 2*E_2)*M_2*r0 + 5*(-17 + 2*E_2)*M*r0_2 + 24*r0_3)) - 4*a_3*M*r0_2*(3*L_6*(2*M + (7 - 2*E_2)*r0) + 3*E_2*r0_5*(6*M_2 + 17*M*r0 - 65*r0_2) + L_2*r0_2*(-504*M_3 + 6*(-13 + 36*E_2)*M_2*r0 + (123 + 121*E_2)*M*r0_2 + 23*(3 - 13*E_2)*r0_3) - 3*L_4*(216*M_3 + 2*(11 + 10*E_2)*M_2*r0 - (55 + 19*E_2)*M*r0_2 + (-29 + 23*E_2)*r0_3)) - 4*a_7*M*(L_2*(72*M_3 + 6*(21 + 8*E_2)*M_2*r0 + (87 - 61*E_2)*M*r0_2 + 3*(7 - 15*E_2)*r0_3) - 3*E_2*r0*(192*M_4 + 148*M_3*r0 - 22*M_2*r0_2 + 33*M*r0_3 + 31*r0_4)) + a_4*E*L*r0_2*(-3*L_4*(4*M_2 + 4*(-1 + E_2)*M*r0 - r0_2) - 3*r0_2*(1804*M_4 + 12*(19 - 52*E_2)*M_3*r0 - (491 + 456*E_2)*M_2*r0_2 + 2*(-41 + 6*E_2)*M*r0_3 + 10*r0_4) - 2*L_2*(2352*M_4 - 20*(-19 + 6*E_2)*M_3*r0 - (607 + 132*E_2)*M_2*r0_2 + 3*(-25 + 14*E_2)*M*r0_3 + 42*r0_4)) + 4*a_5*M*r0*(-3*L_4*(16*M_2 + (31 - 8*E_2)*M*r0 + 2*(7 - 5*E_2)*r0_2) + 3*E_2*r0_3*(228*M_3 + 34*M_2*r0 + 35*M*r0_2 + 65*r0_3) + L_2*(576*M_4 + 12*(23 + 34*E_2)*M_3*r0 - 8*(21 + 25*E_2)*M_2*r0_2 - (198 + 29*E_2)*M*r0_3 + (-66 + 161*E_2)*r0_4))))/(3.*r0_4*expr2_3); A34200 = (-12*E*L*r0_6)/expr2_2; A34220 = (4*(2*a_7*E_2*M*(-24*M_2 + 3*M*r0 + 10*r0_2) + a_6*E*L*M*(96*M_2 + 48*M*r0 + (7 - 6*E_2)*r0_2) + a_4*E*L*r0*(-768*M_4 + 32*(-3 + E_2)*M_3*r0 + (253 + 80*E_2)*M_2*r0_2 + 2*(18 - 5*E_2)*M*r0_3 - 8*r0_4 + 4*L_2*M*(8*M - (-2 + E_2)*r0)) + E*L*r0_5*(L_2*(-93*M_2 + (25 - 4*E_2)*M*r0 + 14*r0_2) + r0_2*(-63*M_2 + 2*(3 + E_2)*M*r0 + 16*r0_2)) + 2*a*M*r0_2*(3*E_2*r0_5*(-18*M + 13*r0) + 2*L_4*(54*M_2 - 23*M*r0 + (-3 + 2*E_2)*r0_2) + L_2*r0_2*(84*M_2 - (32 + 63*E_2)*M*r0 + (-7 + 52*E_2)*r0_2)) + a_2*E*L*r0_2*(-4*L_4*M + L_2*(-400*M_3 + 118*M_2*r0 + (61 - 8*E_2)*M*r0_2 - 13*r0_3) + r0_2*(-508*M_3 + 2*(61 + 64*E_2)*M_2*r0 + (83 - 2*E_2)*M*r0_2 + 8*r0_3)) - 2*a_5*M*(L_2*(24*M_2 + (27 + 8*E_2)*M*r0 + (10 - 9*E_2)*r0_2) - E_2*r0*(192*M_3 + 58*M_2*r0 - 4*M*r0_2 + 41*r0_3)) - 2*a_3*M*r0*(2*L_4*(4*M + (5 - 2*E_2)*r0) + E_2*r0_3*(-78*M_2 + 25*M*r0 - 70*r0_2) + L_2*(-192*M_3 + 2*(5 - 38*E_2)*M_2*r0 + 53*(1 + E_2)*M*r0_2 + (17 - 27*E_2)*r0_3))))/(r0*expr2_3); A34400 = (r0_2*(36*a_5*E_2*M*(-2*M + r0) + 9*a_4*E*L*(16*M_2 - r0_2) - 2*a_2*E*L*r0*(576*M_3 + 12*(-18 + E_2)*M_2*r0 + 6*(-14 + E_2)*M*r0_2 - r0_3) + 12*a*M*r0*(3*E_2*r0_3*(-6*M + 5*r0) + L_2*(48*M_2 + 4*(-7 + E_2)*M*r0 + r0_2)) - 12*a_3*M*(3*L_2*(2*M + r0) - 2*E_2*r0*(24*M_2 - 4*M*r0 + 7*r0_2)) + E*L*r0_2*(12*L_2*M*(-2*M + r0) + r0_2*(-261*M_2 + 2*(25 - 6*E_2)*M*r0 + 50*r0_2))))/(6.*expr2_3); A35020 = (-8*r0*(6*a_5*E_2*M*(2*M + r0) - a_4*E*L*r0*(3*M + 2*r0) - 6*a*M*r0*(L_4 + (1 - 2*E_2)*L_2*r0_2 - 3*E_2*r0_4) + E*L*r0_4*(4*L_2 + r0*(-2*M + 5*r0)) + 2*a_3*M*(6*E_2*r0_2*(3*M + 2*r0) + L_2*(-6*M - 3*r0 + 2*E_2*r0)) + a_2*E*L*r0*(2*L_2*(M - r0) + r0*(-10*M_2 + 9*M*r0 + 3*r0_2))))/expr2_3; A35040 = (4*(-2*a_11*E_2*M*(48*(-9 + 2*E_2)*M_3 + 8*(-67 + 15*E_2)*M_2*r0 + 6*(-1 + 6*E_2)*M*r0_2 + 81*r0_3) + a_10*E*L*M*(576*(-3 + E_2)*M_3 - 4*(528 + 95*E_2)*M_2*r0 - 6*(99 + 58*E_2)*M*r0_2 + 3*(-7 + 10*E_2)*r0_3) + E*L*r0_5*(2*L_6*M*(468*M_2 - 472*M*r0 + 119*r0_2) + L_2*r0_4*(578*M_3 - (1119 + 1388*E_2)*M_2*r0 + (439 + 752*E_2)*M*r0_2 - 30*r0_3) + 4*L_4*r0_2*(482*M_3 - 58*(11 + 3*E_2)*M_2*r0 + (242 + 89*E_2)*M*r0_2 - 24*r0_3) + 3*r0_6*(-138*M_3 + (131 - 236*E_2)*M_2*r0 + (-65 + 138*E_2)*M*r0_2 + 14*r0_3)) + 2*a*M*r0_3*(9*E_2*r0_8*(-113*M_2 + 2*(43 + 12*E_2)*M*r0 - 13*r0_2) - 4*L_8*(110*M_2 - 109*M*r0 + 27*r0_2) + L_4*r0_3*(4272*M_3 - 2*(1851 + 2011*E_2)*M_2*r0 + 2*(336 + 2095*E_2 + 180*E_4)*M*r0_2 + 9*(7 - 130*E_2)*r0_3) + 3*L_2*r0_5*(736*M_3 - (659 + 1437*E_2)*M_2*r0 + 2*(65 + 608*E_2 + 96*E_4)*M*r0_2 + 3*(3 - 91*E_2)*r0_3) + L_6*r0*(2160*M_3 - (2261 + 360*E_2)*M_2*r0 + 2*(371 + 314*E_2)*M*r0_2 - 12*(6 + 19*E_2)*r0_3)) + 2*a_9*M*(L_2*(-144*(-3 + 2*E_2)*M_3 + 40*(13 + 24*E_2)*M_2*r0 + 6*(51 + 56*E_2 + 4*E_4)*M*r0_2 + 9*(9 - 19*E_2)*r0_3) + E_2*r0*(48*(-137 + 34*E_2)*M_4 + 4*(-1819 + 540*E_2)*M_3*r0 + 2*(-59 + 300*E_2)*M_2*r0_2 - 6*(-49 + 8*E_2)*M*r0_3 - 477*r0_4)) + a_2*E*L*r0_3*(4*L_6*M*(356*M_2 - 322*M*r0 + 71*r0_2) + 3*r0_5*(-4606*M_4 + (4181 + 724*E_2)*M_3*r0 - 8*(101 + 94*E_2)*M_2*r0_2 + 2*(-96 + 247*E_2)*M*r0_3 + 61*r0_4) + 2*L_4*r0*(-568*M_4 + (3527 - 684*E_2)*M_3*r0 - (2279 + 916*E_2)*M_2*r0_2 + 3*(69 + 121*E_2)*M*r0_3 + 120*r0_4) + L_2*r0_3*(-13742*M_4 + (17785 + 4144*E_2)*M_3*r0 - (6037 + 6868*E_2)*M_2*r0_2 + (-47 + 2168*E_2)*M*r0_3 + 291*r0_4)) + 2*a_3*M*r0_2*(12*L_8*M + 3*E_2*r0_6*(1056*M_3 + (-1273 + 720*E_2)*M_2*r0 + 2*(465 + 118*E_2)*M*r0_2 - 203*r0_3) + L_6*(-2208*M_3 + 72*(-9 + 7*E_2)*M_2*r0 + 4*(160 + 101*E_2)*M*r0_2 + 6*(13 - 35*E_2)*r0_3) + 2*L_2*r0_3*(5160*M_4 - 3*(776 + 359*E_2)*M_3*r0 + (-1782 - 4751*E_2 + 432*E_4)*M_2*r0_2 + 6*(83 + 622*E_2 + 144*E_4)*M*r0_3 + (165 - 982*E_2)*r0_4) + L_4*r0*(9840*M_4 - 8*(729 + 416*E_2)*M_3*r0 + 2*(-2232 - 2087*E_2 + 288*E_4)*M_2*r0_2 + 2*(657 + 2230*E_2 + 380*E_4)*M*r0_3 + 21*(25 - 54*E_2)*r0_4)) + 2*a_7*M*r0*(2*L_4*(10*(11 + 9*E_2)*M_2 + 3*(47 + 72*E_2 + 4*E_4)*M*r0 + 9*(9 - 4*E_2)*r0_2) - 2*L_2*(24*(137 + 72*E_2)*M_4 + 2*(1013 + 2766*E_2 - 480*E_4)*M_3*r0 + (-629 + 889*E_2 - 864*E_4)*M_2*r0_2 - 2*(375 + 374*E_2 + 156*E_4)*M*r0_3 + 3*(-73 + 178*E_2)*r0_4) + 3*E_2*r0*(3840*M_5 + 4*(589 + 216*E_2)*M_4*r0 + 8*(-535 + 276*E_2)*M_3*r0_2 + (-1159 + 1176*E_2)*M_2*r0_3 + 4*(143 + 24*E_2)*M*r0_4 - 362*r0_5)) - a_4*E*L*r0_2*(6*L_6*M*(20*M + 3*r0) + L_4*(-9408*M_4 + 16*(-330 + 173*E_2)*M_3*r0 + 8*(287 + 155*E_2)*M_2*r0_2 - 22*(-5 + 16*E_2)*M*r0_3 + 54*r0_4) + L_2*r0*(28704*M_5 + 4*(-5923 + 140*E_2)*M_4*r0 + (-22617 + 136*E_2)*M_3*r0_2 + 30*(311 + 196*E_2)*M_2*r0_3 - 4*(-88 + 523*E_2)*M*r0_4 - 240*r0_5) + 3*r0_3*(16628*M_5 + 8*(-627 + 28*E_2)*M_4*r0 - 24*(317 + 56*E_2)*M_3*r0_2 + (2787 + 1252*E_2)*M_2*r0_3 + (191 - 664*E_2)*M*r0_4 - 71*r0_5)) - a_8*E*L*(3*L_2*M*(-64*M_3 + 20*(29 + 2*E_2)*M_2*r0 + 4*(68 + 43*E_2)*M*r0_2 + (11 - 4*E_2)*r0_3) + r0*(192*(-137 + 22*E_2)*M_5 + 16*(-1416 + 161*E_2)*M_4*r0 + 32*(104 + 103*E_2)*M_3*r0_2 + 2*(2155 + 1112*E_2)*M_2*r0_3 - 6*(-64 + 55*E_2)*M*r0_4 + 27*r0_5)) + 2*a_5*M*r0*(3*L_6*(20*M_2 + 4*(-1 + 9*E_2)*M*r0 + 3*(9 + 2*E_2)*r0_2) + 3*E_2*r0_4*(4812*M_4 + 132*(-5 + 12*E_2)*M_3*r0 + (-1843 + 1656*E_2)*M_2*r0_2 + 4*(287 + 66*E_2)*M*r0_3 - 394*r0_4) - 2*L_4*(1392*M_4 + 4*(895 + 108*E_2)*M_3*r0 + (211 + 804*E_2 - 304*E_4)*M_2*r0_2 - (699 + 603*E_2 + 212*E_4)*M*r0_3 + 24*(-13 + 15*E_2)*r0_4) + L_2*r0*(11520*M_5 + 12*(59 + 148*E_2)*M_4*r0 + 2*(-5574 - 6427*E_2 + 1008*E_4)*M_3*r0_2 + 3*(-507 - 2283*E_2 + 992*E_4)*M_2*r0_3 + 8*(225 + 722*E_2 + 219*E_4)*M*r0_4 + 2*(330 - 1021*E_2)*r0_5)) - a_6*E*L*r0*(6*L_4*M*(60*M_2 + 2*(31 + 14*E_2)*M*r0 + (5 + 3*E_2)*r0_2) + L_2*(-13440*M_5 + 48*(-723 + 148*E_2)*M_4*r0 + 32*(-203 + 132*E_2)*M_3*r0_2 + 4*(1364 + 661*E_2)*M_2*r0_3 + (763 - 688*E_2)*M*r0_4 + 81*r0_5) + r0*(46080*M_6 - 288*(-54 + E_2)*M_5*r0 - 2*(25075 + 216*E_2)*M_4*r0_2 + (-9459 + 736*E_2)*M_3*r0_3 + 4*(2231 + 1021*E_2)*M_2*r0_4 + 3*(185 - 408*E_2)*M*r0_5 - 45*r0_6))))/(3.*r0_5*expr2_4); A35200 = (-2*r0_4*(6*a_3*E_2*M - 3*a_2*E*L*r0 + E*L*r0_2*(-2*M + 5*r0) - 6*a*M*(L_2 - 3*E_2*r0_2)))/expr2_3; A35220 = (-24*a_9*E_2*M*(4*(-6 + E_2)*M_2 + 3*(-13 + E_2)*M*r0 - 4*r0_2) + 3*a_8*E*L*(96*(-4 + E_2)*M_3 - 8*(32 + 19*E_2)*M_2*r0 + (-43 + 2*E_2)*M*r0_2 - 9*r0_3) + 6*a_7*M*(L_2*(-48*(-2 + E_2)*M_2 + 4*(-7 + 48*E_2 + E_4)*M*r0 + (-16 + 39*E_2)*r0_2) + 2*E_2*r0*(16*(-61 + 14*E_2)*M_3 + (-683 + 200*E_2)*M_2*r0 + 10*(17 + 2*E_2)*M*r0_2 - 13*r0_3)) + E*L*r0_4*(4*L_4*M*(398*M_2 - 405*M*r0 + 103*r0_2) + L_2*r0_2*(1106*M_3 - 25*(81 + 44*E_2)*M_2*r0 + 28*(31 + 20*E_2)*M*r0_2 - 84*r0_3) + 6*r0_4*(-170*M_3 + (125 - 184*E_2)*M_2*r0 + 2*(-23 + 52*E_2)*M*r0_2 + 10*r0_3)) - 2*a*M*r0_2*(180*L_6*r0_2M_2 - 18*E_2*r0_6*(-97*M_2 + 2*(35 + 9*E_2)*M*r0 - 9*r0_2) - 3*L_2*r0_3*(1552*M_3 - (1438 + 1469*E_2)*M_2*r0 + 2*(166 + 663*E_2 + 84*E_4)*M*r0_2 + 2*(1 - 161*E_2)*r0_3) + 2*L_4*r0*(-2280*M_3 + (2223 + 328*E_2)*M_2*r0 - (621 + 520*E_2)*M*r0_2 + 3*(12 + 59*E_2)*r0_3)) + 6*a_5*M*r0*(4*L_4*(M + 9*E_2*M + 2*(-2 + E_2)*r0) + L_2*(-32*(61 + 18*E_2)*M_3 + 2*(-5 - 628*E_2 + 156*E_4)*M_2*r0 + 4*(105 + 121*E_2 + 44*E_4)*M*r0_2 + (46 - 139*E_2)*r0_3) + 2*E_2*r0*(1776*M_4 + 36*(5 + 8*E_2)*M_3*r0 + (-1293 + 536*E_2)*M_2*r0_2 + 8*(43 + 14*E_2)*M*r0_3 - 81*r0_4)) - 3*a_6*E*L*(L_2*(-32*M_3 + 8*(27 + 5*E_2)*M_2*r0 + 8*(6 + E_2)*M*r0_2 + 9*r0_3) + r0*(128*(-61 + 11*E_2)*M_4 + 4*(-688 + 171*E_2)*M_3*r0 + 8*(183 + 112*E_2)*M_2*r0_2 + (167 - 158*E_2)*M*r0_3 + 3*r0_4)) + a_2*E*L*r0_2*(24*L_4*M*(102*M_2 - 93*M*r0 + 20*r0_2) + 3*r0_3*(-7902*M_4 + (6345 + 796*E_2)*M_3*r0 - 7*(121 + 144*E_2)*M_2*r0_2 + 2*(-157 + 285*E_2)*M*r0_3 + 88*r0_4) + L_2*r0*(-10992*M_4 + 2*(7035 - 1076*E_2)*M_3*r0 - (4603 + 2500*E_2)*M_2*r0_2 + 4*(28 + 281*E_2)*M*r0_3 + 216*r0_4)) + 6*a_3*M*r0*(8*L_6*M + 2*E_2*r0_4*(996*M_3 + (-829 + 360*E_2)*M_2*r0 + 10*(47 + 14*E_2)*M*r0_2 - 87*r0_3) + L_4*(-640*M_3 + 4*(-185 + 54*E_2)*M_2*r0 + 2*(229 + 100*E_2)*M*r0_2 + 10*(1 - 11*E_2)*r0_3) + L_2*r0*(3552*M_4 - 8*(201 + 40*E_2)*M_3*r0 + (-1640 - 1935*E_2 + 312*E_4)*M_2*r0_2 + 2*(314 + 715*E_2 + 170*E_4)*M*r0_3 + 2*(32 - 239*E_2)*r0_4)) - 3*a_4*E*L*r0*(8*L_4*M*(7*M + r0) + L_2*(-2944*M_4 + 12*(-323 + 116*E_2)*M_3*r0 + 4*(267 + 122*E_2)*M_2*r0_2 + 12*(8 - 15*E_2)*M*r0_3 - 21*r0_4) + r0*(14208*M_5 - 16*(156 + 7*E_2)*M_4*r0 - 8923*M_3*r0_2 + (2447 + 1528*E_2)*M_2*r0_3 + 14*(20 - 37*E_2)*M*r0_4 - 74*r0_5)))/(3.*r0_2*expr2_4); A35400 = (r0*(18*a_7*E_2*M*(4*M + 15*r0) - 9*a_6*E*L*(16*M_2 + 4*E_2*M*r0 + r0_2) - a_4*E*L*r0*(36*L_2*M + 48*(-107 + 22*E_2)*M_3 + 24*(34 + 15*E_2)*M_2*r0 - 6*(-49 + 33*E_2)*M*r0_2 + 5*r0_3) + 2*a_5*M*(9*L_2*(4*M + (-15 + 4*E_2)*r0) + E_2*r0*(12*(-107 + 22*E_2)*M_2 + 6*(-65 + 22*E_2)*M*r0 + 197*r0_2)) + E*L*r0_3*(6*L_2*M*(136*M_2 - 146*M*r0 + 39*r0_2) + r0_2*(-606*M_3 - 9*(-43 + 44*E_2)*M_2*r0 + 2*(-68 + 105*E_2)*M*r0_2 + 38*r0_3)) + 2*a_3*M*r0*(-2*L_2*(642*M_2 - 3*(133 + 40*E_2)*M*r0 + (58 + 69*E_2)*r0_2) + E_2*r0*(2448*M_3 + 3*(-349 + 72*E_2)*M_2*r0 + 2*(73 + 120*E_2)*M*r0_2 + 62*r0_3)) - 2*a*M*r0*(12*L_4*(22*M_2 - 23*M*r0 + 6*r0_2) + 3*E_2*r0_4*(243*M_2 - 4*(38 + 9*E_2)*M*r0 + 10*r0_2) + L_2*r0*(-2448*M_3 + 3*(779 + 200*E_2)*M_2*r0 - 4*(154 + 159*E_2)*M*r0_2 + 2*(13 + 87*E_2)*r0_3)) + a_2*E*L*r0*(6*L_2*M*(176*M_2 - 156*M*r0 + 37*r0_2) + r0*(-9792*M_4 - 48*(-141 + E_2)*M_3*r0 - 3*(63 + 292*E_2)*M_2*r0_2 + 4*(-113 + 111*E_2)*M*r0_3 + 114*r0_4))))/(12.*expr2_4); A36000 = (-4*E*L*r0_6)/expr2_3; A36020 = (-2*(48*a_7*E_2*M*(3*M_2 - 2*M*r0 - 2*r0_2) + 3*a_6*E*L*(-96*M_3 + 12*(-4 + E_2)*M_2*r0 + 6*(-1 + 2*E_2)*M*r0_2 + r0_3) + E*L*r0_3*(8*L_4*M*(-2*M + r0) + L_2*r0_2*(111*M_2 + 16*E_2*M*r0 - 36*r0_2) + r0_4*(103*M_2 + 4*(-5 + 2*E_2)*M*r0 - 24*r0_2)) + a_4*E*L*r0*(1536*M_4 - 16*(6 + 7*E_2)*M_3*r0 - 8*(86 + 23*E_2)*M_2*r0_2 + 2*(-13 + 40*E_2)*M*r0_3 + 51*r0_4 - 3*L_2*(20*M_2 + (4 - 8*E_2)*M*r0 - r0_2)) - 4*a*M*r0_2*(3*E_2*r0_5*(-29*M + 15*r0) + L_4*(108*M_2 - (27 + 8*E_2)*M*r0 + 3*(-5 + 4*E_2)*r0_2) + L_2*r0_2*(84*M_2 - (15 + 133*E_2)*M*r0 + 3*(-5 + 31*E_2)*r0_2)) + 12*a_5*M*(2*L_2*(6*M_2 - (-10 + E_2)*M*r0 + (4 - 5*E_2)*r0_2) + E_2*r0*(-64*M_3 + 14*M_2*r0 + 9*M*r0_2 - 25*r0_3)) + a_2*E*L*r0_2*(24*L_4*M + r0_2*(998*M_3 - (477 + 364*E_2)*M_2*r0 + 2*(-83 + 26*E_2)*M*r0_2 + 24*r0_3) + 2*L_2*(376*M_3 - 4*(45 + 2*E_2)*M_2*r0 + 5*(-9 + 4*E_2)*M*r0_2 + 30*r0_3)) + 4*a_3*M*r0*(12*L_4*(M - (-2 + E_2)*r0) - 6*E_2*r0_3*(5*M_2 - 17*M*r0 + 16*r0_2) + L_2*(-192*M_3 - 2*(9 + 26*E_2)*M_2*r0 + (57 + 109*E_2)*M*r0_2 + 3*(13 - 23*E_2)*r0_3))))/(3.*r0*expr2_4); A36200 = (r0_2*(12*a_5*E_2*M*(-6*M + 7*r0) - 3*a_4*E*L*(-48*M_2 + 8*E_2*M*r0 + 5*r0_2) - 2*a_2*E*L*r0*(12*L_2*M + 384*M_3 - 4*(54 + E_2)*M_2*r0 + (-61 + 22*E_2)*M*r0_2 + 12*r0_3) - 12*a_3*M*(L_2*(6*M + (7 - 4*E_2)*r0) + E_2*r0*(-32*M_2 + 23*M*r0 - 17*r0_2)) + E*L*r0_2*(4*L_2*M*(2*M - r0) + r0_2*(-151*M_2 + 4*(11 - 5*E_2)*M*r0 + 24*r0_2)) + 4*a*M*r0*(3*E_2*r0_3*(-23*M + 12*r0) + L_2*(96*M_2 - (39 + 4*E_2)*M*r0 + 6*(-1 + 2*E_2)*r0_2))))/(6.*expr2_4); A37000 = (2*r0_4*(-2*a_3*E_2*M + a_2*E*L*r0 + E*L*(M - 2*r0)*r0_2 + 2*a*M*(L_2 - 3*E_2*r0_2)))/expr2_4; A37020 = (-6*a_9*E_2*M*(20*(-5 + E_2)*M_2 + 4*(-4 + 3*E_2)*M*r0 + 33*r0_2) + 3*a_8*E*L*(16*(-25 + 6*E_2)*M_3 - 28*(8 + E_2)*M_2*r0 + 2*(-13 + 7*E_2)*M*r0_2 - 3*r0_3) + E*L*r0_4*(4*L_4*M*(138*M_2 - 139*M*r0 + 35*r0_2) + r0_4*(-365*M_3 - 340*(-1 + E_2)*M_2*r0 + 6*(-23 + 31*E_2)*M*r0_2 + 24*r0_3) + L_2*r0_2*(247*M_3 - 6*(53 + 64*E_2)*M_2*r0 + 2*(19 + 98*E_2)*M*r0_2 + 24*r0_3)) + 2*a_7*M*(3*L_2*(-4*(-25 + 6*E_2)*M_2 + 4*(24 + 24*E_2 + E_4)*M*r0 + 3*(11 - 9*E_2)*r0_2) - 2*E_2*r0*(-4*(-297 + 62*E_2)*M_3 - 2*(-50 + 61*E_2)*M_2*r0 + (-343 + 46*E_2)*M*r0_2 + 213*r0_3)) - 2*a*M*r0_2*(4*L_6*(64*M_2 - 62*M*r0 + 15*r0_2) + 3*E_2*r0_6*(259*M_2 - 8*(26 + 3*E_2)*M*r0 + 34*r0_2) + L_4*r0*(-1560*M_3 + 3*(491 + 88*E_2)*M_2*r0 - 4*(87 + 110*E_2)*M*r0_2 + 150*E_2*r0_3) + L_2*r0_3*(-1608*M_3 + (1433 + 1459*E_2)*M_2*r0 - 4*(64 + 287*E_2 + 45*E_4)*M*r0_2 + 6*(-5 + 33*E_2)*r0_3)) + 2*a_5*M*(3*L_4*(12*M_2 + 4*(8 + 9*E_2)*M*r0 + 33*r0_2) + L_2*r0*(-72*(33 + 8*E_2)*M_3 + 4*(-130 - 449*E_2 + 76*E_4)*M_2*r0 + 2*(329 + 673*E_2 + 106*E_4)*M*r0_2 + 9*(37 - 49*E_2)*r0_3) + E_2*r0_2*(3648*M_4 + 2*(-583 + 360*E_2)*M_3*r0 + 7*(-309 + 148*E_2)*M_2*r0_2 + 2*(917 - 2*E_2)*M*r0_3 - 699*r0_4)) - a_6*E*L*(3*L_2*(32*M_3 + 4*(51 + 10*E_2)*M_2*r0 + 26*M*r0_2 + 3*r0_3) + r0*(32*(-297 + 50*E_2)*M_4 - 4*(360 + 29*E_2)*M_3*r0 + 2*(1471 + 404*E_2)*M_2*r0_2 - 3*(-63 + 76*E_2)*M*r0_3 - 27*r0_4)) + a_2*E*L*r0_2*(4*L_4*M*(232*M_2 - 227*M*r0 + 49*r0_2) + L_2*r0*(-4048*M_4 + 60*(113 - 10*E_2)*M_3*r0 - (2475 + 1084*E_2)*M_2*r0_2 + 6*(-17 + 70*E_2)*M*r0_3 + 84*r0_4) + r0_3*(-8206*M_4 + (8089 + 308*E_2)*M_3*r0 - 3*(497 + 88*E_2)*M_2*r0_2 + 12*(-36 + 43*E_2)*M*r0_3 + 96*r0_4)) + 2*a_3*M*r0*(24*L_6*M + 2*E_2*r0_4*(855*M_3 + 2*(-568 + 207*E_2)*M_2*r0 + 2*(476 + 31*E_2)*M*r0_2 - 237*r0_3) - 2*L_4*(344*M_3 + 6*(79 - 12*E_2)*M_2*r0 - 47*(3 + 4*E_2)*M*r0_2 + 3*(-32 + 25*E_2)*r0_3) + L_2*r0*(3648*M_4 + 2*(-785 + 44*E_2)*M_3*r0 + 3*(-667 - 1087*E_2 + 96*E_4)*M_2*r0_2 + 2*(208 + 1121*E_2 + 190*E_4)*M*r0_3 + 12*(22 - 57*E_2)*r0_4)) + a_4*E*L*r0*(-168*L_4*M_2 + L_2*(3136*M_4 + 4*(1221 - 328*E_2)*M_3*r0 - 4*(566 + 191*E_2)*M_2*r0_2 + (-125 + 224*E_2)*M*r0_3 + 54*r0_4) + r0*(-14592*M_5 + 16*(342 - 43*E_2)*M_4*r0 + 8*(1251 + 77*E_2)*M_3*r0_2 - 15*(293 + 72*E_2)*M_2*r0_3 + 3*(-133 + 172*E_2)*M*r0_4 + 108*r0_5)))/(3.*r0_2*expr2_5); A37200 = (r0*(-6*a_7*E_2*M*((-44 + 8*E_2)*M + 13*r0) + 3*a_6*E*L*(16*(-11 + 2*E_2)*M_2 + 8*E_2*M*r0 + 3*r0_2) + 2*a_5*M*(3*L_2*(44*M + (13 - 8*E_2)*r0) + E_2*r0*(40*(-27 + 5*E_2)*M_2 + 4*(134 - 5*E_2)*M*r0 - 183*r0_2)) + 2*a_3*M*(24*L_4*M - 2*L_2*r0*(540*M_2 - 4*(41 + 19*E_2)*M*r0 + 3*(-17 + 19*E_2)*r0_2) + E_2*r0_2*(1680*M_3 + (-1591 + 216*E_2)*M_2*r0 + 2*(499 + 20*E_2)*M*r0_2 - 216*r0_3)) + E*L*r0_3*(2*L_2*M*(236*M_2 - 244*M*r0 + 63*r0_2) + r0_2*(-413*M_3 - 4*(-79 + 58*E_2)*M_2*r0 + 114*(-1 + E_2)*M*r0_2 + 24*r0_3)) + a_4*E*L*(24*L_2*M*(-4*M + r0) + r0*(-160*(-27 + 5*E_2)*M_3 + 8*(-216 + 13*E_2)*M_2*r0 + (-241 + 178*E_2)*M*r0_2 + 36*r0_3)) - 2*a*M*r0*(4*L_4*(50*M_2 - 49*M*r0 + 12*r0_2) + 3*E_2*r0_4*(231*M_2 - 2*(89 + 6*E_2)*M*r0 + 26*r0_2) + L_2*r0*(-1680*M_3 + (1529 + 256*E_2)*M_2*r0 - 2*(155 + 166*E_2)*M*r0_2 + 18*(-1 + 5*E_2)*r0_3)) + a_2*E*L*r0*(2*L_2*M*(400*M_2 - 380*M*r0 + 73*r0_2) + r0*(-6720*M_4 - 8*(-780 + 49*E_2)*M_3*r0 - (909 + 256*E_2)*M_2*r0_2 + 4*(-97 + 67*E_2)*M*r0_3 + 96*r0_4))))/(12.*expr2_5); A38000 = (r0_2*(-6*a_5*E_2*M*(2*M - 3*r0) - 3*a_4*E*L*(-8*M_2 + 2*E_2*M*r0 + r0_2) - 2*a_2*E*L*r0*(3*L_2*M + 48*M_3 - 2*(18 + E_2)*M_2*r0 + (-8 + 5*E_2)*M*r0_2 + 3*r0_3) + E*L*M*r0_2*(L_2*(4*M - 2*r0) + r0_2*(-17*M + 2*(5 - 2*E_2)*r0)) - 6*a_3*M*(L_2*(2*M + (3 - 2*E_2)*r0) - 2*E_2*r0*(4*M_2 - 5*M*r0 + 3*r0_2)) + 2*a*M*r0*(3*E_2*r0_3*(-8*M + 3*r0) + L_2*(24*M_2 - 2*(3 + 2*E_2)*M*r0 + 3*(-1 + 2*E_2)*r0_2))))/(3.*expr2_5); A39000 = (r0*(-6*a_7*E_2*M*(2*(-5 + E_2)*M + 7*r0) + 3*a_6*E*L*(8*(-5 + E_2)*M_2 + 3*E_2*M*r0 + r0_2) + 2*a_5*M*(3*L_2*(10*M + (7 - 3*E_2)*r0) + E_2*r0*(2*(-81 + 14*E_2)*M_2 + (163 - 16*E_2)*M*r0 - 60*r0_2)) + E*L*M*r0_3*(L_2*(48*M_2 - 46*M*r0 + 11*r0_2) + 2*r0_2*(-27*M_2 + 2*(11 - 6*E_2)*M*r0 + 5*(-1 + E_2)*r0_2)) + 2*a_3*M*(6*L_4*M + L_2*r0*(-162*M_2 + (17 + 16*E_2)*M*r0 + 3*(11 - 5*E_2)*r0_2) + E_2*r0_2*(216*M_3 + 2*(-151 + 18*E_2)*M_2*r0 + 2*(113 - 5*E_2)*M*r0_2 - 57*r0_3)) + a_4*E*L*(3*L_2*M*(-8*M + 3*r0) + r0*(-8*(-81 + 14*E_2)*M_3 + 2*(-180 + 29*E_2)*M_2*r0 + (-35 + 26*E_2)*M*r0_2 + 9*r0_3)) - 2*a*M*r0*(3*E_2*r0_4*(36*M_2 - 31*M*r0 + 6*r0_2) + L_4*(28*M_2 - 26*M*r0 + 6*r0_2) + L_2*r0*(-216*M_3 + 2*(95 + 6*E_2)*M_2*r0 - (29 + 26*E_2)*M*r0_2 + 6*(-1 + E_2)*r0_3)) + a_2*E*L*r0*(2*L_2*M*(56*M_2 - 55*M*r0 + 8*r0_2) + r0*(-864*M_4 + 24*(41 - 4*E_2)*M_3*r0 + 2*(-100 + 7*E_2)*M_2*r0_2 + 3*(-19 + 9*E_2)*M*r0_3 + 12*r0_4))))/(6.*expr2_6); } /* A_{r,r} */ { A40080 = (1024*expr1_3*(a_6*E_2*M*(7*M + 3*r0) - 2*a_5*E*L*M*(7*M + 3*r0) - 2*a_3*E*L*M*r0*(3*L_2 - 4*M_2 + 9*M*r0 + 5*r0_2) + 2*a*E*L*M*r0_2*(L_2*(2*M - 3*r0) - 4*M*r0_2) + r0_2*(2*E_2*M*r0_5 + L_4*M*(-2*M + r0) + L_2*r0_2*(2*M_2 + (-3 + 2*E_2)*M*r0 + r0_2)) + a_4*M*(L_2*(7*M + 3*(1 + E_2)*r0) + 2*E_2*r0*(-2*M_2 + 7*M*r0 + 4*r0_2)) + a_2*M*r0*(3*L_4 + E_2*r0_3*(11*M + 7*r0) + L_2*(-4*M_2 - 2*(-2 + E_2)*M*r0 + (2 + 5*E_2)*r0_2))))/(r0_7*expr2_2); A40260 = (256*expr1_2*(3*a_6*E_2*M*(9*M + 4*r0) - 6*a_5*E*L*M*(9*M + 4*r0) - 2*a_3*E*L*M*r0*(12*L_2 - 16*M_2 + 31*M*r0 + 21*r0_2) + 2*a*E*L*M*r0_2*(4*L_2*(2*M - 3*r0) - r0_2*(10*M + 3*r0)) + r0_2*(8*E_2*M*r0_5 + 4*L_4*M*(-2*M + r0) + L_2*r0_2*(4*M_2 + 8*(-1 + E_2)*M*r0 + 3*r0_2)) + a_4*M*(3*L_2*(9*M + 4*(1 + E_2)*r0) + 2*E_2*r0*(-8*M_2 + 25*M*r0 + 16*r0_2)) + a_2*M*r0*(12*L_4 + 7*E_2*r0_3*(5*M + 4*r0) - 2*L_2*(8*M_2 + 2*(-3 + 2*E_2)*M*r0 - 5*(1 + 2*E_2)*r0_2))))/(r0_4*expr2_2); A40440 = (192*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(a_6*E_2*M*(13*M + 6*r0) - 2*a_5*E*L*M*(13*M + 6*r0) - 2*a_3*E*L*M*r0*(6*L_2 - 8*M_2 + 13*M*r0 + 11*r0_2) + r0_2*(4*E_2*M*r0_5 + 2*L_4*M*(-2*M + r0) + L_2*r0_3*(-2*M + 4*E_2*M + r0)) + 2*a*E*L*M*r0_2*(L_2*(4*M - 6*r0) - r0_2*(2*M + 3*r0)) + a_4*M*(L_2*(13*M + 6*(1 + E_2)*r0) + 2*E_2*r0*(-4*M_2 + 11*M*r0 + 8*r0_2)) + a_2*M*r0*(6*L_4 + E_2*r0_3*(13*M + 14*r0) + L_2*(-8*M_2 - 4*(-1 + E_2)*M*r0 + 2*(3 + 5*E_2)*r0_2))))/(r0*expr2_2); A40620 = (16*r0_2*(E_2*M_2*expr3_2 + L_2*expr5_2 + 2*E*L*M*(a_3 + 3*a*r0_2)*(-(a_2*M) + r0_2*(-2*M + r0)) - 4*M*r0*(L_2 + r0_2 + (a_2*(2*M + r0))/r0)*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-2*M + 3*r0) + a_2*(-3*L_2 + E_2*(2*M - 5*r0)*r0) - r0*(2*E_2*r0_3 + L_2*(-2*M + r0)))))/expr2_2; A40800 = (-4*M*r0_5*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-2*M + 3*r0) + a_2*(-3*L_2 + E_2*(2*M - 5*r0)*r0) - r0*(2*E_2*r0_3 + L_2*(-2*M + r0))))/expr2_2; A41080 = (-512*expr1_2*(a_10*E_2*M*(21*M_2 + 17*M*r0 + 3*r0_2) - 2*a_9*E*L*M*((21 + 11*E_2)*M_2 + (17 + 6*E_2)*M*r0 + 3*r0_2) - 2*a*E*L*M*r0_4*(-4*L_4*M*(6*M - 5*r0) + L_2*r0_2*(-54*M_2 + (49 + 12*E_2)*M*r0 - 3*r0_2) + r0_4*(-6*M_2 + (5 + 12*E_2)*M*r0 + 3*r0_2)) + a_8*M*(L_2*(3*(7 + 22*E_2)*M_2 + (17 + 53*E_2)*M*r0 + 3*(1 + 2*E_2)*r0_2) + E_2*r0*(-94*M_3 + 5*M_2*r0 + 74*M*r0_2 + 19*r0_3)) - 2*a_7*E*L*M*(L_2*(33*M_2 + (35 + 6*E_2)*M*r0 + 6*r0_2) + r0*(-2*(47 + 4*E_2)*M_3 + (-4 + 43*E_2)*M_2*r0 + 2*(35 + 17*E_2)*M*r0_2 + 19*r0_3)) + 2*a_3*E*L*M*r0_2*(L_4*(12*M_2 - 40*M*r0 - 3*r0_2) + L_2*r0*(36*M_3 + 6*(17 + 2*E_2)*M_2*r0 - (97 + 34*E_2)*M*r0_2 - 27*r0_3) - r0_3*(36*M_3 - (88 + 15*E_2)*M_2*r0 + 2*(14 + 23*E_2)*M*r0_2 + 29*r0_3)) + a_2*r0_2*(2*L_6*M*(-4*M_2 + 6*M*r0 + r0_2) + E_2*M*r0_6*(-30*M_2 + 29*M*r0 + 22*r0_2) + L_2*r0_3*(36*M_4 - 4*(16 + 39*E_2)*M_3*r0 + (11 + 174*E_2)*M_2*r0_2 + 3*(6 + 5*E_2)*M*r0_3 - 3*r0_4) - L_4*r0*(12*M_4 + 4*(14 + 15*E_2)*M_3*r0 - (39 + 100*E_2)*M_2*r0_2 + (-16 + E_2)*M*r0_3 + 4*r0_4)) + a_6*M*(L_4*(22*M_2 + (29 + 36*E_2)*M*r0 + 3*(2 + E_2)*r0_2) + L_2*r0*(-2*(47 + 24*E_2)*M_3 + (-13 + 128*E_2)*M_2*r0 + 6*(11 + 34*E_2)*M*r0_2 + (19 + 23*E_2)*r0_3) + E_2*r0_2*(24*M_4 - 152*M_3*r0 - 123*M_2*r0_2 + 106*M*r0_3 + 43*r0_4)) + r0_4*(4*E_2*M*r0_8 - L_6*M*(12*M_2 - 8*M*r0 + r0_2) + L_4*r0_2*(-20*M_3 + 4*(5 + 3*E_2)*M_2*r0 - (9 + 2*E_2)*M*r0_2 + 2*r0_3) + L_2*r0_5*(r0*(-2*M + r0) + 2*E_2*M*(6*M + r0))) + a_4*r0*(3*L_6*M*(4*M + r0) + E_2*M*r0_4*(6*M_3 - 97*M_2*r0 + 78*M*r0_2 + 45*r0_3) + L_4*M*(-16*M_3 - 4*(11 + 6*E_2)*M_2*r0 + 2*(27 + 62*E_2)*M*r0_2 + (21 + 4*E_2)*r0_3) + L_2*r0*(24*M_5 - 2*(48 + 49*E_2)*M_3*r0_2 + 7*(10 + 39*E_2)*M_2*r0_3 + 2*(13 + 15*E_2)*M*r0_4 - 4*r0_5 - 36*M_4*(r0 + 3*E_2*r0))) + 2*a_5*E*L*M*r0*(-3*L_4*(6*M + r0) - r0*(24*M_4 - 2*(47 + 12*E_2)*M_3*r0 + (-107 + 25*E_2)*M_2*r0_2 + 2*(48 + 31*E_2)*M*r0_3 + 42*r0_4) + L_2*(24*M_3 - (95 + 28*E_2)*M*r0_2 - 22*r0_3 + M_2*(r0 + 4*E_2*r0)))))/(r0_8*expr2_3); A41260 = (-128*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(a_10*E_2*M*(66*M_2 + 52*M*r0 + 9*r0_2) - 2*a_9*E*L*M*((66 + 34*E_2)*M_2 + 2*(26 + 9*E_2)*M*r0 + 9*r0_2) - 2*a*E*L*M*r0_4*(L_4*(-72*M_2 + 50*M*r0 + 9*r0_2) + L_2*r0_2*(-138*M_2 + (103 + 36*E_2)*M*r0 + 15*r0_2) + r0_4*(-18*M_2 + (5 + 36*E_2)*M*r0 + 18*r0_2)) + r0_4*(16*E_2*M*r0_8 - L_6*M*(36*M_2 - 20*M*r0 + r0_2) + L_2*r0_5*(4*(-1 + 9*E_2)*M_2 + 2*(-2 + 7*E_2)*M*r0 + 3*r0_2) + L_4*r0_2*(-52*M_3 + 4*(10 + 9*E_2)*M_2*r0 - (17 + 2*E_2)*M*r0_2 + 5*r0_3)) + a_8*M*(L_2*(6*(11 + 34*E_2)*M_2 + 4*(13 + 40*E_2)*M*r0 + 9*(1 + 2*E_2)*r0_2) + E_2*r0*(-320*M_3 + 34*M_2*r0 + 253*M*r0_2 + 65*r0_3)) - 2*a_7*E*L*M*(2*L_2*(51*M_2 + (53 + 9*E_2)*M*r0 + 9*r0_2) + r0*(-8*(40 + 3*E_2)*M_3 + 2*(4 + 69*E_2)*M_2*r0 + (241 + 102*E_2)*M*r0_2 + 65*r0_3)) + 2*a_3*E*L*M*r0_2*(2*L_4*(18*M_2 - 56*M*r0 - 9*r0_2) + 2*L_2*r0*(54*M_3 + 2*(77 + 9*E_2)*M_2*r0 - (137 + 51*E_2)*M*r0_2 - 58*r0_3) - r0_3*(72*M_3 - 2*(140 + 9*E_2)*M_2*r0 + (95 + 138*E_2)*M*r0_2 + 111*r0_3)) + a_2*r0_2*(-4*L_6*M*(6*M_2 - 7*M*r0 - 4*r0_2) + E_2*M*r0_6*(-90*M_2 + 87*M*r0 + 86*r0_2) + L_4*r0*(-36*M_4 - 12*(14 + 15*E_2)*M_3*r0 + (89 + 284*E_2)*M_2*r0_2 + 9*(8 + E_2)*M*r0_3 - 11*r0_4) + L_2*r0_3*(84*M_4 - 18*(10 + 21*E_2)*M_3*r0 + (19 + 461*E_2)*M_2*r0_2 + (65 + 77*E_2)*M*r0_3 - 8*r0_4)) + 2*a_5*E*L*M*r0*(-9*L_4*(6*M + r0) + L_2*(72*M_3 + 4*(4 + 3*E_2)*M_2*r0 - (305 + 84*E_2)*M*r0_2 - 83*r0_3) - r0*(72*M_4 - 8*(44 + 9*E_2)*M_3*r0 + 2*(-164 + 51*E_2)*M_2*r0_2 + (335 + 186*E_2)*M*r0_3 + 149*r0_4)) + a_6*M*(L_4*(68*M_2 + 4*(22 + 27*E_2)*M*r0 + 9*(2 + E_2)*r0_2) + L_2*r0*(-16*(20 + 9*E_2)*M_3 + 2*(-9 + 199*E_2)*M_2*r0 + (229 + 629*E_2)*M*r0_2 + 5*(13 + 17*E_2)*r0_3) + E_2*r0_2*(72*M_4 - 556*M_3*r0 - 384*M_2*r0_2 + 381*M*r0_3 + 157*r0_4)) + a_4*r0*(9*L_6*M*(4*M + r0) + 3*E_2*M*r0_4*(-12*M_3 - 110*M_2*r0 + 89*M*r0_2 + 57*r0_3) + L_4*M*(-48*M_3 - 2*(77 + 36*E_2)*M_2*r0 + (185 + 364*E_2)*M*r0_2 + (81 + 20*E_2)*r0_3) + L_2*r0*(72*M_5 - 4*(37 + 81*E_2)*M_4*r0 - 4*(75 + 61*E_2)*M_3*r0_2 + 2*(116 + 399*E_2)*M_2*r0_3 + (97 + 130*E_2)*M*r0_4 - 11*r0_5))))/(r0_5*expr2_3); A41440 = (-32*(a_10*E_2*M*(69*M_2 + 53*M*r0 + 9*r0_2) - 2*a_9*E*L*M*((69 + 35*E_2)*M_2 + (53 + 18*E_2)*M*r0 + 9*r0_2) - 6*a*E*L*M*r0_4*(L_4*(-24*M_2 + 10*M*r0 + 9*r0_2) + r0_4*(-6*M_2 + (-5 + 12*E_2)*M*r0 + 12*r0_2) + L_2*r0_2*(-38*M_2 + (13 + 12*E_2)*M*r0 + 19*r0_2)) + 2*a_3*E*L*M*r0_2*(12*L_4*(3*M_2 - 8*M*r0 - 3*r0_2) + L_2*r0*(108*M_3 + 2*(175 + 18*E_2)*M_2*r0 - (257 + 102*E_2)*M*r0_2 - 187*r0_3) - 3*r0_3*(12*M_3 + (-112 + 3*E_2)*M_2*r0 + 2*(19 + 23*E_2)*M*r0_2 + 54*r0_3)) + a_8*M*(L_2*(3*(23 + 70*E_2)*M_2 + (53 + 161*E_2)*M*r0 + 9*(1 + 2*E_2)*r0_2) + E_2*r0*(-390*M_3 + 53*M_2*r0 + 308*M*r0_2 + 81*r0_3)) - 2*a_7*E*L*M*(L_2*(105*M_2 + (107 + 18*E_2)*M*r0 + 18*r0_2) + r0*(-6*(65 + 4*E_2)*M_3 + (32 + 147*E_2)*M_2*r0 + 6*(50 + 17*E_2)*M*r0_2 + 82*r0_3)) + a_2*r0_2*(12*L_6*M*(-2*M_2 + M*r0 + 3*r0_2) + 3*E_2*M*r0_6*(-30*M_2 + 29*M*r0 + 42*r0_2) + L_4*r0*(-36*M_4 - 4*(46 + 45*E_2)*M_3*r0 + 9*(5 + 28*E_2)*M_2*r0_2 + 3*(40 + 11*E_2)*M*r0_3 - 10*r0_4) + L_2*r0_3*(60*M_4 - 8*(23 + 36*E_2)*M_3*r0 + 3*(-1 + 128*E_2)*M_2*r0_2 + 3*(30 + 47*E_2)*M*r0_3 - 7*r0_4)) + a_6*M*(L_4*(70*M_2 + (89 + 108*E_2)*M*r0 + 9*(2 + E_2)*r0_2) + L_2*r0*(-6*(65 + 24*E_2)*M_3 + (11 + 380*E_2)*M_2*r0 + 2*(146 + 331*E_2)*M*r0_2 + (83 + 117*E_2)*r0_3) + 3*E_2*r0_2*(24*M_4 - 240*M_3*r0 - 149*M_2*r0_2 + 164*M*r0_3 + 71*r0_4)) + 2*a_5*E*L*M*r0*(-9*L_4*(6*M + r0) + L_2*(72*M_3 + (61 + 12*E_2)*M_2*r0 - 3*(115 + 28*E_2)*M*r0_2 - 118*r0_3) - r0*(72*M_4 - 6*(77 + 12*E_2)*M_3*r0 + (-371 + 129*E_2)*M_2*r0_2 + 2*(214 + 93*E_2)*M*r0_3 + 199*r0_4)) + a_4*r0*(9*L_6*M*(4*M + r0) + 3*E_2*M*r0_4*(-30*M_3 - 139*M_2*r0 + 108*M*r0_2 + 81*r0_3) + L_4*M*(-48*M_3 - 8*(26 + 9*E_2)*M_2*r0 + 116*(2 + 3*E_2)*M*r0_2 + (119 + 36*E_2)*r0_3) + L_2*r0*(72*M_5 - 12*(17 + 27*E_2)*M_4*r0 - 2*(176 + 129*E_2)*M_3*r0_2 + 3*(94 + 259*E_2)*M_2*r0_3 + 6*(23 + 35*E_2)*M*r0_4 - 10*r0_5)) + r0_4*(24*E_2*M*r0_8 + 3*L_6*M*(-12*M_2 + 4*M*r0 + r0_2) + 3*L_2*r0_5*(4*(-1 + 3*E_2)*M_2 + 10*E_2*M*r0 + r0_2) + L_4*r0_2*(-44*M_3 + 3*(-1 + 2*E_2)*M*r0_2 + 4*r0_3 + 12*M_2*(r0 + 3*E_2*r0)))))/(r0_2*expr2_3); A41620 = (-8*r0*(3*a_8*E_2*M*(4*M + r0) - 6*a_7*E*L*M*(2*(2 + E_2)*M + r0) + 2*a_5*E*L*M*(-3*L_2*(6*M + r0) + r0*((98 + 4*E_2)*M_2 - (61 + 28*E_2)*M*r0 - 42*r0_2)) + 2*a*E*L*M*r0_3*(r0_2*(6*M_2 + (25 - 12*E_2)*M*r0 - 30*r0_2) + L_2*(24*M_2 + 10*M*r0 - 27*r0_2)) + r0_3*(16*E_2*M*r0_6 + L_2*r0_3*(12*(-1 + E_2)*M_2 + 2*(2 + 5*E_2)*M*r0 + r0_2) + L_4*M*(-12*M_2 - 4*M*r0 + 5*r0_2)) + a_6*M*(3*L_2*(4*M + 12*E_2*M + r0 + E_2*r0) + E_2*r0*(-98*M_2 + 61*M*r0 + 40*r0_2)) + 2*a_3*E*L*M*r0*(2*L_2*(6*M_2 - 8*M*r0 - 15*r0_2) - r0*(12*M_3 - 4*(32 + 3*E_2)*M_2*r0 + 2*(10 + 17*E_2)*M*r0_2 + 77*r0_3)) + a_4*M*(3*L_4*(4*M + r0) + L_2*r0*(-2*(49 + 12*E_2)*M_2 + (61 + 100*E_2)*M*r0 + 4*(11 + 7*E_2)*r0_2) + E_2*r0_2*(12*M_3 - 196*M_2*r0 + 30*M*r0_2 + 87*r0_3)) - a_2*r0*(3*E_2*M*r0_4*(10*M_2 + M*r0 - 22*r0_2) + 4*L_4*M*(2*M_2 + 3*M*r0 - 8*r0_2) + L_2*r0*(-12*M_4 + 60*(1 + E_2)*M_3*r0 + (15 - 52*E_2)*M_2*r0_2 - (51 + 35*E_2)*M*r0_3 + 3*r0_4))))/expr2_3; A41800 = (4*M*r0_5*(4*a_4*E_2*(M - r0) + a*E*L*r0_2*(-10*M + 9*r0) + a_3*E*L*(-8*M + 9*r0) + a_2*(L_2*(4*M - 5*r0) + 2*E_2*(4*M - 3*r0)*r0_2) - r0_2*(2*E_2*r0_3 + L_2*(-2*M + r0))))/expr2_3; A42060 = (256*expr1_2*(3*a_6*E_2*M*(9*M + 4*r0) - 6*a_5*E*L*M*(9*M + 4*r0) - 2*a_3*E*L*M*r0*(12*L_2 - 16*M_2 + 31*M*r0 + 21*r0_2) + 2*a*E*L*M*r0_2*(4*L_2*(2*M - 3*r0) - r0_2*(10*M + 3*r0)) + r0_2*(8*E_2*M*r0_5 + 4*L_4*M*(-2*M + r0) + L_2*r0_2*(4*M_2 + 8*(-1 + E_2)*M*r0 + 3*r0_2)) + a_4*M*(3*L_2*(9*M + 4*(1 + E_2)*r0) + 2*E_2*r0*(-8*M_2 + 25*M*r0 + 16*r0_2)) + a_2*M*r0*(12*L_4 + 7*E_2*r0_3*(5*M + 4*r0) - 2*L_2*(8*M_2 + 2*(-3 + 2*E_2)*M*r0 - 5*(1 + 2*E_2)*r0_2))))/(r0_4*expr2_3); A42240 = (384*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(a_6*E_2*M*(13*M + 6*r0) - 2*a_5*E*L*M*(13*M + 6*r0) - 2*a_3*E*L*M*r0*(6*L_2 - 8*M_2 + 13*M*r0 + 11*r0_2) + r0_2*(4*E_2*M*r0_5 + 2*L_4*M*(-2*M + r0) + L_2*r0_3*(-2*M + 4*E_2*M + r0)) + 2*a*E*L*M*r0_2*(L_2*(4*M - 6*r0) - r0_2*(2*M + 3*r0)) + a_4*M*(L_2*(13*M + 6*(1 + E_2)*r0) + 2*E_2*r0*(-4*M_2 + 11*M*r0 + 8*r0_2)) + a_2*M*r0*(6*L_4 + E_2*r0_3*(13*M + 14*r0) + L_2*(-8*M_2 - 4*(-1 + E_2)*M*r0 + 2*(3 + 5*E_2)*r0_2))))/(r0*expr2_3); A42420 = (48*r0_2*(E_2*M_2*expr3_2 + L_2*expr5_2 + 2*E*L*M*(a_3 + 3*a*r0_2)*(-(a_2*M) + r0_2*(-2*M + r0)) - 4*M*r0*(L_2 + r0_2 + (a_2*(2*M + r0))/r0)*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-2*M + 3*r0) + a_2*(-3*L_2 + E_2*(2*M - 5*r0)*r0) - r0*(2*E_2*r0_3 + L_2*(-2*M + r0)))))/expr2_3; A42600 = (-16*M*r0_5*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-2*M + 3*r0) + a_2*(-3*L_2 + E_2*(2*M - 5*r0)*r0) - r0*(2*E_2*r0_3 + L_2*(-2*M + r0))))/expr2_3; A43060 = (-128*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(a_10*E_2*M*(66*M_2 + 52*M*r0 + 9*r0_2) - 2*a_9*E*L*M*((66 + 34*E_2)*M_2 + 2*(26 + 9*E_2)*M*r0 + 9*r0_2) - 2*a*E*L*M*r0_4*(4*L_2*r0_2*(-32*M_2 + 3*(7 + 3*E_2)*M*r0 + 6*r0_2) + L_4*(-70*M_2 + 45*M*r0 + 12*r0_2) + r0_4*(-10*M_2 + 9*(-1 + 4*E_2)*M*r0 + 24*r0_2)) + r0_4*(-2*E_2*M*(M - 9*r0)*r0_7 + 17*L_6*M_2*(-2*M + r0) + 2*L_4*r0_2*(-22*M_3 + (13 + 17*E_2)*M_2*r0 - 5*M*r0_2 + 2*r0_3) + L_2*r0_4*(6*M_3 + (-15 + 32*E_2)*M_2*r0 + 2*(1 + 9*E_2)*M*r0_2 + 2*r0_3)) + a_8*M*(L_2*(6*(11 + 34*E_2)*M_2 + 4*(13 + 40*E_2)*M*r0 + 9*(1 + 2*E_2)*r0_2) + E_2*r0*(-330*M_3 + 33*M_2*r0 + 261*M*r0_2 + 68*r0_3)) - 2*a_7*E*L*M*(2*L_2*(51*M_2 + (53 + 9*E_2)*M*r0 + 9*r0_2) + r0*(-6*(55 + 4*E_2)*M_3 + (7 + 138*E_2)*M_2*r0 + 3*(83 + 34*E_2)*M*r0_2 + 68*r0_3)) + 2*a_3*E*L*M*r0_2*(L_4*(36*M_2 - 109*M*r0 - 21*r0_2) + L_2*r0*(100*M_3 + (319 + 36*E_2)*M_2*r0 - 6*(44 + 17*E_2)*M*r0_2 - 129*r0_3) - r0_3*(92*M_3 - 3*(101 + 6*E_2)*M_2*r0 + (85 + 138*E_2)*M*r0_2 + 124*r0_3)) + a_2*r0_2*(L_6*M*(-24*M_2 + 25*M*r0 + 19*r0_2) + E_2*M*r0_6*(-87*M_2 + 75*M*r0 + 95*r0_2) + L_4*r0*(-28*M_4 - 2*(86 + 89*E_2)*M_3*r0 + (75 + 277*E_2)*M_2*r0_2 + 2*(41 + 7*E_2)*M*r0_3 - 11*r0_4) + L_2*r0_3*(100*M_4 - (196 + 373*E_2)*M_3*r0 + 2*(5 + 221*E_2)*M_2*r0_2 + (75 + 91*E_2)*M*r0_3 - 9*r0_4)) + 2*a_5*E*L*M*r0*(-9*L_4*(6*M + r0) + L_2*(72*M_3 + 3*(9 + 4*E_2)*M_2*r0 - 2*(155 + 42*E_2)*M*r0_2 - 89*r0_3) - r0*(80*M_4 - 6*(59 + 12*E_2)*M_3*r0 + 2*(-176 + 51*E_2)*M_2*r0_2 + (343 + 186*E_2)*M*r0_3 + 159*r0_4)) + a_6*M*(L_4*(68*M_2 + 4*(22 + 27*E_2)*M*r0 + 9*(2 + E_2)*r0_2) + L_2*r0*(-6*(55 + 24*E_2)*M_3 + (-19 + 387*E_2)*M_2*r0 + (237 + 634*E_2)*M*r0_2 + (68 + 91*E_2)*r0_3) + E_2*r0_2*(80*M_4 - 564*M_3*r0 - 407*M_2*r0_2 + 393*M*r0_3 + 168*r0_4)) + a_4*r0*(9*L_6*M*(4*M + r0) + 3*E_2*M*r0_4*(-6*M_3 - 119*M_2*r0 + 87*M*r0_2 + 62*r0_3) + L_4*M*(-48*M_3 - 3*(55 + 24*E_2)*M_2*r0 + 19*(10 + 19*E_2)*M*r0_2 + (87 + 23*E_2)*r0_3) + L_2*r0*(80*M_5 - 4*(36 + 79*E_2)*M_4*r0 - (325 + 262*E_2)*M_3*r0_2 + 4*(59 + 198*E_2)*M_2*r0_3 + 2*(53 + 73*E_2)*M*r0_4 - 11*r0_5))))/(r0_5*expr2_4); A43240 = (-32*(2*a_10*E_2*M*(69*M_2 + 53*M*r0 + 9*r0_2) - 4*a_9*E*L*M*((69 + 35*E_2)*M_2 + (53 + 18*E_2)*M*r0 + 9*r0_2) - 6*a*E*L*M*r0_4*(L_4*(-46*M_2 + 15*M*r0 + 21*r0_2) + 2*L_2*r0_2*(-34*M_2 + (5 + 12*E_2)*M*r0 + 23*r0_2) + r0_4*(-6*M_2 + 3*(-7 + 8*E_2)*M*r0 + 29*r0_2)) + r0_4*(-6*E_2*M*(M - 9*r0)*r0_7 + 3*L_6*M*(-22*M_2 + 5*M*r0 + 3*r0_2) + 2*L_4*r0_2*(-34*M_3 + (-5 + 33*E_2)*M_2*r0 + (5 + 9*E_2)*M*r0_2 + 3*r0_3) + L_2*r0_4*(14*M_3 + (-49 + 60*E_2)*M_2*r0 + (13 + 72*E_2)*M*r0_2 + 4*r0_3)) + a_8*M*(2*L_2*(3*(23 + 70*E_2)*M_2 + (53 + 161*E_2)*M*r0 + 9*(1 + 2*E_2)*r0_2) + E_2*r0*(-812*M_3 + 104*M_2*r0 + 641*M*r0_2 + 171*r0_3)) - 2*a_7*E*L*M*(L_2*(210*M_2 + 2*(107 + 18*E_2)*M*r0 + 36*r0_2) + r0*(-4*(203 + 12*E_2)*M_3 + 2*(31 + 147*E_2)*M_2*r0 + (625 + 204*E_2)*M*r0_2 + 173*r0_3)) + 2*a_3*E*L*M*r0_2*(3*L_4*(24*M_2 - 61*M*r0 - 27*r0_2) + 2*L_2*r0*(96*M_3 + 9*(41 + 4*E_2)*M_2*r0 - (245 + 102*E_2)*M*r0_2 - 206*r0_3) - r0_3*(120*M_3 + 2*(-367 + 9*E_2)*M_2*r0 + 69*(3 + 4*E_2)*M*r0_2 + 359*r0_3)) + a_2*r0_2*(3*L_6*M*(-16*M_2 + 5*M*r0 + 27*r0_2) + 3*E_2*M*r0_6*(-60*M_2 + 49*M*r0 + 93*r0_2) + L_4*r0*(-48*M_4 - 6*(64 + 59*E_2)*M_3*r0 + 3*(18 + 161*E_2)*M_2*r0_2 + (268 + 81*E_2)*M*r0_3 - 20*r0_4) + L_2*r0_3*(160*M_4 - 6*(68 + 95*E_2)*M_3*r0 + (-29 + 720*E_2)*M_2*r0_2 + (205 + 324*E_2)*M*r0_3 - 16*r0_4)) + 2*a_5*E*L*M*r0*(-18*L_4*(6*M + r0) + 2*L_2*(72*M_3 + 6*(13 + 2*E_2)*M_2*r0 - (353 + 84*E_2)*M*r0_2 - 127*r0_3) - r0*(168*M_4 - 4*(235 + 36*E_2)*M_3*r0 + 2*(-404 + 129*E_2)*M_2*r0_2 + 3*(295 + 124*E_2)*M*r0_3 + 427*r0_4)) + a_6*M*(2*L_4*(70*M_2 + (89 + 108*E_2)*M*r0 + 9*(2 + E_2)*r0_2) + L_2*r0*(-4*(203 + 72*E_2)*M_3 + 2*(10 + 363*E_2)*M_2*r0 + (609 + 1340*E_2)*M*r0_2 + 7*(25 + 36*E_2)*r0_3) + E_2*r0_2*(168*M_4 - 1476*M_3*r0 - 958*M_2*r0_2 + 1027*M*r0_3 + 459*r0_4)) + a_4*r0*(18*L_6*M*(4*M + r0) + 3*E_2*M*r0_4*(-48*M_3 - 304*M_2*r0 + 215*M*r0_2 + 177*r0_3) + L_4*M*(-96*M_3 - 18*(25 + 8*E_2)*M_2*r0 + 3*(160 + 229*E_2)*M*r0_2 + (256 + 81*E_2)*r0_3) + L_2*r0*(168*M_5 - 4*(101 + 156*E_2)*M_4*r0 - 4*(193 + 144*E_2)*M_3*r0_2 + 3*(193 + 514*E_2)*M_2*r0_3 + (301 + 468*E_2)*M*r0_4 - 20*r0_5))))/(r0_2*expr2_4); A43420 = (-8*r0*(9*a_8*E_2*M*(4*M + r0) - 18*a_7*E*L*M*(2*(2 + E_2)*M + r0) + 2*a_5*E*L*M*(-9*L_2*(6*M + r0) + r0*((311 + 12*E_2)*M_2 - (191 + 84*E_2)*M*r0 - 135*r0_2)) - 6*a*E*L*M*r0_3*(L_2*(-22*M_2 - 15*M*r0 + 30*r0_2) + r0_2*(-2*M_2 + 3*(-11 + 4*E_2)*M*r0 + 34*r0_2)) + a_6*M*(9*L_2*(4*M + 12*E_2*M + r0 + E_2*r0) + E_2*r0*(-311*M_2 + 191*M*r0 + 129*r0_2)) + r0_3*(-6*E_2*M*(M - 9*r0)*r0_5 - 3*L_4*M*(10*M_2 + 7*M*r0 - 6*r0_2) + L_2*r0_2*(10*M_3 + (-53 + 30*E_2)*M_2*r0 + 4*(5 + 9*E_2)*M*r0_2 + 2*r0_3)) + a_4*M*(9*L_4*(4*M + r0) + L_2*r0*(-((311 + 72*E_2)*M_2) + (191 + 291*E_2)*M*r0 + 3*(47 + 31*E_2)*r0_2) + 3*E_2*r0_2*(16*M_3 - 206*M_2*r0 + 28*M*r0_2 + 95*r0_3)) + 2*a_3*E*L*M*r0*(L_2*(36*M_2 - 39*M*r0 - 99*r0_2) - r0*(48*M_3 - (403 + 36*E_2)*M_2*r0 + 6*(8 + 17*E_2)*M*r0_2 + 250*r0_3)) - a_2*r0*(3*E_2*M*r0_4*(29*M_2 + 11*M*r0 - 73*r0_2) + 3*L_4*M*(8*M_2 + 15*M*r0 - 35*r0_2) + L_2*r0*(-48*M_4 + 2*(94 + 87*E_2)*M_3*r0 - 9*(-7 + 15*E_2)*M_2*r0_2 - (167 + 120*E_2)*M*r0_3 + 9*r0_4))))/expr2_4; A43600 = (-2*M*r0_5*(2*a_3*E*L*(35*M - 39*r0) - 35*a_4*E_2*(M - r0) - 2*a*E*L*r0*(2*M_2 - 45*M*r0 + 39*r0_2) + (M - 9*r0)*r0*(L_2*(2*M - r0) - 2*E_2*r0_3) + a_2*(L_2*(-35*M + 43*r0) + E_2*r0*(2*M_2 - 71*M*r0 + 53*r0_2))))/expr2_4; A44040 = (192*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(a_6*E_2*M*(13*M + 6*r0) - 2*a_5*E*L*M*(13*M + 6*r0) - 2*a_3*E*L*M*r0*(6*L_2 - 8*M_2 + 13*M*r0 + 11*r0_2) + r0_2*(4*E_2*M*r0_5 + 2*L_4*M*(-2*M + r0) + L_2*r0_3*(-2*M + 4*E_2*M + r0)) + 2*a*E*L*M*r0_2*(L_2*(4*M - 6*r0) - r0_2*(2*M + 3*r0)) + a_4*M*(L_2*(13*M + 6*(1 + E_2)*r0) + 2*E_2*r0*(-4*M_2 + 11*M*r0 + 8*r0_2)) + a_2*M*r0*(6*L_4 + E_2*r0_3*(13*M + 14*r0) + L_2*(-8*M_2 - 4*(-1 + E_2)*M*r0 + 2*(3 + 5*E_2)*r0_2))))/(r0*expr2_4); A44220 = (48*r0_2*(E_2*M_2*expr3_2 + L_2*expr5_2 + 2*E*L*M*(a_3 + 3*a*r0_2)*(-(a_2*M) + r0_2*(-2*M + r0)) - 4*M*r0*(L_2 + r0_2 + (a_2*(2*M + r0))/r0)*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-2*M + 3*r0) + a_2*(-3*L_2 + E_2*(2*M - 5*r0)*r0) - r0*(2*E_2*r0_3 + L_2*(-2*M + r0)))))/expr2_4; A44400 = (-24*M*r0_5*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-2*M + 3*r0) + a_2*(-3*L_2 + E_2*(2*M - 5*r0)*r0) - r0*(2*E_2*r0_3 + L_2*(-2*M + r0))))/expr2_4; A45040 = (-32*(a_10*E_2*M*(69*M_2 + 53*M*r0 + 9*r0_2) - 2*a_9*E*L*M*((69 + 35*E_2)*M_2 + (53 + 18*E_2)*M*r0 + 9*r0_2) - 6*a*E*L*M*r0_4*(r0_5*(4*(-4 + 3*E_2)*M + 17*r0) + 3*L_2*r0_2*(-10*M_2 + (-1 + 4*E_2)*M*r0 + 9*r0_2) + L_4*(-22*M_2 + 5*M*r0 + 12*r0_2)) + r0_4*(-6*E_2*M*(M - 5*r0)*r0_7 + 3*L_6*M*(-10*M_2 + M*r0 + 2*r0_2) + L_2*r0_4*(14*M_3 + (-37 + 24*E_2)*M_2*r0 + (13 + 42*E_2)*M*r0_2 + r0_3) + L_4*r0_2*(-24*M_3 + 2*(-11 + 15*E_2)*M_2*r0 + (13 + 12*E_2)*M*r0_2 + 2*r0_3)) + a_8*M*(L_2*(3*(23 + 70*E_2)*M_2 + (53 + 161*E_2)*M*r0 + 9*(1 + 2*E_2)*r0_2) + E_2*r0*(-422*M_3 + 51*M_2*r0 + 333*M*r0_2 + 90*r0_3)) - 2*a_7*E*L*M*(L_2*(105*M_2 + (107 + 18*E_2)*M*r0 + 18*r0_2) + r0*(-2*(211 + 12*E_2)*M_3 + 3*(10 + 49*E_2)*M_2*r0 + (325 + 102*E_2)*M*r0_2 + 91*r0_3)) + 2*a_3*E*L*M*r0_2*(L_4*(36*M_2 - 87*M*r0 - 45*r0_2) + L_2*r0*(84*M_3 + 4*(97 + 9*E_2)*M_2*r0 - (233 + 102*E_2)*M*r0_2 - 225*r0_3) - r0_3*(84*M_3 + (-398 + 9*E_2)*M_2*r0 + 3*(31 + 46*E_2)*M*r0_2 + 197*r0_3)) + a_2*r0_2*(3*L_6*M*(-8*M_2 + M*r0 + 15*r0_2) + 3*E_2*M*r0_6*(-30*M_2 + 20*M*r0 + 51*r0_2) + L_4*r0*(-12*M_4 - 2*(100 + 87*E_2)*M_3*r0 + 3*(3 + 77*E_2)*M_2*r0_2 + 4*(37 + 12*E_2)*M*r0_3 - 10*r0_4) + L_2*r0_3*(100*M_4 - 2*(112 + 141*E_2)*M_3*r0 + 2*(-13 + 168*E_2)*M_2*r0_2 + (115 + 183*E_2)*M*r0_3 - 9*r0_4)) + 2*a_5*E*L*M*r0*(-9*L_4*(6*M + r0) + L_2*(72*M_3 + (95 + 12*E_2)*M_2*r0 - (361 + 84*E_2)*M*r0_2 - 136*r0_3) - r0*(96*M_4 - 2*(239 + 36*E_2)*M_3*r0 + (-437 + 129*E_2)*M_2*r0_2 + (457 + 186*E_2)*M*r0_3 + 228*r0_4)) + a_6*M*(L_4*(70*M_2 + (89 + 108*E_2)*M*r0 + 9*(2 + E_2)*r0_2) + L_2*r0*(-2*(211 + 72*E_2)*M_3 + (9 + 346*E_2)*M_2*r0 + (317 + 678*E_2)*M*r0_2 + (92 + 135*E_2)*r0_3) + E_2*r0_2*(96*M_4 - 756*M_3*r0 - 511*M_2*r0_2 + 535*M*r0_3 + 246*r0_4)) + a_4*r0*(9*L_6*M*(4*M + r0) + 3*E_2*M*r0_4*(-18*M_3 - 165*M_2*r0 + 107*M*r0_2 + 96*r0_3) + L_4*M*(-48*M_3 - 2*(121 + 36*E_2)*M_2*r0 + (248 + 339*E_2)*M*r0_2 + (137 + 45*E_2)*r0_3) + L_2*r0*(96*M_5 - 100*(2 + 3*E_2)*M_4*r0 - 6*(70 + 53*E_2)*M_3*r0_2 + 9*(33 + 85*E_2)*M_2*r0_3 + (163 + 258*E_2)*M*r0_4 - 10*r0_5))))/(r0_2*expr2_5); A45220 = (-8*r0*(9*a_8*E_2*M*(4*M + r0) - 18*a_7*E*L*M*(2*(2 + E_2)*M + r0) + 2*a_5*E*L*M*(-9*L_2*(6*M + r0) + r0*(4*(82 + 3*E_2)*M_2 - (199 + 84*E_2)*M*r0 - 144*r0_2)) - 6*a*E*L*M*r0_3*(L_2*(-20*M_2 - 20*M*r0 + 33*r0_2) + r0_2*(2*M_2 + (-41 + 12*E_2)*M*r0 + 38*r0_2)) + a_6*M*(9*L_2*(4*M + 12*E_2*M + r0 + E_2*r0) + E_2*r0*(-328*M_2 + 199*M*r0 + 138*r0_2)) + r0_3*(-12*E_2*M*(M - 5*r0)*r0_5 - 3*L_4*M*(8*M_2 + 10*M*r0 - 7*r0_2) + L_2*r0_2*(20*M_3 + 2*(-35 + 12*E_2)*M_2*r0 + 14*(2 + 3*E_2)*M*r0_2 + r0_3)) + a_4*M*(9*L_4*(4*M + r0) + L_2*r0*(-8*(41 + 9*E_2)*M_2 + (199 + 282*E_2)*M*r0 + 6*(25 + 17*E_2)*r0_2) + 3*E_2*r0_2*(20*M_3 - 216*M_2*r0 + 26*M*r0_2 + 103*r0_3)) + 2*a_3*E*L*M*r0*(6*L_2*(6*M_2 - 5*M*r0 - 18*r0_2) - r0*(60*M_3 - 2*(211 + 18*E_2)*M_2*r0 + 6*(6 + 17*E_2)*M*r0_2 + 269*r0_3)) - a_2*r0*(3*E_2*M*r0_4*(28*M_2 + 19*M*r0 - 80*r0_2) + 6*L_4*M*(4*M_2 + 9*M*r0 - 19*r0_2) + L_2*r0*(-60*M_4 + 28*(7 + 6*E_2)*M_3*r0 + 3*(27 - 38*E_2)*M_2*r0_2 - (181 + 135*E_2)*M*r0_3 + 9*r0_4))))/expr2_5; A45400 = (-6*M*r0_5*(2*a_3*E*L*(19*M - 21*r0) - 19*a_4*E_2*(M - r0) - 2*a*E*L*r0*(2*M_2 - 25*M*r0 + 21*r0_2) + (M - 5*r0)*r0*(L_2*(2*M - r0) - 2*E_2*r0_3) + a_2*(L_2*(-19*M + 23*r0) + E_2*r0*(2*M_2 - 39*M*r0 + 29*r0_2))))/expr2_5; A46020 = (16*r0_2*(E_2*M_2*expr3_2 + L_2*expr5_2 + 2*E*L*M*(a_3 + 3*a*r0_2)*(-(a_2*M) + r0_2*(-2*M + r0)) - 4*M*r0*(L_2 + r0_2 + (a_2*(2*M + r0))/r0)*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-2*M + 3*r0) + a_2*(-3*L_2 + E_2*(2*M - 5*r0)*r0) - r0*(2*E_2*r0_3 + L_2*(-2*M + r0)))))/expr2_5; A46200 = (-16*M*r0_5*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-2*M + 3*r0) + a_2*(-3*L_2 + E_2*(2*M - 5*r0)*r0) - r0*(2*E_2*r0_3 + L_2*(-2*M + r0))))/expr2_5; A47020 = (-8*r0*(3*a_8*E_2*M*(4*M + r0) - 6*a_7*E*L*M*(2*(2 + E_2)*M + r0) + 2*a_5*E*L*M*(-3*L_2*(6*M + r0) + r0*((115 + 4*E_2)*M_2 - (69 + 28*E_2)*M*r0 - 51*r0_2)) - 2*a*E*L*M*r0_3*(L_2*(-18*M_2 - 25*M*r0 + 36*r0_2) + r0_2*(6*M_2 + (-49 + 12*E_2)*M*r0 + 42*r0_2)) + a_6*M*(3*L_2*(4*M + 12*E_2*M + r0 + E_2*r0) + E_2*r0*(-115*M_2 + 69*M*r0 + 49*r0_2)) + M*r0_3*(2*E_2*r0_5*(-3*M + 11*r0) + L_4*(-6*M_2 - 13*M*r0 + 8*r0_2) + L_2*r0_2*(10*M_2 + (-29 + 6*E_2)*M*r0 + 4*(3 + 4*E_2)*r0_2)) + 2*a_3*E*L*M*r0*(L_2*(12*M_2 - 7*M*r0 - 39*r0_2) - r0*(24*M_3 - 3*(49 + 4*E_2)*M_2*r0 + 2*(4 + 17*E_2)*M*r0_2 + 96*r0_3)) + a_4*M*(3*L_4*(4*M + r0) + L_2*r0*(-((115 + 24*E_2)*M_2) + (69 + 91*E_2)*M*r0 + (53 + 37*E_2)*r0_2) + E_2*r0_2*(24*M_3 - 226*M_2*r0 + 24*M*r0_2 + 111*r0_3)) - a_2*r0*(L_4*M*(8*M_2 + 21*M*r0 - 41*r0_2) + 3*E_2*M*r0_4*(9*M_2 + 9*M*r0 - 29*r0_2) + L_2*r0*(-24*M_4 + 2*(34 + 27*E_2)*M_3*r0 + (33 - 31*E_2)*M_2*r0_2 - 5*(13 + 10*E_2)*M*r0_3 + 3*r0_4))))/expr2_6; A47200 = (-2*M*r0_5*(2*a_3*E*L*(41*M - 45*r0) - 41*a_4*E_2*(M - r0) - 2*a*E*L*r0*(6*M_2 - 55*M*r0 + 45*r0_2) + (3*M - 11*r0)*r0*(L_2*(2*M - r0) - 2*E_2*r0_3) + a_2*(L_2*(-41*M + 49*r0) + E_2*r0*(6*M_2 - 85*M*r0 + 63*r0_2))))/expr2_6; A48000 = (-4*M*r0_5*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-2*M + 3*r0) + a_2*(-3*L_2 + E_2*(2*M - 5*r0)*r0) - r0*(2*E_2*r0_3 + L_2*(-2*M + r0))))/expr2_6; A49000 = (-2*M*r0_5*(2*a_3*E*L*(11*M - 12*r0) - 11*a_4*E_2*(M - r0) - 2*a*E*L*r0*(2*M_2 - 15*M*r0 + 12*r0_2) + (M - 3*r0)*r0*(L_2*(2*M - r0) - 2*E_2*r0_3) + a_2*(L_2*(-11*M + 13*r0) + E_2*r0*(2*M_2 - 23*M*r0 + 17*r0_2))))/expr2_7; } /* A_{r,theta} */ { A50180 = (-512*expr1_3*(-(a_8*E_2*M*(7*M + 3*r0)) + a_7*E*L*M*((14 + 3*E_2)*M + 6*r0) + a*E*L*M*r0_3*(3*r0_3*((-4 + E_2)*M + 2*r0) + L_2*(-52*M_2 + 44*M*r0 - 9*r0_2)) + (2*M - r0)*r0_3*(5*L_4*M*(2*M - r0) - 3*E_2*M*r0_5 + L_2*r0_2*(2*M_2 + (3 - 4*E_2)*M*r0 - 2*r0_2)) - a_6*M*(L_2*((7 + 9*E_2)*M + 3*(1 + E_2)*r0) + E_2*r0*(-2*M_2 + 7*M*r0 + 6*r0_2)) + a_5*E*L*M*(L_2*(9*M + 6*r0) + r0*(-4*(1 + E_2)*M_2 + (8 + 13*E_2)*M*r0 + 10*r0_2)) + a_3*E*L*M*r0*(L_2*(-12*M_2 + 29*M*r0 - 3*r0_2) + r0*(-48*M_3 - 12*(-1 + E_2)*M_2*r0 + (-2 + 13*E_2)*M*r0_2 + 10*r0_3)) + a_2*r0*(3*E_2*M*r0_4*(-6*M_2 + M*r0 + 2*r0_2) + L_4*M*(4*M_2 - 8*M*r0 + 3*r0_2) + L_2*r0*(24*M_4 + 4*(-3 + 11*E_2)*M_3*r0 - 37*E_2*M_2*r0_2 + (-4 + 7*E_2)*M*r0_3 + 2*r0_4)) - a_4*M*(3*L_4*(M + r0) - 3*E_2*M*r0_2*(8*M_2 + 3*r0_2) + L_2*r0*(-2*(1 + 6*E_2)*M_2 + 4*r0_2 + M*(r0 + 34*E_2*r0)))))/(r0_8*expr2_2); A50360 = (384*expr1_2*(a_8*E_2*M*(9*M + 4*r0) - a_7*E*L*M*(3*(6 + E_2)*M + 8*r0) + a_5*E*L*M*(-(L_2*(9*M + 8*r0)) + r0*(4*(1 + E_2)*M_2 - (10 + 13*E_2)*M*r0 - 13*r0_2)) - (2*M - r0)*r0_3*(6*L_4*M*(2*M - r0) - 4*E_2*M*r0_5 + L_2*r0_2*(4*M_2 + (2 - 5*E_2)*M*r0 - 2*r0_2)) + a*E*L*M*r0_3*(r0_2*(8*M_2 - 3*(-2 + E_2)*M*r0 - 5*r0_2) + 10*L_2*(6*M_2 - 5*M*r0 + r0_2)) + a_6*M*((1 + E_2)*L_2*(9*M + 4*r0) + E_2*r0*(-2*M_2 + 9*M*r0 + 8*r0_2)) + a_3*E*L*M*r0*(L_2*(12*M_2 - 29*M*r0 + 2*r0_2) - r0*(-64*M_3 - 4*(-4 + 3*E_2)*M_2*r0 + (2 + 13*E_2)*M*r0_2 + 10*r0_3)) - a_2*r0*(L_4*M*(4*M_2 - 8*M*r0 + 3*r0_2) + E_2*M*r0_4*(-18*M_2 + M*r0 + 8*r0_2) + L_2*r0*(32*M_4 + 16*(-1 + 3*E_2)*M_3*r0 - (2 + 39*E_2)*M_2*r0_2 + (-3 + 8*E_2)*M*r0_3 + 2*r0_4)) + a_4*M*(L_4*(3*M + 4*r0) - E_2*M*r0_2*(32*M_2 + 9*r0_2) + L_2*r0*(-2*(1 + 6*E_2)*M_2 + (5 + E_2)*r0_2 + M*(r0 + 34*E_2*r0)))))/(r0_5*expr2_2); A50540 = (96*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(a_8*E_2*M*(13*M + 6*r0) - a_7*E*L*M*((26 + 3*E_2)*M + 12*r0) + a_5*E*L*M*(-3*L_2*(3*M + 4*r0) + r0*(4*(1 + E_2)*M_2 - (14 + 13*E_2)*M*r0 - 19*r0_2)) - (2*M - r0)*r0_3*(8*L_4*M*(2*M - r0) - 6*E_2*M*r0_5 + L_2*r0_2*(8*M_2 - 7*E_2*M*r0 - 2*r0_2)) + a*E*L*M*r0_3*(-3*r0_2*(-8*M_2 + (2 + E_2)*M*r0 + r0_2) + 2*L_2*(38*M_2 - 31*M*r0 + 6*r0_2)) + a_6*M*(L_2*((13 + 9*E_2)*M + 6*(1 + E_2)*r0) + E_2*r0*(-2*M_2 + 13*M*r0 + 12*r0_2)) + a_3*E*L*M*r0*(L_2*M*(12*M - 29*r0) - r0*(-96*M_3 - 12*(-2 + E_2)*M_2*r0 + (10 + 13*E_2)*M*r0_2 + 10*r0_3)) + a_2*r0*(3*E_2*M*r0_4*(6*M_2 + M*r0 - 4*r0_2) + L_4*M*(-4*M_2 + 8*M*r0 - 3*r0_2) + L_2*r0*(-48*M_4 - 8*(-3 + 7*E_2)*M_3*r0 + (6 + 43*E_2)*M_2*r0_2 + (1 - 10*E_2)*M*r0_3 - 2*r0_4)) + a_4*M*(3*L_4*(M + 2*r0) - 3*E_2*M*r0_2*(16*M_2 + 3*r0_2) + L_2*r0*(-2*(1 + 6*E_2)*M_2 + (7 + 3*E_2)*r0_2 + M*(r0 + 34*E_2*r0)))))/(r0_2*expr2_2); A50720 = (-8*r0*(-(a_8*E_2*M*(25*M + 12*r0)) + a_7*E*L*M*((50 + 3*E_2)*M + 24*r0) + (2*M - r0)*r0_3*(14*L_4*M*(2*M - r0) - 12*E_2*M*r0_5 - L_2*r0_2*(-20*M_2 + (6 + 13*E_2)*M*r0 + 2*r0_2)) + a*E*L*M*r0_3*(-3*r0_2*(24*M_2 - (14 + E_2)*M*r0 + r0_2) - 2*L_2*(62*M_2 - 49*M*r0 + 9*r0_2)) - a_6*M*(L_2*((25 + 9*E_2)*M + 12*(1 + E_2)*r0) + E_2*r0*(-2*M_2 + 25*M*r0 + 24*r0_2)) + a_5*E*L*M*(3*L_2*(3*M + 8*r0) + r0*(-4*(1 + E_2)*M_2 + 13*(2 + E_2)*M*r0 + 37*r0_2)) + a_3*E*L*M*r0*(L_2*(-12*M_2 + 29*M*r0 + 6*r0_2) + r0*(-192*M_3 - 12*(-4 + E_2)*M_2*r0 + (34 + 13*E_2)*M*r0_2 + 10*r0_3)) + a_2*r0*(-3*E_2*M*r0_4*(6*M_2 + 5*M*r0 - 8*r0_2) + L_4*M*(4*M_2 - 8*M*r0 + 3*r0_2) + L_2*r0*(96*M_4 + 16*(-3 + 5*E_2)*M_3*r0 - (18 + 55*E_2)*M_2*r0_2 + (5 + 16*E_2)*M*r0_3 + 2*r0_4)) - a_4*M*(3*L_4*(M + 4*r0) - 3*E_2*M*r0_2*(32*M_2 + 3*r0_2) + L_2*r0*(-2*(1 + 6*E_2)*M_2 + (13 + 9*E_2)*r0_2 + M*(r0 + 34*E_2*r0)))))/expr2_2; A50900 = (6*M*r0_4*(a_4*E_2 - 2*a_3*E*L + a*E*L*r0*(-4*M + r0) + a_2*(L_2 + 2*E_2*M*r0) - r0*(E_2*r0_3 + L_2*(-2*M + r0))))/(a_2 + r0*(-2*M + r0)); A52160 = (384*expr1_2*(a_8*E_2*M*(9*M + 4*r0) - a_7*E*L*M*(3*(6 + E_2)*M + 8*r0) + a_5*E*L*M*(-(L_2*(9*M + 8*r0)) + r0*(4*(1 + E_2)*M_2 - (10 + 13*E_2)*M*r0 - 13*r0_2)) - (2*M - r0)*r0_3*(6*L_4*M*(2*M - r0) - 4*E_2*M*r0_5 + L_2*r0_2*(4*M_2 + (2 - 5*E_2)*M*r0 - 2*r0_2)) + a*E*L*M*r0_3*(r0_2*(8*M_2 - 3*(-2 + E_2)*M*r0 - 5*r0_2) + 10*L_2*(6*M_2 - 5*M*r0 + r0_2)) + a_6*M*((1 + E_2)*L_2*(9*M + 4*r0) + E_2*r0*(-2*M_2 + 9*M*r0 + 8*r0_2)) + a_3*E*L*M*r0*(L_2*(12*M_2 - 29*M*r0 + 2*r0_2) - r0*(-64*M_3 - 4*(-4 + 3*E_2)*M_2*r0 + (2 + 13*E_2)*M*r0_2 + 10*r0_3)) - a_2*r0*(L_4*M*(4*M_2 - 8*M*r0 + 3*r0_2) + E_2*M*r0_4*(-18*M_2 + M*r0 + 8*r0_2) + L_2*r0*(32*M_4 + 16*(-1 + 3*E_2)*M_3*r0 - (2 + 39*E_2)*M_2*r0_2 + (-3 + 8*E_2)*M*r0_3 + 2*r0_4)) + a_4*M*(L_4*(3*M + 4*r0) - E_2*M*r0_2*(32*M_2 + 9*r0_2) + L_2*r0*(-2*(1 + 6*E_2)*M_2 + (5 + E_2)*r0_2 + M*(r0 + 34*E_2*r0)))))/(r0_5*expr2_3); A52340 = (192*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(a_8*E_2*M*(13*M + 6*r0) - a_7*E*L*M*((26 + 3*E_2)*M + 12*r0) + a_5*E*L*M*(-3*L_2*(3*M + 4*r0) + r0*(4*(1 + E_2)*M_2 - (14 + 13*E_2)*M*r0 - 19*r0_2)) - (2*M - r0)*r0_3*(8*L_4*M*(2*M - r0) - 6*E_2*M*r0_5 + L_2*r0_2*(8*M_2 - 7*E_2*M*r0 - 2*r0_2)) + a*E*L*M*r0_3*(-3*r0_2*(-8*M_2 + (2 + E_2)*M*r0 + r0_2) + 2*L_2*(38*M_2 - 31*M*r0 + 6*r0_2)) + a_6*M*(L_2*((13 + 9*E_2)*M + 6*(1 + E_2)*r0) + E_2*r0*(-2*M_2 + 13*M*r0 + 12*r0_2)) + a_3*E*L*M*r0*(L_2*M*(12*M - 29*r0) - r0*(-96*M_3 - 12*(-2 + E_2)*M_2*r0 + (10 + 13*E_2)*M*r0_2 + 10*r0_3)) + a_2*r0*(3*E_2*M*r0_4*(6*M_2 + M*r0 - 4*r0_2) + L_4*M*(-4*M_2 + 8*M*r0 - 3*r0_2) + L_2*r0*(-48*M_4 - 8*(-3 + 7*E_2)*M_3*r0 + (6 + 43*E_2)*M_2*r0_2 + (1 - 10*E_2)*M*r0_3 - 2*r0_4)) + a_4*M*(3*L_4*(M + 2*r0) - 3*E_2*M*r0_2*(16*M_2 + 3*r0_2) + L_2*r0*(-2*(1 + 6*E_2)*M_2 + (7 + 3*E_2)*r0_2 + M*(r0 + 34*E_2*r0)))))/(r0_2*expr2_3); A52520 = (-24*r0*(-(a_8*E_2*M*(25*M + 12*r0)) + a_7*E*L*M*((50 + 3*E_2)*M + 24*r0) + (2*M - r0)*r0_3*(14*L_4*M*(2*M - r0) - 12*E_2*M*r0_5 - L_2*r0_2*(-20*M_2 + (6 + 13*E_2)*M*r0 + 2*r0_2)) + a*E*L*M*r0_3*(-3*r0_2*(24*M_2 - (14 + E_2)*M*r0 + r0_2) - 2*L_2*(62*M_2 - 49*M*r0 + 9*r0_2)) - a_6*M*(L_2*((25 + 9*E_2)*M + 12*(1 + E_2)*r0) + E_2*r0*(-2*M_2 + 25*M*r0 + 24*r0_2)) + a_5*E*L*M*(3*L_2*(3*M + 8*r0) + r0*(-4*(1 + E_2)*M_2 + 13*(2 + E_2)*M*r0 + 37*r0_2)) + a_3*E*L*M*r0*(L_2*(-12*M_2 + 29*M*r0 + 6*r0_2) + r0*(-192*M_3 - 12*(-4 + E_2)*M_2*r0 + (34 + 13*E_2)*M*r0_2 + 10*r0_3)) + a_2*r0*(-3*E_2*M*r0_4*(6*M_2 + 5*M*r0 - 8*r0_2) + L_4*M*(4*M_2 - 8*M*r0 + 3*r0_2) + L_2*r0*(96*M_4 + 16*(-3 + 5*E_2)*M_3*r0 - (18 + 55*E_2)*M_2*r0_2 + (5 + 16*E_2)*M*r0_3 + 2*r0_4)) - a_4*M*(3*L_4*(M + 4*r0) - 3*E_2*M*r0_2*(32*M_2 + 3*r0_2) + L_2*r0*(-2*(1 + 6*E_2)*M_2 + (13 + 9*E_2)*r0_2 + M*(r0 + 34*E_2*r0)))))/expr2_3; A52700 = (24*M*r0_4*(a_4*E_2 - 2*a_3*E*L + a*E*L*r0*(-4*M + r0) + a_2*(L_2 + 2*E_2*M*r0) - r0*(E_2*r0_3 + L_2*(-2*M + r0))))/expr2_2; A54140 = (96*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(a_8*E_2*M*(13*M + 6*r0) - a_7*E*L*M*((26 + 3*E_2)*M + 12*r0) + a_5*E*L*M*(-3*L_2*(3*M + 4*r0) + r0*(4*(1 + E_2)*M_2 - (14 + 13*E_2)*M*r0 - 19*r0_2)) - (2*M - r0)*r0_3*(8*L_4*M*(2*M - r0) - 6*E_2*M*r0_5 + L_2*r0_2*(8*M_2 - 7*E_2*M*r0 - 2*r0_2)) + a*E*L*M*r0_3*(-3*r0_2*(-8*M_2 + (2 + E_2)*M*r0 + r0_2) + 2*L_2*(38*M_2 - 31*M*r0 + 6*r0_2)) + a_6*M*(L_2*((13 + 9*E_2)*M + 6*(1 + E_2)*r0) + E_2*r0*(-2*M_2 + 13*M*r0 + 12*r0_2)) + a_3*E*L*M*r0*(L_2*M*(12*M - 29*r0) - r0*(-96*M_3 - 12*(-2 + E_2)*M_2*r0 + (10 + 13*E_2)*M*r0_2 + 10*r0_3)) + a_2*r0*(3*E_2*M*r0_4*(6*M_2 + M*r0 - 4*r0_2) + L_4*M*(-4*M_2 + 8*M*r0 - 3*r0_2) + L_2*r0*(-48*M_4 - 8*(-3 + 7*E_2)*M_3*r0 + (6 + 43*E_2)*M_2*r0_2 + (1 - 10*E_2)*M*r0_3 - 2*r0_4)) + a_4*M*(3*L_4*(M + 2*r0) - 3*E_2*M*r0_2*(16*M_2 + 3*r0_2) + L_2*r0*(-2*(1 + 6*E_2)*M_2 + (7 + 3*E_2)*r0_2 + M*(r0 + 34*E_2*r0)))))/(r0_2*expr2_4); A54320 = (-24*r0*(-(a_8*E_2*M*(25*M + 12*r0)) + a_7*E*L*M*((50 + 3*E_2)*M + 24*r0) + (2*M - r0)*r0_3*(14*L_4*M*(2*M - r0) - 12*E_2*M*r0_5 - L_2*r0_2*(-20*M_2 + (6 + 13*E_2)*M*r0 + 2*r0_2)) + a*E*L*M*r0_3*(-3*r0_2*(24*M_2 - (14 + E_2)*M*r0 + r0_2) - 2*L_2*(62*M_2 - 49*M*r0 + 9*r0_2)) - a_6*M*(L_2*((25 + 9*E_2)*M + 12*(1 + E_2)*r0) + E_2*r0*(-2*M_2 + 25*M*r0 + 24*r0_2)) + a_5*E*L*M*(3*L_2*(3*M + 8*r0) + r0*(-4*(1 + E_2)*M_2 + 13*(2 + E_2)*M*r0 + 37*r0_2)) + a_3*E*L*M*r0*(L_2*(-12*M_2 + 29*M*r0 + 6*r0_2) + r0*(-192*M_3 - 12*(-4 + E_2)*M_2*r0 + (34 + 13*E_2)*M*r0_2 + 10*r0_3)) + a_2*r0*(-3*E_2*M*r0_4*(6*M_2 + 5*M*r0 - 8*r0_2) + L_4*M*(4*M_2 - 8*M*r0 + 3*r0_2) + L_2*r0*(96*M_4 + 16*(-3 + 5*E_2)*M_3*r0 - (18 + 55*E_2)*M_2*r0_2 + (5 + 16*E_2)*M*r0_3 + 2*r0_4)) - a_4*M*(3*L_4*(M + 4*r0) - 3*E_2*M*r0_2*(32*M_2 + 3*r0_2) + L_2*r0*(-2*(1 + 6*E_2)*M_2 + (13 + 9*E_2)*r0_2 + M*(r0 + 34*E_2*r0)))))/expr2_4; A54500 = (36*M*r0_4*(a_4*E_2 - 2*a_3*E*L + a*E*L*r0*(-4*M + r0) + a_2*(L_2 + 2*E_2*M*r0) - r0*(E_2*r0_3 + L_2*(-2*M + r0))))/expr2_3; A56120 = (-8*r0*(-(a_8*E_2*M*(25*M + 12*r0)) + a_7*E*L*M*((50 + 3*E_2)*M + 24*r0) + (2*M - r0)*r0_3*(14*L_4*M*(2*M - r0) - 12*E_2*M*r0_5 - L_2*r0_2*(-20*M_2 + (6 + 13*E_2)*M*r0 + 2*r0_2)) + a*E*L*M*r0_3*(-3*r0_2*(24*M_2 - (14 + E_2)*M*r0 + r0_2) - 2*L_2*(62*M_2 - 49*M*r0 + 9*r0_2)) - a_6*M*(L_2*((25 + 9*E_2)*M + 12*(1 + E_2)*r0) + E_2*r0*(-2*M_2 + 25*M*r0 + 24*r0_2)) + a_5*E*L*M*(3*L_2*(3*M + 8*r0) + r0*(-4*(1 + E_2)*M_2 + 13*(2 + E_2)*M*r0 + 37*r0_2)) + a_3*E*L*M*r0*(L_2*(-12*M_2 + 29*M*r0 + 6*r0_2) + r0*(-192*M_3 - 12*(-4 + E_2)*M_2*r0 + (34 + 13*E_2)*M*r0_2 + 10*r0_3)) + a_2*r0*(-3*E_2*M*r0_4*(6*M_2 + 5*M*r0 - 8*r0_2) + L_4*M*(4*M_2 - 8*M*r0 + 3*r0_2) + L_2*r0*(96*M_4 + 16*(-3 + 5*E_2)*M_3*r0 - (18 + 55*E_2)*M_2*r0_2 + (5 + 16*E_2)*M*r0_3 + 2*r0_4)) - a_4*M*(3*L_4*(M + 4*r0) - 3*E_2*M*r0_2*(32*M_2 + 3*r0_2) + L_2*r0*(-2*(1 + 6*E_2)*M_2 + (13 + 9*E_2)*r0_2 + M*(r0 + 34*E_2*r0)))))/expr2_5; A56300 = (24*M*r0_4*(a_4*E_2 - 2*a_3*E*L + a*E*L*r0*(-4*M + r0) + a_2*(L_2 + 2*E_2*M*r0) - r0*(E_2*r0_3 + L_2*(-2*M + r0))))/expr2_4; A58100 = (6*M*r0_4*(a_4*E_2 - 2*a_3*E*L + a*E*L*r0*(-4*M + r0) + a_2*(L_2 + 2*E_2*M*r0) - r0*(E_2*r0_3 + L_2*(-2*M + r0))))/expr2_5; } /* A_{r,phi} */ { A60061 = (256*L*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0))*expr1_3)/(r0_5*(a_2 + r0*(-2*M + r0))); A60081 = (128*expr1_2*(12*a_12*E_2*M_2*(26*M_2 + 25*M*r0 + 6*r0_2) - a_11*E*L*M_2*(624*M_2 + 611*M*r0 + 150*r0_2) - a_9*E*L*M*r0*(32*(-39 + 28*E_2)*M_4 + 4*(215 + 336*E_2)*M_3*r0 + (1739 + 672*E_2)*M_2*r0_2 + 2*(135 + 56*E_2)*M*r0_3 - 114*r0_4 + 2*L_2*M*(332*M + 165*r0)) - a*E*L*M*r0_5*(L_2*r0_4*(-112*M_2 + 2*(271 + 126*E_2)*M*r0 - 243*r0_2) + 12*L_4*r0_2*(14*M_2 + (33 + 10*E_2)*M*r0 - 20*r0_2) + 6*r0_6*(2*M_2 + (13 + 24*E_2)*M*r0 - 7*r0_2) + 60*L_6*(4*M_2 - r0_2)) - 2*a_3*E*L*M*r0_3*(30*L_6*(12*M_2 - 2*M*r0 - r0_2) + L_2*r0_3*(-8*M_3 + 42*(11 + 12*E_2)*M_2*r0 + 2*(293 + 183*E_2)*M*r0_2 - 407*r0_3) + r0_5*(-372*M_3 + 18*(13 + 24*E_2)*M_2*r0 + (219 + 272*E_2)*M*r0_2 - 144*r0_3) + 6*L_4*r0*(96*M_3 + 2*(41 + 10*E_2)*M_2*r0 + (31 + 20*E_2)*M*r0_2 - 40*r0_3)) - a_5*E*L*M*r0_2*(12*L_4*(228*M_3 + 4*(12 + 5*E_2)*M_2*r0 + (13 + 10*E_2)*M*r0_2 - 20*r0_3) + L_2*r0*(1568*M_4 + 16*(52 + 63*E_2)*M_3*r0 + 48*(41 + 40*E_2)*M_2*r0_2 + 6*(135 + 118*E_2)*M*r0_3 - 865*r0_4) + 3*r0_3*(-548*M_4 + 4*(-131 + 144*E_2)*M_3*r0 + 5*(127 + 160*E_2)*M_2*r0_2 + 4*(35 + 64*E_2)*M*r0_3 - 188*r0_4)) - a_7*E*L*M*r0*(180*L_4*M*r0 + 2*L_2*(1344*M_4 + 24*(20 + 19*E_2)*M_3*r0 + 114*(7 + 4*E_2)*M_2*r0_2 + (289 + 114*E_2)*M*r0_3 - 147*r0_4) + 3*r0_2*(12*(-81 + 32*E_2)*M_4 + 64*(-3 + 16*E_2)*M_3*r0 + (795 + 736*E_2)*M_2*r0_2 + 20*(3 + 8*E_2)*M*r0_3 - 144*r0_4)) + a_10*M*(L_2*M*(312*M_2 + (311 + 332*E_2)*M*r0 + 6*(13 + 27*E_2)*r0_2) + 12*E_2*r0*(-52*M_4 + 60*M_3*r0 + 102*M_2*r0_2 + 23*M*r0_3 - 3*r0_4)) + a_2*r0_3*(120*L_8*M_2*(2*M - r0) + 36*E_2*M*r0_8*(6*M_2 + 5*M*r0 - 5*r0_2) + 6*L_6*M*r0*(12*M_3 + 8*(3 + 10*E_2)*M_2*r0 + 5*(5 + 8*E_2)*M*r0_2 - 20*(1 + E_2)*r0_3) + L_4*r0_3*(-368*M_4 + 24*(3 + 49*E_2)*M_3*r0 + 2*(251 + 402*E_2)*M_2*r0_2 - (205 + 486*E_2)*M*r0_3 - 9*r0_4) - 2*L_2*r0_5*(100*M_4 + 6*(1 - 82*E_2)*M_3*r0 - 2*(41 + 196*E_2)*M_2*r0_2 + 3*(1 + 95*E_2)*M*r0_3 + 12*r0_4)) + a_8*M*r0*(2*L_4*M*(166*M + 84*r0 + 45*E_2*r0) - 12*E_2*r0_2*(168*M_4 + 28*M_3*r0 - 154*M_2*r0_2 - 34*M*r0_3 + 15*r0_4) + L_2*(48*(-13 + 56*E_2)*M_4 + 4*(35 + 624*E_2)*M_3*r0 + 4*(127 + 498*E_2)*M_2*r0_2 + (-9 + 578*E_2)*M*r0_3 - 6*(13 + 21*E_2)*r0_4)) + a_6*M*r0*(90*L_6*M*r0 - 24*E_2*r0_4*(66*M_4 + 66*M_3*r0 - 52*M_2*r0_2 - 13*M*r0_3 + 15*r0_4) + 2*L_4*(448*M_4 + 24*(-4 + 57*E_2)*M_3*r0 + 138*(1 + 6*E_2)*M_2*r0_2 + 6*(9 + 32*E_2)*M*r0_3 - 3*(28 + 25*E_2)*r0_4) + L_2*r0_2*(4*(-225 + 628*E_2)*M_4 + 4*(3 + 998*E_2)*M_3*r0 + (863 + 3612*E_2)*M_2*r0_2 + 6*(-10 + 149*E_2)*M*r0_3 - 2*(109 + 263*E_2)*r0_4)) + a_4*r0_2*(-36*E_2*M*r0_6*(18*M_3 - 15*M_2*r0 - 6*M*r0_2 + 10*r0_3) + 6*L_6*M*(152*M_3 + 4*(-7 + 30*E_2)*M_2*r0 + 20*E_2*M*r0_2 - 5*(3 + 2*E_2)*r0_3) + L_4*M*r0*(208*M_4 + 8*(-11 + 261*E_2)*M_3*r0 + 8*(73 + 345*E_2)*M_2*r0_2 + 2*(166 + 381*E_2)*M*r0_3 - (359 + 468*E_2)*r0_4) + L_2*r0_3*(-536*M_5 + 4*(-101 + 402*E_2)*M_4*r0 + 2*(347 + 1436*E_2)*M_3*r0_2 + 69*(3 + 14*E_2)*M_2*r0_3 - 6*(33 + 137*E_2)*M*r0_4 - 12*r0_5)) + (2*M - r0)*r0_7*(36*E_2*M*r0_7 + 30*L_6*M*(-2*M + r0 + 2*E_2*r0) + 4*L_2*r0_4*(2*M_2 + (-7 + 37*E_2)*M*r0 + 3*r0_2) + L_4*r0_2*(-64*M_2 + 9*r0_2 + 14*M*(r0 + 12*E_2*r0)))))/(3.*r0_11*expr2_2); A60241 = (192*L*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0))*expr1_2)/(r0_2*(a_2 + r0*(-2*M + r0))); A60261 = (-64*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-6*a_12*E_2*M_2*(110*M_2 + 107*M*r0 + 26*r0_2) + a_11*E*L*M*(24*(55 + E_2)*M_3 + (1307 + 24*E_2)*M_2*r0 + 6*(55 + E_2)*M*r0_2 + 3*r0_3) + a*E*L*M*r0_5*(L_4*r0_2*(80*M_2 + 2*(469 + 114*E_2)*M*r0 - 489*r0_2) + L_2*r0_4*(-476*M_2 + 2*(596 + 243*E_2)*M*r0 - 477*r0_2) + 3*r0_6*(-40*M_2 + 2*(41 + 45*E_2)*M*r0 - 31*r0_2) + 6*L_6*(64*M_2 + 10*M*r0 - 21*r0_2)) + (2*M - r0)*r0_5*(9*L_8*M*(2*M - r0) - 72*E_2*M*r0_9 + L_2*r0_6*(8*M_2 + 10*(5 - 29*E_2)*M*r0 - 27*r0_2) - 2*L_6*r0_2*(-80*M_2 + 2*(17 + 30*E_2)*M*r0 + 3*r0_2) - L_4*r0_4*(-162*M_2 + (21 + 334*E_2)*M*r0 + 30*r0_2)) + a_3*E*L*M*r0_3*(12*L_6*(114*M_2 - 17*M*r0 - 10*r0_2) + L_4*r0*(1768*M_3 + 24*(82 + 19*E_2)*M_2*r0 + 4*(241 + 114*E_2)*M*r0_2 - 975*r0_3) + r0_5*(-1668*M_3 + 2*(257 + 792*E_2)*M_2*r0 + 2*(596 + 523*E_2)*M*r0_2 - 579*r0_3) - 2*L_2*r0_3*(406*M_3 - (785 + 954*E_2)*M_2*r0 - 2*(681 + 358*E_2)*M*r0_2 + 803*r0_3)) + a_5*E*L*M*r0_2*(6*L_6*r0 + L_4*(5232*M_3 + 4*(319 + 114*E_2)*M_2*r0 + 2*(199 + 114*E_2)*M*r0_2 - 471*r0_3) + L_2*r0*(2224*M_4 + 4*(223 + 468*E_2)*M_3*r0 + 4*(1077 + 925*E_2)*M_2*r0_2 + 4*(506 + 353*E_2)*M*r0_3 - 1711*r0_4) + r0_3*(-2964*M_4 + 8*(-520 + 387*E_2)*M_3*r0 + 21*(175 + 216*E_2)*M_2*r0_2 + 6*(231 + 254*E_2)*M*r0_3 - 1104*r0_4)) + a_7*E*L*M*r0*(3*L_4*(12*M_2 + 132*M*r0 + 5*r0_2) + r0_2*(4*(-1535 + 504*E_2)*M_4 + 4*(-445 + 1434*E_2)*M_3*r0 + 3*(1753 + 1448*E_2)*M_2*r0_2 + 6*(133 + 166*E_2)*M*r0_3 - 840*r0_4) + 2*L_2*(2544*M_4 + 8*(119 + 109*E_2)*M_3*r0 + (1775 + 902*E_2)*M_2*r0_2 + (667 + 236*E_2)*M*r0_3 - 285*r0_4)) + a_9*E*L*M*(2*L_2*(36*M_3 + 2*(364 + 3*E_2)*M_2*r0 + 3*(121 + E_2)*M*r0_2 + 6*r0_3) + r0*(16*(-165 + 106*E_2)*M_4 + 888*(2 + 3*E_2)*M_3*r0 + 3*(1271 + 472*E_2)*M_2*r0_2 + 2*(344 + 127*E_2)*M*r0_3 - 219*r0_4)) - a_10*M*(L_2*(12*(55 + 6*E_2)*M_3 + (665 + 764*E_2)*M_2*r0 + 3*(58 + 121*E_2)*M*r0_2 + 3*(1 + E_2)*r0_3) + 6*E_2*r0*(-220*M_4 + 244*M_3*r0 + 438*M_2*r0_2 + 105*M*r0_3 - 12*r0_4)) - a_8*M*(L_4*(24*M_3 + 4*(179 + 9*E_2)*M_2*r0 + 9*(41 + 23*E_2)*M*r0_2 + 3*(3 + 2*E_2)*r0_3) - 12*E_2*r0_3*(348*M_4 + 86*M_3*r0 - 321*M_2*r0_2 - 84*M*r0_3 + 30*r0_4) + L_2*r0*(24*(-55 + 212*E_2)*M_4 + 4*(78 + 1237*E_2)*M_3*r0 + 2*(578 + 2141*E_2)*M_2*r0_2 + (38 + 1305*E_2)*M*r0_3 - 3*(50 + 83*E_2)*r0_4)) - a_4*r0_2*(3*L_8*M*r0 - 18*E_2*M*r0_6*(78*M_3 - 49*M_2*r0 - 34*M*r0_2 + 40*r0_3) + 2*L_6*M*(872*M_3 + 12*(-11 + 57*E_2)*M_2*r0 + 10*(1 + 12*E_2)*M*r0_2 - 3*(31 + 19*E_2)*r0_3) + L_2*r0_3*(-928*M_5 + 4*(-347 + 588*E_2)*M_4*r0 + 22*(67 + 245*E_2)*M_3*r0_2 + 3*(236 + 729*E_2)*M_2*r0_3 - 3*(150 + 547*E_2)*M*r0_4 - 45*r0_5) + L_4*r0*(104*M_5 + 4*(-96 + 923*E_2)*M_4*r0 + 72*(19 + 74*E_2)*M_3*r0_2 + (817 + 1647*E_2)*M_2*r0_3 - (753 + 934*E_2)*M*r0_4 - 15*r0_5)) - a_6*r0*(3*L_6*M*(4*M_2 + 65*M*r0 + (3 + E_2)*r0_2) - 12*E_2*M*r0_4*(246*M_4 + 294*M_3*r0 - 202*M_2*r0_2 - 73*M*r0_3 + 60*r0_4) + L_4*M*(1696*M_4 + 4*(-95 + 1308*E_2)*M_3*r0 + 76*(9 + 44*E_2)*M_2*r0_2 + 2*(128 + 425*E_2)*M*r0_3 - 3*(110 + 97*E_2)*r0_4) + L_2*r0_2*(4*(-491 + 1034*E_2)*M_5 + 4*(-58 + 1753*E_2)*M_4*r0 + 5*(405 + 1468*E_2)*M_3*r0_2 + (17 + 2063*E_2)*M_2*r0_3 - (472 + 1055*E_2)*M*r0_4 - 9*r0_5)) + a_2*r0_3*(-18*E_2*M*r0_8*(18*M_2 + 23*M*r0 - 20*r0_2) + 6*L_8*M*(-76*M_2 + 36*M*r0 + r0_2) + L_6*r0*(52*M_4 - 4*(85 + 219*E_2)*M_3*r0 - 3*(131 + 160*E_2)*M_2*r0_2 + (263 + 237*E_2)*M*r0_3 + 6*r0_4) + L_2*r0_5*(460*M_4 + 12*(19 - 140*E_2)*M_3*r0 - (535 + 1646*E_2)*M_2*r0_2 + 3*(9 + 376*E_2)*M*r0_3 + 63*r0_4) + L_4*r0_3*(944*M_4 - 8*(153 + 209*E_2)*M_2*r0_2 + (405 + 971*E_2)*M*r0_3 + 45*r0_4 - 4*M_3*(r0 + 530*E_2*r0)))))/(3.*r0_8*expr2_2); A60421 = (48*L*r0*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0))*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/(a_2 + r0*(-2*M + r0)); A60441 = (-8*(-36*a_12*E_2*M_2*(58*M_2 + 57*M*r0 + 14*r0_2) + a_11*E*L*M*(144*(29 + E_2)*M_3 + (4199 + 144*E_2)*M_2*r0 + 18*(61 + 2*E_2)*M*r0_2 + 21*r0_3) + a*E*L*M*r0_5*(3*L_4*r0_2*(-196*M_2 + 20*(54 + 11*E_2)*M*r0 - 491*r0_2) + L_6*(752*M_2 + 464*M*r0 - 420*r0_2) + 3*r0_6*(-264*M_2 + 2*(163 + 126*E_2)*M*r0 - 97*r0_2) - 39*L_2*r0_4*(56*M_2 - 2*(49 + 18*E_2)*M*r0 + 35*r0_2)) + (2*M - r0)*r0_5*(62*L_8*M*(2*M - r0) - 216*E_2*M*r0_9 + L_2*r0_6*(96*M_2 - 142*(-1 + 6*E_2)*M*r0 - 95*r0_2) - L_6*r0_2*(-604*M_2 + 52*(4 + 7*E_2)*M*r0 + 47*r0_2) - L_4*r0_4*(-588*M_2 + 4*(4 + 249*E_2)*M*r0 + 139*r0_2)) + a_5*E*L*M*r0_2*(36*L_6*(M + r0) + L_4*(14832*M_3 + 160*(27 + 8*E_2)*M_2*r0 + 4*(404 + 175*E_2)*M*r0_2 - 1399*r0_3) + L_2*r0*(3936*M_4 + 16*(16 + 315*E_2)*M_3*r0 + 8*(1711 + 1332*E_2)*M_2*r0_2 + 2*(3785 + 2154*E_2)*M*r0_3 - 4973*r0_4) + r0_3*(-8028*M_4 + 12*(-1307 + 684*E_2)*M_3*r0 + (10409 + 12816*E_2)*M_2*r0_2 + 108*(55 + 42*E_2)*M*r0_3 - 3150*r0_4)) + a_7*E*L*M*r0*(3*L_4*(96*M_2 + 4*(113 + E_2)*M*r0 + 31*r0_2) + r0_2*(12*(-1615 + 432*E_2)*M_4 + 16*(-460 + 999*E_2)*M_3*r0 + (17257 + 12816*E_2)*M_2*r0_2 + 36*(109 + 86*E_2)*M*r0_3 - 2382*r0_4) + 2*L_2*(7200*M_4 + 8*(349 + 309*E_2)*M_3*r0 + 2*(2933 + 1356*E_2)*M_2*r0_2 + (2357 + 762*E_2)*M*r0_3 - 811*r0_4)) + a_9*E*L*M*(L_2*(432*M_3 + 8*(599 + 12*E_2)*M_2*r0 + 6*(403 + 8*E_2)*M*r0_2 + 78*r0_3) + r0*(96*(-87 + 50*E_2)*M_4 + 4*(1367 + 1980*E_2)*M_3*r0 + (12535 + 4464*E_2)*M_2*r0_2 + 2*(1309 + 426*E_2)*M*r0_3 - 607*r0_4)) - a_10*M*(L_2*(72*(29 + 6*E_2)*M_3 + (2147 + 2612*E_2)*M_2*r0 + 6*(99 + 203*E_2)*M*r0_2 + 3*(7 + 6*E_2)*r0_3) - 36*E_2*r0*(116*M_4 - 124*M_3*r0 - 234*M_2*r0_2 - 59*M*r0_3 + 6*r0_4)) + a_2*r0_3*(-108*E_2*M*r0_8*(6*M_2 + 13*M*r0 - 10*r0_2) - 16*L_8*M*(80*M_2 - 34*M*r0 - 3*r0_2) + L_6*r0*(840*M_4 - 4*(293 + 562*E_2)*M_3*r0 - 2*(751 + 782*E_2)*M_2*r0_2 + (839 + 718*E_2)*M*r0_3 + 50*r0_4) + L_4*r0_3*(3408*M_4 - 8*(-82 + 693*E_2)*M_3*r0 - 2*(2215 + 2646*E_2)*M_2*r0_2 + (1123 + 2922*E_2)*M*r0_3 + 251*r0_4) + L_2*r0_5*(1560*M_4 - 8*(-175 + 522*E_2)*M_3*r0 - 12*(189 + 431*E_2)*M_2*r0_2 + (85 + 3348*E_2)*M*r0_3 + 252*r0_4)) - a_4*r0_2*(6*L_8*M*(2*M + 3*r0) - 108*E_2*M*r0_6*(42*M_3 - 19*M_2*r0 - 22*M*r0_2 + 20*r0_3) + L_6*(4944*M_4 + 24*(-23 + 160*E_2)*M_3*r0 + 4*(41 + 214*E_2)*M_2*r0_2 - 4*(145 + 84*E_2)*M*r0_3 - 3*r0_4) + L_2*r0_3*(-2424*M_5 + 4*(-1493 + 1170*E_2)*M_4*r0 + 2*(2287 + 7488*E_2)*M_3*r0_2 + (3155 + 7338*E_2)*M_2*r0_3 - 18*(83 + 273*E_2)*M*r0_4 - 222*r0_5) + L_4*r0*(-624*M_5 + 8*(-229 + 1155*E_2)*M_4*r0 + 8*(566 + 1917*E_2)*M_3*r0_2 + 2*(1552 + 2763*E_2)*M_2*r0_3 - (2341 + 2820*E_2)*M*r0_4 - 118*r0_5)) - a_6*r0*(3*L_6*M*(32*M_2 + 2*(109 + 6*E_2)*M*r0 + (19 + 6*E_2)*r0_2) - 72*E_2*M*r0_4*(114*M_4 + 162*M_3*r0 - 98*M_2*r0_2 - 47*M*r0_3 + 30*r0_4) + L_2*r0_2*(12*(-535 + 812*E_2)*M_5 + 12*(-131 + 1506*E_2)*M_4*r0 + (6991 + 22204*E_2)*M_3*r0_2 + 2*(300 + 3533*E_2)*M_2*r0_3 - 2*(764 + 1587*E_2)*M*r0_4 - 68*r0_5) + 2*L_4*(2400*M_5 + 8*(-73 + 927*E_2)*M_4*r0 + 6*(203 + 858*E_2)*M_3*r0_2 + 6*(83 + 248*E_2)*M_2*r0_3 - 13*(37 + 33*E_2)*M*r0_4 - 3*r0_5)) - a_8*(2*L_4*M*(72*M_3 + 2*(581 + 72*E_2)*M_2*r0 + 3*(206 + 125*E_2)*M*r0_2 + 6*(5 + 3*E_2)*r0_3) - 72*E_2*M*r0_3*(180*M_4 + 58*M_3*r0 - 167*M_2*r0_2 - 50*M*r0_3 + 15*r0_4) + L_2*r0*(144*(-29 + 100*E_2)*M_5 + 4*(251 + 3668*E_2)*M_4*r0 + 172*(23 + 80*E_2)*M_3*r0_2 + (351 + 4414*E_2)*M_2*r0_3 - 2*(215 + 369*E_2)*M*r0_4 - 3*r0_5)) + a_3*E*L*M*r0_3*(4*L_6*(960*M_2 - 97*M*r0 - 96*r0_2) + L_4*r0*(3360*M_3 + 4*(1463 + 312*E_2)*M_2*r0 + 4*(931 + 337*E_2)*M*r0_2 - 2965*r0_3) + 2*L_2*r0_3*(-2280*M_3 + 2*(845 + 1332*E_2)*M_2*r0 + 2*(2339 + 1059*E_2)*M*r0_2 - 2319*r0_3) + r0_5*(-5544*M_3 + 2*(2257 + 1506*E_2)*M*r0_2 - 1687*r0_3 + 120*M_2*(r0 + 36*E_2*r0)))))/(3.*r0_5*expr2_2); A60601 = (4*L*r0_4*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0)))/(a_2 + r0*(-2*M + r0)); A60621 = (-4*(-6*a_10*E_2*M_2*(61*M + 30*r0) + 6*a_9*E*L*M*(2*(61 + 3*E_2)*M_2 + (64 + 3*E_2)*M*r0 + 2*r0_2) + 2*a*E*L*M*r0_4*(L_2*r0_2*(-286*M_2 + (467 + 108*E_2)*M*r0 - 162*r0_2) + L_4*(40*M_2 + 142*M*r0 - 81*r0_2) + 3*r0_4*(-68*M_2 + 3*(22 + 13*E_2)*M*r0 - 16*r0_2)) + (2*M - r0)*r0_4*(35*L_6*M*(2*M - r0) - 72*E_2*M*r0_7 + 2*L_2*r0_4*(28*M_2 + (24 - 103*E_2)*M*r0 - 19*r0_2) - L_4*r0_2*(-174*M_2 + (29 + 124*E_2)*M*r0 + 29*r0_2)) + 2*a_3*E*L*M*r0_2*(L_4*(588*M_2 - 8*M*r0 - 72*r0_2) + L_2*r0*(100*M_3 + 2*(23 + 90*E_2)*M_2*r0 + 2*(408 + 115*E_2)*M*r0_2 - 347*r0_3) + r0_3*(-606*M_3 + 3*(-145 + 138*E_2)*M_2*r0 + 7*(115 + 52*E_2)*M*r0_2 - 215*r0_3)) + 2*a_5*E*L*M*r0*(9*L_4*(2*M + r0) + L_2*(1128*M_3 + 2*(125 + 98*E_2)*M_2*r0 + (501 + 128*E_2)*M*r0_2 - 170*r0_3) + 2*r0_2*(3*(-283 + 60*E_2)*M_3 + (211 + 431*E_2)*M_2*r0 + (468 + 193*E_2)*M*r0_2 - 134*r0_3)) + 2*a_7*E*L*M*(3*L_2*(18*M_2 + 2*(38 + E_2)*M*r0 + 5*r0_2) + r0*(4*(-183 + 94*E_2)*M_3 + (831 + 466*E_2)*M_2*r0 + (545 + 148*E_2)*M*r0_2 - 95*r0_3)) - 3*a_8*M*(L_2*(2*(61 + 18*E_2)*M_2 + 17*(4 + 5*E_2)*M*r0 + (4 + 3*E_2)*r0_2) + 2*E_2*r0*(-122*M_3 + 187*M_2*r0 + 125*M*r0_2 - 12*r0_3)) - a_6*(3*L_4*M*(12*M_2 + (73 + 12*E_2)*M*r0 + (7 + 3*E_2)*r0_2) + 6*E_2*M*r0_3*(-372*M_3 + 101*M_2*r0 + 203*M*r0_2 - 48*r0_3) + L_2*r0*(12*(-61 + 188*E_2)*M_4 + 4*(135 + 412*E_2)*M_3*r0 + (299 + 1010*E_2)*M_2*r0_2 - 2*(71 + 90*E_2)*M*r0_3 - 3*r0_4)) + a_4*r0*(-3*L_6*M*(4*M + 3*r0) + 18*E_2*M*r0_4*(70*M_3 + 21*M_2*r0 - 57*M*r0_2 + 24*r0_3) + L_4*(-752*M_4 - 24*(-9 + 49*E_2)*M_3*r0 - 8*(36 + 47*E_2)*M_2*r0_2 + (181 + 114*E_2)*M*r0_3 + 3*r0_4) + L_2*r0_2*(-4*(-291 + 295*E_2)*M_4 - 18*(29 + 106*E_2)*M_3*r0 - (790 + 1623*E_2)*M_2*r0_2 + (330 + 593*E_2)*M*r0_3 + 38*r0_4)) + a_2*r0_2*(2*L_6*M*(-196*M_2 + 68*M*r0 + 15*r0_2) + 18*E_2*M*r0_6*(10*M_2 - 29*M*r0 + 16*r0_2) + L_4*r0*(260*M_4 + (92 - 580*E_2)*M_3*r0 - (689 + 604*E_2)*M_2*r0_2 + (225 + 247*E_2)*M*r0_3 + 32*r0_4) + L_2*r0_3*(356*M_4 + (548 - 460*E_2)*M_3*r0 - (783 + 1280*E_2)*M_2*r0_2 + 2*(32 + 305*E_2)*M*r0_3 + 73*r0_4))))/(3.*r0_2*expr2_2); A60801 = -(r0*(-96*a_8*E_2*M_2 + 3*a_7*E*L*M*(4*(16 + E_2)*M + 3*r0) + a_5*E*L*M*(12*L_2*(3*M + r0) + r0*(16*(-24 + 11*E_2)*M_2 + 4*(155 + 37*E_2)*M*r0 - 91*r0_2)) + a_3*E*L*M*r0*(r0_2*(4*(-223 + 36*E_2)*M_2 + 4*(196 + 61*E_2)*M*r0 - 145*r0_2) + L_2*(528*M_2 + 68*M*r0 - 84*r0_2)) + (2*M - r0)*r0_3*(26*L_4*M*(2*M - r0) - 36*E_2*M*r0_5 + L_2*r0_2*(40*M_2 + (26 - 64*E_2)*M*r0 - 23*r0_2)) - 3*a_6*M*(L_2*(4*(8 + 3*E_2)*M + (3 + 2*E_2)*r0) - 4*E_2*r0*(16*M_2 - 32*M*r0 + 3*r0_2)) + a*E*L*M*r0_3*(3*r0_2*(-92*M_2 + 4*(19 + 9*E_2)*M*r0 - 15*r0_2) - 32*L_2*(2*M_2 - 7*M*r0 + 3*r0_2)) + a_4*(-6*L_4*M*(2*M + r0) + 36*E_2*M*r0_3*(16*M_2 - 14*M*r0 + 3*r0_2) + L_2*r0*(-48*(-4 + 11*E_2)*M_3 - 4*(59 + 64*E_2)*M_2*r0 + 10*(7 + 6*E_2)*M*r0_2 + 3*r0_3)) + a_2*r0*(-8*L_4*M*(22*M_2 - 5*M*r0 - 3*r0_2) + 36*E_2*M*r0_4*(8*M_2 - 8*M*r0 + 3*r0_2) + L_2*r0_2*(-4*(-79 + 46*E_2)*M_3 - 4*(89 + 91*E_2)*M_2*r0 + (47 + 130*E_2)*M*r0_2 + 26*r0_3))))/(6.*expr2_2); A61061 = (128*expr1_2*(2*a_8*E_2*M_2*(2*M + r0) - a_7*E*L*M*(8*M_2 + 5*M*r0 + r0_2) + a*E*L*M*r0_3*(L_4*(4*M - 6*r0) + L_2*(4*M - 9*r0)*r0_2 + 6*r0_4*(-3*M + r0)) - a_5*E*L*M*r0*(L_2*(12*M + 7*r0) - 2*r0*(-17*M_2 - 4*M*r0 + r0_2)) + L_2*r0_3*(2*E_2*L_2*M*r0_3 + L_4*M*(-2*M + r0) + r0_4*(6*M_2 + (-5 + 2*E_2)*M*r0 + r0_2)) - a_3*E*L*M*r0_2*(6*L_4 + r0_2*(54*M_2 + 17*M*r0 - 9*r0_2) + L_2*(-8*M_2 + 4*M*r0 + 12*r0_2)) + a_6*M*(2*E_2*M*r0_2*(12*M + 7*r0) + L_2*(4*M_2 + 3*M*r0 + 6*E_2*M*r0 + r0_2 + 3*E_2*r0_2)) + a_4*r0*(6*E_2*M_2*r0_3*(6*M + 5*r0) + L_4*M*(6*M + (4 + 3*E_2)*r0) + L_2*r0*((10 - 4*E_2)*M_3 + (-5 + 8*E_2)*M_2*r0 + (3 + 8*E_2)*M*r0_2 + 2*r0_3)) + a_2*r0_2*(3*L_6*M + 18*E_2*M_2*r0_5 + L_4*(-4*M_3 - 2*(2 + E_2)*M_2*r0 + (4 + 5*E_2)*M*r0_2 + 2*r0_3) + L_2*r0_2*(24*M_3 + 2*(-5 + E_2)*M_2*r0 + (-5 + 7*E_2)*M*r0_2 + 3*r0_3))))/(r0_7*expr2_2); A61241 = (32*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(6*a_8*E_2*M_2*(2*M + r0) - 2*a_7*E*L*M*(12*M_2 + 9*M*r0 + 2*r0_2) + 6*a*E*L*M*r0_3*(L_4*(2*M - 3*r0) + 3*r0_4*(-3*M + r0) - L_2*r0_2*(M + 3*r0)) - 2*a_5*E*L*M*r0*(L_2*(20*M + 11*r0) + r0*(48*M_2 + 17*M*r0 - r0_2)) + L_2*r0_3*(3*L_4*M*(-2*M + r0) + 3*r0_4*(6*M_2 + (-5 + 2*E_2)*M*r0 + r0_2) + L_2*r0_2*(4*M_2 + 2*(-2 + 3*E_2)*M*r0 + r0_2)) - 6*a_3*E*L*M*r0_2*(3*L_4 + r0_2*(24*M_2 + 9*M*r0 - 4*r0_2) + L_2*(-4*M_2 + 5*M*r0 + 6*r0_2)) + a_6*M*(6*E_2*M*r0_2*(12*M + 7*r0) + L_2*(12*M_2 + 4*(3 + 5*E_2)*M*r0 + (4 + 9*E_2)*r0_2)) + a_4*r0*(18*E_2*M_2*r0_3*(6*M + 5*r0) + L_4*M*(20*M + (13 + 9*E_2)*r0) + L_2*r0*(-12*(-2 + E_2)*M_3 + 4*(-2 + 9*E_2)*M_2*r0 + 3*(3 + 8*E_2)*M*r0_2 + 5*r0_3)) + a_2*r0_2*(9*L_6*M + 54*E_2*M_2*r0_5 + L_4*(-12*M_3 - 6*(1 + E_2)*M_2*r0 + (11 + 15*E_2)*M*r0_2 + 5*r0_3) + L_2*r0_2*(60*M_3 + 2*(-11 + 12*E_2)*M_2*r0 + 7*(-2 + 3*E_2)*M*r0_2 + 8*r0_3))))/(r0_4*expr2_2); A61421 = (8*(6*a_8*E_2*M_2*(2*M + r0) - a_7*E*L*M*(24*M_2 + 21*M*r0 + 5*r0_2) + 3*a*E*L*M*r0_3*(L_4*(4*M - 6*r0) + 6*r0_4*(-3*M + r0) - L_2*r0_2*(8*M + 3*r0)) - a_5*E*L*M*r0*(L_2*(44*M + 23*r0) + 2*r0*(45*M_2 + 22*M*r0 + r0_2)) + L_2*r0_3*(3*L_4*M*(-2*M + r0) + 3*r0_4*(6*M_2 + (-5 + 2*E_2)*M*r0 + r0_2) + 2*L_2*r0_2*(4*M_2 + (-4 + 3*E_2)*M*r0 + r0_2)) - 3*a_3*E*L*M*r0_2*(6*L_4 + r0_2*(42*M_2 + 19*M*r0 - 7*r0_2) + L_2*(-8*M_2 + 16*M*r0 + 12*r0_2)) + a_6*M*(6*E_2*M*r0_2*(12*M + 7*r0) + L_2*(12*M_2 + (15 + 22*E_2)*M*r0 + (5 + 9*E_2)*r0_2)) + a_4*r0*(18*E_2*M_2*r0_3*(6*M + 5*r0) + L_4*M*(22*M + (14 + 9*E_2)*r0) + L_2*r0*(-6*(-3 + 2*E_2)*M_3 + (-1 + 48*E_2)*M_2*r0 + 3*(3 + 8*E_2)*M*r0_2 + 4*r0_3)) + a_2*r0_2*(9*L_6*M + 54*E_2*M_2*r0_5 + L_4*(-12*M_3 - 6*E_2*M_2*r0 + 5*(2 + 3*E_2)*M*r0_2 + 4*r0_3) + L_2*r0_2*(48*M_3 + 14*(-1 + 3*E_2)*M_2*r0 + (-13 + 21*E_2)*M*r0_2 + 7*r0_3))))/(r0*expr2_2); A61601 = (2*r0_2*(2*a_6*E_2*M_2 - 2*a_5*E*L*M*(2*M + r0) - 2*a_3*E*L*M*r0*(3*L_2 + 7*M*r0) + 2*a*E*L*M*r0_2*(L_2*(2*M - 3*r0) + 3*r0_2*(-3*M + r0)) + a_4*M*(12*E_2*M*r0_2 + L_2*(2*M + 2*r0 + 3*E_2*r0)) + L_2*r0_2*(L_2*M*(-2*M + r0) + r0_2*(6*M_2 + (-5 + 2*E_2)*M*r0 + r0_2)) + a_2*r0*(3*L_4*M + 18*E_2*M_2*r0_3 + L_2*r0*(-2*(-1 + E_2)*M_2 + (-1 + 5*E_2)*M*r0 + r0_2))))/expr2_2; A62041 = (192*L*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0))*expr1_2)/(r0_2*expr2_2); A62061 = (-32*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-12*a_12*E_2*M_2*(92*M_2 + 88*M*r0 + 21*r0_2) + a_11*E*L*M*(-24*(-92 + 11*E_2)*M_3 + (2137 - 300*E_2)*M_2*r0 + 6*(85 - 14*E_2)*M*r0_2 - 6*r0_3) + a*E*L*M*r0_5*(2*L_4*r0_2*(584*M_2 + (557 + 192*E_2)*M*r0 - 474*r0_2) + 2*L_2*r0_4*(250*M_2 + (571 + 360*E_2)*M*r0 - 393*r0_2) + 3*r0_6*(-16*M_2 + 8*(14 + 15*E_2)*M*r0 - 61*r0_2) + 12*L_6*(88*M_2 - 8*M*r0 - 21*r0_2)) + a_3*E*L*M*r0_3*(12*L_6*(234*M_2 - 57*M*r0 - 22*r0_2) + 2*L_2*r0_3*(2134*M_3 + (1219 + 1800*E_2)*M_2*r0 + 10*(117 + 94*E_2)*M*r0_2 - 1459*r0_3) + r0_5*(-2820*M_3 + 2*(805 + 1818*E_2)*M_2*r0 + 4*(404 + 301*E_2)*M*r0_2 - 1227*r0_3) + 2*L_4*r0*(2704*M_3 + 12*(151 + 41*E_2)*M_2*r0 + 2*(38 + 177*E_2)*M*r0_2 - 909*r0_3)) + r0_5*(18*L_8*M_2*(-2*M + r0) + 144*E_2*M*r0_9*(-2*M + r0) + 2*L_6*M*r0_2*(158*M_2 - (167 + 210*E_2)*M*r0 + 2*(22 + 57*E_2)*r0_2) + 2*L_4*r0_4*(174*M_3 - (81 + 584*E_2)*M_2*r0 + 5*(-9 + 62*E_2)*M*r0_2 + 21*r0_3) + L_2*r0_6*(20*M_3 - 2*(-77 + 526*E_2)*M_2*r0 + 32*(-5 + 17*E_2)*M*r0_2 + 39*r0_3)) + a_5*E*L*M*r0_2*(-12*L_6*(9*M + r0) + 2*L_4*(5520*M_3 + 4*(76 + 117*E_2)*M_2*r0 + (-337 + 144*E_2)*M*r0_2 - 486*r0_3) + r0_3*(-6636*M_4 + 8*(-626 + 1035*E_2)*M_3*r0 + 3*(2363 + 2896*E_2)*M_2*r0_2 + 6*(173 + 228*E_2)*M*r0_3 - 2379*r0_4) + 2*L_2*r0*(3520*M_4 + 2*(2129 + 1080*E_2)*M_3*r0 + 4*(513 + 790*E_2)*M_2*r0_2 + 4*(77 + 185*E_2)*M*r0_3 - 1651*r0_4)) + a_7*E*L*M*r0*(-6*L_4*(120*M_2 + 6*(-8 + E_2)*M*r0 + 5*r0_2) + r0_2*((-9700 + 4896*E_2)*M_4 + 4*(-125 + 3114*E_2)*M_3*r0 + 3*(2803 + 2152*E_2)*M_2*r0_2 + 6*(-13 + 80*E_2)*M*r0_3 - 1815*r0_4) + 2*L_2*(5520*M_4 + 4*(443 + 460*E_2)*M_3*r0 + (1309 + 1240*E_2)*M_2*r0_2 + 2*(181 + 50*E_2)*M*r0_3 - 597*r0_4)) + a_9*E*L*M*(-2*L_2*(396*M_3 + 10*(-73 + 12*E_2)*M_2*r0 + 3*(-151 + 20*E_2)*M*r0_2 + 12*r0_3) + r0*(32*(-129 + 115*E_2)*M_4 + 264*(13 + 17*E_2)*M_3*r0 + 3*(1985 + 368*E_2)*M_2*r0_2 + 2*(337 - 64*E_2)*M*r0_3 - 486*r0_4)) + a_10*M*(L_2*(24*(-46 + 33*E_2)*M_3 - (1081 + 280*E_2)*M_2*r0 - 6*(43 + 54*E_2)*M*r0_2 + 6*(1 + E_2)*r0_3) + 12*E_2*r0*(172*M_4 - 228*M_3*r0 - 357*M_2*r0_2 - 74*M*r0_3 + 12*r0_4)) + a_2*r0_3*(-36*E_2*M*r0_8*(27*M_2 + 14*M*r0 - 20*r0_2) + 18*L_8*M*(-52*M_2 + 27*M*r0 + r0_2) - 2*L_6*r0*(272*M_4 + 2*(146 + 501*E_2)*M_3*r0 + 3*(64 + 105*E_2)*M_2*r0_2 - (203 + 234*E_2)*M*r0_3 - 18*r0_4) + 2*L_4*r0_3*(188*M_4 - 242*(-1 + 10*E_2)*M_3*r0 - (927 + 994*E_2)*M_2*r0_2 + (315 + 908*E_2)*M*r0_3 + 48*r0_4) + L_2*r0_5*(824*M_4 - 48*(-5 + 109*E_2)*M_3*r0 - 2*(430 + 647*E_2)*M_2*r0_2 + 3*(31 + 704*E_2)*M*r0_3 + 96*r0_4)) + a_8*M*(2*L_4*(132*M_3 + 40*(-11 + 9*E_2)*M_2*r0 + 3*(-83 + 6*E_2)*M*r0_2 + 3*(3 + 2*E_2)*r0_3) + 24*E_2*r0_3*(276*M_4 + 8*M_3*r0 - 278*M_2*r0_2 - 47*M*r0_3 + 30*r0_4) + L_2*r0*(-48*(-43 + 230*E_2)*M_4 - 8*(87 + 1063*E_2)*M_3*r0 - 2*(823 + 1786*E_2)*M_2*r0_2 + 19*(11 - 30*E_2)*M*r0_3 + 6*(56 + 83*E_2)*r0_4)) + a_6*r0*(6*L_6*M*(40*M_2 + 2*(-17 + 9*E_2)*M*r0 + (3 + E_2)*r0_2) + 24*E_2*M*r0_4*(246*M_4 + 222*M_3*r0 - 181*M_2*r0_2 - 22*M*r0_3 + 60*r0_4) - 2*L_4*M*(1840*M_4 + 4*(-59 + 1380*E_2)*M_3*r0 + (75 + 2012*E_2)*M_2*r0_2 + 2*(2 - 49*E_2)*M*r0_3 - 15*(23 + 20*E_2)*r0_4) + L_2*r0_2*(-4*(-769 + 2716*E_2)*M_5 - 4*(175 + 4916*E_2)*M_4*r0 - (3129 + 9496*E_2)*M_3*r0_2 + 2*(226 + 25*E_2)*M_2*r0_3 + (983 + 2002*E_2)*M*r0_4 + 18*r0_5)) + a_4*r0_2*(6*L_8*M*(6*M + r0) + 36*E_2*M*r0_6*(60*M_3 - 52*M_2*r0 - 7*M*r0_2 + 40*r0_3) + 2*L_6*M*(-1840*M_3 - 468*(-1 + 3*E_2)*M_2*r0 + (139 - 45*E_2)*M*r0_2 + 3*(62 + 41*E_2)*r0_3) - 2*L_4*r0*(536*M_5 + 2*(327 + 2296*E_2)*M_4*r0 + 3*(203 + 1560*E_2)*M_3*r0_2 + 5*(101 + 66*E_2)*M_2*r0_3 - 4*(177 + 223*E_2)*M*r0_4 - 27*r0_5) + L_2*r0_3*(2360*M_5 - 8*(-161 + 1434*E_2)*M_4*r0 - 4*(665 + 2563*E_2)*M_3*r0_2 + 27*(-35 + 2*E_2)*M_2*r0_3 + 6*(151 + 513*E_2)*M*r0_4 + 75*r0_5))))/(3.*r0_8*expr2_3); A62221 = (96*L*r0*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0))*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/expr2_2; A62241 = (-8*(-48*a_12*E_2*M_2*(72*M_2 + 70*M*r0 + 17*r0_2) + a_11*E*L*M_2*(-144*(-48 + 5*E_2)*M_2 + (6841 - 792*E_2)*M*r0 + 6*(283 - 36*E_2)*r0_2) + a*E*L*M*r0_5*(12*L_4*r0_2*(227*M_2 + (269 + 83*E_2)*M*r0 - 216*r0_2) + 4*L_6*(664*M_2 - 8*M*r0 - 189*r0_2) + 9*r0_6*(-112*M_2 + 12*(14 + 9*E_2)*M*r0 - 65*r0_2) - 24*L_2*r0_4*(21*M_2 - (182 + 81*E_2)*M*r0 + 97*r0_2)) + a_3*E*L*M*r0_3*(8*L_6*(1005*M_2 - 259*M*r0 - 99*r0_2) + 2*L_2*r0_3*(1896*M_3 + 2*(1897 + 2727*E_2)*M_2*r0 + (4915 + 2544*E_2)*M*r0_2 - 4447*r0_3) + 4*L_4*r0*(3192*M_3 + (3127 + 714*E_2)*M_2*r0 + (217 + 440*E_2)*M*r0_2 - 1419*r0_3) + 3*r0_5*(-3096*M_3 + 4*(181 + 756*E_2)*M_2*r0 + 20*(111 + 56*E_2)*M*r0_2 - 1213*r0_3)) + r0_5*(432*E_2*M*r0_9*(-2*M + r0) + 2*L_8*M*(50*M_2 - 77*M*r0 + 26*r0_2) + 2*L_6*r0_2*(662*M_3 - (569 + 614*E_2)*M_2*r0 + (59 + 334*E_2)*M*r0_2 + 30*r0_3) + 6*L_4*r0_4*(258*M_3 - (113 + 572*E_2)*M_2*r0 + 76*(-1 + 4*E_2)*M*r0_2 + 34*r0_3) + 3*L_2*r0_6*(116*M_3 + 2*(45 - 514*E_2)*M_2*r0 + 28*(-6 + 19*E_2)*M*r0_2 + 47*r0_3)) + a_5*E*L*M*r0_2*(-36*L_6*(12*M + r0) + 4*L_4*(7920*M_3 + 5*(159 + 134*E_2)*M_2*r0 + (-488 + 155*E_2)*M*r0_2 - 753*r0_3) + 2*L_2*r0*(7680*M_4 + 16*(523 + 378*E_2)*M_3*r0 + 6*(1360 + 1549*E_2)*M_2*r0_2 + (2077 + 1992*E_2)*M*r0_3 - 5062*r0_4) + 3*r0_3*(-5244*M_4 + 4*(-1765 + 1728*E_2)*M_3*r0 + 3*(2187 + 2504*E_2)*M_2*r0_2 + 14*(151 + 96*E_2)*M*r0_3 - 2299*r0_4)) + a_7*E*L*M*r0*(-12*L_4*(171*M_2 + 4*(-17 + 3*E_2)*M*r0 + 6*r0_2) + 2*L_2*(15696*M_4 + 32*(149 + 165*E_2)*M_3*r0 + 2*(2629 + 1821*E_2)*M_2*r0_2 + 5*(307 + 48*E_2)*M*r0_3 - 1797*r0_4) + 3*r0_2*(12*(-823 + 360*E_2)*M_4 + 16*(-140 + 687*E_2)*M_3*r0 + 21*(433 + 280*E_2)*M_2*r0_2 + 2*(415 + 276*E_2)*M*r0_3 - 1739*r0_4)) + a_9*E*L*M*(-2*L_2*(1080*M_3 + 2*(-1232 + 171*E_2)*M_2*r0 + 3*(-491 + 60*E_2)*M*r0_2 + 18*r0_3) + r0*(96*(-135 + 109*E_2)*M_4 + 44*(227 + 288*E_2)*M_3*r0 + (19657 + 3384*E_2)*M_2*r0_2 - 6*(-499 + 34*E_2)*M*r0_3 - 1374*r0_4)) + a_10*M*(L_2*(432*(-8 + 5*E_2)*M_3 - (3481 + 1276*E_2)*M_2*r0 - 18*(49 + 62*E_2)*M*r0_2 + 18*E_2*r0_3) + 12*E_2*r0*(540*M_4 - 664*M_3*r0 - 1125*M_2*r0_2 - 253*M*r0_3 + 36*r0_4)) + a_2*r0_3*(-108*E_2*M*r0_8*(21*M_2 + 17*M*r0 - 20*r0_2) + 2*L_8*M*(-1340*M_2 + 673*M*r0 + 39*r0_2) - 2*L_6*r0*(168*M_4 + 2*(613 + 1403*E_2)*M_3*r0 + (717 + 787*E_2)*M_2*r0_2 - 2*(340 + 341*E_2)*M*r0_3 - 57*r0_4) + 6*L_4*r0_3*(576*M_4 + (212 - 2450*E_2)*M_3*r0 - 3*(373 + 280*E_2)*M_2*r0_2 + 36*(9 + 25*E_2)*M*r0_3 + 71*r0_4) + 3*L_2*r0_5*(960*M_4 + (632 - 4308*E_2)*M_3*r0 - 2*(629 + 789*E_2)*M_2*r0_2 + (109 + 2092*E_2)*M*r0_3 + 130*r0_4)) + a_8*(2*L_4*M*(360*M_3 + 2*(-715 + 513*E_2)*M_2*r0 + 3*(-269 + 22*E_2)*M*r0_2 + 9*(1 + 2*E_2)*r0_3) + 48*E_2*M*r0_3*(414*M_4 + 63*M_3*r0 - 416*M_2*r0_2 - 89*M*r0_3 + 45*r0_4) + L_2*r0*(-144*(-45 + 218*E_2)*M_5 - 4*(505 + 5944*E_2)*M_4*r0 - 68*(87 + 179*E_2)*M_3*r0_2 - 7*(-43 + 350*E_2)*M_2*r0_3 + 6*(175 + 257*E_2)*M*r0_4 + 18*r0_5)) + a_4*r0_2*(18*L_8*M*(8*M + r0) + 432*E_2*M*r0_6*(15*M_3 - 10*M_2*r0 - 4*M*r0_2 + 10*r0_3) + 2*L_6*(-5280*M_4 - 6*(-171 + 670*E_2)*M_3*r0 + (388 + 53*E_2)*M_2*r0_2 + 3*(205 + 119*E_2)*M*r0_3 + 9*r0_4) - 2*L_4*r0*(600*M_5 + 4*(157 + 3066*E_2)*M_4*r0 + 2*(1462 + 7161*E_2)*M_3*r0_2 + 2*(998 + 405*E_2)*M_2*r0_3 - 6*(379 + 447*E_2)*M*r0_4 - 129*r0_5) + 3*L_2*r0_3*(1720*M_5 + 4*(685 - 2022*E_2)*M_4*r0 - 2*(1403 + 4574*E_2)*M_3*r0_2 - (1591 + 694*E_2)*M_2*r0_3 + 2*(502 + 1545*E_2)*M*r0_4 + 125*r0_5)) + a_6*r0*(6*L_6*M*(114*M_2 + 2*(-49 + 36*E_2)*M*r0 + 3*(2 + E_2)*r0_2) + 216*E_2*M*r0_4*(70*M_4 + 80*M_3*r0 - 55*M_2*r0_2 - 13*M*r0_3 + 20*r0_4) - 2*L_4*(5232*M_5 + 16*(-49 + 990*E_2)*M_4*r0 + 6*(144 + 1043*E_2)*M_3*r0_2 + (103 - 348*E_2)*M_2*r0_3 - 3*(367 + 304*E_2)*M*r0_4 - 18*r0_5) + L_2*r0_2*((9756 - 27120*E_2)*M_5 + (508 - 48456*E_2)*M_4*r0 - (11533 + 28712*E_2)*M_3*r0_2 + 2*(125 - 883*E_2)*M_2*r0_3 + 3*(1077 + 2038*E_2)*M*r0_4 + 144*r0_5))))/(3.*r0_5*expr2_3); A62401 = (12*L*r0_4*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0)))/expr2_2; A62421 = (-2*(-12*a_10*E_2*M_2*(150*M + 73*r0) - 3*a_9*E*L*M*(12*(-100 + 9*E_2)*M_2 + 6*(-101 + 10*E_2)*M*r0 - 5*r0_2) + 3*a*E*L*M*r0_4*(L_2*r0_2*(-212*M_2 + 2*(533 + 144*E_2)*M*r0 - 543*r0_2) + r0_4*(-624*M_2 + 4*(163 + 72*E_2)*M*r0 - 197*r0_2) + 4*L_4*(160*M_2 + 36*M*r0 - 67*r0_2)) + a_5*E*L*M*r0*(-36*L_4*(13*M + r0) + L_2*(14832*M_3 + 36*(9 + 70*E_2)*M_2*r0 + 6*(379 + 80*E_2)*M*r0_2 - 2231*r0_3) + 2*r0_2*(6*(-1273 + 468*E_2)*M_3 + 2*(1364 + 2253*E_2)*M_2*r0 + 3*(1317 + 286*E_2)*M*r0_2 - 1808*r0_3)) + a_3*E*L*M*r0_2*(60*L_4*(126*M_2 - 31*M*r0 - 14*r0_2) + L_2*r0*(4800*M_3 + 12*(221 + 222*E_2)*M_2*r0 + 4*(1237 + 375*E_2)*M*r0_2 - 4127*r0_3) + 2*r0_3*(-3186*M_3 + 3*(-473 + 918*E_2)*M_2*r0 + 11*(349 + 102*E_2)*M*r0_2 - 1444*r0_3)) + a_7*E*L*M*(-3*L_2*(324*M_2 + 4*(-113 + 13*E_2)*M*r0 + 7*r0_2) + 2*r0*(24*(-141 + 103*E_2)*M_3 + 3*(1393 + 578*E_2)*M_2*r0 + (2371 + 78*E_2)*M*r0_2 - 652*r0_3)) + 3*a_8*M*(L_2*(12*(-50 + 27*E_2)*M_2 - 2*(157 + 68*E_2)*M*r0 + (-5 + 6*E_2)*r0_2) + 4*E_2*r0*(282*M_3 - 463*M_2*r0 - 283*M*r0_2 + 36*r0_3)) + r0_4*(432*E_2*M*r0_7*(-2*M + r0) + 6*L_6*M*(62*M_2 - 71*M*r0 + 20*r0_2) + L_4*r0_2*(1416*M_3 - 4*(221 + 303*E_2)*M_2*r0 + 2*(-89 + 330*E_2)*M*r0_2 + 133*r0_3) + L_2*r0_4*(636*M_3 + 2*(59 - 1074*E_2)*M_2*r0 + 8*(-71 + 141*E_2)*M*r0_2 + 175*r0_3)) + a_6*(3*L_4*M*(108*M_2 + 4*(-64 + 39*E_2)*M*r0 + (1 + 6*E_2)*r0_2) + 36*E_2*M*r0_3*(276*M_3 - 109*M_2*r0 - 145*M*r0_2 + 48*r0_3) + L_2*r0*(-72*(-47 + 206*E_2)*M_4 - 6*(467 + 894*E_2)*M_3*r0 - 2*(580 + 759*E_2)*M_2*r0_2 + (1019 + 1140*E_2)*M*r0_3 + 33*r0_4)) + a_4*r0*(6*L_6*M*(26*M + 3*r0) + 108*E_2*M*r0_4*(58*M_3 + 11*M_2*r0 - 37*M*r0_2 + 24*r0_3) + L_4*(-4944*M_4 + 12*(131 - 630*E_2)*M_3*r0 + 6*(-152 + 35*E_2)*M_2*r0_2 + 2*(586 + 357*E_2)*M*r0_3 + 33*r0_4) + L_2*r0_2*(-12*(-445 + 902*E_2)*M_4 - 2*(1537 + 5850*E_2)*M_3*r0 - 2*(1931 + 1608*E_2)*M_2*r0_2 + (2053 + 3354*E_2)*M*r0_3 + 211*r0_4)) + a_2*r0_2*(-18*L_6*M*(140*M_2 - 65*M*r0 - 7*r0_2) + 108*E_2*M*r0_6*(M_2 - 20*M*r0 + 16*r0_2) + L_4*r0*(408*M_4 + 12*(3 - 413*E_2)*M_3*r0 - 2*(1448 + 753*E_2)*M_2*r0_2 + 3*(397 + 452*E_2)*M*r0_3 + 166*r0_4) + L_2*r0_3*(2016*M_4 - 28*(-86 + 213*E_2)*M_3*r0 - 2*(2017 + 1767*E_2)*M_2*r0_2 + 7*(73 + 480*E_2)*M*r0_3 + 353*r0_4))))/(3.*r0_2*expr2_3); A62601 = -(r0*(-312*a_8*E_2*M_2 + 3*a_7*E*L*M*(-16*(-13 + E_2)*M + 3*r0) + a_5*E*L*M*(-12*L_2*(12*M + r0) + r0*(8*(-147 + 97*E_2)*M_2 + 4*(506 + 37*E_2)*M*r0 - 419*r0_2)) + a*E*L*M*r0_3*(4*L_2*(80*M_2 + 92*M*r0 - 75*r0_2) + 3*r0_2*(-304*M_2 + 4*(65 + 21*E_2)*M*r0 - 63*r0_2)) + a_3*E*L*M*r0*(r0_2*(8*(-332 + 99*E_2)*M_2 + 28*(93 + 16*E_2)*M*r0 - 689*r0_2) + 8*L_2*(291*M_2 - 59*M*r0 - 39*r0_2)) + 3*a_6*M*(L_2*(8*(-13 + 6*E_2)*M + (-3 + 2*E_2)*r0) + 4*E_2*r0*(49*M_2 - 101*M*r0 + 12*r0_2)) + a_4*(6*L_4*M*(8*M + r0) + 72*E_2*M*r0_3*(23*M_2 - 22*M*r0 + 6*r0_2) + L_2*r0*((588 - 2328*E_2)*M_3 + 14*(-58 + E_2)*M_2*r0 + 2*(157 + 123*E_2)*M*r0_2 + 15*r0_3)) + r0_3*(144*E_2*M*r0_5*(-2*M + r0) + 2*L_4*M*(118*M_2 - 127*M*r0 + 34*r0_2) + L_2*r0_2*(308*M_3 + (2 - 404*E_2)*M_2*r0 + 4*(-56 + 55*E_2)*M*r0_2 + 73*r0_3)) + a_2*r0*(36*E_2*M*r0_4*(23*M_2 - 23*M*r0 + 12*r0_2) + L_4*(-776*M_3 + 310*M_2*r0 + 66*M*r0_2) + L_2*r0_2*(-4*(-250 + 337*E_2)*M_3 - 2*(623 + 281*E_2)*M_2*r0 + 5*(43 + 92*E_2)*M*r0_2 + 88*r0_3))))/(6.*expr2_3); A63041 = (32*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(6*a_8*E_2*M_2*(2*M + r0) - 2*a_7*E*L*M*(12*M_2 + 9*M*r0 + 2*r0_2) + 3*a*E*L*M*r0_3*(L_4*(4*M - 6*r0) - L_2*r0_2*(3*M + 5*r0) + r0_4*(-19*M + 7*r0)) - a_5*E*L*M*r0*(L_2*(40*M + 22*r0) + r0*(98*M_2 + 33*M*r0 - 3*r0_2)) + L_2*r0_3*(3*L_4*M*(-2*M + r0) + 2*r0_4*(10*M_2 + 3*(-3 + E_2)*M*r0 + 2*r0_2) + L_2*r0_2*(6*M_2 + (-7 + 6*E_2)*M*r0 + 2*r0_2)) - a_3*E*L*M*r0_2*(18*L_4 + 2*r0_2*(75*M_2 + 26*M*r0 - 14*r0_2) + L_2*(-24*M_2 + 31*M*r0 + 35*r0_2)) + a_6*M*(6*E_2*M*r0_2*(12*M + 7*r0) + L_2*(12*M_2 + 4*(3 + 5*E_2)*M*r0 + (4 + 9*E_2)*r0_2)) + a_4*r0*(18*E_2*M_2*r0_3*(6*M + 5*r0) + L_4*M*(20*M + (13 + 9*E_2)*r0) + L_2*r0*((26 - 12*E_2)*M_3 + 9*(-1 + 4*E_2)*M_2*r0 + 8*(1 + 3*E_2)*M*r0_2 + 5*r0_3)) + a_2*r0_2*(9*L_6*M + 54*E_2*M_2*r0_5 + L_4*(-12*M_3 - (5 + 6*E_2)*M_2*r0 + 5*(2 + 3*E_2)*M*r0_2 + 5*r0_3) + L_2*r0_2*(64*M_3 + (-25 + 24*E_2)*M_2*r0 + (-16 + 21*E_2)*M*r0_2 + 9*r0_3))))/(r0_4*expr2_3); A63221 = (16*(6*a_8*E_2*M_2*(2*M + r0) - a_7*E*L*M*(24*M_2 + 21*M*r0 + 5*r0_2) + 3*a*E*L*M*r0_3*(L_4*(4*M - 6*r0) - L_2*r0_2*(9*M + 2*r0) + r0_4*(-19*M + 7*r0)) - a_5*E*L*M*r0*(L_2*(44*M + 23*r0) + r0*(92*M_2 + 43*M*r0 + r0_2)) + L_2*r0_3*(3*L_4*M*(-2*M + r0) + 2*r0_4*(10*M_2 + 3*(-3 + E_2)*M*r0 + 2*r0_2) + L_2*r0_2*(10*M_2 + (-11 + 6*E_2)*M*r0 + 3*r0_2)) - a_3*E*L*M*r0_2*(18*L_4 + r0_2*(132*M_2 + 55*M*r0 - 25*r0_2) + L_2*(-24*M_2 + 49*M*r0 + 35*r0_2)) + a_6*M*(6*E_2*M*r0_2*(12*M + 7*r0) + L_2*(12*M_2 + (15 + 22*E_2)*M*r0 + (5 + 9*E_2)*r0_2)) + a_4*r0*(18*E_2*M_2*r0_3*(6*M + 5*r0) + L_4*M*(22*M + (14 + 9*E_2)*r0) + 2*L_2*r0*((10 - 6*E_2)*M_3 + (-1 + 24*E_2)*M_2*r0 + 4*(1 + 3*E_2)*M*r0_2 + 2*r0_3)) + a_2*r0_2*(9*L_6*M + 54*E_2*M_2*r0_5 + L_2*r0_2*(52*M_3 + (-17 + 42*E_2)*M_2*r0 + 3*(-5 + 7*E_2)*M*r0_2 + 8*r0_3) + L_4*(-12*M_3 + 3*(3 + 5*E_2)*M*r0_2 + 4*r0_3 + M_2*(r0 - 6*E_2*r0)))))/(r0*expr2_3); A63401 = (2*r0_2*(6*a_6*E_2*M_2 - 6*a_5*E*L*M*(2*M + r0) + a_3*E*L*M*r0*(-18*L_2 + r0*(-43*M + r0)) + 3*a*E*L*M*r0_2*(L_2*(4*M - 6*r0) + r0_2*(-19*M + 7*r0)) + 3*a_4*M*(12*E_2*M*r0_2 + L_2*(2*M + 2*r0 + 3*E_2*r0)) + L_2*r0_2*(3*L_2*M*(-2*M + r0) + 2*r0_2*(10*M_2 + 3*(-3 + E_2)*M*r0 + 2*r0_2)) + a_2*r0*(9*L_4*M + 54*E_2*M_2*r0_3 + L_2*r0*((7 - 6*E_2)*M_2 + (-4 + 15*E_2)*M*r0 + 3*r0_2))))/expr2_3; A64021 = (48*L*r0*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0))*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/expr2_3; A64041 = (-8*(-12*a_12*E_2*M_2*(114*M_2 + 109*M*r0 + 26*r0_2) + a_11*E*L*M*(-144*(-19 + 6*E_2)*M_3 + (2642 - 936*E_2)*M_2*r0 + 12*(50 - 21*E_2)*M*r0_2 - 21*r0_3) + a*E*L*M*r0_5*(3*L_4*r0_2*(1207*M_2 + 4*(-45 + 28*E_2)*M*r0 - 296*r0_2) + 3*L_2*r0_4*(634*M_2 + 4*(13 + 45*E_2)*M*r0 - 257*r0_2) + 4*L_6*(482*M_2 - 139*M*r0 - 75*r0_2) - 9*r0_6*(31*M_2 - 4*(17 + 6*E_2)*M*r0 + 33*r0_2)) + a_3*E*L*M*r0_3*(4*L_6*(1050*M_2 - 430*M*r0 - 93*r0_2) + L_4*r0*(9504*M_3 + (6719 + 1608*E_2)*M_2*r0 + 2*(-1583 + 206*E_2)*M*r0_2 - 2568*r0_3) + 2*L_2*r0_3*(4260*M_3 + (2059 + 2790*E_2)*M_2*r0 + 2*(61 + 213*E_2)*M*r0_2 - 2024*r0_3) + 3*r0_5*(-1440*M_3 + 3*(283 + 528*E_2)*M_2*r0 + 4*(196 + 29*E_2)*M*r0_2 - 671*r0_3)) + r0_5*(216*E_2*M*r0_9*(-2*M + r0) - 16*L_8*M*(10*M_2 - 7*M*r0 + r0_2) + 3*L_2*r0_6*(54*M_3 + (25 - 456*E_2)*M_2*r0 + 4*(-15 + 61*E_2)*M*r0_2 + 17*r0_3) + 3*L_4*r0_4*(100*M_3 + (30 - 472*E_2)*M_2*r0 + 2*(-51 + 134*E_2)*M*r0_2 + 31*r0_3) + L_6*r0_2*(26*M_3 + (55 - 488*E_2)*M_2*r0 + 2*(-53 + 146*E_2)*M*r0_2 + 36*r0_3)) + a_5*E*L*M*r0_2*(-36*L_6*(13*M + 2*r0) + L_4*(16848*M_3 + 4*(-309 + 350*E_2)*M_2*r0 - 2*(1769 + 40*E_2)*M*r0_2 - 1551*r0_3) + L_2*r0*(11520*M_4 + 8*(2075 + 882*E_2)*M_3*r0 + 6*(419 + 1322*E_2)*M_2*r0_2 - 2*(1801 + 162*E_2)*M*r0_3 - 5119*r0_4) + 3*r0_3*(-2868*M_4 + 4*(-449 + 1044*E_2)*M_3*r0 + (3421 + 3240*E_2)*M_2*r0_2 - 8*(-16 + 21*E_2)*M*r0_3 - 1290*r0_4)) + a_9*E*L*M*(-2*L_2*(1296*M_3 + 2*(-34 + 195*E_2)*M_2*r0 + 12*(-22 + 17*E_2)*M*r0_2 + 57*r0_3) + r0*(96*(-49 + 59*E_2)*M_4 + 4*(1145 + 1188*E_2)*M_3*r0 - 40*(-179 + 27*E_2)*M_2*r0_2 - 12*(-29 + 88*E_2)*M*r0_3 - 777*r0_4)) + a_10*M*(L_2*(72*(-19 + 36*E_2)*M_3 + 2*(-667 + 668*E_2)*M_2*r0 + 6*(-48 + 17*E_2)*M*r0_2 + 3*(7 + 12*E_2)*r0_3) + 12*E_2*r0*(196*M_4 - 292*M_3*r0 - 426*M_2*r0_2 - 77*M*r0_3 + 18*r0_4)) + a_2*r0_3*(-108*E_2*M*r0_8*(14*M_2 + 5*M*r0 - 10*r0_2) + 4*L_8*M*(-350*M_2 + 205*M*r0 + 3*r0_2) + L_6*r0*(-1224*M_4 - (1343 + 3376*E_2)*M_3*r0 + 2*(123 + 16*E_2)*M_2*r0_2 + 2*(241 + 308*E_2)*M*r0_3 + 36*r0_4) + 3*L_2*r0_5*(520*M_4 + 3*(13 - 980*E_2)*M_3*r0 + 2*(-237 + 94*E_2)*M_2*r0_2 + (97 + 958*E_2)*M*r0_3 + 40*r0_4) + 3*L_4*r0_3*(32*M_4 + 2*(65 - 1558*E_2)*M_3*r0 + 4*(-173 + 44*E_2)*M_2*r0_2 + (265 + 798*E_2)*M*r0_3 + 49*r0_4)) - a_7*E*L*M*r0*(3*L_4*(780*M_2 + 4*(45 + 13*E_2)*M*r0 + 55*r0_2) - 2*L_2*(8496*M_4 + 8*(241 + 351*E_2)*M_3*r0 + (-599 + 930*E_2)*M_2*r0_2 - (803 + 522*E_2)*M*r0_3 - 978*r0_4) + 3*r0_2*(-4*(-895 + 648*E_2)*M_4 - 8*(41 + 708*E_2)*M_3*r0 - 3*(1147 + 536*E_2)*M_2*r0_2 + 8*(67 + 60*E_2)*M*r0_3 + 970*r0_4)) + a_8*(2*L_4*M*(432*M_3 + 2*(-134 + 585*E_2)*M_2*r0 + 63*(-3 + 7*E_2)*M*r0_2 + 3*(13 + 12*E_2)*r0_3) + 24*E_2*M*r0_3*(300*M_4 - 46*M_3*r0 - 341*M_2*r0_2 - 32*M*r0_3 + 45*r0_4) + L_2*r0*(-48*(-49 + 354*E_2)*M_5 - 4*(269 + 2264*E_2)*M_4*r0 + 2*(-981 + 800*E_2)*M_3*r0_2 + 2*(346 + 961*E_2)*M_2*r0_3 + 6*(105 + 131*E_2)*M*r0_4 + 15*r0_5)) + a_6*r0*(3*L_6*M*(260*M_2 + 2*(11 + 78*E_2)*M*r0 + (31 + 12*E_2)*r0_2) + 24*E_2*M*r0_4*(306*M_4 + 246*M_3*r0 - 220*M_2*r0_2 + 13*M*r0_3 + 90*r0_4) + L_4*(-5664*M_5 + 16*(28 - 1053*E_2)*M_4*r0 + 6*(113 - 362*E_2)*M_3*r0_2 + 2*(397 + 1830*E_2)*M_2*r0_3 + 6*(207 + 155*E_2)*M*r0_4 + 30*r0_5) + L_2*r0_2*((3540 - 17424*E_2)*M_5 - 28*(49 + 1086*E_2)*M_4*r0 - 5*(901 + 1268*E_2)*M_3*r0_2 + 2*(508 + 2635*E_2)*M_2*r0_3 + 6*(276 + 479*E_2)*M*r0_4 + 48*r0_5)) + a_4*r0_2*(12*L_8*M*(13*M + 3*r0) + 36*E_2*M*r0_6*(66*M_3 - 67*M_2*r0 + 10*M*r0_2 + 60*r0_3) + L_6*(-5616*M_4 + 12*(129 - 350*E_2)*M_3*r0 + 2*(461 + 490*E_2)*M_2*r0_2 + 24*(26 + 15*E_2)*M*r0_3 + 15*r0_4) + 3*L_2*r0_3*(1064*M_5 + 12*(51 - 550*E_2)*M_4*r0 - 2*(703 + 2048*E_2)*M_3*r0_2 + 3*(-141 + 598*E_2)*M_2*r0_3 + 2*(253 + 711*E_2)*M*r0_4 + 34*r0_5) + L_4*r0*(-1872*M_5 - 8*(398 + 1917*E_2)*M_4*r0 - 4*(326 + 3327*E_2)*M_3*r0_2 + 2*(-308 + 2025*E_2)*M_2*r0_3 + 3*(709 + 816*E_2)*M*r0_4 + 84*r0_5))))/(3.*r0_5*expr2_4); A64201 = (12*L*r0_4*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0)))/expr2_3; A64221 = (-4*(-2*a_10*E_2*M_2*(117*M + 56*r0) + a_9*E*L*M*(-36*(-13 + 4*E_2)*M_2 + 6*(37 - 13*E_2)*M*r0 - 7*r0_2) + a*E*L*M*r0_4*(L_2*r0_2*(401*M_2 + 3*(19 + 24*E_2)*M*r0 - 181*r0_2) + 2*L_4*(284*M_2 - 80*M*r0 - 47*r0_2) + 3*r0_4*(-79*M_2 + 2*(47 + 9*E_2)*M*r0 - 34*r0_2)) + a_3*E*L*M*r0_2*(4*L_4*(336*M_2 - 154*M*r0 - 31*r0_2) + L_2*r0*(1416*M_3 + (791 + 528*E_2)*M_2*r0 + 8*(-3 + 5*E_2)*M*r0_2 - 658*r0_3) + r0_3*(-1008*M_3 + (-5 + 1008*E_2)*M_2*r0 + 2*(497 + 10*E_2)*M*r0_2 - 543*r0_3)) + a_5*E*L*M*r0*(-6*L_4*(32*M + 5*r0) + r0_2*(32*(-55 + 36*E_2)*M_3 + (1033 + 1280*E_2)*M_2*r0 - 8*(-96 + 25*E_2)*M*r0_2 - 679*r0_3) + L_2*(2688*M_3 + 4*(-103 + 112*E_2)*M_2*r0 - 3*(79 + 32*E_2)*M*r0_2 - 392*r0_3)) + a_8*M*(L_2*(18*(-13 + 24*E_2)*M_2 + (-110 + 119*E_2)*M*r0 + (7 + 15*E_2)*r0_2) + 2*E_2*r0*(202*M_3 - 367*M_2*r0 - 193*M*r0_2 + 36*r0_3)) + a_6*(L_4*M*(144*M_2 + (-37 + 192*E_2)*M*r0 + (22 + 15*E_2)*r0_2) + 2*E_2*M*r0_3*(564*M_3 - 361*M_2*r0 - 275*M*r0_2 + 144*r0_3) + L_2*r0*((404 - 2688*E_2)*M_4 - (399 + 130*E_2)*M_3*r0 + (-87 + 500*E_2)*M_2*r0_2 + 2*(99 + 97*E_2)*M*r0_3 + 8*r0_4)) + a_4*r0*(L_6*M*(64*M + 15*r0) + 6*E_2*M*r0_4*(150*M_3 + M_2*r0 - 61*M*r0_2 + 72*r0_3) + L_4*(-896*M_4 - 6*(-53 + 224*E_2)*M_3*r0 + (-19 + 452*E_2)*M_2*r0_2 + 2*(102 + 59*E_2)*M*r0_3 + 8*r0_4) + L_2*r0_2*((632 - 2436*E_2)*M_4 - 4*(134 + 495*E_2)*M_3*r0 + (-469 + 563*E_2)*M_2*r0_2 + (351 + 509*E_2)*M*r0_3 + 26*r0_4)) + a_2*r0_2*(-18*E_2*M*r0_6*(6*M_2 + 13*M*r0 - 16*r0_2) + L_6*(-448*M_3 + 260*M_2*r0 + 6*M*r0_2) + L_4*r0*(-132*M_4 - (91 + 1076*E_2)*M_3*r0 + 2*(-123 + 58*E_2)*M_2*r0_2 + (167 + 195*E_2)*M*r0_3 + 17*r0_4) + L_2*r0_3*(356*M_4 + (191 - 1542*E_2)*M_3*r0 + (-547 + 130*E_2)*M_2*r0_2 + 4*(29 + 124*E_2)*M*r0_3 + 40*r0_4)) - a_7*E*L*M*(r0*((808 - 896*E_2)*M_3 - (1133 + 224*E_2)*M_2*r0 + 2*(-247 + 122*E_2)*M*r0_2 + 245*r0_3) + L_2*(432*M_2 + 37*r0_2 + 4*M*(r0 + 16*E_2*r0))) + r0_4*(72*E_2*M*r0_7*(-2*M + r0) + L_6*M*(-20*M_2 + 4*M*r0 + 3*r0_2) + L_4*r0_2*(110*M_3 - (35 + 152*E_2)*M_2*r0 + 2*(-25 + 46*E_2)*M*r0_2 + 20*r0_3) + L_2*r0_4*(102*M_3 + 2*(-34 + 83*E_2)*M*r0_2 + 22*r0_3 - 3*M_2*(r0 + 100*E_2*r0)))))/(r0_2*expr2_4); A64401 = -(r0*(-360*a_8*E_2*M_2 - 9*a_7*E*L*M*(8*(-10 + 3*E_2)*M + 3*r0) + a_5*E*L*M*(-108*L_2*(6*M + r0) + r0*(24*(-52 + 53*E_2)*M_2 + 12*(197 - 37*E_2)*M*r0 - 703*r0_2)) + a_3*E*L*M*r0*(r0_2*(3*(-895 + 504*E_2)*M_2 + 10*(317 - 12*E_2)*M*r0 - 1198*r0_2) + 12*L_2*(318*M_2 - 155*M*r0 - 33*r0_2)) + 3*a*E*L*M*r0_3*(r0_2*(-381*M_2 + 350*M*r0 + 36*E_2*M*r0 - 100*r0_2) + 4*L_2*(114*M_2 - 25*M*r0 - 24*r0_2)) + 3*a_6*M*(3*L_2*(-40*M + 72*E_2*M + 3*r0 + 6*E_2*r0) + 8*E_2*r0*(26*M_2 - 56*M*r0 + 9*r0_2)) + a_4*(54*L_4*M*(4*M + r0) + 72*E_2*M*r0_3*(22*M_2 - 25*M*r0 + 9*r0_2) + L_2*r0*((624 - 3816*E_2)*M_3 + 12*(-85 + 133*E_2)*M_2*r0 + 2*(257 + 180*E_2)*M*r0_2 + 27*r0_3)) + r0_3*(216*E_2*M*r0_5*(-2*M + r0) + 6*L_4*M*(12*M_2 - 20*M*r0 + 7*r0_2) + L_2*r0_2*(450*M_3 - (73 + 432*E_2)*M_2*r0 + 8*(-31 + 33*E_2)*M*r0_2 + 86*r0_3)) + a_2*r0*(216*E_2*M*r0_4*(4*M_2 - 4*M*r0 + 3*r0_2) + 12*L_4*M*(-106*M_2 + 59*M*r0 + 3*r0_2) + L_2*r0_2*(-3*(-367 + 984*E_2)*M_3 + 2*(-799 + 270*E_2)*M_2*r0 + 6*(62 + 95*E_2)*M*r0_2 + 98*r0_3))))/(6.*expr2_4); A65021 = (8*(6*a_8*E_2*M_2*(2*M + r0) - a_7*E*L*M*(24*M_2 + 21*M*r0 + 5*r0_2) + 3*a*E*L*M*r0_3*(L_4*(4*M - 6*r0) - L_2*r0_2*(10*M + r0) + 4*r0_4*(-5*M + 2*r0)) - a_5*E*L*M*r0*(2*M*r0*(47*M + 21*r0) + L_2*(44*M + 23*r0)) + L_2*r0_3*(3*L_4*M*(-2*M + r0) + 2*L_2*r0_2*(6*M_2 + (-7 + 3*E_2)*M*r0 + 2*r0_2) + r0_4*(22*M_2 + 3*(-7 + 2*E_2)*M*r0 + 5*r0_2)) - a_3*E*L*M*r0_2*(18*L_4 + r0_2*(138*M_2 + 53*M*r0 - 29*r0_2) + L_2*(-24*M_2 + 50*M*r0 + 34*r0_2)) + a_6*M*(6*E_2*M*r0_2*(12*M + 7*r0) + L_2*(12*M_2 + (15 + 22*E_2)*M*r0 + (5 + 9*E_2)*r0_2)) + a_4*r0*(18*E_2*M_2*r0_3*(6*M + 5*r0) + L_4*M*(22*M + (14 + 9*E_2)*r0) + L_2*r0*((22 - 12*E_2)*M_3 + 3*(-1 + 16*E_2)*M_2*r0 + (7 + 24*E_2)*M*r0_2 + 4*r0_3)) + a_2*r0_2*(9*L_6*M + 54*E_2*M_2*r0_5 + L_4*(-12*M_3 + (2 - 6*E_2)*M_2*r0 + (8 + 15*E_2)*M*r0_2 + 4*r0_3) + L_2*r0_2*(56*M_3 + 2*(-10 + 21*E_2)*M_2*r0 + (-17 + 21*E_2)*M*r0_2 + 9*r0_3))))/(r0*expr2_4); A65201 = (2*r0_2*(6*a_6*E_2*M_2 - 6*a_5*E*L*M*(2*M + r0) - 2*a_3*E*L*M*r0*(9*L_2 + (22*M - r0)*r0) + 6*a*E*L*M*r0_2*(L_2*(2*M - 3*r0) + 2*r0_2*(-5*M + 2*r0)) + 3*a_4*M*(12*E_2*M*r0_2 + L_2*(2*M + 2*r0 + 3*E_2*r0)) + a_2*r0*(9*L_4*M + 54*E_2*M_2*r0_3 + L_2*r0*((8 - 6*E_2)*M_2 + 5*(-1 + 3*E_2)*M*r0 + 3*r0_2)) + L_2*r0_2*(3*L_2*M*(-2*M + r0) + r0_2*(22*M_2 + 3*(-7 + 2*E_2)*M*r0 + 5*r0_2))))/expr2_4; A66001 = (4*L*r0_4*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0)))/expr2_4; A66021 = (-2*(-12*a_10*E_2*M_2*(28*M + 13*r0) - 3*a_9*E*L*M*(4*(-56 + 39*E_2)*M_2 + 2*(-47 + 42*E_2)*M*r0 + 11*r0_2) - a*E*L*M*r0_4*(3*r0_4*(131*M_2 + 2*(-97 + 12*E_2)*M*r0 + 80*r0_2) + L_4*(-1648*M_2 + 824*M*r0 + 84*r0_2) + L_2*r0_2*(-1871*M_2 + 934*M*r0 + 132*r0_2)) + a_5*E*L*M*r0*(-36*L_4*(17*M + 3*r0) + r0_2*(6*(-349 + 456*E_2)*M_3 + (2457 + 2116*E_2)*M_2*r0 + 2*(225 - 686*E_2)*M*r0_2 - 1539*r0_3) + L_2*(5808*M_3 + 4*(-449 + 238*E_2)*M_2*r0 - 4*(423 + 136*E_2)*M*r0_2 - 801*r0_3)) + a_3*E*L*M*r0_2*(4*L_4*(714*M_2 - 467*M*r0 - 48*r0_2) + L_2*r0*(4096*M_3 + (2269 + 1224*E_2)*M_2*r0 - 10*(181 + 34*E_2)*M*r0_2 - 1218*r0_3) + 2*r0_3*(-1077*M_3 + 6*(95 + 183*E_2)*M_2*r0 + 2*(381 - 167*E_2)*M*r0_2 - 633*r0_3)) + 3*a_8*M*(L_2*(4*(-28 + 117*E_2)*M_2 + 6*(-7 + 34*E_2)*M*r0 + (11 + 18*E_2)*r0_2) + 4*E_2*r0*(42*M_3 - 91*M_2*r0 - 35*M*r0_2 + 12*r0_3)) + r0_4*(144*E_2*M*r0_7*(-2*M + r0) - 2*L_6*M*(106*M_2 - 85*M*r0 + 16*r0_2) + L_2*r0_4*(218*M_3 - (101 + 476*E_2)*M_2*r0 + 4*(-13 + 70*E_2)*M*r0_2 + 24*r0_3) + L_4*r0_2*(-42*M_3 + (165 - 196*E_2)*M_2*r0 + 4*(-36 + 35*E_2)*M*r0_2 + 36*r0_3)) - a_7*E*L*M*(3*L_2*(468*M_2 + 4*(39 + 17*E_2)*M*r0 + 47*r0_2) + 2*r0*((504 - 968*E_2)*M_3 + 2*(-441 + 65*E_2)*M_2*r0 + (-201 + 514*E_2)*M*r0_2 + 273*r0_3)) + a_6*(3*L_4*M*(156*M_2 + 12*(3 + 17*E_2)*M*r0 + (29 + 18*E_2)*r0_2) + 12*E_2*M*r0_3*(108*M_3 - 135*M_2*r0 - 43*M*r0_2 + 48*r0_3) + L_2*r0*((504 - 5808*E_2)*M_4 + 56*(-12 + 23*E_2)*M_3*r0 + 2*(20 + 1249*E_2)*M_2*r0_2 + 3*(151 + 128*E_2)*M*r0_3 + 21*r0_4)) + a_4*r0*(6*L_6*M*(34*M + 9*r0) + 36*E_2*M*r0_4*(46*M_3 - 11*M_2*r0 - 7*M*r0_2 + 24*r0_3) + L_4*(-1936*M_4 + 24*(32 - 119*E_2)*M_3*r0 + 2*(111 + 875*E_2)*M_2*r0_2 + 6*(69 + 37*E_2)*M*r0_3 + 21*r0_4) + L_2*r0_2*((798 - 6152*E_2)*M_4 - (1213 + 3996*E_2)*M_3*r0 + 4*(-133 + 837*E_2)*M_2*r0_2 + 2*(361 + 443*E_2)*M*r0_3 + 21*r0_4)) + a_2*r0_2*(-36*E_2*M*r0_6*(11*M_2 + 8*M*r0 - 16*r0_2) - 2*L_6*M*(476*M_2 - 331*M*r0 + 15*r0_2) + L_4*M*r0*(-680*M_3 - (389 + 2660*E_2)*M_2*r0 + 2*(12 + 497*E_2)*M*r0_2 + 2*(135 + 154*E_2)*r0_3) + L_2*r0_3*(868*M_4 - (229 + 4208*E_2)*M_3*r0 + (-805 + 1754*E_2)*M_2*r0_2 + 4*(85 + 209*E_2)*M*r0_3 + 24*r0_4))))/(3.*r0_2*expr2_5); A66201 = (r0*(168*a_8*E_2*M_2 + 3*a_7*E*L*M*(16*(-7 + 5*E_2)*M + 15*r0) - 3*a_6*M*(L_2*(8*(-7 + 30*E_2)*M + (15 + 22*E_2)*r0) + 4*E_2*r0*(21*M_2 - 49*M*r0 + 12*r0_2)) + a*E*L*M*r0_3*(L_2*(-1520*M_2 + 808*M*r0 + 60*r0_2) + 3*r0_2*(227*M_2 - 242*M*r0 + 36*E_2*M*r0 + 80*r0_2)) + a_5*E*L*M*(12*L_2*(60*M + 11*r0) + r0*((504 - 920*E_2)*M_2 + 4*(-284 + 185*E_2)*M*r0 + 513*r0_2)) + a_3*E*L*M*r0*(-8*L_2*(345*M_2 - 254*M*r0 - 24*r0_2) + r0_2*((979 - 1224*E_2)*M_2 + 2*(-841 + 304*E_2)*M*r0 + 918*r0_2)) + r0_3*(144*E_2*M*(2*M - r0)*r0_5 + 2*L_4*M*(74*M_2 - 53*M*r0 + 8*r0_2) + L_2*r0_2*(-314*M_3 + (149 + 164*E_2)*M_2*r0 + 4*(19 - 31*E_2)*M*r0_2 - 36*r0_3)) - a_4*(6*L_4*M*(40*M + 11*r0) + 72*E_2*M*r0_3*(7*M_2 - 12*M*r0 + 6*r0_2) + L_2*r0*((252 - 2760*E_2)*M_3 + 2*(-274 + 1063*E_2)*M_2*r0 + 6*(61 + 37*E_2)*M*r0_2 + 21*r0_3)) - a_2*r0*(36*E_2*M*r0_4*(11*M_2 - 11*M*r0 + 12*r0_2) - 2*L_4*M*(460*M_2 - 323*M*r0 + 15*r0_2) + L_2*r0_2*((475 - 2596*E_2)*M_3 + 10*(-90 + 131*E_2)*M_2*r0 + 8*(37 + 35*E_2)*M*r0_2 + 36*r0_3))))/(6.*expr2_5); A67001 = (2*r0_2*(2*a_6*E_2*M_2 - 2*a_5*E*L*M*(2*M + r0) + a_3*E*L*M*r0*(-6*L_2 + r0*(-15*M + r0)) + a*E*L*M*r0_2*(L_2*(4*M - 6*r0) + 3*r0_2*(-7*M + 3*r0)) + a_4*M*(12*E_2*M*r0_2 + L_2*(2*M + 2*r0 + 3*E_2*r0)) + L_2*r0_2*(L_2*M*(-2*M + r0) + 2*r0_2*(4*M_2 + (-4 + E_2)*M*r0 + r0_2)) + a_2*r0*(3*L_4*M + 18*E_2*M_2*r0_3 + L_2*r0*((3 - 2*E_2)*M_2 + (-2 + 5*E_2)*M*r0 + r0_2))))/expr2_5; A68001 = -(r0*(-12*a_8*E_2*M_2 - 3*a_7*E*L*M*(2*(-4 + 7*E_2)*M + 3*r0) + a_5*E*L*M*(-6*L_2*(21*M + 4*r0) + r0*(4*(-6 + 31*E_2)*M_2 + 4*(22 - 37*E_2)*M*r0 - 69*r0_2)) + a_3*E*L*M*r0*(r0_2*((-29 + 180*E_2)*M_2 - 2*(-83 + 71*E_2)*M*r0 - 132*r0_2) + 4*L_2*(93*M_2 - 89*M*r0 - 3*r0_2)) + 3*a_6*M*(L_2*(-4*M + 42*E_2*M + 3*r0 + 4*E_2*r0) + 2*E_2*r0*(2*M_2 - 6*M*r0 + 3*r0_2)) + a*E*L*M*r0_3*(2*L_2*(134*M_2 - 91*M*r0 + 6*r0_2) - 3*r0_2*(29*M_2 + 2*(-19 + 6*E_2)*M*r0 + 14*r0_2)) + M*r0_3*(18*E_2*r0_5*(-2*M + r0) + L_4*(-44*M_2 + 38*M*r0 - 8*r0_2) + L_2*r0_2*(46*M_2 - (43 + 4*E_2)*M*r0 + 2*(5 + 4*E_2)*r0_2)) + a_2*M*r0*(-4*L_4*(31*M_2 - 26*M*r0 + 3*r0_2) + 18*E_2*r0_4*(2*M_2 - 2*M*r0 + 3*r0_2) + L_2*r0_2*((29 - 404*E_2)*M_2 + 2*(-48 + 143*E_2)*M*r0 + 2*(23 + 10*E_2)*r0_2)) + a_4*(6*L_4*M*(7*M + 2*r0) + 18*E_2*M*r0_4*(-4*M + 3*r0) + L_2*r0*((12 - 372*E_2)*M_3 + 4*(-13 + 100*E_2)*M_2*r0 + 24*(2 + E_2)*M*r0_2 + 3*r0_3))))/(3.*expr2_6); } /* A_{theta,theta} */ { A70080 = (1024*M*expr1_4*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/(r0_7*(a_2 + r0*(-2*M + r0))); A70260 = (1024*M*expr1_3*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/(r0_4*(a_2 + r0*(-2*M + r0))); A70440 = (384*M*r0*expr4_2*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/(a_2 + r0*(-2*M + r0)); A70620 = (64*M*r0_3*(L_2 + r0_2 + (a_2*(2*M + r0))/r0)*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/(a_2 + r0*(-2*M + r0)); A70800 = (4*M*r0_5*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/(a_2 + r0*(-2*M + r0)); A71080 = (512*M*expr4_3*((-(a_2*M) + r0_3 + (2*L*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0)))/(a_2 + r0*(-2*M + r0)))*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))) - 4*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(3*a_4*E_2 - 6*a_3*E*L + 2*a*E*L*(4*M - 3*r0)*r0 + a_2*(3*L_2 + 4*E_2*r0*(-M + r0)) + r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))) + 3*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(5*a_4*E_2 - 10*a_3*E*L + 8*a*E*L*(M - r0)*r0 + r0*(E_2*r0_3 + L_2*(-4*M + 2*r0)) + a_2*(5*L_2 + 2*E_2*r0*(-2*M + 3*r0)))))/(r0_5*(a_2 + r0*(-2*M + r0))); A71260 = (128*M*expr4_2*(3*(-(a_2*M) + r0_3 + (2*L*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0)))/(a_2 + r0*(-2*M + r0)))*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))) - 17*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(3*a_4*E_2 - 6*a_3*E*L + 2*a*E*L*(4*M - 3*r0)*r0 + a_2*(3*L_2 + 4*E_2*r0*(-M + r0)) + r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))) + 12*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(5*a_4*E_2 - 10*a_3*E*L + 8*a*E*L*(M - r0)*r0 + r0*(E_2*r0_3 + L_2*(-4*M + 2*r0)) + a_2*(5*L_2 + 2*E_2*r0*(-2*M + 3*r0)))))/(r0_3*(a_2 + r0*(-2*M + r0))); A71440 = (96*M*(L_2 + r0_2 + (a_2*(2*M + r0))/r0)*(9*(L_2 + r0_2 + (a_2*(2*M + r0))/r0)*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))) + ((-(a_2*M) + r0_3 + (2*L*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0)))/(a_2 + r0*(-2*M + r0)))*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/r0 + (6*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(5*a_4*E_2 - 10*a_3*E*L + 8*a*E*L*(M - r0)*r0 + r0*(E_2*r0_3 + L_2*(-4*M + 2*r0)) + a_2*(5*L_2 + 2*E_2*r0*(-2*M + 3*r0))))/r0))/(a_2 + r0*(-2*M + r0)); A71620 = (8*M*r0*((-(a_2*M) + r0_3 + (2*L*(a_3*E*M - a_2*L*M + 3*a*E*M*r0_2 + L*r0_2*(-2*M + r0)))/(a_2 + r0*(-2*M + r0)))*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))) - 19*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(3*a_4*E_2 - 6*a_3*E*L + 2*a*E*L*(4*M - 3*r0)*r0 + a_2*(3*L_2 + 4*E_2*r0*(-M + r0)) + r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))) + 12*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(5*a_4*E_2 - 10*a_3*E*L + 8*a*E*L*(M - r0)*r0 + r0*(E_2*r0_3 + L_2*(-4*M + 2*r0)) + a_2*(5*L_2 + 2*E_2*r0*(-2*M + 3*r0)))))/(a_2 + r0*(-2*M + r0)); A71800 = (4*M*r0_5*(L_2*(4*M - 2*r0) + a_2*E_2*(4*M - r0) - E_2*r0_3 + a*E*L*(-8*M + 3*r0)))/(a_2 + r0*(-2*M + r0)); A72060 = (1024*M*expr1_3*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/(r0_4*expr2_2); A72240 = (768*M*r0*expr4_2*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/expr2_2; A72420 = (192*M*r0_2*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/expr2_2; A72600 = (16*M*r0_5*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/expr2_2; A73060 = (-128*M*expr1_2*(-9*a_8*E_2*(3*M + r0) + 18*a_7*E*L*((3 + E_2)*M + r0) + r0_3*(E_2*r0_3 + L_2*(-4*M + 2*r0))*(r0_2*(-15*M + 7*r0) + L_2*(-21*M + 10*r0)) + 2*a*E*L*r0_3*(L_2*(-120*M_2 + 97*M*r0 - 18*r0_2) + r0_2*(-60*M_2 + (49 + 9*E_2)*M*r0 - 9*r0_2)) - a_6*(9*L_2*(3*M + 6*E_2*M + r0 + E_2*r0) + 4*E_2*r0*(-8*M_2 + 13*M*r0 + 4*r0_2)) + 2*a_5*E*L*(9*L_2*(3*M + r0) + r0*(-4*(8 + 3*E_2)*M_2 + (35 + 39*E_2)*M*r0 + 9*r0_2)) + a_4*(-9*L_4*(2*M + r0) + L_2*r0*(8*(4 + 9*E_2)*M_2 - (18 + 203*E_2)*M*r0 + 2*(-1 + E_2)*r0_2) + 2*E_2*r0_2*(24*M_3 + 32*M_2*r0 - 27*M*r0_2 + r0_3)) - 2*a_3*E*L*r0*(L_2*(36*M_2 - 86*M*r0 + 9*r0_2) + r0*(48*M_3 + 4*(7 + 9*E_2)*M_2*r0 - 3*(19 + 13*E_2)*M*r0_2 + 9*r0_3)) + a_2*r0*(4*E_2*r0_4*(12*M_2 - 11*M*r0 + 4*r0_2) + L_4*(24*M_2 - 47*M*r0 + 16*r0_2) + L_2*r0*(48*M_3 + 4*(-2 + 57*E_2)*M_2*r0 - (53 + 190*E_2)*M*r0_2 + 21*(1 + E_2)*r0_3))))/(r0_5*expr2_3); A73240 = (-96*M*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-6*a_8*E_2*(3*M + r0) + 12*a_7*E*L*((3 + E_2)*M + r0) + r0_3*(E_2*r0_3 + L_2*(-4*M + 2*r0))*(r0_2*(-15*M + 7*r0) + L_2*(-19*M + 9*r0)) + 2*a*E*L*r0_3*(L_2*(-100*M_2 + 81*M*r0 - 15*r0_2) + r0_2*(-60*M_2 + (49 + 6*E_2)*M*r0 - 9*r0_2)) + 2*a_5*E*L*(6*L_2*(3*M + r0) + r0*(-2*(1 + 4*E_2)*M_2 + (27 + 26*E_2)*M*r0 + 3*r0_2)) - a_6*(6*L_2*(3*M + 6*E_2*M + r0 + E_2*r0) + E_2*r0*(-2*M_2 + 41*M*r0 + 9*r0_2)) + a_4*(-6*L_4*(2*M + r0) + L_2*r0*((2 + 48*E_2)*M_2 - (13 + 145*E_2)*M*r0 + 3*(1 + E_2)*r0_2) + E_2*r0_2*(72*M_3 + 36*M_2*r0 - 51*M*r0_2 + 7*r0_3)) + a_2*r0*(L_4*(16*M_2 - 41*M*r0 + 15*r0_2) + E_2*r0_4*(42*M_2 - 43*M*r0 + 17*r0_2) + L_2*r0*(72*M_3 + 4*(-6 + 43*E_2)*M_2*r0 - 5*(11 + 28*E_2)*M*r0_2 + (23 + 18*E_2)*r0_3)) - 2*a_3*E*L*r0*(L_2*(24*M_2 - 67*M*r0 + 9*r0_2) + 2*r0*(36*M_3 - (29 + 13*E_2)*M*r0_2 + 6*r0_3 + 3*M_2*(r0 + 4*E_2*r0)))))/(r0_2*expr2_3); A73420 = (-24*M*r0*(-3*a_8*E_2*(3*M + r0) + 6*a_7*E*L*((3 + E_2)*M + r0) + r0_3*(E_2*r0_3 + L_2*(-4*M + 2*r0))*(r0_2*(-15*M + 7*r0) + L_2*(-17*M + 8*r0)) + 2*a*E*L*r0_3*(L_2*(-80*M_2 + 65*M*r0 - 12*r0_2) + r0_2*(-60*M_2 + (49 + 3*E_2)*M*r0 - 9*r0_2)) + 2*a_5*E*L*(3*L_2*(3*M + r0) + r0*(-4*(-7 + E_2)*M_2 + (19 + 13*E_2)*M*r0 - 3*r0_2)) - a_6*(3*L_2*(3*M + 6*E_2*M + r0 + E_2*r0) + 2*E_2*r0*(14*M_2 + 15*M*r0 + r0_2)) + a_4*(-3*L_4*(2*M + r0) + L_2*r0*(4*(-7 + 6*E_2)*M_2 - (8 + 87*E_2)*M*r0 + 4*(2 + E_2)*r0_2) + 4*E_2*r0_2*(24*M_3 + 2*M_2*r0 - 12*M*r0_2 + 3*r0_3)) - 2*a_3*E*L*r0*(3*L_2*(4*M_2 - 16*M*r0 + 3*r0_2) + r0*(96*M_3 + 4*(-4 + 3*E_2)*M_2*r0 - (59 + 13*E_2)*M*r0_2 + 15*r0_3)) + a_2*r0*(6*E_2*r0_4*(6*M_2 - 7*M*r0 + 3*r0_2) + L_4*(8*M_2 - 35*M*r0 + 14*r0_2) + L_2*r0*(96*M_3 + 4*(-10 + 29*E_2)*M_2*r0 - 3*(19 + 30*E_2)*M*r0_2 + 5*(5 + 3*E_2)*r0_3))))/expr2_3; A73600 = (-2*M*r0_5*(2*a_3*E*L*(29*M - 9*r0) + a_4*E_2*(-29*M + 5*r0) - 2*a*E*L*r0*(60*M_2 - 49*M*r0 + 9*r0_2) + (15*M - 7*r0)*r0*(L_2*(4*M - 2*r0) - E_2*r0_3) + a_2*(L_2*(-29*M + 13*r0) + 4*E_2*r0*(15*M_2 - 10*M*r0 + 3*r0_2))))/expr2_3; A74040 = (384*M*r0*expr4_2*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/expr2_3; A74220 = (192*M*r0_2*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/expr2_3; A74400 = (24*M*r0_5*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/expr2_3; A75040 = (-96*M*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-3*a_8*E_2*(3*M + r0) + 6*a_7*E*L*((3 + E_2)*M + r0) + r0_3*(E_2*r0_3 + L_2*(-4*M + 2*r0))*(r0_2*(-7*M + 3*r0) + L_2*(-9*M + 4*r0)) + a_4*(-3*L_4*(2*M + r0) + L_2*M*r0*(4*M + 24*E_2*M - 8*r0 - 71*E_2*r0) + 8*E_2*M*r0_2*(4*M_2 + 3*M*r0 - 3*r0_2)) + 2*a*E*L*r0_3*(L_2*(-48*M_2 + 37*M*r0 - 6*r0_2) + r0_2*(-28*M_2 + 3*(7 + E_2)*M*r0 - 3*r0_2)) - a_6*(3*L_2*(3*M + 6*E_2*M + r0 + E_2*r0) + 2*E_2*r0*(-2*M_2 + 11*M*r0 + 3*r0_2)) + 2*a_5*E*L*(3*L_2*(3*M + r0) + r0*(-4*(1 + E_2)*M_2 + (15 + 13*E_2)*M*r0 + 3*r0_2)) - 2*a_3*E*L*r0*(L_2*(12*M_2 - 32*M*r0 + 3*r0_2) + r0*(32*M_3 + 4*(2 + 3*E_2)*M_2*r0 - (27 + 13*E_2)*M*r0_2 + 3*r0_3)) + a_2*r0*(2*E_2*r0_4*(10*M_2 - 9*M*r0 + 3*r0_2) + L_4*(8*M_2 - 19*M*r0 + 6*r0_2) + L_2*r0*(32*M_3 + 4*(-2 + 21*E_2)*M_2*r0 - (25 + 66*E_2)*M*r0_2 + (9 + 7*E_2)*r0_3))))/(r0_2*expr2_4); A75220 = (-24*M*r0*(-3*a_8*E_2*(3*M + r0) + 6*a_7*E*L*((3 + E_2)*M + r0) + r0_3*(E_2*r0_3 + L_2*(-4*M + 2*r0))*(2*r0_2*(-7*M + 3*r0) + L_2*(-16*M + 7*r0)) + 2*a_5*E*L*(3*L_2*(3*M + r0) + M*r0*(22*M - 4*E_2*M + 22*r0 + 13*E_2*r0)) + 2*a*E*L*r0_3*(L_2*(-76*M_2 + 58*M*r0 - 9*r0_2) + r0_2*(-56*M_2 + 3*(14 + E_2)*M*r0 - 6*r0_2)) - a_6*(3*L_2*(3*M + 6*E_2*M + r0 + E_2*r0) + E_2*r0*(22*M_2 + 33*M*r0 + 5*r0_2)) + a_4*(-3*L_4*(2*M + r0) + L_2*r0*((-22 + 24*E_2)*M_2 - (11 + 84*E_2)*M*r0 + (5 + E_2)*r0_2) + E_2*r0_2*(88*M_3 + 20*M_2*r0 - 45*M*r0_2 + 5*r0_3)) - 2*a_3*E*L*r0*(3*L_2*(4*M_2 - 15*M*r0 + 2*r0_2) + r0*(88*M_3 + 6*(-1 + 2*E_2)*M_2*r0 - (55 + 13*E_2)*M*r0_2 + 9*r0_3)) + a_2*r0*(L_4*(8*M_2 - 32*M*r0 + 11*r0_2) + E_2*r0_4*(34*M_2 - 35*M*r0 + 13*r0_2) + L_2*r0*(88*M_3 + 16*(-2 + 7*E_2)*M_2*r0 - 2*(26 + 41*E_2)*M*r0_2 + (20 + 11*E_2)*r0_3))))/expr2_4; A75400 = (-6*M*r0_5*(2*a_3*E*L*(13*M - 3*r0) + a_4*E_2*(-13*M + r0) - 2*a*E*L*r0*(28*M_2 - 21*M*r0 + 3*r0_2) + (7*M - 3*r0)*r0*(L_2*(4*M - 2*r0) - E_2*r0_3) + a_2*(L_2*(-13*M + 5*r0) + 4*E_2*r0*(7*M_2 - 4*M*r0 + r0_2))))/expr2_4; A76020 = (64*M*r0_2*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/expr2_4; A76200 = (16*M*r0_5*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/expr2_4; A77020 = (-8*M*r0*(-3*a_8*E_2*(3*M + r0) + 6*a_7*E*L*((3 + E_2)*M + r0) + r0_3*(E_2*r0_3 + L_2*(-4*M + 2*r0))*(r0_2*(-13*M + 5*r0) + L_2*(-15*M + 6*r0)) + 2*a*E*L*r0_3*(L_2*(-72*M_2 + 51*M*r0 - 6*r0_2) + r0_2*(-52*M_2 + (35 + 3*E_2)*M*r0 - 3*r0_2)) - a_6*(3*L_2*(3*M + 6*E_2*M + r0 + E_2*r0) + 4*E_2*r0*(4*M_2 + 9*M*r0 + 2*r0_2)) + 2*a_5*E*L*(3*L_2*(3*M + r0) + r0*(-4*(-4 + E_2)*M_2 + (25 + 13*E_2)*M*r0 + 3*r0_2)) - a_4*(3*L_4*(2*M + r0) + L_2*r0*(-8*(-2 + 3*E_2)*M_2 + (14 + 81*E_2)*M*r0 + 2*(-1 + E_2)*r0_2) + 2*E_2*r0_2*(-40*M_3 - 16*M_2*r0 + 21*M*r0_2 + r0_3)) + a_2*r0*(4*E_2*r0_4*(8*M_2 - 7*M*r0 + 2*r0_2) + L_4*(8*M_2 - 29*M*r0 + 8*r0_2) + L_2*r0*(80*M_3 + 12*(-2 + 9*E_2)*M_2*r0 - (47 + 74*E_2)*M*r0_2 + (15 + 7*E_2)*r0_3)) - 2*a_3*E*L*r0*(3*L_2*(4*M_2 - 14*M*r0 + r0_2) + r0*(80*M_3 - (51 + 13*E_2)*M*r0_2 + 3*r0_3 + 4*M_2*(r0 + 3*E_2*r0)))))/expr2_5; A77200 = (-2*M*r0_5*(2*a_3*E*L*(23*M - 3*r0) - a_4*E_2*(23*M + r0) - 2*a*E*L*r0*(52*M_2 - 35*M*r0 + 3*r0_2) + (13*M - 5*r0)*r0*(L_2*(4*M - 2*r0) - E_2*r0_3) + a_2*(L_2*(-23*M + 7*r0) + 4*E_2*r0*(13*M_2 - 6*M*r0 + r0_2))))/expr2_5; A78000 = (4*M*r0_5*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/expr2_5; A79000 = (-2*M*r0_5*(10*a_3*E*L*M - a_4*E_2*(5*M + r0) + 2*a*E*L*M*r0*(-12*M + 7*r0) + (3*M - r0)*r0*(L_2*(4*M - 2*r0) - E_2*r0_3) + a_2*(4*E_2*M*(3*M - r0)*r0 + L_2*(-5*M + r0))))/expr2_6; } /* A_{theta,phi} */ { A80161 = (-128*L*expr1_3*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/(r0_6*(a_2 + r0*(-2*M + r0))); A80341 = (-96*L*expr1_2*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/(r0_3*(a_2 + r0*(-2*M + r0))); A80521 = (-24*L*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/(a_2 + r0*(-2*M + r0)); A80701 = 2*L*r0_3*(E*M*(a_3 - 3*a*r0_2) - L*(a_2*M + 2*r0_2*(-M + r0)) + (L*M*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/(a_2 + r0*(-2*M + r0))); A81161 = (64*expr1_2*(2*a_10*E_2*M_2*(2*M + r0) - a_9*E*L*M*(8*(1 + 3*E_2)*M_2 + (7 + 12*E_2)*M*r0 + 2*r0_2) + L_2*(2*M - r0)*r0_4*(8*L_4*M*(-2*M + r0) + 2*L_2*r0_2*(-8*M_2 + 3*E_2*M*r0 + 2*r0_2) + r0_4*(8*M_2 + (-16 + 7*E_2)*M*r0 + 6*r0_2)) + a*E*L*M*r0_4*(2*L_2*r0_2*(62*M_2 - (47 + 3*E_2)*M*r0 + 8*r0_2) + 2*L_4*(44*M_2 - 40*M*r0 + 9*r0_2) - r0_4*(40*M_2 + 6*(-11 + 2*E_2)*M*r0 + 23*r0_2)) + a_8*M*(4*E_2*M*r0*(-2*M_2 + r0_2) + L_2*((4 + 72*E_2)*M_2 + (5 + 37*E_2)*M*r0 + 2*(1 + E_2)*r0_2)) - a_7*E*L*M*(L_2*(72*M_2 + 2*(19 + 3*E_2)*M*r0 + 6*r0_2) + r0*(-16*(1 + 2*E_2)*M_3 + 8*(-1 + 11*E_2)*M_2*r0 + (15 + 64*E_2)*M*r0_2 + 9*r0_3)) + a_3*E*L*M*r0_2*(2*L_4*(12*M_2 - 33*M*r0 + 7*r0_2) + r0_3*(-116*M_3 + 12*(9 + 2*E_2)*M_2*r0 + (51 - 64*E_2)*M*r0_2 - 51*r0_3) + 2*L_2*r0*(152*M_3 + 12*(-4 + E_2)*M_2*r0 - (81 + 13*E_2)*M*r0_2 + 17*r0_3)) + a_5*E*L*M*r0*(-2*L_4*(9*M + 2*r0) + 2*L_2*(48*M_3 + 2*(-55 + 2*E_2)*M_2*r0 - (45 + 13*E_2)*M*r0_2 + 6*r0_3) - r0_2*((4 - 96*E_2)*M_3 + 4*(-21 + 10*E_2)*M_2*r0 + (23 + 104*E_2)*M*r0_2 + 35*r0_3)) + a_6*M*(-8*E_2*M*r0_4*(5*M + 2*r0) + L_4*(24*M_2 + (13 + 18*E_2)*M*r0 + 2*(2 + E_2)*r0_2) + L_2*r0*(-8*(1 + 12*E_2)*M_3 + 2*(-4 + 121*E_2)*M_2*r0 + 5*(2 + 29*E_2)*M*r0_2 - 7*(-1 + E_2)*r0_3)) + a_4*r0*(2*L_6*M*(3*M + r0) + 36*E_2*M_2*r0_4*(2*M_2 - r0_2) + L_4*M*(-32*M_3 + 6*(11 - 4*E_2)*M_2*r0 + 9*(1 + 8*E_2)*M*r0_2 - (5 + 6*E_2)*r0_3) + L_2*r0_2*((4 - 296*E_2)*M_4 + 4*(-12 + 23*E_2)*M_3*r0 + (33 + 217*E_2)*M_2*r0_2 - 3*(-4 + 9*E_2)*M*r0_3 - 6*r0_4)) - a_2*r0_2*(18*E_2*M_2*r0_6*(-2*M + r0) + 4*L_6*M*(2*M_2 - 5*M*r0 + 2*r0_2) + L_4*r0*(104*M_4 + 4*(-11 + 20*E_2)*M_3*r0 - 2*(19 + 37*E_2)*M_2*r0_2 + (9 + 14*E_2)*M*r0_3 + 4*r0_4) + L_2*r0_3*(-56*M_4 + 6*(16 + 17*E_2)*M_3*r0 - 3*(4 + 41*E_2)*M_2*r0_2 + 5*(-7 + 5*E_2)*M*r0_3 + 12*r0_4))))/(r0_8*expr2_2); A81341 = (16*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(6*a_10*E_2*M_2*(2*M + r0) - a_9*E*L*M*(24*(1 + 3*E_2)*M_2 + 12*(2 + 3*E_2)*M*r0 + 7*r0_2) + L_2*(2*M - r0)*r0_4*(26*L_4*M*(-2*M + r0) + 3*r0_4*(8*M_2 + (-16 + 7*E_2)*M*r0 + 6*r0_2) + L_2*r0_2*(-44*M_2 + (-6 + 19*E_2)*M*r0 + 14*r0_2)) + a*E*L*M*r0_4*(3*L_2*r0_2*(112*M_2 - 2*(39 + 4*E_2)*M*r0 + 11*r0_2) + 4*L_4*(76*M_2 - 68*M*r0 + 15*r0_2) - 3*r0_4*(40*M_2 + 6*(-11 + 2*E_2)*M*r0 + 23*r0_2)) + a_8*M*(12*E_2*M*r0*(-2*M_2 + r0_2) + L_2*(12*(1 + 18*E_2)*M_2 + 2*(9 + 61*E_2)*M*r0 + (7 + 9*E_2)*r0_2)) - a_7*E*L*M*(L_2*(216*M_2 + 8*(17 + 3*E_2)*M*r0 + 25*r0_2) + 2*r0*(-24*(1 + 2*E_2)*M_3 + 6*(-3 + 22*E_2)*M_2*r0 + (19 + 96*E_2)*M*r0_2 + 13*r0_3)) + a_5*E*L*M*r0*(-18*L_4*(4*M + r0) + L_2*(288*M_3 + 16*(-37 + 2*E_2)*M_2*r0 - 26*(11 + 4*E_2)*M*r0_2 + 23*r0_3) - 2*r0_2*((12 - 144*E_2)*M_3 + 4*(-28 + 15*E_2)*M_2*r0 + (31 + 156*E_2)*M*r0_2 + 50*r0_3)) + a_3*E*L*M*r0_2*(L_4*(96*M_2 - 236*M*r0 + 42*r0_2) - 6*r0_3*(52*M_3 - 2*(25 + 6*E_2)*M_2*r0 + (-25 + 32*E_2)*M*r0_2 + 25*r0_3) + L_2*r0*(864*M_3 + 8*(-31 + 12*E_2)*M_2*r0 - 8*(58 + 13*E_2)*M*r0_2 + 81*r0_3)) + a_6*(-24*E_2*M_2*r0_4*(5*M + 2*r0) + L_4*M*(72*M_2 + 2*(25 + 36*E_2)*M*r0 + (16 + 9*E_2)*r0_2) + L_2*r0*(-24*(1 + 12*E_2)*M_4 + 4*(-9 + 173*E_2)*M_3*r0 + 2*(13 + 224*E_2)*M_2*r0_2 + (27 - 14*E_2)*M*r0_3 + 2*r0_4)) + a_4*r0*(3*L_6*M*(8*M + 3*r0) + 108*E_2*M_2*r0_4*(2*M_2 - r0_2) + L_2*r0_2*((24 - 864*E_2)*M_4 + 8*(-16 + 31*E_2)*M_3*r0 + 2*(35 + 318*E_2)*M_2*r0_2 + (37 - 76*E_2)*M*r0_3 - 14*r0_4) + L_4*(-96*M_4 + 4*(41 - 24*E_2)*M_3*r0 + 2*(15 + 137*E_2)*M_2*r0_2 - (8 + 17*E_2)*M*r0_3 + 2*r0_4)) - a_2*r0_2*(54*E_2*M_2*r0_6*(-2*M + r0) + L_6*M*(32*M_2 - 66*M*r0 + 25*r0_2) + L_4*r0*(288*M_4 + 8*(-15 + 37*E_2)*M_3*r0 - 8*(13 + 34*E_2)*M_2*r0_2 + (22 + 45*E_2)*M*r0_3 + 12*r0_4) + L_2*r0_3*(-144*M_4 + 4*(62 + 69*E_2)*M_3*r0 - 22*(1 + 16*E_2)*M_2*r0_2 + (-101 + 74*E_2)*M*r0_3 + 34*r0_4))))/(r0_5*expr2_2); A81521 = (4*(6*a_10*E_2*M_2*(2*M + r0) - a_9*E*L*M*(24*(1 + 3*E_2)*M_2 + 9*(3 + 4*E_2)*M*r0 + 8*r0_2) + L_2*(2*M - r0)*r0_4*(28*L_4*M*(-2*M + r0) + 4*L_2*r0_2*(-10*M_2 + (-3 + 5*E_2)*M*r0 + 4*r0_2) + 3*r0_4*(8*M_2 + (-16 + 7*E_2)*M*r0 + 6*r0_2)) + a*E*L*M*r0_4*(6*L_2*r0_2*(50*M_2 - (31 + 5*E_2)*M*r0 + 3*r0_2) - 3*r0_4*(40*M_2 + 6*(-11 + 2*E_2)*M*r0 + 23*r0_2) + L_4*(344*M_2 - 304*M*r0 + 66*r0_2)) + a_8*M*(12*E_2*M*r0*(-2*M_2 + r0_2) + L_2*(12*(1 + 18*E_2)*M_2 + 7*(3 + 19*E_2)*M*r0 + 4*(2 + 3*E_2)*r0_2)) - a_7*E*L*M*(2*L_2*(108*M_2 + (79 + 15*E_2)*M*r0 + 16*r0_2) + r0*(-48*(1 + 2*E_2)*M_3 + 24*(-2 + 11*E_2)*M_2*r0 + (31 + 192*E_2)*M*r0_2 + 25*r0_3)) + a_3*E*L*M*r0_2*(2*L_4*(60*M_2 - 137*M*r0 + 21*r0_2) + 2*L_2*r0*(408*M_3 + 4*(-26 + 15*E_2)*M_2*r0 - 13*(17 + 5*E_2)*M*r0_2 + 30*r0_3) - 3*r0_3*(92*M_3 - 4*(23 + 6*E_2)*M_2*r0 + (-49 + 64*E_2)*M*r0_2 + 49*r0_3)) + a_5*E*L*M*r0*(-6*L_4*(15*M + 4*r0) + 2*L_2*(144*M_3 + 2*(-131 + 10*E_2)*M_2*r0 - (151 + 65*E_2)*M*r0_2 + 5*r0_3) - r0_2*(-36*(-1 + 8*E_2)*M_3 + 4*(-49 + 30*E_2)*M_2*r0 + (55 + 312*E_2)*M*r0_2 + 95*r0_3)) + a_6*(-24*E_2*M_2*r0_4*(5*M + 2*r0) + L_4*M*(72*M_2 + (61 + 90*E_2)*M*r0 + 4*(5 + 3*E_2)*r0_2) + L_2*r0*(-24*(1 + 12*E_2)*M_4 + 2*(-24 + 329*E_2)*M_3*r0 + (22 + 461*E_2)*M_2*r0_2 + (33 - 7*E_2)*M*r0_3 + 4*r0_4)) + a_4*r0*(6*L_6*M*(5*M + 2*r0) + 108*E_2*M_2*r0_4*(2*M_2 - r0_2) + L_2*r0_2*((36 - 840*E_2)*M_4 + 4*(-28 + 55*E_2)*M_3*r0 + (41 + 621*E_2)*M_2*r0_2 + (38 - 71*E_2)*M*r0_3 - 10*r0_4) + L_4*(-96*M_4 + 10*(13 - 12*E_2)*M_3*r0 + (33 + 332*E_2)*M_2*r0_2 - (1 + 16*E_2)*M*r0_3 + 4*r0_4)) - a_2*r0_2*(54*E_2*M_2*r0_6*(-2*M + r0) + 2*L_6*M*(20*M_2 - 36*M*r0 + 13*r0_2) + L_4*r0*(264*M_4 + 4*(-27 + 88*E_2)*M_3*r0 - 2*(47 + 161*E_2)*M_2*r0_2 + (17 + 48*E_2)*M*r0_3 + 12*r0_4) + L_2*r0_3*(-120*M_4 + 2*(104 + 123*E_2)*M_3*r0 - (8 + 335*E_2)*M_2*r0_2 + (-97 + 73*E_2)*M*r0_3 + 32*r0_4))))/(r0_2*expr2_2); A81701 = -((r0*(-2*a_8*E_2*M_2 + a_7*E*L*M*(4*(1 + 3*E_2)*M + 3*r0) - a_6*M*(2*E_2*M*r0*(-2*M + r0) + L_2*(2*M + 36*E_2*M + 3*r0 + 5*E_2*r0)) + a_5*E*L*M*(2*L_2*(18*M + 5*r0) + r0*(-8*(1 + 2*E_2)*M_2 + 2*(-3 + 26*E_2)*M*r0 + 5*r0_2)) - L_2*(2*M - r0)*r0_3*(10*L_2*M*(-2*M + r0) + r0_2*(8*M_2 + (-16 + 7*E_2)*M*r0 + 6*r0_2)) + a*E*L*M*r0_3*(-8*L_2*(16*M_2 - 14*M*r0 + 3*r0_2) + r0_2*(40*M_2 + 6*(-11 + 2*E_2)*M*r0 + 23*r0_2)) + a_3*E*L*M*r0*(-2*L_2*(24*M_2 - 52*M*r0 + 7*r0_2) + r0_2*((8 - 48*E_2)*M_2 + 4*(-7 + 13*E_2)*M*r0 + 25*r0_2)) + a_4*(18*E_2*M_2*r0_4 - L_4*M*(12*M + 5*r0) + L_2*r0*((4 + 48*E_2)*M_3 + 2*(4 - 65*E_2)*M_2*r0 + (-6 + 5*E_2)*M*r0_2 - 2*r0_3)) + a_2*r0*(18*E_2*M_2*r0_4*(-2*M + r0) + L_4*M*(16*M_2 - 26*M*r0 + 9*r0_2) + L_2*r0_2*(8*(-1 + 17*E_2)*M_3 - 2*(-9 + 62*E_2)*M_2*r0 + (-15 + 17*E_2)*M*r0_2 + 4*r0_3))))/expr2_2); A82141 = (-96*L*expr1_2*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/(r0_3*expr2_2); A82321 = (-48*L*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/expr2_2; A82501 = (-6*L*r0_3*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/expr2_2; A83141 = (-16*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-6*a_10*E_2*M_2*(2*M + r0) + a_9*E*L*M*(24*(1 + 3*E_2)*M_2 + 12*(2 + 3*E_2)*M*r0 + 7*r0_2) + a*E*L*M*r0_4*(L_4*(-312*M_2 + 286*M*r0 - 66*r0_2) + L_2*r0_2*(-338*M_2 + (239 + 24*E_2)*M*r0 - 36*r0_2) + 9*r0_4*(14*M_2 + (-23 + 4*E_2)*M*r0 + 8*r0_2)) - a_8*M*(12*E_2*M*r0*(-2*M_2 + r0_2) + L_2*(12*(1 + 18*E_2)*M_2 + 2*(9 + 61*E_2)*M*r0 + (7 + 9*E_2)*r0_2)) + L_2*r0_4*(2*L_4*M*(54*M_2 - 55*M*r0 + 14*r0_2) + L_2*r0_2*(88*M_3 - (28 + 39*E_2)*M_2*r0 + 20*(-2 + E_2)*M*r0_2 + 16*r0_3) + r0_4*(-52*M_3 + (130 - 43*E_2)*M_2*r0 + 2*(-46 + 11*E_2)*M*r0_2 + 20*r0_3)) + a_7*E*L*M*(L_2*(216*M_2 + 8*(17 + 3*E_2)*M*r0 + 25*r0_2) + r0*(-48*(1 + 2*E_2)*M_3 + 2*(-17 + 132*E_2)*M_2*r0 + (37 + 192*E_2)*M*r0_2 + 25*r0_3)) + a_5*E*L*M*r0*(18*L_4*(4*M + r0) + L_2*(-288*M_3 + 4*(151 - 8*E_2)*M_2*r0 + (281 + 104*E_2)*M*r0_2 - 30*r0_3) + r0_2*(-4*(-5 + 72*E_2)*M_3 + 2*(-113 + 60*E_2)*M_2*r0 + (67 + 312*E_2)*M*r0_2 + 101*r0_3)) + a_3*E*L*M*r0_2*(L_4*(-96*M_2 + 242*M*r0 - 48*r0_2) + L_2*r0*(-880*M_3 + (266 - 96*E_2)*M_2*r0 + 8*(59 + 13*E_2)*M*r0_2 - 91*r0_3) + r0_3*(324*M_3 - 2*(157 + 36*E_2)*M_2*r0 + 3*(-51 + 64*E_2)*M*r0_2 + 155*r0_3)) - a_6*(-24*E_2*M_2*r0_4*(5*M + 2*r0) + L_4*M*(72*M_2 + 2*(25 + 36*E_2)*M*r0 + (16 + 9*E_2)*r0_2) + L_2*r0*(-24*(1 + 12*E_2)*M_4 + 2*(-17 + 349*E_2)*M_3*r0 + 5*(5 + 89*E_2)*M_2*r0_2 + (26 - 17*E_2)*M*r0_3 + 2*r0_4)) - a_4*r0*(3*L_6*M*(8*M + 3*r0) + 108*E_2*M_2*r0_4*(2*M_2 - r0_2) + L_2*r0_2*((20 - 872*E_2)*M_4 + 4*(-32 + 65*E_2)*M_3*r0 + 3*(26 + 213*E_2)*M_2*r0_2 + (35 - 83*E_2)*M*r0_3 - 16*r0_4) + L_4*(-96*M_4 + 2*(85 - 48*E_2)*M_3*r0 + (28 + 277*E_2)*M_2*r0_2 - 4*(3 + 5*E_2)*M*r0_3 + 2*r0_4)) + a_2*r0_2*(54*E_2*M_2*r0_6*(-2*M + r0) + L_6*M*(32*M_2 - 69*M*r0 + 28*r0_2) + L_4*r0*(296*M_4 + 6*(-21 + 50*E_2)*M_3*r0 - 10*(11 + 28*E_2)*M_2*r0_2 + (24 + 49*E_2)*M*r0_3 + 14*r0_4) + L_2*r0_3*(-152*M_4 + 2*(133 + 139*E_2)*M_3*r0 - (29 + 359*E_2)*M_2*r0_2 + (-108 + 79*E_2)*M*r0_3 + 38*r0_4))))/(r0_5*expr2_3); A83321 = (8*(6*a_10*E_2*M_2*(2*M + r0) - a_9*E*L*M*(24*(1 + 3*E_2)*M_2 + 9*(3 + 4*E_2)*M*r0 + 8*r0_2) + a*E*L*M*r0_4*(-9*r0_4*(14*M_2 + (-23 + 4*E_2)*M*r0 + 8*r0_2) + L_2*r0_2*(302*M_2 - (191 + 30*E_2)*M*r0 + 21*r0_2) + L_4*(352*M_2 - 318*M*r0 + 72*r0_2)) + a_8*M*(12*E_2*M*r0*(-2*M_2 + r0_2) + L_2*(12*(1 + 18*E_2)*M_2 + 7*(3 + 19*E_2)*M*r0 + 4*(2 + 3*E_2)*r0_2)) + L_2*r0_4*(-2*L_4*M*(58*M_2 - 59*M*r0 + 15*r0_2) + r0_4*(52*M_3 + (-130 + 43*E_2)*M_2*r0 + 2*(46 - 11*E_2)*M*r0_2 - 20*r0_3) + L_2*r0_2*(-80*M_3 + (12 + 41*E_2)*M_2*r0 + (50 - 21*E_2)*M*r0_2 - 18*r0_3)) - 2*a_7*E*L*M*(L_2*(108*M_2 + (79 + 15*E_2)*M*r0 + 16*r0_2) + r0*(-24*(1 + 2*E_2)*M_3 + (-23 + 132*E_2)*M_2*r0 + 3*(5 + 32*E_2)*M*r0_2 + 12*r0_3)) + 2*a_3*E*L*M*r0_2*(4*L_4*(15*M_2 - 35*M*r0 + 6*r0_2) + r0_3*(-144*M_3 + (145 + 36*E_2)*M_2*r0 + 3*(25 - 32*E_2)*M*r0_2 - 76*r0_3) + L_2*r0*(416*M_3 + (-113 + 60*E_2)*M_2*r0 - 5*(45 + 13*E_2)*M*r0_2 + 35*r0_3)) + a_5*E*L*M*r0*(-6*L_4*(15*M + 4*r0) + L_2*(288*M_3 + 8*(-67 + 5*E_2)*M_2*r0 - (297 + 130*E_2)*M*r0_2 + 17*r0_3) - 2*r0_2*(-16*(-1 + 9*E_2)*M_3 + 3*(-33 + 20*E_2)*M_2*r0 + 6*(5 + 26*E_2)*M*r0_2 + 48*r0_3)) + a_6*(-24*E_2*M_2*r0_4*(5*M + 2*r0) + L_4*M*(72*M_2 + (61 + 90*E_2)*M*r0 + 4*(5 + 3*E_2)*r0_2) + L_2*r0*(-24*(1 + 12*E_2)*M_4 + 2*(-23 + 332*E_2)*M_3*r0 + (21 + 458*E_2)*M_2*r0_2 + 2*(16 - 5*E_2)*M*r0_3 + 4*r0_4)) + a_4*r0*(6*L_6*M*(5*M + 2*r0) + 108*E_2*M_2*r0_4*(2*M_2 - r0_2) + L_2*r0_2*((32 - 848*E_2)*M_4 + 8*(-14 + 29*E_2)*M_3*r0 + (49 + 624*E_2)*M_2*r0_2 + 6*(6 - 13*E_2)*M*r0_3 - 12*r0_4) + L_4*(-96*M_4 - 8*(-17 + 15*E_2)*M_3*r0 + (31 + 335*E_2)*M_2*r0_2 - (5 + 19*E_2)*M*r0_3 + 4*r0_4)) - a_2*r0_2*(54*E_2*M_2*r0_6*(-2*M + r0) + L_6*M*(40*M_2 - 75*M*r0 + 29*r0_2) + L_4*r0*(272*M_4 + 2*(-57 + 178*E_2)*M_3*r0 - 10*(10 + 33*E_2)*M_2*r0_2 + (19 + 52*E_2)*M*r0_3 + 14*r0_4) + L_2*r0_3*(-128*M_4 + 2*(113 + 124*E_2)*M_3*r0 - 3*(5 + 114*E_2)*M_2*r0_2 + 26*(-4 + 3*E_2)*M*r0_3 + 36*r0_4))))/(r0_2*expr2_3); A83501 = -((r0*(-6*a_8*E_2*M_2 + 3*a_7*E*L*M*(4*(1 + 3*E_2)*M + 3*r0) - 3*a_6*M*(2*E_2*M*r0*(-2*M + r0) + L_2*(2*M + 36*E_2*M + 3*r0 + 5*E_2*r0)) + a*E*L*M*r0_3*(L_2*(-392*M_2 + 350*M*r0 - 78*r0_2) + 9*r0_2*(14*M_2 + (-23 + 4*E_2)*M*r0 + 8*r0_2)) + a_5*E*L*M*(6*L_2*(18*M + 5*r0) + r0*(-24*(1 + 2*E_2)*M_2 + (-17 + 156*E_2)*M*r0 + 14*r0_2)) + a_3*E*L*M*r0*(-6*L_2*(24*M_2 - 53*M*r0 + 8*r0_2) + r0_2*((22 - 144*E_2)*M_2 + 12*(-7 + 13*E_2)*M*r0 + 77*r0_2)) + a_4*(54*E_2*M_2*r0_4 - 3*L_4*M*(12*M + 5*r0) + L_2*r0*(12*(1 + 12*E_2)*M_3 + (23 - 393*E_2)*M_2*r0 + (-17 + 18*E_2)*M*r0_2 - 6*r0_3)) + a_2*r0*(54*E_2*M_2*r0_4*(-2*M + r0) + 3*L_4*M*(16*M_2 - 27*M*r0 + 10*r0_2) + L_2*r0_2*((-22 + 412*E_2)*M_3 + (53 - 380*E_2)*M_2*r0 + (-48 + 55*E_2)*M*r0_2 + 14*r0_3)) + L_2*r0_3*(2*L_2*M*(62*M_2 - 63*M*r0 + 16*r0_2) + r0_2*(-52*M_3 + (130 - 43*E_2)*M_2*r0 + 2*(-46 + 11*E_2)*M*r0_2 + 20*r0_3))))/expr2_3); A84121 = (-24*L*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/expr2_3; A84301 = (-6*L*r0_3*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/expr2_3; A85121 = (-4*(-6*a_10*E_2*M_2*(2*M + r0) + a_9*E*L*M*(24*(1 + 3*E_2)*M_2 + 9*(3 + 4*E_2)*M*r0 + 8*r0_2) + a*E*L*M*r0_4*(L_4*(-360*M_2 + 332*M*r0 - 78*r0_2) + 2*L_2*r0_2*(-152*M_2 + (98 + 15*E_2)*M*r0 - 12*r0_2) + 3*r0_4*(44*M_2 + 12*(-6 + E_2)*M*r0 + 25*r0_2)) - a_8*M*(12*E_2*M*r0*(-2*M_2 + r0_2) + L_2*(12*(1 + 18*E_2)*M_2 + 7*(3 + 19*E_2)*M*r0 + 4*(2 + 3*E_2)*r0_2)) + L_2*r0_4*(4*L_4*M*(30*M_2 - 31*M*r0 + 8*r0_2) + 2*L_2*r0_2*(40*M_3 - (4 + 21*E_2)*M_2*r0 + (-28 + 11*E_2)*M*r0_2 + 10*r0_3) + r0_4*(-56*M_3 + 4*(35 - 11*E_2)*M_2*r0 + (-100 + 23*E_2)*M*r0_2 + 22*r0_3)) + a_7*E*L*M*(2*L_2*(108*M_2 + (79 + 15*E_2)*M*r0 + 16*r0_2) + r0*(-48*(1 + 2*E_2)*M_3 + 44*(-1 + 6*E_2)*M_2*r0 + (29 + 192*E_2)*M*r0_2 + 23*r0_3)) + a_5*E*L*M*r0*(6*L_4*(15*M + 4*r0) + L_2*(-288*M_3 + (548 - 40*E_2)*M_2*r0 + 2*(146 + 65*E_2)*M*r0_2 - 24*r0_3) + r0_2*(-4*(-7 + 72*E_2)*M_3 + 40*(-5 + 3*E_2)*M_2*r0 + 13*(5 + 24*E_2)*M*r0_2 + 97*r0_3)) + a_3*E*L*M*r0_2*(-2*L_4*(60*M_2 - 143*M*r0 + 27*r0_2) - 2*L_2*r0*(424*M_3 + 2*(-61 + 30*E_2)*M_2*r0 - (229 + 65*E_2)*M*r0_2 + 40*r0_3) + r0_3*(300*M_3 - 8*(38 + 9*E_2)*M_2*r0 + 3*(-51 + 64*E_2)*M*r0_2 + 157*r0_3)) - a_6*(-24*E_2*M_2*r0_4*(5*M + 2*r0) + L_4*M*(72*M_2 + (61 + 90*E_2)*M*r0 + 4*(5 + 3*E_2)*r0_2) + L_2*r0*(-24*(1 + 12*E_2)*M_4 + 2*(-22 + 335*E_2)*M_3*r0 + 5*(4 + 91*E_2)*M_2*r0_2 + (31 - 13*E_2)*M*r0_3 + 4*r0_4)) - a_4*r0*(6*L_6*M*(5*M + 2*r0) + 108*E_2*M_2*r0_4*(2*M_2 - r0_2) + L_2*r0_2*((28 - 856*E_2)*M_4 + 4*(-28 + 61*E_2)*M_3*r0 + 57*(1 + 11*E_2)*M_2*r0_2 + 17*(2 - 5*E_2)*M*r0_3 - 14*r0_4) + L_4*(-96*M_4 - 2*(-71 + 60*E_2)*M_3*r0 + (29 + 338*E_2)*M_2*r0_2 - (9 + 22*E_2)*M*r0_3 + 4*r0_4)) + a_2*r0_2*(54*E_2*M_2*r0_6*(-2*M + r0) + 2*L_6*M*(20*M_2 - 39*M*r0 + 16*r0_2) + L_4*r0*(280*M_4 + 120*(-1 + 3*E_2)*M_3*r0 - 2*(53 + 169*E_2)*M_2*r0_2 + 7*(3 + 8*E_2)*M*r0_3 + 16*r0_4) + L_2*r0_3*(-136*M_4 + 2*(122 + 125*E_2)*M_3*r0 - (22 + 349*E_2)*M_2*r0_2 + (-111 + 83*E_2)*M*r0_3 + 40*r0_4))))/(r0_2*expr2_4); A85301 = -((r0*(-6*a_8*E_2*M_2 + 3*a_7*E*L*M*(4*(1 + 3*E_2)*M + 3*r0) - 3*a_6*M*(2*E_2*M*r0*(-2*M + r0) + L_2*(2*M + 36*E_2*M + 3*r0 + 5*E_2*r0)) + a_5*E*L*M*(6*L_2*(18*M + 5*r0) + r0*(-24*(1 + 2*E_2)*M_2 + 4*(-4 + 39*E_2)*M*r0 + 13*r0_2)) + a*E*L*M*r0_3*(-4*L_2*(100*M_2 - 91*M*r0 + 21*r0_2) + 3*r0_2*(44*M_2 + 12*(-6 + E_2)*M*r0 + 25*r0_2)) + a_3*E*L*M*r0*(-18*L_2*(8*M_2 - 18*M*r0 + 3*r0_2) + r0_2*(-4*(-5 + 36*E_2)*M_2 + 12*(-7 + 13*E_2)*M*r0 + 79*r0_2)) + a_4*(54*E_2*M_2*r0_4 - 3*L_4*M*(12*M + 5*r0) + L_2*r0*(12*(1 + 12*E_2)*M_3 + 22*(1 - 18*E_2)*M_2*r0 + (-16 + 21*E_2)*M*r0_2 - 6*r0_3)) + a_2*r0*(54*E_2*M_2*r0_4*(-2*M + r0) + 3*L_4*M*(16*M_2 - 28*M*r0 + 11*r0_2) + L_2*r0_2*(4*(-5 + 104*E_2)*M_3 + 4*(13 - 97*E_2)*M_2*r0 + (-51 + 59*E_2)*M*r0_2 + 16*r0_3)) + L_2*r0_3*(2*L_2*M*(64*M_2 - 66*M*r0 + 17*r0_2) + r0_2*(-56*M_3 + 4*(35 - 11*E_2)*M_2*r0 + (-100 + 23*E_2)*M*r0_2 + 22*r0_3))))/expr2_4); A86101 = (-2*L*r0_3*(-(a_5*E*M) + a_4*(1 + 3*E_2)*L*M + a*E*M*r0*(L_2*(8*M - 6*r0) + 3*r0_2*(-2*M + r0)) + 2*a_3*E*M*(-3*L_2 + r0*(M + r0)) + L*r0*(2*L_2*M*(-2*M + r0) + r0_2*(4*M_2 + (-6 + E_2)*M*r0 + 2*r0_2)) + a_2*L*(3*L_2*M + r0*(-2*(1 + 2*E_2)*M_2 + (-1 + 4*E_2)*M*r0 + 2*r0_2))))/expr2_4; A87101 = -((r0*(-2*a_8*E_2*M_2 + a_7*E*L*M*(4*(1 + 3*E_2)*M + 3*r0) - a_6*M*(2*E_2*M*r0*(-2*M + r0) + L_2*(2*M + 36*E_2*M + 3*r0 + 5*E_2*r0)) + a_5*E*L*M*(2*L_2*(18*M + 5*r0) + r0*(-8*(1 + 2*E_2)*M_2 + (-5 + 52*E_2)*M*r0 + 4*r0_2)) + a*E*L*M*r0_3*(-2*L_2*(68*M_2 - 63*M*r0 + 15*r0_2) + r0_2*(46*M_2 + 3*(-25 + 4*E_2)*M*r0 + 26*r0_2)) + a_3*E*L*M*r0*(-2*L_2*(24*M_2 - 55*M*r0 + 10*r0_2) + r0_2*((6 - 48*E_2)*M_2 + 4*(-7 + 13*E_2)*M*r0 + 27*r0_2)) + a_4*(18*E_2*M_2*r0_4 - L_4*M*(12*M + 5*r0) + L_2*r0*((4 + 48*E_2)*M_3 + 7*(1 - 19*E_2)*M_2*r0 + (-5 + 8*E_2)*M*r0_2 - 2*r0_3)) + a_2*r0*(18*E_2*M_2*r0_4*(-2*M + r0) + L_4*M*(16*M_2 - 29*M*r0 + 12*r0_2) + L_2*r0_2*(2*(-3 + 70*E_2)*M_3 + (17 - 132*E_2)*M_2*r0 + 3*(-6 + 7*E_2)*M*r0_2 + 6*r0_3)) + L_2*r0_3*(2*L_2*M*(22*M_2 - 23*M*r0 + 6*r0_2) + r0_2*(-20*M_3 + 5*(10 - 3*E_2)*M_2*r0 + 4*(-9 + 2*E_2)*M*r0_2 + 8*r0_3))))/expr2_5); } /* A_{phi,phi} */ { A90060 = 256*L_2*expr4_3; A90080 = (-128*expr1_2*(-24*a_9*E*L*M_2*(2*M + r0) - 4*a_7*E*L*M*(192*M_4 + 5*L_2*M*r0 + 264*M_3*r0 + 180*M_2*r0_2 + 42*M*r0_3 - 6*r0_4) - 4*a*E*L*M*r0_5*(48*L_4*M + L_2*(106*M - 15*r0)*r0_2 + 6*(10*M - 3*r0)*r0_4) + a_8*M*(24*E_2*r0_p_2M_4 + L_2*M*(48*M + 23*r0)) - 4*a_3*E*L*M*r0_2*(48*L_4*M*(2*M + r0) + L_2*r0_2*(274*M_2 + 177*M*r0 - 20*r0_2) + 6*r0_4*(30*M_2 + 17*M*r0 - 7*r0_2)) + r0_7*(24*E_2*M*r0_5 + 2*L_2*r0_2*(46*M_2 + (-47 + 38*E_2)*M*r0 + 12*r0_2) + L_4*(80*M_2 + 2*(-41 + 24*E_2)*M*r0 + 21*r0_2)) - 4*a_5*E*L*M*r0*(6*r0_2*(36*M_3 + 50*M_2*r0 + 13*M*r0_2 - 5*r0_3) + L_2*(304*M_3 + 294*M_2*r0 + 96*M*r0_2 - 5*r0_3)) + a_2*r0_2*(192*L_6*M_3 + 96*E_2*M*r0_7*(2*M + r0) + L_4*r0_2*(224*M_3 + 24*(5 + 8*E_2)*M_2*r0 + 16*(-5 + 6*E_2)*M*r0_2 + 21*r0_3) + 2*L_2*r0_4*(100*M_3 + 6*(3 + 38*E_2)*M_2*r0 + 3*(-23 + 38*E_2)*M*r0_2 + 24*r0_3)) + a_4*r0*(144*E_2*M*r0_5*r0_p_2M_2 + 4*L_4*M*(152*M_3 + 6*(11 + 8*E_2)*M_2*r0 + 3*(5 + 16*E_2)*M*r0_2 + 2*(-5 + 6*E_2)*r0_3) + L_2*r0_2*(188*M_4 + 4*(85 + 228*E_2)*M_3*r0 + 3*(5 + 304*E_2)*M_2*r0_2 + 6*(-15 + 38*E_2)*M*r0_3 + 24*r0_4)) + 2*a_6*M*(10*L_4*M*r0 + 48*E_2*r0_3*r0_p_2M_3 + L_2*(192*M_4 + 16*(9 + 19*E_2)*M_3*r0 + 2*(49 + 228*E_2)*M_2*r0_2 + (-1 + 228*E_2)*M*r0_3 + (-23 + 38*E_2)*r0_4))))/(3.*r0_9*(a_2 + r0*(-2*M + r0))); A90240 = 192*L_2*expr1_2; A90260 = (-64*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-12*a_9*E*L*M*(14*M_2 + 11*M*r0 + 2*r0_2) - 2*a*E*L*M*r0_5*(L_2*(358*M - 39*r0)*r0_2 + 6*(34*M - 9*r0)*r0_4 + L_4*(158*M + 9*r0)) - 2*a_3*E*L*M*r0_2*(6*r0_4*(114*M_2 + 59*M*r0 - 19*r0_2) + L_2*r0_2*(964*M_2 + 598*M*r0 - 19*r0_2) + 2*L_4*(164*M_2 + 79*M*r0 + 12*r0_2)) + r0_5*(48*E_2*M*r0_7 - 2*L_6*(8*M_2 + 2*M*r0 - 3*r0_2) + 2*L_4*r0_2*(54*M_2 + (-75 + 44*E_2)*M*r0 + 24*r0_2) + L_2*r0_4*(136*M_2 + 2*(-79 + 70*E_2)*M*r0 + 45*r0_2)) + a_8*M*(48*E_2*r0_p_2M_4 + L_2*(24*(7 + E_2)*M_2 + (125 + 24*E_2)*M*r0 + 3*(7 + 2*E_2)*r0_2)) - 2*a_5*E*L*M*r0*(3*L_4*(4*M + 5*r0) + 6*r0_2*(156*M_3 + 182*M_2*r0 + 51*M*r0_2 - 9*r0_3) + L_2*(1072*M_3 + 980*M_2*r0 + 386*M*r0_2 + 47*r0_3)) + a_2*r0_2*(192*E_2*M*r0_7*(2*M + r0) + L_6*(328*M_3 - 36*M_2*r0 + 32*M*r0_2 + 6*r0_3) + L_4*r0_2*(380*M_3 + 4*(12 + 85*E_2)*M_2*r0 + 7*(-9 + 26*E_2)*M*r0_2 + 63*r0_3) + L_2*r0_4*(340*M_3 + 12*(-5 + 69*E_2)*M_2*r0 + 3*(-61 + 142*E_2)*M*r0_2 + 99*r0_3)) - 2*a_7*E*L*M*(L_2*(24*M_2 + 82*M*r0 + 27*r0_2) + 6*(128*M_4 + 164*M_3*r0 + 106*M_2*r0_2 + 37*M*r0_3 + 3*r0_4)) + a_4*r0*(288*E_2*M*r0_5*r0_p_2M_2 + 12*L_6*M*(M + 2*r0) + L_4*(1072*M_4 + 8*(38 + 41*E_2)*M_3*r0 + 4*(35 + 88*E_2)*M_2*r0_2 + 2*(33 + 50*E_2)*M*r0_3 + 15*r0_4) + L_2*r0_2*(484*M_4 + 8*(43 + 204*E_2)*M_3*r0 + 3*(-1 + 560*E_2)*M_2*r0_2 + 3*(-5 + 146*E_2)*M*r0_3 + 63*r0_4)) + a_6*(192*E_2*M*r0_3*r0_p_2M_3 + L_4*M*(24*M_2 + 4*(35 + 3*E_2)*M*r0 + 3*(15 + 2*E_2)*r0_2) + L_2*(768*M_5 + 16*(27 + 67*E_2)*M_4*r0 + 36*(7 + 46*E_2)*M_3*r0_2 + 6*(29 + 146*E_2)*M_2*r0_3 + (31 + 158*E_2)*M*r0_4 + 9*r0_5))))/(3.*r0_6*(a_2 + r0*(-2*M + r0))); A90420 = 48*L_2*r0_3*(a_2*(2*M + r0) + r0*(L_2 + r0_2)); A90440 = (-8*(-72*a_9*E*L*M*(10*M_2 + 9*M*r0 + 2*r0_2) + 4*a*E*L*M*r0_3*(L_6*(8*M - 6*r0) - 30*L_4*r0_2*(6*M + r0) + 18*r0_6*(-14*M + 3*r0) + 3*L_2*r0_4*(-146*M + 9*r0)) - 4*a_3*E*L*M*r0_2*(6*L_6 + 18*r0_4*(54*M_2 + 25*M*r0 - 5*r0_2) + 12*L_4*(32*M_2 + 15*M*r0 + 7*r0_2) + L_2*r0_2*(1266*M_2 + 721*M*r0 + 64*r0_2)) + r0_3*(144*E_2*M*r0_9 + 8*L_8*M*(-2*M + r0) + L_6*r0_2*(-100*M_2 + 4*(-11 + E_2)*M*r0 + 47*r0_2) + L_2*r0_6*(264*M_2 + 2*(-197 + 192*E_2)*M*r0 + 131*r0_2) + L_4*r0_4*(168*M_2 + 2*(-217 + 120*E_2)*M*r0 + 175*r0_2)) + a_8*(144*E_2*M*r0_p_2M_4 + L_2*(144*(5 + E_2)*M_3 + (635 + 144*E_2)*M_2*r0 + 36*(4 + E_2)*M*r0_2 + 3*r0_3)) - 4*a_5*E*L*M*r0*(6*L_4*(8*M + 9*r0) + 18*r0_2*(84*M_3 + 82*M_2*r0 + 25*M*r0_2 + r0_3) + L_2*(1392*M_3 + 1166*M_2*r0 + 572*M*r0_2 + 175*r0_3)) + a_2*r0_2*(12*L_8*M + 576*E_2*M*r0_7*(2*M + r0) + 2*L_6*(384*M_3 - 8*(15 + E_2)*M_2*r0 + 2*(53 + 4*E_2)*M*r0_2 + 25*r0_3) + 2*L_2*r0_4*(420*M_3 + 2*(-157 + 558*E_2)*M_2*r0 + 27*(-5 + 22*E_2)*M*r0_2 + 162*r0_3) + L_4*r0_2*(960*M_3 + 32*(-17 + 27*E_2)*M_2*r0 + 12*(9 + 44*E_2)*M*r0_2 + 287*r0_3)) - 4*a_7*E*L*M*(L_2*(72*M_2 + 221*M*r0 + 84*r0_2) + 18*(64*M_4 + 76*M_3*r0 + 46*M_2*r0_2 + 23*M*r0_3 + 5*r0_4)) + a_4*r0*(864*E_2*M*r0_5*r0_p_2M_2 + 3*L_6*(32*M_2 + 4*(14 + E_2)*M*r0 + r0_2) + 2*L_4*(1392*M_4 + 4*(25 + 96*E_2)*M_3*r0 + 2*(107 + 240*E_2)*M_2*r0_2 + 8*(44 + 21*E_2)*M*r0_3 + 59*r0_4) + L_2*r0_2*(1740*M_4 + 4*(-7 + 1080*E_2)*M_3*r0 + (-161 + 4608*E_2)*M_2*r0_2 + 6*(83 + 210*E_2)*M*r0_3 + 258*r0_4)) + 2*a_6*(288*E_2*M*r0_3*r0_p_2M_3 + L_4*(72*M_3 + 2*(185 + 24*E_2)*M_2*r0 + 6*(25 + 4*E_2)*M*r0_2 + 3*r0_3) + L_2*(1152*M_5 + 48*(9 + 29*E_2)*M_4*r0 + 2*(77 + 1116*E_2)*M_3*r0_2 + 7*(77 + 180*E_2)*M_2*r0_3 + (259 + 246*E_2)*M*r0_4 + 34*r0_5))))/(3.*r0_3*(a_2 + r0*(-2*M + r0))); A90600 = 4*L_2*r0_6; A90620 = (4*(12*a_7*E*L*M*(13*M + 6*r0) + 6*a_5*E*L*M*(128*M_3 + 76*M_2*r0 + 40*M*r0_2 + 22*r0_3 + L_2*(12*M + 17*r0)) + 2*a*E*L*M*r0_2*(-4*L_4*(4*M - 3*r0) + 6*(22*M - 3*r0)*r0_4 + L_2*r0_2*(94*M + 21*r0)) - 3*a_6*(16*E_2*M*r0_p_2M_3 + L_2*(4*(13 + 3*E_2)*M_2 + (25 + 6*E_2)*M*r0 + r0_2)) - r0_2*(48*E_2*M*r0_7 + 8*L_6*M*(-2*M + r0) + 4*L_2*r0_4*(10*M_2 + (-27 + 17*E_2)*M*r0 + 11*r0_2) + L_4*r0_2*(-36*M_2 + 4*(-10 + E_2)*M*r0 + 29*r0_2)) + 4*a_3*E*L*M*r0*(6*L_4 + 3*r0_2*(58*M_2 + 25*M*r0 + 2*r0_2) + L_2*(100*M_2 + 35*M*r0 + 36*r0_2)) - a_2*r0*(12*L_6*M + 144*E_2*M*r0_5*(2*M + r0) + 4*L_4*(50*M_3 - (33 + 4*E_2)*M_2*r0 + 4*(6 + E_2)*M*r0_2 + 8*r0_3) + L_2*r0_2*(140*M_3 + 4*(-50 + 59*E_2)*M_2*r0 + (23 + 154*E_2)*M*r0_2 + 79*r0_3)) - a_4*(144*E_2*M*r0_3*r0_p_2M_2 + 3*L_4*(12*M_2 + 4*(7 + E_2)*M*r0 + r0_2) + 2*L_2*(192*M_4 + 20*(-3 + 5*E_2)*M_3*r0 + 8*(2 + 17*E_2)*M_2*r0_2 + 13*(7 + 4*E_2)*M*r0_3 + 19*r0_4))))/(3.*(a_2 + r0*(-2*M + r0))); A90800 = (r0_3*(48*a_3*E*L*M - 24*L_2*(2*a_2*M + r0_3) + L_2*r0*(-3*a_2 + r0*(-2*M + r0)) - (24*M*expr8_2)/(a_2 + r0*(-2*M + r0)) + (4*L_2*M*(-3*a_4*E_2 + 6*a_3*E*L + 2*a*E*L*r0*(-4*M + 3*r0) + a_2*(-3*L_2 + 4*E_2*(M - r0)*r0) - r0*(E_2*r0_3 + L_2*(-4*M + 2*r0))))/(a_2 + r0*(-2*M + r0))))/6.; A91060 = (128*L*expr1_2*(4*a_5*E*M*(2*M + r0) - a_4*L*M*(8*M + 3*r0) + 6*a*E*M*r0_3*(L_2 + 2*r0_2) - L*(2*M - r0)*r0_3*(2*L_2 + 3*r0_2) + 2*a_3*E*M*r0*(L_2 + 4*r0*(3*M + 2*r0)) - a_2*L*r0*(2*L_2*M + 3*r0*(6*M_2 + M*r0 - r0_2))))/(r0_5*(a_2 + r0*(-2*M + r0))); A91080 = (-64*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-48*a_14*E_2*M_3*r0_p_2M_2 + 4*a_13*E*L*M_2*(96*M_3 + 226*M_2*r0 + 161*M*r0_2 + 36*r0_3) + 2*a*E*L*M*r0_6*(L_4*r0_4*(56*M_2 + 2*(313 + 222*E_2)*M*r0 - 327*r0_2) + 6*L_6*r0_2*(68*M_2 + 4*(14 + 5*E_2)*M*r0 - 45*r0_2) + 2*L_2*r0_6*(58*M_2 + (-23 + 288*E_2)*M*r0 - 3*r0_2) + 60*L_8*(4*M_2 - r0_2) + 12*r0_8*(30*M_2 + (-41 + 24*E_2)*M*r0 + 13*r0_2)) - (2*M - r0)*r0_8*(48*E_2*M*r0_9 - 24*L_8*M*(4*M - (2 + 5*E_2)*r0) + 2*L_6*r0_2*(-64*M_2 + 2*(-5 + 129*E_2)*M*r0 + 21*r0_2) + 2*L_2*r0_6*(92*M_2 + (-118 + 205*E_2)*M*r0 + 36*r0_2) + L_4*r0_4*(116*M_2 + 2*(-134 + 373*E_2)*M*r0 + 105*r0_2)) + 4*a_3*E*L*M*r0_4*(30*L_8*(12*M_2 - 2*M*r0 - r0_2) + L_4*r0_3*(244*M_3 + 2*(649 + 444*E_2)*M_2*r0 + (899 + 618*E_2)*M*r0_2 - 543*r0_3) + L_2*r0_5*(-216*M_3 + 2*(131 + 864*E_2)*M_2*r0 + 2*(337 + 518*E_2)*M*r0_2 - 177*r0_3) + 6*L_6*r0*(84*M_3 + 4*(46 + 5*E_2)*M_2*r0 + 2*(13 + 10*E_2)*M*r0_2 - 45*r0_3) + 2*r0_7*(204*M_3 + 2*(-139 + 288*E_2)*M_2*r0 + (-119 + 320*E_2)*M*r0_2 + 120*r0_3)) + a_2*r0_4*(-240*L_10*M_2*(2*M - r0) + 24*E_2*M*r0_10*(-46*M_2 + 13*M*r0 + 7*r0_2) + 24*L_8*M*r0*(32*M_3 - 2*(27 + 20*E_2)*M_2*r0 + (3 - 20*E_2)*M*r0_2 + 2*(4 + 5*E_2)*r0_3) - 2*L_2*r0_7*(804*M_4 + 4*(-304 + 685*E_2)*M_3*r0 + 5*(21 + 122*E_2)*M_2*r0_2 + (367 - 763*E_2)*M*r0_3 - 108*r0_4) + 2*L_6*r0_3*(1256*M_4 - 12*(43 + 182*E_2)*M_3*r0 - 2*(287 + 516*E_2)*M_2*r0_2 + (217 + 654*E_2)*M*r0_3 + 21*r0_4) + L_4*r0_5*(880*M_4 + 4*(383 - 1890*E_2)*M_3*r0 - 8*(160 + 361*E_2)*M_2*r0_2 + 21*(-13 + 112*E_2)*M*r0_3 + 210*r0_4)) + 2*a_5*E*L*M*r0_3*(6*L_6*(696*M_3 + 8*(39 + 5*E_2)*M_2*r0 + 20*(1 + E_2)*M*r0_2 - 45*r0_3) + L_4*r0*(32*M_4 + 24*(309 + 74*E_2)*M_3*r0 + 144*(49 + 22*E_2)*M_2*r0_2 + 4*(449 + 285*E_2)*M*r0_3 - 1149*r0_4) + L_2*r0_3*(-4236*M_4 + 4*(515 + 1728*E_2)*M_3*r0 + 3*(2395 + 2992*E_2)*M_2*r0_2 + 276*(11 + 10*E_2)*M*r0_3 - 894*r0_4) + 2*r0_5*(-2340*M_4 + 108*(-7 + 32*E_2)*M_3*r0 + (-249 + 3968*E_2)*M_2*r0_2 + 4*(131 + 280*E_2)*M*r0_3 + 240*r0_4)) + 2*a_11*E*L*M*r0*(5*L_2*M*(144*M_2 + 191*M*r0 + 60*r0_2) + 4*(64*(15 + 8*E_2)*M_5 + 4*(481 + 256*E_2)*M_4*r0 + 3*(529 + 256*E_2)*M_3*r0_2 + (683 + 256*E_2)*M_2*r0_3 + (115 + 32*E_2)*M*r0_4 - 6*r0_5)) - a_12*M*(L_2*M*(192*M_3 + 8*(89 + 90*E_2)*M_2*r0 + (587 + 696*E_2)*M*r0_2 + 6*(23 + 28*E_2)*r0_3) + 24*E_2*r0*(160*M_5 + 440*M_4*r0 + 412*M_3*r0_2 + 170*M_2*r0_3 + 33*M*r0_4 + 3*r0_5)) + 2*a_7*E*L*M*r0_2*(144*L_6*M*r0 + 2*L_4*(4128*M_4 + 8*(611 + 87*E_2)*M_3*r0 + 2*(1285 + 348*E_2)*M_2*r0_2 + 6*(90 + 29*E_2)*M*r0_3 - 195*r0_4) + L_2*r0*(-4736*M_5 + 12*(301 + 384*E_2)*M_4*r0 + 8*(1877 + 1380*E_2)*M_3*r0_2 + (12329 + 7584*E_2)*M_2*r0_3 + 8*(334 + 201*E_2)*M*r0_4 - 750*r0_5) + 12*r0_3*(-1164*M_5 + 4*(-215 + 192*E_2)*M_4*r0 + (235 + 1408*E_2)*M_3*r0_2 + (369 + 832*E_2)*M_2*r0_3 + 4*(39 + 40*E_2)*M*r0_4 + 10*r0_5)) - a_6*r0_2*(144*L_8*M_2*r0 - 48*E_2*M*r0_6*(200*M_4 + 68*M_3*r0 - 31*M_2*r0_2 + M*r0_3 - 5*r0_4) + 4*L_6*M*(1376*M_4 + 4*(353 + 522*E_2)*M_3*r0 + 168*(2 + 9*E_2)*M_2*r0_2 + 2*(29 + 156*E_2)*M*r0_3 - 3*(36 + 23*E_2)*r0_4) + L_4*M*r0*(-9344*M_5 + 8*(35 + 1732*E_2)*M_4*r0 + 8*(1095 + 4148*E_2)*M_3*r0_2 + 26*(229 + 932*E_2)*M_2*r0_3 + 2*(597 + 2624*E_2)*M*r0_4 - (1115 + 1088*E_2)*r0_5) + L_2*r0_3*(-11144*M_6 + 4*(-773 + 3824*E_2)*M_5*r0 + 2*(607 + 16744*E_2)*M_4*r0_2 + (2449 + 25488*E_2)*M_3*r0_3 + (1889 + 4936*E_2)*M_2*r0_4 - 4*(97 + 239*E_2)*M*r0_5 - 72*r0_6)) + 2*a_9*E*L*M*r0*(12*L_4*M*r0*(52*M + 31*r0) + L_2*(6144*M_5 + 32*(437 + 86*E_2)*M_4*r0 + 12*(1097 + 344*E_2)*M_3*r0_2 + 3*(2345 + 688*E_2)*M_2*r0_3 + 2*(665 + 172*E_2)*M*r0_4 - 204*r0_5) + 4*r0*(-2112*M_6 + 4*(-787 + 288*E_2)*M_5*r0 + 2*(289 + 1664*E_2)*M_4*r0_2 + (2521 + 3264*E_2)*M_3*r0_3 + 2*(733 + 672*E_2)*M_2*r0_4 + (307 + 200*E_2)*M*r0_5 - 15*r0_6)) - a_10*M*r0*(2*L_4*M*(360*M_2 + (607 + 312*E_2)*M*r0 + 3*(71 + 52*E_2)*r0_2) + L_2*(768*(5 + 16*E_2)*M_5 + 32*(151 + 821*E_2)*M_4*r0 + 2*(1505 + 13176*E_2)*M_3*r0_2 + 3*(493 + 4568*E_2)*M_2*r0_3 + (65 + 2996*E_2)*M*r0_4 + 6*(-23 + 19*E_2)*r0_5) + 24*E_2*r0*(-352*M_6 - 720*M_5*r0 + 24*M_4*r0_2 + 704*M_3*r0_3 + 450*M_2*r0_4 + 111*M*r0_5 + 13*r0_6)) - a_8*M*r0*(48*L_6*M*r0*(13*M + 3*(3 + E_2)*r0) + 48*E_2*r0_4*(-392*M_5 - 436*M_4*r0 + 68*M_3*r0_2 + 174*M_2*r0_3 + 55*M*r0_4 + 10*r0_5) + 2*L_4*(2048*M_5 + 48*(103 + 172*E_2)*M_4*r0 + 20*(153 + 554*E_2)*M_3*r0_2 + (1525 + 6532*E_2)*M_2*r0_3 + 5*(39 + 314*E_2)*M*r0_4 - 3*(71 + 19*E_2)*r0_5) + L_2*r0*(-8448*M_6 + 32*(-247 + 284*E_2)*M_5*r0 + 4*(1173 + 8392*E_2)*M_4*r0_2 + 4*(1367 + 11612*E_2)*M_3*r0_3 + (3221 + 29360*E_2)*M_2*r0_4 + (437 + 6836*E_2)*M*r0_5 + 2*(-194 + 23*E_2)*r0_6)) - a_4*r0_3*(24*E_2*M*r0_8*(28*M_3 + 42*M_2*r0 - 51*M*r0_2 - 5*r0_3) + 2*L_6*M*r0*(-2288*M_4 + 8*(233 + 396*E_2)*M_3*r0 + 12*(135 + 394*E_2)*M_2*r0_2 + 4*(97 + 267*E_2)*M*r0_3 - (443 + 534*E_2)*r0_4) + L_2*r0_5*(-1392*M_5 + 4*(-331 + 3264*E_2)*M_4*r0 + 8*(-263 + 1827*E_2)*M_3*r0_2 + (2245 + 1328*E_2)*M_2*r0_3 + 12*(18 - 167*E_2)*M*r0_4 - 216*r0_5) + L_4*r0_3*(-8008*M_5 + 80*(-1 + 201*E_2)*M_4*r0 + 2*(1439 + 9676*E_2)*M_3*r0_2 + 6*(457 + 636*E_2)*M_2*r0_3 - 6*(149 + 430*E_2)*M*r0_4 - 105*r0_5) + 24*L_8*M*(116*M_3 + (-13 + 10*E_2)*M*r0_2 - (6 + 5*E_2)*r0_3 + 20*M_2*(r0 + 3*E_2*r0)))))/(3.*r0_11*expr2_2); A91240 = (-32*L*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-12*a_5*E*M*(2*M + r0) + a_4*L*(24*M_2 + 12*M*r0 + r0_2) - 12*a*E*M*r0_3*(2*L_2 + 3*r0_2) - 8*a_3*E*M*r0*(L_2 + 9*M*r0 + 6*r0_2) + L*(2*M - r0)*r0_3*(7*L_2 + 9*r0_2) + a_2*L*r0*(L_2*(8*M + r0) + 2*r0*(24*M_2 + 5*M*r0 - 4*r0_2))))/(r0_2*(a_2 + r0*(-2*M + r0))); A91260 = (-16*(-48*a_14*E_2*M_2*r0_p_2M_2*(7*M + 2*r0) + 8*a_13*E*L*M*(2*M + r0)*(24*(7 + E_2)*M_3 + (365 + 24*E_2)*M_2*r0 + 6*(36 + E_2)*M*r0_2 + 36*r0_3) + 2*a*E*L*M*r0_6*(2*L_6*r0_2*(728*M_2 + 2*(241 + 105*E_2)*M*r0 - 423*r0_2) + 3*L_4*r0_4*(16*M_2 + 2*(283 + 256*E_2)*M*r0 - 287*r0_2) + 210*L_8*(4*M_2 - r0_2) + 24*r0_8*(40*M_2 + (-70 + 39*E_2)*M*r0 + 25*r0_2) + 2*L_2*r0_6*(130*M_2 + (-395 + 1008*E_2)*M*r0 + 165*r0_2)) - (2*M - r0)*r0_8*(192*E_2*M*r0_9 + 4*L_8*(-88*M_2 + (32 + 105*E_2)*M*r0 + 6*r0_2) + 2*L_2*r0_6*(272*M_2 + 2*(-203 + 362*E_2)*M*r0 + 135*r0_2) + L_6*r0_2*(-520*M_2 + 2*(-101 + 902*E_2)*M*r0 + 231*r0_2) + 2*L_4*r0_4*(170*M_2 + (-553 + 1314*E_2)*M*r0 + 234*r0_2)) + 4*a_3*E*L*M*r0_4*(105*L_8*(12*M_2 - 2*M*r0 - r0_2) + 2*L_4*r0_3*(-258*M_3 + 2*(1285 + 777*E_2)*M_2*r0 + (1193 + 1063*E_2)*M*r0_2 - 669*r0_3) + 2*L_6*r0*(848*M_3 + 70*(29 + 3*E_2)*M_2*r0 + 2*(53 + 105*E_2)*M*r0_2 - 393*r0_3) + L_2*r0_5*(-3216*M_3 + 4*(218 + 1503*E_2)*M_2*r0 + 21*(83 + 174*E_2)*M*r0_2 + 147*r0_3) + 4*r0_7*(66*M_3 + (-571 + 918*E_2)*M_2*r0 + (-169 + 532*E_2)*M*r0_2 + 264*r0_3)) + 2*a_5*E*L*M*r0_3*(2*L_6*(7368*M_3 + 4*(811 + 105*E_2)*M_2*r0 + 6*(-9 + 35*E_2)*M*r0_2 - 291*r0_3) + L_4*r0*(-2688*M_4 + 8*(3395 + 786*E_2)*M_3*r0 + 8*(3096 + 1379*E_2)*M_2*r0_2 + 2*(2537 + 1942*E_2)*M*r0_3 - 2151*r0_4) + L_2*r0_3*(-29172*M_4 + 4*(799 + 5976*E_2)*M_3*r0 + 3*(8421 + 10504*E_2)*M_2*r0_2 + 12*(909 + 820*E_2)*M*r0_3 - 126*r0_4) + 4*r0_5*(-5076*M_4 + 24*(-116 + 225*E_2)*M_3*r0 + (-513 + 6484*E_2)*M_2*r0_2 + 2*(680 + 961*E_2)*M*r0_3 + 744*r0_4)) + a_2*r0_4*(-840*L_10*M_2*(2*M - r0) + 24*E_2*M*r0_10*(-154*M_2 + 35*M*r0 + 29*r0_2) - 2*L_2*r0_7*(1692*M_4 + 4*(-917 + 2308*E_2)*M_3*r0 + (343 + 2102*E_2)*M_2*r0_2 - 3*(-458 + 893*E_2)*M*r0_3 - 420*r0_4) + 2*L_8*r0*(1448*M_4 - 4*(661 + 420*E_2)*M_3*r0 + 2*(271 - 420*E_2)*M_2*r0_2 + 5*(37 + 84*E_2)*M*r0_3 + 12*r0_4) + 2*L_6*r0_3*(5552*M_4 - 4*(803 + 1933*E_2)*M_3*r0 - 2*(457 + 1734*E_2)*M_2*r0_2 + (266 + 2265*E_2)*M*r0_3 + 150*r0_4) + L_4*r0_5*(6528*M_4 - 100*(-29 + 264*E_2)*M_3*r0 - 4*(715 + 2518*E_2)*M_2*r0_2 + 79*(-27 + 104*E_2)*M*r0_3 + 1011*r0_4)) - a_4*r0_3*(24*E_2*M*r0_8*(52*M_3 + 118*M_2*r0 - 141*M*r0_2 - 25*r0_3) + 4*L_8*M*(2456*M_3 + 4*(106 + 315*E_2)*M_2*r0 + 6*(-82 + 35*E_2)*M*r0_2 + 7*(1 - 15*E_2)*r0_3) + L_4*r0_3*(-37848*M_5 + 4*(1091 + 13224*E_2)*M_4*r0 + 2*(4783 + 34268*E_2)*M_3*r0_2 + 9*(685 + 1516*E_2)*M_2*r0_3 - 6*(45 + 1474*E_2)*M*r0_4 - 618*r0_5) + 2*L_2*r0_5*(-4992*M_5 + 24*(-113 + 731*E_2)*M_4*r0 + 12*(-242 + 2045*E_2)*M_3*r0_2 + 8*(452 + 341*E_2)*M_2*r0_3 + (791 - 3467*E_2)*M*r0_4 - 450*r0_5) + L_6*r0*(-18528*M_5 + 16*(1024 + 1391*E_2)*M_4*r0 + 8*(1318 + 4127*E_2)*M_3*r0_2 + 4*(-188 + 1737*E_2)*M_2*r0_3 - 22*(38 + 165*E_2)*M*r0_4 - 69*r0_5)) - a_12*M*(L_2*(192*(7 + 6*E_2)*M_4 + 16*(341 + 288*E_2)*M_3*r0 + 17*(329 + 216*E_2)*M_2*r0_2 + 3*(713 + 288*E_2)*M*r0_3 + 18*(15 + E_2)*r0_4) + 24*E_2*r0*(544*M_5 + 1640*M_4*r0 + 1684*M_3*r0_2 + 758*M_2*r0_3 + 151*M*r0_4 + 11*r0_5)) + 2*a_11*E*L*M*(L_2*(576*M_4 + 48*(78 + E_2)*M_3*r0 + (5657 + 48*E_2)*M_2*r0_2 + 6*(473 + 2*E_2)*M*r0_3 + 432*r0_4) + 8*r0*(32*(51 + 26*E_2)*M_5 + 8*(405 + 223*E_2)*M_4*r0 + 3*(1021 + 488*E_2)*M_3*r0_2 + 2*(940 + 271*E_2)*M_2*r0_3 + (647 + 76*E_2)*M*r0_4 + 84*r0_5)) + 2*a_7*E*L*M*r0_2*(-24*L_6*(3*M_2 - 20*M*r0 - 6*r0_2) + 2*L_4*(14544*M_4 + 8*(2235 + 307*E_2)*M_3*r0 + 4*(2075 + 599*E_2)*M_2*r0_2 + (2269 + 578*E_2)*M*r0_3 + 48*r0_4) + 24*r0_3*(-2116*M_5 + 168*(-11 + 7*E_2)*M_4*r0 + (181 + 2264*E_2)*M_3*r0_2 + (729 + 1412*E_2)*M_2*r0_3 + 6*(77 + 48*E_2)*M*r0_4 + 100*r0_5) + L_2*r0*(-26432*M_5 + 4*(689 + 3960*E_2)*M_4*r0 + 8*(6781 + 4830*E_2)*M_3*r0_2 + (42983 + 27000*E_2)*M_2*r0_3 + 4*(3299 + 1458*E_2)*M*r0_4 + 618*r0_5)) - a_6*r0_2*(-6*L_8*M*(8*M_2 - 82*M*r0 - 45*r0_2) - 48*E_2*M*r0_6*(728*M_4 + 356*M_3*r0 - 121*M_2*r0_2 - 43*M*r0_3 - 15*r0_4) + 2*L_6*M*(9696*M_4 + 24*(437 + 614*E_2)*M_3*r0 + 4*(59 + 2608*E_2)*M_2*r0_2 + 16*(40 + 127*E_2)*M*r0_3 + (423 - 443*E_2)*r0_4) + L_2*r0_3*(-41192*M_6 + 4*(-3823 + 6752*E_2)*M_5*r0 + 2*(2127 + 48568*E_2)*M_4*r0_2 + 3*(2001 + 30976*E_2)*M_3*r0_3 + (8091 + 20392*E_2)*M_2*r0_4 - 76*(-8 + 41*E_2)*M*r0_5 - 360*r0_6) + L_4*r0*(-40256*M_6 + 8*(-19 + 5604*E_2)*M_5*r0 + 4*(8619 + 28804*E_2)*M_4*r0_2 + 2*(5675 + 43864*E_2)*M_3*r0_3 + 3*(1895 + 6404*E_2)*M_2*r0_4 + (467 - 3516*E_2)*M*r0_5 - 75*r0_6)) - a_10*M*(L_4*(384*M_4 + 288*(12 + E_2)*M_3*r0 + 2*(3965 + 1224*E_2)*M_2*r0_2 + 3*(1597 + 404*E_2)*M*r0_3 + 18*(45 + 2*E_2)*r0_4) + L_2*r0*(768*(17 + 52*E_2)*M_5 + 32*(390 + 2897*E_2)*M_4*r0 + 2*(4257 + 50792*E_2)*M_3*r0_2 + (10973 + 55200*E_2)*M_2*r0_3 + (5755 + 12236*E_2)*M*r0_4 + 2*(410 + 253*E_2)*r0_5) + 24*E_2*r0_2*(-1312*M_6 - 2800*M_5*r0 - 216*M_4*r0_2 + 2624*M_3*r0_3 + 1894*M_2*r0_4 + 489*M*r0_5 + 47*r0_6)) + 2*a_9*E*L*M*r0*(6*L_4*(24*M_3 - 4*(-96 + E_2)*M_2*r0 + (361 - 2*E_2)*M*r0_2 + 72*r0_3) + L_2*(19968*M_5 + 32*(1559 + 303*E_2)*M_4*r0 + 12*(3933 + 1232*E_2)*M_3*r0_2 + 3*(9007 + 2520*E_2)*M_2*r0_3 + 6*(1567 + 216*E_2)*M*r0_4 + 1140*r0_5) + 8*r0*(-3936*M_6 + 4*(-1493 + 432*E_2)*M_5*r0 + 2*(161 + 2644*E_2)*M_4*r0_2 + (4231 + 5520*E_2)*M_3*r0_3 + 42*(77 + 58*E_2)*M_2*r0_4 + (1250 + 391*E_2)*M*r0_5 + 183*r0_6)) - a_8*r0*(6*L_6*M*(16*M_3 - 8*(-47 + 3*E_2)*M_2*r0 + 2*(262 + 37*E_2)*M*r0_2 + 3*(45 + E_2)*r0_3) - 48*E_2*M*r0_4*(1400*M_5 + 1724*M_4*r0 - 124*M_3*r0_2 - 722*M_2*r0_3 - 259*M*r0_4 - 35*r0_5) + L_4*M*(13312*M_5 + 96*(371 + 606*E_2)*M_4*r0 + 8*(2029 + 10014*E_2)*M_3*r0_2 + 2*(4317 + 23924*E_2)*M_2*r0_3 + 13*(627 + 892*E_2)*M*r0_4 + 14*(117 - 16*E_2)*r0_5) + L_2*r0*(-31488*M_7 + 64*(-443 + 235*E_2)*M_6*r0 + 4*(3539 + 22568*E_2)*M_5*r0_2 + 8*(1609 + 20166*E_2)*M_4*r0_3 + (10687 + 113840*E_2)*M_3*r0_4 + (7329 + 27616*E_2)*M_2*r0_5 + 36*(27 + 11*E_2)*M*r0_6 - 30*r0_7))))/(3.*r0_8*expr2_2); A91420 = (8*L*r0*(12*a_5*E*M*(2*M + r0) - a_4*L*(24*M_2 + 15*M*r0 + 2*r0_2) + 6*a*E*M*r0_3*(5*L_2 + 6*r0_2) - L*(2*M - r0)*r0_3*(8*L_2 + 9*r0_2) + 2*a_3*E*M*r0*(5*L_2 + 12*r0*(3*M + 2*r0)) - a_2*L*r0*(2*L_2*(5*M + r0) + r0*(42*M_2 + 11*M*r0 - 7*r0_2))))/(a_2 + r0*(-2*M + r0)); A91440 = (-4*(-144*a_12*E_2*M_2*(10*M_2 + 9*M*r0 + 2*r0_2) + 4*a_11*E*L*M*(144*(5 + E_2)*M_3 + (1733 + 144*E_2)*M_2*r0 + 36*(32 + E_2)*M*r0_2 + 231*r0_3) - (2*M - r0)*r0_5*(288*E_2*M*r0_9 + 16*L_8*M*(-2*M + r0) + 2*L_6*r0_2*(-310*M_2 + (71 + 271*E_2)*M*r0 + 42*r0_2) + 6*L_4*r0_4*(-50*M_2 + (-115 + 298*E_2)*M*r0 + 70*r0_2) + 3*L_2*r0_6*(176*M_2 + 14*(-25 + 38*E_2)*M*r0 + 131*r0_2)) + 2*a*E*L*M*r0_5*(3*L_4*r0_2*(52*M_2 + 4*(115 + 43*E_2)*M*r0 - 243*r0_2) + 10*L_6*(104*M_2 + 2*M*r0 - 27*r0_2) + 3*L_2*r0_4*(-356*M_2 + 24*(3 + 20*E_2)*M*r0 + 53*r0_2) + 6*r0_6*(120*M_2 + 2*(-179 + 90*E_2)*M*r0 + 149*r0_2)) + 2*a_3*E*L*M*r0_3*(4*L_6*(804*M_2 - 142*M*r0 - 69*r0_2) + L_4*r0*(384*M_3 + 4*(1793 + 276*E_2)*M_2*r0 + 4*(303 + 251*E_2)*M*r0_2 - 1055*r0_3) + 4*L_2*r0_3*(-2454*M_3 + (1067 + 1404*E_2)*M_2*r0 + (895 + 996*E_2)*M*r0_2 + 104*r0_3) + 2*r0_5*(-2160*M_3 + 72*(-29 + 42*E_2)*M_2*r0 + 4*(-112 + 501*E_2)*M*r0_2 + 1373*r0_3)) - a_10*M*(L_2*(288*(5 + 6*E_2)*M_3 + 4*(1409 + 876*E_2)*M_2*r0 + 3*(1401 + 472*E_2)*M*r0_2 + 3*(287 + 22*E_2)*r0_3) + 72*E_2*r0*(112*M_4 + 324*M_3*r0 + 258*M_2*r0_2 + 71*M*r0_3 + 5*r0_4)) + a_2*r0_3*(2*L_8*M*(-1072*M_2 + 522*M*r0 + 7*r0_2) + 72*E_2*M*r0_8*(-46*M_2 + 9*M*r0 + 11*r0_2) + 2*L_6*r0*(2544*M_4 - 4*(789 + 544*E_2)*M_3*r0 + 16*(45 - 62*E_2)*M_2*r0_2 + (23 + 537*E_2)*M*r0_3 + 44*r0_4) + L_4*r0_3*(11640*M_4 - 4*(1315 + 3042*E_2)*M_3*r0 - 2*(21 + 3706*E_2)*M_2*r0_2 + (-1365 + 4216*E_2)*M*r0_3 + 623*r0_4) + L_2*r0_5*(1032*M_4 - 108*(-39 + 112*E_2)*M_3*r0 - 2*(1 + 3174*E_2)*M_2*r0_2 + (-3001 + 4554*E_2)*M*r0_3 + 910*r0_4)) + 2*a_9*E*L*M*(3*L_2*(288*M_3 + 16*(55 + E_2)*M_2*r0 + 4*(259 + 2*E_2)*M*r0_2 + 309*r0_3) + 2*r0*(192*(21 + 10*E_2)*M_4 + 4*(1409 + 900*E_2)*M_3*r0 + (5485 + 2304*E_2)*M_2*r0_2 + 2*(1891 + 246*E_2)*M*r0_3 + 929*r0_4)) + 2*a_5*E*L*M*r0_2*(-6*L_6*(6*M + r0) + L_4*(12096*M_3 + 8*(897 + 134*E_2)*M_2*r0 + 4*(107 + 119*E_2)*M*r0_2 + 133*r0_3) + 2*L_2*r0*(-6816*M_4 + 4*(743 + 684*E_2)*M_3*r0 + 10*(845 + 492*E_2)*M_2*r0_2 + 2*(1633 + 918*E_2)*M*r0_3 + 785*r0_4) + 2*r0_3*(-11988*M_4 + 36*(-167 + 156*E_2)*M_3*r0 + (491 + 8064*E_2)*M_2*r0_2 + 36*(83 + 78*E_2)*M*r0_3 + 1872*r0_4)) - a_8*(3*L_4*M*(192*M_3 + 16*(49 + 6*E_2)*M_2*r0 + 4*(412 + 65*E_2)*M*r0_2 + 5*(115 + 4*E_2)*r0_3) - 288*E_2*M*r0_2*(76*M_5 + 132*M_4*r0 - 19*M_3*r0_2 - 102*M_2*r0_3 - 41*M*r0_4 - 4*r0_5) + L_2*r0*(1152*(7 + 20*E_2)*M_5 + 16*(-49 + 2724*E_2)*M_4*r0 + 4*(689 + 9582*E_2)*M_3*r0_2 + (8609 + 12372*E_2)*M_2*r0_3 + 8*(341 + 54*E_2)*M*r0_4 + 5*r0_5)) + a_4*r0_2*(6*L_8*M*(4*M + r0) + 144*E_2*M*r0_6*(48*M_3 - 3*M_2*r0 + 4*M*r0_2 + 2*r0_3) - 2*L_6*(4032*M_4 + 12*(121 + 268*E_2)*M_3*r0 + 2*(-729 + 215*E_2)*M_2*r0_2 + (473 - 269*E_2)*M*r0_3 - 2*r0_4) + L_4*r0*(20544*M_5 - 32*(298 + 525*E_2)*M_4*r0 - 4*(1711 + 6928*E_2)*M_3*r0_2 + 4*(437 - 2283*E_2)*M_2*r0_3 + (-2197 + 3008*E_2)*M*r0_4 + 202*r0_5) + L_2*r0_3*(18528*M_5 - 36*(15 + 308*E_2)*M_4*r0 - 4*(-601 + 8034*E_2)*M_3*r0_2 - (3203 + 12948*E_2)*M_2*r0_3 + 12*(-213 + 335*E_2)*M*r0_4 + 636*r0_5)) + 2*a_7*E*L*M*r0*(3*L_4*(48*M_2 - 4*(-59 + E_2)*M*r0 + 153*r0_2) + 4*L_2*(2880*M_4 + 24*(229 + 42*E_2)*M_3*r0 + (3283 + 1068*E_2)*M_2*r0_2 + 3*(571 + 96*E_2)*M*r0_3 + 560*r0_4) + 2*r0*(-10944*M_5 + 12*(-941 + 288*E_2)*M_4*r0 + 8*(283 + 1134*E_2)*M_3*r0_2 + 25*(235 + 288*E_2)*M_2*r0_3 + 24*(208 + 75*E_2)*M*r0_4 + 1644*r0_5)) - a_6*r0*(6*L_6*M*(16*M_2 - 6*(-19 + 2*E_2)*M*r0 - (-143 + E_2)*r0_2) - 144*E_2*M*r0_4*(232*M_4 + 178*M_3*r0 - 64*M_2*r0_2 - 53*M*r0_3 - 7*r0_4) + L_4*(7680*M_5 + 1344*(11 + 18*E_2)*M_4*r0 + 8*(-356 + 2499*E_2)*M_3*r0_2 + 2*(1663 + 3038*E_2)*M_2*r0_3 + 5*(731 - 104*E_2)*M*r0_4 + r0_5) + L_2*r0*(-21888*M_6 + 48*(-149 + 148*E_2)*M_5*r0 + 60*(121 + 644*E_2)*M_4*r0_2 + 16*(-148 + 3465*E_2)*M_3*r0_3 + (6035 + 20748*E_2)*M_2*r0_4 + 6*(543 - 116*E_2)*M*r0_5 - 114*r0_6))))/(3.*r0_5*expr2_2); A91600 = (2*L*r0_4*(4*a_3*E*M + 12*a*E*M*r0_2 + 3*L*r0_2*(-2*M + r0) - a_2*L*(4*M + r0)))/(a_2 + r0*(-2*M + r0)); A91620 = (48*a_10*E_2*M_2*(13*M + 6*r0) - 24*a_9*E*L*M*(4*(13 + 3*E_2)*M_2 + 2*(55 + 3*E_2)*M*r0 + 41*r0_2) - 2*a*E*L*M*r0_4*(36*r0_5*(2*(-17 + 7*E_2)*M + 17*r0) + 2*L_4*(140*M_2 + 116*M*r0 - 93*r0_2) + L_2*r0_2*(-1012*M_2 + 8*(85 + 36*E_2)*M*r0 - 87*r0_2)) + (2*M - r0)*r0_4*(-56*L_6*M*(2*M - r0) + 192*E_2*M*r0_7 + 8*L_2*r0_4*(20*M_2 + (-76 + 85*E_2)*M*r0 + 33*r0_2) + L_4*r0_2*(-420*M_2 + 4*(-12 + 79*E_2)*M*r0 + 129*r0_2)) + 3*a_8*(L_2*(16*(13 + 18*E_2)*M_3 + 16*(49 + 18*E_2)*M_2*r0 + (319 + 26*E_2)*M*r0_2 + 3*r0_3) + 8*E_2*M*r0*(88*M_3 + 262*M_2*r0 + 129*M*r0_2 + 9*r0_3)) - 2*a_7*E*L*M*(3*L_2*(144*M_2 + 4*(54 + E_2)*M*r0 + 175*r0_2) + 8*r0*(8*(33 + 14*E_2)*M_3 + (181 + 202*E_2)*M_2*r0 + (337 + 82*E_2)*M*r0_2 + 193*r0_3)) - 2*a_3*E*L*M*r0_2*(2*L_4*(804*M_2 - 64*M*r0 - 81*r0_2) + L_2*r0*(-2768*M_3 + 28*(79 + 18*E_2)*M_2*r0 + 4*(262 + 151*E_2)*M*r0_2 + 191*r0_3) + 8*r0_3*(-510*M_3 + (-169 + 198*E_2)*M_2*r0 + 5*(-9 + 38*E_2)*M*r0_2 + 205*r0_3)) + a_6*(3*L_4*(96*M_3 + 24*(8 + E_2)*M_2*r0 + 4*(81 + 2*E_2)*M*r0_2 + 3*r0_3) + 24*E_2*M*r0_2*(-280*M_4 - 380*M_3*r0 + 152*M_2*r0_2 + 197*M*r0_3 + 19*r0_4) + L_2*r0*(192*(11 + 28*E_2)*M_4 + 8*(-424 + 1049*E_2)*M_3*r0 + 2*(891 + 2434*E_2)*M_2*r0_2 + 3*(807 + 22*E_2)*M*r0_3 + 43*r0_4)) - 2*a_5*E*L*M*r0*(12*L_4*(3*M + 2*r0) + L_2*(2688*M_3 + 8*(443 + 67*E_2)*M_2*r0 + 8*(87 + 41*E_2)*M*r0_2 + 803*r0_3) + 16*r0*(-420*M_4 + (-223 + 72*E_2)*M_3*r0 + (49 + 191*E_2)*M_2*r0_2 + 2*(61 + 50*E_2)*M*r0_3 + 130*r0_4)) - a_2*r0_2*(-8*L_6*M*(134*M_2 - 57*M*r0 - 5*r0_2) + 24*E_2*M*r0_6*(-30*M_2 + M*r0 + 15*r0_2) + L_4*r0*(3920*M_4 - 32*(111 + 56*E_2)*M_3*r0 - 8*(-152 + 181*E_2)*M_2*r0_2 + 4*(-109 + 156*E_2)*M*r0_3 + 113*r0_4) + L_2*r0_3*(2840*M_4 - 4*(125 + 424*E_2)*M_3*r0 + 2*(519 - 1858*E_2)*M_2*r0_2 + (-1563 + 1450*E_2)*M*r0_3 + 407*r0_4)) + a_4*r0*(24*L_6*M*(M + r0) - 24*E_2*M*r0_4*(252*M_3 + 70*M_2*r0 - 63*M*r0_2 - 3*r0_3) + L_4*(1792*M_4 + 8*(241 + 402*E_2)*M_3*r0 + 4*(-541 + 214*E_2)*M_2*r0_2 + 2*(687 - 142*E_2)*M*r0_3 + 25*r0_4) + L_2*r0*(-6720*M_5 + 16*(124 + 43*E_2)*M_4*r0 + 4*(-145 + 1746*E_2)*M_3*r0_2 + 40*(-29 + 159*E_2)*M_2*r0_3 + (2083 - 782*E_2)*M*r0_4 - 109*r0_5)))/(3.*r0_2*expr2_2); A91800 = -(r0*(-96*a_8*E_2*M_2 + 12*a_7*E*L*M*(4*(4 + E_2)*M + 29*r0) + (2*M - r0)*r0_3*(40*L_4*M*(2*M - r0) - 48*E_2*M*r0_5 + L_2*r0_2*(8*M_2 + 2*(67 - 37*E_2)*M*r0 - 69*r0_2)) - 3*a_6*(16*E_2*M*r0*(4*M_2 + 14*M*r0 + r0_2) + L_2*(16*(2 + 3*E_2)*M_2 + 2*(58 + 5*E_2)*M*r0 + 3*r0_2)) + 4*a*E*L*M*r0_3*(L_2*(-80*M_2 + 106*M*r0 - 33*r0_2) + 3*r0_2*(-20*M_2 + 4*(-11 + 3*E_2)*M*r0 + 27*r0_2)) + 4*a_5*E*L*M*(3*L_2*(12*M + 5*r0) + r0*(32*(3 + E_2)*M_2 + 4*(-7 + 19*E_2)*M*r0 + 191*r0_2)) - a_4*(6*L_4*M*(8*M + 5*r0) + 48*E_2*M*r0_2*(-16*M_3 - 16*M_2*r0 + 12*M*r0_2 + r0_3) + L_2*r0*(192*(1 + 2*E_2)*M_3 + 4*(-196 + 149*E_2)*M_2*r0 + 2*(288 - 23*E_2)*M*r0_2 + 29*r0_3)) + 4*a_3*E*L*M*r0*(2*L_2*(48*M_2 + 35*M*r0 - 9*r0_2) + r0*(-384*M_3 - 4*M_2*r0 + 20*(-4 + 5*E_2)*M*r0_2 + 185*r0_3)) + a_2*r0*(48*E_2*M*r0_4*(4*M_2 - 2*M*r0 + r0_2) + 2*L_4*M*(-64*M_2 + 6*M*r0 + 13*r0_2) + L_2*r0*(768*M_4 + 16*(-47 + 10*E_2)*M_3*r0 + 4*(167 - 166*E_2)*M_2*r0_2 + 10*(-34 + 15*E_2)*M*r0_3 + 49*r0_4))))/(12.*expr2_2); A92040 = (192*L_2*expr1_2)/(a_2 + r0*(-2*M + r0)); A92060 = (-32*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(-24*a_10*E_2*M_2*r0_p_2M_2 + 48*a_9*E*L*M*(4*M_3 + 4*M_2*r0 + 3*M*r0_2 + r0_3) - 4*a*E*L*M*r0_6*(L_4*(191*M - 18*r0) + L_2*(427*M - 93*r0)*r0_2 + 6*(31*M - 9*r0)*r0_4) - 4*a_3*E*L*M*r0_3*(L_2*r0_2*(1180*M_2 + 655*M*r0 - 157*r0_2) + L_4*(352*M_2 + 185*M*r0 - 27*r0_2) + 6*r0_4*(84*M_2 + 57*M*r0 - 23*r0_2)) + r0_6*(8*L_6*M*(2*M - r0) + 96*E_2*M*r0_7 + 2*L_4*r0_2*(138*M_2 + (-135 + 82*E_2)*M*r0 + 33*r0_2) + L_2*r0_4*(248*M_2 + 2*(-125 + 134*E_2)*M*r0 + 63*r0_2)) + 4*a_5*E*L*M*r0_2*(3*L_4*(4*M + 5*r0) - L_2*(1120*M_3 + 1232*M_2*r0 + 293*M*r0_2 - 91*r0_3) - 18*r0_2*(36*M_3 + 52*M_2*r0 + 13*M*r0_2 - 7*r0_3)) + 2*a_2*r0_3*(12*E_2*M*r0_7*(23*M + 16*r0) + L_6*(352*M_3 + 42*M_2*r0 - 28*M*r0_2 - 6*r0_3) + L_4*r0_2*(530*M_3 + (237 + 340*E_2)*M_2*r0 + (-183 + 158*E_2)*M*r0_2 + 18*r0_3) + L_2*r0_4*(250*M_3 + 15*(9 + 58*E_2)*M_2*r0 + 9*(-23 + 44*E_2)*M*r0_2 + 54*r0_3)) + 4*a_7*E*L*M*r0*(L_2*(12*M_2 + 47*M*r0 + 27*r0_2) - 6*(128*M_4 + 156*M_3*r0 + 88*M_2*r0_2 + 7*M*r0_3 - 9*r0_4)) - a_8*M*(L_2*(96*M_3 + 24*(4 + E_2)*M_2*r0 + (119 + 36*E_2)*M*r0_2 + 6*(7 + 2*E_2)*r0_3) - 96*E_2*r0*(16*M_4 + 26*M_3*r0 + 17*M_2*r0_2 + 6*M*r0_3 + r0_4)) + a_4*r0_2*(-24*L_6*M*(M + 2*r0) + 288*E_2*M*r0_5*(5*M_2 + 6*M*r0 + 2*r0_2) + 2*L_4*(1120*M_4 + 8*(95 + 44*E_2)*M_3*r0 + (59 + 328*E_2)*M_2*r0_2 + 7*(-27 + 10*E_2)*M*r0_3 - 15*r0_4) + L_2*r0_2*(380*M_4 + 4*(355 + 882*E_2)*M_3*r0 + 3*(51 + 1132*E_2)*M_2*r0_2 + 12*(-37 + 64*E_2)*M*r0_3 + 27*r0_4)) + 2*a_6*r0*(-(L_4*M*(12*M_2 + 4*(19 + 3*E_2)*M*r0 + 3*(15 + 2*E_2)*r0_2)) + 24*E_2*M*r0_3*(46*M_3 + 66*M_2*r0 + 37*M*r0_2 + 8*r0_3) + L_2*(768*M_5 + 16*(39 + 70*E_2)*M_4*r0 + 24*(16 + 71*E_2)*M_3*r0_2 + 6*(-26 + 135*E_2)*M_2*r0_3 + (-161 + 116*E_2)*M*r0_4 - 9*r0_5))))/(3.*r0_7*expr2_2); A92220 = (96*L_2*r0_3*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/(a_2 + r0*(-2*M + r0)); A92240 = (-8*(-72*a_10*E_2*M_2*r0_p_2M_2 + 24*a_9*E*L*M*(24*M_3 + 12*M_2*r0 + 2*M*r0_2 + r0_3) + 4*a*E*L*M*r0_4*(4*L_6*M - 9*L_4*(54*M - 5*r0)*r0_2 + 18*r0_6*(-25*M + 6*r0) + 6*L_2*r0_4*(-165*M + 29*r0)) - 4*a_3*E*L*M*r0_3*(L_2*r0_2*(2778*M_2 + 1535*M*r0 - 241*r0_2) + 18*r0_4*(84*M_2 + 47*M*r0 - 15*r0_2) + 6*L_4*(144*M_2 + 78*M*r0 - r0_2)) + r0_4*(288*E_2*M*r0_9 + 4*L_8*M*(-2*M + r0) - 2*L_6*r0_2*(22*M_2 + (37 + 2*E_2)*M*r0 - 24*r0_2) + 12*L_4*r0_4*(36*M_2 + 4*(-14 + 9*E_2)*M*r0 + 19*r0_2) + 3*L_2*r0_6*(152*M_2 + 2*(-97 + 122*E_2)*M*r0 + 59*r0_2)) - 4*a_5*E*L*M*r0_2*(3*L_4*(2*M + r0) + L_2*(2928*M_3 + 2806*M_2*r0 + 784*M*r0_2 - 70*r0_3) + 6*r0_2*(396*M_3 + 432*M_2*r0 + 95*M*r0_2 - 37*r0_3)) + 2*a_2*r0_3*(36*E_2*M*r0_7*(23*M + 16*r0) + L_6*(864*M_3 - 4*(-9 + E_2)*M_2*r0 + (11 - 2*E_2)*M*r0_2 - 3*r0_3) + 9*L_4*r0_2*(128*M_3 + 2*(11 + 51*E_2)*M_2*r0 + (-25 + 48*E_2)*M*r0_2 + 13*r0_3) + 3*L_2*r0_4*(204*M_3 + 2*(-5 + 348*E_2)*M_2*r0 + 3*(-39 + 122*E_2)*M*r0_2 + 61*r0_3)) + 4*a_7*E*L*M*r0*(L_2*(24*M_2 - 19*M*r0 + 3*r0_2) - 6*(384*M_4 + 444*M_3*r0 + 208*M_2*r0_2 + 27*M*r0_3 - 11*r0_4)) + a_8*(288*E_2*M*r0*(16*M_4 + 26*M_3*r0 + 17*M_2*r0_2 + 6*M*r0_3 + r0_4) + L_2*(-288*M_4 - 48*E_2*M_3*r0 + (73 - 24*E_2)*M_2*r0_2 + 18*M*r0_3 + 6*r0_4)) + a_4*r0_2*(6*L_6*(2*M_2 + 2*M*r0 + r0_2) + 864*E_2*M*r0_5*(5*M_2 + 6*M*r0 + 2*r0_2) + 2*L_4*(2928*M_4 + 4*(341 + 216*E_2)*M_3*r0 + 4*(47 + 225*E_2)*M_2*r0_2 + 108*(-1 + 2*E_2)*M*r0_3 + 9*r0_4) + 3*L_2*r0_2*(844*M_4 + 4*(181 + 696*E_2)*M_3*r0 + (-1 + 2808*E_2)*M_2*r0_2 + 12*(-9 + 61*E_2)*M*r0_3 + 69*r0_4)) + 2*a_6*r0*(L_4*(-24*M_3 + 2*(25 + 3*E_2)*M_2*r0 + 15*M*r0_2 + 6*r0_3) + 72*E_2*M*r0_3*(46*M_3 + 66*M_2*r0 + 37*M*r0_2 + 8*r0_3) + L_2*(2304*M_5 + 48*(33 + 61*E_2)*M_4*r0 + 2*(259 + 2124*E_2)*M_3*r0_2 + (-49 + 2112*E_2)*M_2*r0_3 + 3*(-31 + 122*E_2)*M*r0_4 + 12*r0_5))))/(3.*r0_4*expr2_2); A92400 = (12*L_2*r0_6)/(a_2 + r0*(-2*M + r0)); A92420 = (-2*(-72*a_8*E_2*M_2*(2*M + r0) + 48*a_7*E*L*M*(6*M_2 - 3*M*r0 - 2*r0_2) + 12*a*E*L*M*r0_3*(L_4*(8*M - 4*r0) + 6*r0_4*(-19*M + 3*r0) + L_2*r0_2*(-119*M + 5*r0)) - 24*a_5*E*L*M*r0*(192*M_3 + 114*M_2*r0 + 25*M*r0_2 + r0_3 + L_2*(5*M + 8*r0)) - 12*a_3*E*L*M*r0_2*(4*L_4 + 12*r0_2*(23*M_2 + 12*M*r0 - 2*r0_2) + L_2*(224*M_2 + 99*M*r0 + 17*r0_2)) + r0_3*(288*E_2*M*r0_7 + 24*L_6*M*(-2*M + r0) + L_4*r0_2*(-132*M_2 - 152*M*r0 + 109*r0_2) + L_2*r0_4*(168*M_2 + 62*(-7 + 6*E_2)*M*r0 + 175*r0_2)) + 3*a_6*(L_2*(-48*M_3 + 4*(18 + 5*E_2)*M_2*r0 + 6*(7 + 2*E_2)*M*r0_2 + 3*r0_3) + 24*E_2*M*r0*(32*M_3 + 36*M_2*r0 + 17*M*r0_2 + 4*r0_3)) + a_2*r0_2*(24*L_6*M + 216*E_2*M*r0_5*(5*M + 4*r0) + 2*L_4*(672*M_3 - 6*(19 + 4*E_2)*M_2*r0 + 6*(17 + 2*E_2)*M*r0_2 + 35*r0_3) + L_2*r0_2*(612*M_3 + 2*(-167 + 654*E_2)*M_2*r0 + 78*(-1 + 10*E_2)*M*r0_2 + 269*r0_3)) + a_4*r0*(3*L_4*(20*M_2 + 4*(13 + 2*E_2)*M*r0 + 3*r0_2) + 216*E_2*M*r0_3*(10*M_2 + 11*M*r0 + 4*r0_2) + L_2*(2304*M_4 + 48*(3 + 28*E_2)*M_3*r0 + 6*(3 + 236*E_2)*M_2*r0_2 + 2*(151 + 222*E_2)*M*r0_3 + 103*r0_4))))/(3.*r0*expr2_2); A92600 = -(r0_2*(-24*a_6*E_2*M_2 + 24*a_5*E*L*M*(2*M - 3*r0) - 24*a_3*E*L*M*r0*(2*L_2 + 32*M_2 + M*r0 + r0_2) + 8*a*E*L*M*r0_2*(2*L_2*(5*M - 3*r0) - 39*M*r0_2) + 3*a_4*(L_2*(-8*M_2 + 8*(3 + E_2)*M*r0 + r0_2) + 16*E_2*M*r0*(8*M_2 + 5*M*r0 + 2*r0_2)) + r0_2*(96*E_2*M*r0_5 + 20*L_4*M*(-2*M + r0) + L_2*r0_2*(-40*M_2 + 2*(-51 + 2*E_2)*M*r0 + 61*r0_2)) + 2*a_2*r0*(12*L_4*M + 12*E_2*M*r0_3*(7*M + 8*r0) + L_2*(192*M_3 - 4*(27 + 5*E_2)*M_2*r0 + (43 + 14*E_2)*M*r0_2 + 32*r0_3))))/(6.*expr2_2); A93040 = (32*L*(a_2*(2*M + r0) + r0*(L_2 + r0_2))*(12*a_5*E*M*(2*M + r0) - a_4*L*(24*M_2 + 12*M*r0 + r0_2) + 12*a*E*M*r0_3*(2*L_2 + 3*r0_2) + 8*a_3*E*M*r0*(L_2 + 9*M*r0 + 6*r0_2) + L*r0_3*(L_2*(-15*M + 8*r0) + r0_2*(-19*M + 10*r0)) - a_2*L*r0*(L_2*(8*M + r0) + r0*(50*M_2 + 9*M*r0 - 9*r0_2))))/(r0_2*expr2_2); A93060 = (-16*(24*a_14*E_2*M_2*r0_p_2M_2*(M + 4*r0) - 4*a_13*E*L*M*(2*M + r0)*(24*M_3 + (-37 + 24*E_2)*M_2*r0 + 12*(1 + E_2)*M*r0_2 + 24*r0_3) + 2*a*E*L*M*r0_6*(L_4*r0_4*(164*M_2 + 4*(562 + 393*E_2)*M*r0 - 1203*r0_2) + 2*L_6*r0_2*(658*M_2 + 6*(106 + 35*E_2)*M*r0 - 489*r0_2) + 210*L_8*(4*M_2 - r0_2) + 6*r0_8*(180*M_2 + 2*(-127 + 72*E_2)*M*r0 + 81*r0_2) + L_2*r0_6*(1176*M_2 + 4*(-233 + 495*E_2)*M*r0 + 141*r0_2)) + 2*a_3*E*L*M*r0_4*(210*L_8*(12*M_2 - 2*M*r0 - r0_2) + 2*L_4*r0_3*(-506*M_3 + (5351 + 3108*E_2)*M_2*r0 + (3245 + 2204*E_2)*M*r0_2 - 1998*r0_3) + L_2*r0_5*(876*M_3 + 2*(797 + 5814*E_2)*M_2*r0 + 12*(271 + 593*E_2)*M*r0_2 - 1035*r0_3) + 4*L_6*r0*(760*M_3 + (1987 + 210*E_2)*M_2*r0 + 42*(8 + 5*E_2)*M*r0_2 - 492*r0_3) + 4*r0_7*(378*M_3 + (-791 + 2088*E_2)*M_2*r0 + (-311 + 950*E_2)*M*r0_2 + 339*r0_3)) + r0_8*(24*E_2*M*r0_9*(-15*M + 7*r0) + 2*L_8*M*(2*M - r0)*(154*M - 3*(27 + 70*E_2)*r0) + L_6*r0_2*(560*M_3 + (46 - 3580*E_2)*M_2*r0 + (-487 + 1794*E_2)*M*r0_2 + 162*r0_3) + L_2*r0_6*(-1236*M_3 + (2198 - 2760*E_2)*M_2*r0 + 2*(-638 + 683*E_2)*M*r0_2 + 243*r0_3) + L_4*r0_4*(-1340*M_3 + 4*(737 - 1279*E_2)*M_2*r0 + (-1961 + 2560*E_2)*M*r0_2 + 411*r0_3)) + 2*a_5*E*L*M*r0_3*(2*L_6*(7296*M_3 + 4*(886 + 105*E_2)*M_2*r0 + 6*(44 + 35*E_2)*M*r0_2 - 531*r0_3) + L_4*r0*(-1888*M_4 + 4*(6037 + 1536*E_2)*M_3*r0 + 8*(3396 + 1397*E_2)*M_2*r0_2 + 8*(775 + 514*E_2)*M*r0_3 - 4473*r0_4) + L_2*r0_3*(-13992*M_4 + 4*(3067 + 5850*E_2)*M_3*r0 + 42*(597 + 724*E_2)*M_2*r0_2 + 6*(1415 + 1576*E_2)*M*r0_3 - 3537*r0_4) + 2*r0_5*(-9972*M_4 + 216*(-11 + 62*E_2)*M_3*r0 + (579 + 14000*E_2)*M_2*r0_2 + 2*(799 + 1634*E_2)*M*r0_3 + 468*r0_4)) + a_2*r0_4*(-840*L_10*M_2*(2*M - r0) - 72*E_2*M*r0_10*(60*M_2 - 19*M*r0 - 8*r0_2) + 2*L_8*r0*(1552*M_4 - 60*(37 + 28*E_2)*M_3*r0 - 30*(1 + 28*E_2)*M_2*r0_2 + (367 + 420*E_2)*M*r0_3 + 12*r0_4) + L_6*r0_3*(10152*M_4 - 4*(1137 + 3826*E_2)*M_3*r0 - 4*(991 + 1814*E_2)*M_2*r0_2 + (1483 + 4540*E_2)*M*r0_3 + 231*r0_4) + L_2*r0_7*(-4200*M_4 + 4*(1777 - 5538*E_2)*M_3*r0 - 4*(162 + 353*E_2)*M_2*r0_2 + (-2345 + 4988*E_2)*M*r0_3 + 723*r0_4) + L_4*r0_5*(2680*M_4 + 4*(1321 - 6546*E_2)*M_3*r0 - 10*(385 + 976*E_2)*M_2*r0_2 + (-1359 + 8000*E_2)*M*r0_3 + 861*r0_4)) - 4*a_11*E*L*M*r0*(L_2*(12*(-53 + 3*E_2)*M_3 + 2*(-404 + 15*E_2)*M_2*r0 + 3*(-33 + 2*E_2)*M*r0_2 + 72*r0_3) - 2*(80*(51 + 22*E_2)*M_5 + 8*(945 + 464*E_2)*M_4*r0 + 21*(251 + 128*E_2)*M_3*r0_2 + 8*(197 + 95*E_2)*M_2*r0_3 + 2*(-7 + 31*E_2)*M*r0_4 - 90*r0_5)) - a_12*M*(L_2*(-96*M_4 + 8*(85 + 123*E_2)*M_3*r0 + 4*(109 + 237*E_2)*M_2*r0_2 + 9*(-17 + 24*E_2)*M*r0_3 - 6*(15 + E_2)*r0_4) + 24*E_2*r0*(680*M_5 + 1604*M_4*r0 + 1314*M_3*r0_2 + 481*M_2*r0_3 + 92*M*r0_4 + 11*r0_5)) + 2*a_7*E*L*M*r0_2*(24*L_6*(3*M_2 + 19*M*r0 - 2*r0_2) + 2*L_4*(14688*M_4 + 4*(4395 + 608*E_2)*M_3*r0 + (9365 + 2492*E_2)*M_2*r0_2 + 4*(355 + 161*E_2)*M*r0_3 - 912*r0_4) + L_2*r0*(-23808*M_5 + 24*(745 + 672*E_2)*M_4*r0 + 4*(15251 + 9474*E_2)*M_3*r0_2 + 18*(2353 + 1432*E_2)*M_2*r0_3 + 2*(2963 + 2736*E_2)*M*r0_4 - 3549*r0_5) - 12*r0_3*(4452*M_5 - 120*(-25 + 24*E_2)*M_4*r0 - (1393 + 5248*E_2)*M_3*r0_2 - (1445 + 2848*E_2)*M_2*r0_3 - (351 + 452*E_2)*M*r0_4 + 43*r0_5)) + a_4*r0_3*(24*E_2*M*r0_8*(-174*M_3 - 145*M_2*r0 + 234*M*r0_2 + 15*r0_3) - 2*L_8*M*(4864*M_3 + 4*(263 + 630*E_2)*M_2*r0 + 420*(-1 + E_2)*M*r0_2 - 7*(49 + 30*E_2)*r0_3) + L_6*r0*(18016*M_5 - 8*(1311 + 2684*E_2)*M_4*r0 - 8*(1805 + 4226*E_2)*M_3*r0_2 - 4*(871 + 1914*E_2)*M_2*r0_3 + 2*(1885 + 1852*E_2)*M*r0_4 + 69*r0_5) + L_4*r0_3*(28492*M_5 + 4*(503 - 13140*E_2)*M_4*r0 - (12553 + 67264*E_2)*M_3*r0_2 - 108*(88 + 115*E_2)*M_2*r0_3 + 21*(173 + 412*E_2)*M*r0_4 + 489*r0_5) + L_2*r0_5*(8364*M_5 - 60*(-83 + 1002*E_2)*M_4*r0 - 63*(-57 + 796*E_2)*M_3*r0_2 + 20*(-349 + 158*E_2)*M_2*r0_3 + (-217 + 6298*E_2)*M*r0_4 + 711*r0_5)) + 4*a_9*E*L*M*r0*(L_4*(-108*M_3 + 6*(139 + 2*E_2)*M_2*r0 + 3*(129 + 2*E_2)*M*r0_2 - 72*r0_3) + L_2*(10560*M_5 + 8*(3409 + 612*E_2)*M_4*r0 + 6*(4067 + 1186*E_2)*M_3*r0_2 + 3*(3591 + 1156*E_2)*M_2*r0_3 + 3*(303 + 190*E_2)*M*r0_4 - 666*r0_5) + r0*(-16128*M_6 + 8*(-2749 + 936*E_2)*M_5*r0 + 4*(2017 + 5984*E_2)*M_4*r0_2 + 2*(10151 + 11760*E_2)*M_3*r0_3 + 276*(33 + 32*E_2)*M_2*r0_4 + 8*(85 + 131*E_2)*M*r0_5 - 447*r0_6)) - a_6*r0_2*(6*L_8*M*(8*M_2 + 74*M*r0 - 15*r0_2) - 24*E_2*M*r0_6*(1320*M_4 + 320*M_3*r0 - 103*M_2*r0_2 + 106*M*r0_3 - 40*r0_4) + 4*L_6*M*(4896*M_4 + 48*(109 + 152*E_2)*M_3*r0 + (1753 + 5510*E_2)*M_2*r0_2 + 2*(10 + 559*E_2)*M*r0_3 - (564 + 241*E_2)*r0_4) + L_2*r0_3*(-43656*M_6 + 4*(-3607 + 16068*E_2)*M_5*r0 + 2*(4865 + 68696*E_2)*M_4*r0_2 + (12817 + 79104*E_2)*M_3*r0_3 + 3*(1471 + 2856*E_2)*M_2*r0_4 - (2243 + 2632*E_2)*M*r0_5 - 225*r0_6) + L_4*r0*(-38784*M_6 + 16*(109 + 2906*E_2)*M_5*r0 + 64*(558 + 1775*E_2)*M_4*r0_2 + 394*(65 + 212*E_2)*M_3*r0_3 + (2097 + 17020*E_2)*M_2*r0_4 - 7*(751 + 508*E_2)*M*r0_5 - 39*r0_6)) + a_10*M*r0*(L_4*(72*(-19 + 6*E_2)*M_3 - 4*(523 + 372*E_2)*M_2*r0 - 3*(41 + 268*E_2)*M*r0_2 + 6*(45 + 2*E_2)*r0_3) - L_2*(960*(17 + 44*E_2)*M_5 + 16*(1374 + 6193*E_2)*M_4*r0 + 2*(5859 + 46232*E_2)*M_3*r0_2 + (2087 + 41976*E_2)*M_2*r0_3 + (-2105 + 8516*E_2)*M*r0_4 + 2*(-463 + 226*E_2)*r0_5) - 24*E_2*r0*(-1344*M_6 - 2416*M_5*r0 + 444*M_4*r0_2 + 2452*M_3*r0_3 + 1366*M_2*r0_4 + 327*M*r0_5 + 48*r0_6)) - a_8*r0*(-6*L_6*M*(24*M_3 - 24*(12 + E_2)*M_2*r0 - 2*(60 + 41*E_2)*M*r0_2 + (45 + E_2)*r0_3) - 24*E_2*M*r0_4*(2808*M_5 + 2772*M_4*r0 - 624*M_3*r0_2 - 1006*M_2*r0_3 - 287*M*r0_4 - 75*r0_5) + L_4*M*(14080*M_5 + 48*(827 + 1224*E_2)*M_4*r0 + 8*(3331 + 9732*E_2)*M_3*r0_2 + (10101 + 44320*E_2)*M_2*r0_3 + 2*(-987 + 5024*E_2)*M*r0_4 - 4*(624 + 89*E_2)*r0_5) + L_2*r0*(-32256*M_7 + 32*(-937 + 660*E_2)*M_6*r0 + 8*(2729 + 16220*E_2)*M_5*r0_2 + 4*(6837 + 43484*E_2)*M_4*r0_3 + (11707 + 92136*E_2)*M_3*r0_4 + (-1673 + 18680*E_2)*M_2*r0_5 + (-2227 + 502*E_2)*M*r0_6 + 6*r0_7))))/(3.*r0_8*expr2_3); A93220 = (16*L*r0*(12*a_5*E*M*(2*M + r0) - a_4*L*(24*M_2 + 15*M*r0 + 2*r0_2) + 6*a*E*M*r0_3*(5*L_2 + 6*r0_2) + 2*a_3*E*M*r0*(5*L_2 + 12*r0*(3*M + 2*r0)) + L*r0_3*(L_2*(-17*M + 9*r0) + r0_2*(-19*M + 10*r0)) - 2*a_2*L*r0*(L_2*(5*M + r0) + r0*(22*M_2 + 5*M*r0 - 4*r0_2))))/expr2_2; A93240 = (-4*(-24*a_12*E_2*M_2*(24*M_2 + 10*M*r0 - r0_2) + 4*a_11*E*L*M*(96*(3 + E_2)*M_3 + (1213 + 48*E_2)*M_2*r0 + 846*M*r0_2 + 150*r0_3) + 4*a*E*L*M*r0_5*(L_4*r0_2*(350*M_2 + (1549 + 534*E_2)*M*r0 - 888*r0_2) + L_6*(1048*M_2 + 6*M*r0 - 267*r0_2) + 3*L_2*r0_4*(-20*M_2 + 4*(5 + 117*E_2)*M*r0 - 17*r0_2) + 9*r0_6*(96*M_2 + 12*(-17 + 9*E_2)*M*r0 + 77*r0_2)) + 4*a_3*E*L*M*r0_3*(L_6*(3180*M_2 - 520*M*r0 - 261*r0_2) + L_4*r0*(928*M_3 + 6*(1057 + 178*E_2)*M_2*r0 + 2*(975 + 532*E_2)*M*r0_2 - 1479*r0_3) + L_2*r0_3*(-5322*M_3 + (4487 + 5454*E_2)*M_2*r0 + (3779 + 3828*E_2)*M*r0_2 - 921*r0_3) + 3*r0_5*(-1176*M_3 + 44*(-17 + 54*E_2)*M_2*r0 + 88*(-2 + 13*E_2)*M*r0_2 + 545*r0_3)) + r0_5*(72*E_2*M*r0_9*(-15*M + 7*r0) + 2*L_8*M*(20*M_2 - 16*M*r0 + 3*r0_2) + 2*L_6*r0_2*(912*M_3 - 10*(79 + 107*E_2)*M_2*r0 + (95 + 537*E_2)*M*r0_2 + 36*r0_3) + 3*L_2*r0_6*(-820*M_3 + 2*(853 - 1004*E_2)*M_2*r0 + 2*(-549 + 499*E_2)*M*r0_2 + 225*r0_3) + L_4*r0_4*(-112*M_3 + (2694 - 6896*E_2)*M_2*r0 + (-2657 + 3464*E_2)*M*r0_2 + 669*r0_3)) - a_10*M*(L_2*(576*(1 + 2*E_2)*M_3 + 4*(1153 + 753*E_2)*M_2*r0 + 3*(1087 + 428*E_2)*M*r0_2 + 18*(31 + 2*E_2)*r0_3) + 24*E_2*r0*(888*M_4 + 1756*M_3*r0 + 1080*M_2*r0_2 + 265*M*r0_3 + 30*r0_4)) + 4*a_5*E*L*M*r0_2*(6*L_6*r0 + L_4*(12240*M_3 + 2*(3411 + 530*E_2)*M_2*r0 + (881 + 530*E_2)*M*r0_2 - 546*r0_3) + L_2*r0*(-11664*M_4 + 2*(5207 + 2808*E_2)*M_3*r0 + 6*(3051 + 1589*E_2)*M_2*r0_2 + (5647 + 3444*E_2)*M*r0_3 - 1014*r0_4) + 3*r0_3*(-8076*M_4 + 12*(-191 + 396*E_2)*M_3*r0 + (1525 + 5784*E_2)*M_2*r0_2 + 6*(223 + 248*E_2)*M*r0_3 + 461*r0_4)) + 4*a_9*E*L*M*(3*L_2*(96*M_3 - 2*(-227 + E_2)*M_2*r0 + 465*M*r0_2 + 99*r0_3) + r0*(96*(111 + 43*E_2)*M_4 + 4*(3361 + 1764*E_2)*M_3*r0 + (7885 + 3576*E_2)*M_2*r0_2 + 6*(533 + 86*E_2)*M*r0_3 + 492*r0_4)) + a_2*r0_3*(10*L_8*M*(-424*M_2 + 210*M*r0 + r0_2) + 72*E_2*M*r0_8*(-120*M_2 + 41*M*r0 + 18*r0_2) + 8*L_6*r0*(1172*M_4 - (1181 + 1063*E_2)*M_3*r0 - (17 + 531*E_2)*M_2*r0_2 + (123 + 265*E_2)*M*r0_3 + 24*r0_4) + 3*L_2*r0_5*(304*M_4 - 4*(-637 + 2710*E_2)*M_3*r0 - 8*(32 + 257*E_2)*M_2*r0_2 + 2*(-753 + 1402*E_2)*M*r0_3 + 495*r0_4) + L_4*r0_3*(18712*M_4 - 8*(804 + 3091*E_2)*M_3*r0 - 6*(597 + 2320*E_2)*M_2*r0_2 + 3*(-223 + 2720*E_2)*M*r0_3 + 969*r0_4)) - a_8*(6*L_4*M*(64*M_3 - 6*(-73 + 2*E_2)*M_2*r0 + 4*(179 + 43*E_2)*M*r0_2 + (185 + 8*E_2)*r0_3) - 24*E_2*M*r0_2*(1872*M_5 + 2496*M_4*r0 - 1020*M_3*r0_2 - 1892*M_2*r0_3 - 623*M*r0_4 - 99*r0_5) + L_2*r0*(576*(37 + 86*E_2)*M_5 + 8*(1454 + 11103*E_2)*M_4*r0 + 3*(2035 + 21028*E_2)*M_3*r0_2 + 2*(2761 + 8838*E_2)*M_2*r0_3 + 6*(155 + 113*E_2)*M*r0_4 + 6*r0_5)) - a_4*r0_2*(12*L_8*M*r0 - 72*E_2*M*r0_6*(108*M_3 - 54*M_2*r0 + 97*M*r0_2 + 2*r0_3) + 2*L_6*(8160*M_4 + 12*(233 + 530*E_2)*M_3*r0 + 2*(-663 + 535*E_2)*M_2*r0_2 - (91 + 517*E_2)*M*r0_3 + 12*r0_4) + 3*L_2*r0_3*(-12132*M_5 + 4*(29 + 4330*E_2)*M_4*r0 + (743 + 23052*E_2)*M_3*r0_2 + 2*(1235 + 1986*E_2)*M_2*r0_3 - 4*(-92 + 603*E_2)*M*r0_4 - 313*r0_5) - 2*L_4*r0*(19440*M_5 - 4*(1853 + 4444*E_2)*M_4*r0 - 2*(4929 + 13514*E_2)*M_3*r0_2 - 6*(215 + 1322*E_2)*M_2*r0_3 + 15*(57 + 196*E_2)*M*r0_4 + 135*r0_5)) + 4*a_7*E*L*M*r0*(L_4*(-18*M_2 + 516*M*r0 + 153*r0_2) + L_2*(12384*M_4 + 12*(1937 + 340*E_2)*M_3*r0 + (13777 + 4026*E_2)*M_2*r0_2 + (4079 + 1020*E_2)*M*r0_3 + 153*r0_4) + 3*r0*(-7488*M_5 + 4*(-1601 + 648*E_2)*M_4*r0 + 32*(118 + 213*E_2)*M_3*r0_2 + 3*(1379 + 1528*E_2)*M_2*r0_3 + 6*(281 + 140*E_2)*M*r0_4 + 261*r0_5)) - a_6*r0*(-12*L_6*M*(2*M_2 - 86*M*r0 - (47 + E_2)*r0_2) - 144*E_2*M*r0_4*(444*M_4 + 226*M_3*r0 - 104*M_2*r0_2 - 39*M*r0_3 - 16*r0_4) + 2*L_4*(8256*M_5 + 12*(1349 + 2040*E_2)*M_4*r0 + 28*(113 + 675*E_2)*M_3*r0_2 + (1359 + 5128*E_2)*M_2*r0_3 - 71*(-5 + 8*E_2)*M*r0_4 + 15*r0_5) + L_2*r0*(-44928*M_6 + 48*(-353 + 486*E_2)*M_5*r0 + 16*(1403 + 6789*E_2)*M_4*r0_2 + 2*(4949 + 50898*E_2)*M_3*r0_3 + (5921 + 28164*E_2)*M_2*r0_4 - 84*(-3 + 14*E_2)*M*r0_5 - 123*r0_6))))/(3.*r0_5*expr2_3); A93400 = (2*L*r0_4*(12*a_3*E*M + 36*a*E*M*r0_2 - 3*a_2*L*(4*M + r0) + L*r0_2*(-19*M + 10*r0)))/expr2_2; A93420 = (24*a_10*E_2*M_2*(27*M + 10*r0) - 12*a_9*E*L*M*(4*(27 + 8*E_2)*M_2 + 4*(86 + 3*E_2)*M*r0 + 131*r0_2) - 4*a*E*L*M*r0_4*(L_4*(592*M_2 + 200*M*r0 - 255*r0_2) + 3*L_2*r0_2*(-268*M_2 + 3*(89 + 46*E_2)*M*r0 - 75*r0_2) + 3*r0_4*(36*M_2 + 2*(-241 + 108*E_2)*M*r0 + 229*r0_2)) + r0_4*(72*E_2*M*(15*M - 7*r0)*r0_7 - 8*L_6*M*(50*M_2 - 51*M*r0 + 13*r0_2) + L_4*r0_2*(-1684*M_3 + 4*(159 + 445*E_2)*M_2*r0 + (679 - 904*E_2)*M*r0_2 - 288*r0_3) + 3*L_2*r0_4*(404*M_3 + 8*(-158 + 157*E_2)*M_2*r0 + 15*(65 - 42*E_2)*M*r0_2 - 222*r0_3)) + 3*a_8*(L_2*(24*(9 + 16*E_2)*M_3 + 36*(36 + 13*E_2)*M_2*r0 + 38*(14 + E_2)*M*r0_2 + 9*r0_3) + 8*E_2*M*r0*(378*M_3 + 619*M_2*r0 + 244*M*r0_2 + 27*r0_3)) - 4*a_7*E*L*M*(3*L_2*(96*M_2 + 2*(99 + E_2)*M*r0 + 145*r0_2) + 2*r0*(12*(189 + 62*E_2)*M_3 + 3*(469 + 344*E_2)*M_2*r0 + 7*(169 + 42*E_2)*M*r0_2 + 572*r0_3)) - 4*a_3*E*L*M*r0_2*(3*L_4*(816*M_2 - 104*M*r0 - 77*r0_2) + L_2*r0*(-3168*M_3 + 12*(293 + 66*E_2)*M_2*r0 + 2*(842 + 423*E_2)*M*r0_2 - 347*r0_3) + 2*r0_3*(-2934*M_3 + 3*(-85 + 504*E_2)*M_2*r0 + (-1 + 906*E_2)*M*r0_2 + 716*r0_3)) + a_6*(3*L_4*(128*M_3 + 12*(31 + 2*E_2)*M_2*r0 + 2*(271 + 8*E_2)*M*r0_2 + 9*r0_3) - 72*E_2*M*r0_2*(288*M_4 + 252*M_3*r0 - 159*M_2*r0_2 - 115*M*r0_3 - 20*r0_4) + L_2*r0*(144*(63 + 124*E_2)*M_4 + 120*(-30 + 187*E_2)*M_3*r0 + 4*(668 + 2559*E_2)*M_2*r0_2 + 3*(1145 + 12*E_2)*M*r0_3 + 73*r0_4)) - 4*a_5*E*L*M*r0*(6*L_4*(3*M + 4*r0) + L_2*(4464*M_3 + 12*(419 + 68*E_2)*M_2*r0 + 3*(379 + 146*E_2)*M*r0_2 + 421*r0_3) + 2*r0*(-5184*M_4 + 54*(-33 + 20*E_2)*M_3*r0 + 8*(203 + 300*E_2)*M_2*r0_2 + 33*(33 + 26*E_2)*M*r0_3 + 748*r0_4)) - a_2*r0_2*(12*L_6*M*(-272*M_2 + 125*M*r0 + 7*r0_2) + 72*E_2*M*r0_6*(-60*M_2 + 25*M*r0 + 12*r0_2) + L_4*r0*(10656*M_4 - 16*(513 + 371*E_2)*M_3*r0 + 4*(249 - 944*E_2)*M_2*r0_2 + 16*(-15 + 112*E_2)*M*r0_3 + 305*r0_4) + L_2*r0_3*(8280*M_4 - 24*(59 + 437*E_2)*M_3*r0 + 4*(284 - 1641*E_2)*M_2*r0_2 + (-3161 + 3972*E_2)*M*r0_3 + 1013*r0_4)) + a_4*r0*(24*L_6*M*(M + 2*r0) - 72*E_2*M*r0_4*(210*M_3 + 13*M_2*r0 + 3*M*r0_2 - 6*r0_3) + L_4*(5952*M_4 + 24*(247 + 408*E_2)*M_3*r0 + 12*(-278 + 167*E_2)*M_2*r0_2 + 5*(335 - 168*E_2)*M*r0_3 + 10*r0_4) + L_2*r0*(-20736*M_5 + 144*(27 + 46*E_2)*M_4*r0 + 4*(857 + 6264*E_2)*M_3*r0_2 + 148*(-4 + 87*E_2)*M_2*r0_3 - 5*(-535 + 432*E_2)*M*r0_4 - 301*r0_5)))/(3.*r0_2*expr2_3); A93600 = -(r0*(-168*a_8*E_2*M_2 + 12*a_7*E*L*M*(4*(7 + 2*E_2)*M + 73*r0) - 3*a_6*(L_2*(8*(7 + 12*E_2)*M_2 + 4*(73 + 6*E_2)*M*r0 + 7*r0_2) + 8*E_2*M*r0*(52*M_2 + 71*M*r0 + 8*r0_2)) + 4*a*E*L*M*r0_3*(L_2*(-156*M_2 + 290*M*r0 - 111*r0_2) + 3*r0_2*(-72*M_2 + 4*(-31 + 9*E_2)*M*r0 + 79*r0_2)) + 4*a_5*E*L*M*(36*L_2*(2*M + r0) + r0*(8*(78 + 19*E_2)*M_2 + 4*(-16 + 49*E_2)*M*r0 + 451*r0_2)) - a_4*(24*L_4*M*(4*M + 3*r0) - 24*E_2*M*r0_2*(132*M_3 + 56*M_2*r0 - 48*M*r0_2 - 9*r0_3) + L_2*r0*(96*(13 + 19*E_2)*M_3 + 280*(-7 + 5*E_2)*M_2*r0 + (1379 - 214*E_2)*M*r0_2 + 64*r0_3)) + r0_3*(24*E_2*M*r0_5*(-15*M + 7*r0) + 2*L_4*M*(228*M_2 - 236*M*r0 + 61*r0_2) + L_2*r0_2*(12*M_3 + 8*(109 - 63*E_2)*M_2*r0 + (-907 + 262*E_2)*M*r0_2 + 234*r0_3)) + 4*a_3*E*L*M*r0*(L_2*(456*M_2 + 112*M*r0 - 75*r0_2) + r0*(-1584*M_3 + 8*(34 + 9*E_2)*M_2*r0 + 8*(-12 + 35*E_2)*M*r0_2 + 445*r0_3)) + a_2*r0*(72*E_2*M*r0_5*(3*M + 2*r0) + 2*L_4*M*(-304*M_2 + 84*M*r0 + 43*r0_2) + L_2*r0*(3168*M_4 - 8*(304 + 15*E_2)*M_3*r0 - 4*(-389 + 452*E_2)*M_2*r0_2 + 2*(-449 + 274*E_2)*M*r0_3 + 191*r0_4))))/(12.*expr2_3); A94020 = (48*L_2*r0_3*(a_2*(2*M + r0) + r0*(L_2 + r0_2)))/expr2_2; A94040 = (-8*(-72*a_10*E_2*M_2*r0_p_2M_2 + 24*a_9*E*L*M*(24*M_3 + 42*M_2*r0 + 29*M*r0_2 + 7*r0_3) - 4*a*E*L*M*r0_4*(L_6*(4*M - 6*r0) + 21*L_4*(15*M - 4*r0)*r0_2 + 3*L_2*(181*M - 46*r0)*r0_4 + 36*(5*M - r0)*r0_6) + r0_4*(4*L_8*M*(2*M - r0) + 144*E_2*M*r0_9 + L_6*r0_2*(71*M_2 - 4*(13 + 2*E_2)*M*r0 + 12*r0_2) + 3*L_2*r0_6*(57*M_2 + 4*(-13 + 29*E_2)*M*r0 + 13*r0_2) + 3*L_4*r0_4*(86*M_2 + 4*(-19 + 16*E_2)*M*r0 + 19*r0_2)) + 4*a_3*E*L*M*r0_3*(6*L_6 - 3*L_4*(160*M_2 + 97*M*r0 - 31*r0_2) + 6*r0_4*(-78*M_2 - 71*M*r0 + 23*r0_2) + L_2*r0_2*(-1494*M_2 - 820*M*r0 + 293*r0_2)) + 4*a_5*E*L*M*r0_2*(L_4*(42*M + 51*r0) - L_2*(1536*M_3 + 1634*M_2*r0 + 215*M*r0_2 - 242*r0_3) - 6*r0_2*(132*M_3 + 182*M_2*r0 + 31*M*r0_2 - 35*r0_3)) + a_2*r0_3*(-12*L_8*M + 72*E_2*M*r0_7*(7*M + 8*r0) + 2*L_6*(480*M_3 + 2*(81 + 2*E_2)*M_2*r0 - 5*(19 + 2*E_2)*M*r0_2 - 36*r0_3) + 3*L_4*r0_2*(408*M_3 + 4*(89 + 81*E_2)*M_2*r0 + 2*(-87 + 56*E_2)*M*r0_2 - 27*r0_3) + 6*L_2*r0_4*(32*M_3 + 18*(7 + 18*E_2)*M_2*r0 + 21*(-3 + 8*E_2)*M*r0_2 + 2*r0_3)) + a_4*r0_2*(864*E_2*M*r0_5*(M + r0)*(M + r0) - 3*L_6*(28*M_2 + 4*(13 + E_2)*M*r0 - r0_2) + 2*L_4*(1536*M_4 + 4*(313 + 120*E_2)*M_3*r0 + (13 + 420*E_2)*M_2*r0_2 + 3*(-161 + 16*E_2)*M*r0_3 - 66*r0_4) + 3*L_2*r0_2*(164*M_4 + 4*(191 + 336*E_2)*M_3*r0 + 3*(49 + 424*E_2)*M_2*r0_2 + 6*(-47 + 52*E_2)*M*r0_3 - 30*r0_4)) + 4*a_7*E*L*M*r0*(L_2*(96*M_2 + 202*M*r0 + 87*r0_2) - 6*(192*M_4 + 212*M_3*r0 + 70*M_2*r0_2 - 39*M*r0_3 - 25*r0_4)) + a_8*(-(L_2*(288*M_4 + 48*(15 + 4*E_2)*M_3*r0 + 2*(281 + 84*E_2)*M_2*r0_2 + 18*(7 + 2*E_2)*M*r0_3 - 3*r0_4)) + 144*E_2*M*r0*(16*M_4 + 20*M_3*r0 + 10*M_2*r0_2 + 4*M*r0_3 + r0_4)) + 2*a_6*r0*(-(L_4*(96*M_3 + 2*(160 + 21*E_2)*M_2*r0 + 3*(45 + 8*E_2)*M*r0_2 - 3*r0_3)) + 72*E_2*M*r0_3*(14*M_3 + 18*M_2*r0 + 13*M*r0_2 + 4*r0_3) + L_2*(1152*M_5 + 48*(23 + 32*E_2)*M_4*r0 + 14*(29 + 144*E_2)*M_3*r0_2 + (-569 + 852*E_2)*M_2*r0_3 + 15*(-25 + 8*E_2)*M*r0_4 - 30*r0_5))))/(3.*r0_4*expr2_3); A94200 = (12*L_2*r0_6)/expr2_2; A94220 = (-4*(-24*a_8*E_2*M_2*(2*M + r0) + 4*a_7*E*L*M*(24*M_2 + 27*M*r0 + 10*r0_2) + 2*a_5*E*L*M*r0*(-384*M_3 - 220*M_2*r0 + 16*M*r0_2 + 58*r0_3 + L_2*(16*M + 19*r0)) + 2*a*E*L*M*r0_4*(4*L_4 + 6*r0_3*(-14*M + r0) + L_2*r0*(-141*M + 28*r0)) + r0_5*(48*E_2*M*r0_5 - L_4*(9*M_2 + (9 + 4*E_2)*M*r0 - 8*r0_2) + L_2*r0_2*(9*M_2 + 2*(-13 + 28*E_2)*M*r0 + 12*r0_2)) + 2*a_3*E*L*M*r0_2*(4*L_4 + 2*r0_2*(-90*M_2 - 73*M*r0 + 22*r0_2) + L_2*(-248*M_2 - 127*M*r0 + 37*r0_2)) + a_6*M*(-(L_2*(48*M_2 + 4*(21 + 4*E_2)*M*r0 + 3*(11 + 2*E_2)*r0_2)) + 24*E_2*r0*(16*M_3 + 12*M_2*r0 + 5*M*r0_2 + 2*r0_3)) + a_2*r0_2*(-4*L_6*M + 72*E_2*M*r0_5*(M + 2*r0) + L_4*(248*M_3 + 54*M_2*r0 - (25 + 8*E_2)*M*r0_2 - 11*r0_3) + L_2*r0_2*(32*M_3 + 4*(29 + 50*E_2)*M_2*r0 + (-37 + 106*E_2)*M*r0_2 + 6*r0_3)) + a_4*r0*(-4*L_4*M*(4*M + (8 + E_2)*r0) + 72*E_2*M*r0_3*(2*M_2 + 3*M*r0 + 2*r0_2) + L_2*(384*M_4 + 8*(19 + 31*E_2)*M_3*r0 + (-13 + 200*E_2)*M_2*r0_2 + 4*(-20 + 11*E_2)*M*r0_3 - 6*r0_4))))/(r0*expr2_3); A94400 = (r0_2*(72*a_6*E_2*M_2 - 72*a_5*E*L*M*(2*M + r0) + 48*a_3*E*L*M*r0*(24*M_2 + M*r0 - 4*r0_2) + 24*a*E*L*M*r0_2*(-2*L_2*M + 3*r0_2*(4*M + r0)) + r0_2*(12*L_4*M*(2*M - r0) - 144*E_2*M*r0_5 + L_2*r0_2*(117*M_2 + 2*(5 + 6*E_2)*M*r0 - 38*r0_2)) + 9*a_4*(-16*E_2*M*r0*(4*M_2 + M*r0 + r0_2) + L_2*(8*M_2 + 8*M*r0 + r0_2)) - 2*a_2*r0*(-36*E_2*M*(M - 4*r0)*r0_3 + L_2*(288*M_3 - 12*(4 + E_2)*M_2*r0 - 6*(-1 + E_2)*M*r0_2 + 19*r0_3))))/(6.*expr2_3); A95020 = (8*L*r0*(12*a_5*E*M*(2*M + r0) - a_4*L*(24*M_2 + 15*M*r0 + 2*r0_2) + 6*a*E*M*r0_3*(5*L_2 + 6*r0_2) + 2*a_3*E*M*r0*(5*L_2 + 12*r0*(3*M + 2*r0)) + L*r0_3*(-2*L_2*(9*M - 5*r0) + r0_2*(-20*M + 11*r0)) - a_2*L*r0*(2*L_2*(5*M + r0) + r0*(46*M_2 + 9*M*r0 - 9*r0_2))))/expr2_3; A95040 = (-4*(24*a_12*E_2*M_2*(36*M_2 + 44*M*r0 + 13*r0_2) - 4*a_11*E*L*M*(48*(9 + E_2)*M_3 + 8*(65 + 12*E_2)*M_2*r0 + 18*(17 + 2*E_2)*M*r0_2 + 81*r0_3) + 2*a*E*L*M*r0_5*(L_4*r0_2*(457*M_2 + 4*(467 + 138*E_2)*M*r0 - 1122*r0_2) + 8*L_6*(126*M_2 + 11*M*r0 - 39*r0_2) + 3*L_2*r0_4*(501*M_2 + 4*(-79 + 114*E_2)*M*r0 + 16*r0_2) + 18*r0_6*(59*M_2 + 6*(-15 + 8*E_2)*M*r0 + 31*r0_2)) + 2*a_3*E*L*M*r0_3*(L_6*(3144*M_2 - 424*M*r0 - 294*r0_2) + L_4*r0*(1424*M_3 + (5491 + 1032*E_2)*M_2*r0 + 2*(1373 + 562*E_2)*M*r0_2 - 1884*r0_3) + 2*L_2*r0_3*(651*M_3 + 2*(755 + 1323*E_2)*M_2*r0 + (1537 + 1836*E_2)*M*r0_2 - 885*r0_3) + 6*r0_5*(-528*M_3 + (35 + 1368*E_2)*M_2*r0 + 2*(-19 + 238*E_2)*M*r0_2 + 105*r0_3)) + r0_5*(72*E_2*M*r0_9*(-7*M + 3*r0) + 2*L_8*M*(12*M_2 - 20*M*r0 + 7*r0_2) + 2*L_6*r0_2*(301*M_3 - (353 + 540*E_2)*M_2*r0 + 2*(60 + 139*E_2)*M*r0_2 - 12*r0_3) + 3*L_2*r0_6*(-476*M_3 + (837 - 940*E_2)*M_2*r0 + (-487 + 462*E_2)*M*r0_2 + 92*r0_3) + L_4*r0_4*(-946*M_3 - 7*(-291 + 476*E_2)*M_2*r0 + (-1355 + 1688*E_2)*M*r0_2 + 276*r0_3)) - 2*a_9*E*L*M*(3*L_2*(96*M_3 + 4*(-7 + 5*E_2)*M_2*r0 + 2*(53 + 4*E_2)*M*r0_2 + 111*r0_3) - 2*r0*(48*(137 + 46*E_2)*M_4 + 4*(1949 + 864*E_2)*M_3*r0 + 2*(1201 + 636*E_2)*M_2*r0_2 + 6*(-95 + 4*E_2)*M*r0_3 - 429*r0_4)) + a_10*M*(L_2*(288*(3 + 2*E_2)*M_3 + 4*(256 + 123*E_2)*M_2*r0 + 6*(157 + 22*E_2)*M*r0_2 + 3*(101 + 10*E_2)*r0_3) - 24*E_2*r0*(548*M_4 + 784*M_3*r0 + 309*M_2*r0_2 + 53*M*r0_3 + 15*r0_4)) + 2*a_5*E*L*M*r0_2*(18*L_6*(2*M + r0) + L_4*(12384*M_3 + 4*(1623 + 262*E_2)*M_2*r0 + 2*(655 + 292*E_2)*M*r0_2 - 1221*r0_3) + L_2*r0*(-9600*M_4 + 10*(1645 + 576*E_2)*M_3*r0 + 3*(6063 + 3076*E_2)*M_2*r0_2 + 4*(1087 + 804*E_2)*M*r0_3 - 3351*r0_4) - 6*r0_3*(4260*M_4 - 180*(-1 + 16*E_2)*M_3*r0 - (1489 + 3096*E_2)*M_2*r0_2 - 12*(25 + 46*E_2)*M*r0_3 + 158*r0_4)) + a_2*r0_3*(-72*E_2*M*r0_8*(71*M_2 - 29*M*r0 - 7*r0_2) + 4*L_8*M*(-524*M_2 + 252*M*r0 + 11*r0_2) + 2*L_6*r0*(2168*M_4 - (1571 + 2052*E_2)*M_3*r0 - (783 + 1192*E_2)*M_2*r0_2 + (407 + 559*E_2)*M*r0_3 + 96*r0_4) + 3*L_2*r0_5*(-78*M_4 + (1137 - 7196*E_2)*M_3*r0 + 4*(-55 + 117*E_2)*M_2*r0_2 + 2*(-268 + 633*E_2)*M*r0_3 + 189*r0_4) + L_4*r0_3*(5458*M_4 + (913 - 12344*E_2)*M_3*r0 - (3685 + 6772*E_2)*M_2*r0_2 + (175 + 3992*E_2)*M*r0_3 + 465*r0_4)) + a_8*(3*L_4*M*(64*M_3 + 4*(-23 + 30*E_2)*M_2*r0 + 12*(18 - 7*E_2)*M*r0_2 + (205 + 4*E_2)*r0_3) + 24*E_2*M*r0_2*(960*M_5 + 936*M_4*r0 - 788*M_3*r0_2 - 688*M_2*r0_3 - 139*M*r0_4 - 51*r0_5) - L_2*r0*(96*(137 + 276*E_2)*M_5 + 16*(773 + 2838*E_2)*M_4*r0 + 648*(5 + 38*E_2)*M_3*r0_2 + 2*(-1477 + 2622*E_2)*M_2*r0_3 + 6*(-287 + 45*E_2)*M*r0_4 + 9*r0_5)) - a_4*r0_2*(6*L_8*M*(4*M + 3*r0) - 72*E_2*M*r0_6*(24*M_3 - 52*M_2*r0 + 81*M*r0_2 - 2*r0_3) + 4*L_6*(2064*M_4 + 6*(113 + 262*E_2)*M_3*r0 + 2*(27 + 166*E_2)*M_2*r0_2 - 2*(137 + 68*E_2)*M*r0_3 + 9*r0_4) + L_4*r0*(-18240*M_5 + 4*(1745 + 4676*E_2)*M_4*r0 + (10747 + 26296*E_2)*M_3*r0_2 + 2*(2165 + 3444*E_2)*M_2*r0_3 - 4*(905 + 733*E_2)*M*r0_4 - 144*r0_5) - 3*L_2*r0_3*(6452*M_5 - 8*(89 + 1804*E_2)*M_4*r0 - 6*(227 + 2024*E_2)*M_3*r0_2 + (-1305 + 992*E_2)*M_2*r0_3 + (425 + 1036*E_2)*M*r0_4 + 99*r0_5)) + 2*a_7*E*L*M*r0*(-3*L_4*(60*M_2 - 4*(27 + E_2)*M*r0 + 51*r0_2) + 2*L_2*(6624*M_4 + 48*(257 + 43*E_2)*M_3*r0 + 70*(101 + 27*E_2)*M_2*r0_2 + 2*(335 + 222*E_2)*M*r0_3 - 933*r0_4) - 6*r0*(3840*M_5 - 4*(-671 + 360*E_2)*M_4*r0 - 24*(129 + 158*E_2)*M_3*r0_2 - 3*(719 + 728*E_2)*M_2*r0_3 + 20*(1 - 12*E_2)*M*r0_4 + 286*r0_5)) - a_6*r0*(-6*L_6*M*(20*M_2 - 2*(29 + 6*E_2)*M*r0 + (49 - 3*E_2)*r0_2) - 48*E_2*M*r0_4*(654*M_4 + 156*M_3*r0 - 139*M_2*r0_2 + 31*M*r0_3 - 27*r0_4) + L_4*(8832*M_5 + 96*(185 + 258*E_2)*M_4*r0 + 8*(1093 + 2229*E_2)*M_3*r0_2 + 20*(-24 + 209*E_2)*M_2*r0_3 - (2789 + 640*E_2)*M*r0_4 + 45*r0_5) + L_2*r0*(-23040*M_6 + 48*(-203 + 340*E_2)*M_5*r0 + 2*(8033 + 35712*E_2)*M_4*r0_2 + (11021 + 45528*E_2)*M_3*r0_3 + 4*(-65 + 1656*E_2)*M_2*r0_4 - 3*(947 + 132*E_2)*M*r0_5 + 3*r0_6))))/(3.*r0_5*expr2_4); A95200 = (2*L*r0_4*(12*a_3*E*M + 36*a*E*M*r0_2 - 3*a_2*L*(4*M + r0) + L*r0_2*(-20*M + 11*r0)))/expr2_3; A95220 = (-192*a_10*E_2*M_2*(3*M + 2*r0) + 48*a_9*E*L*M*(2*(12 + E_2)*M_2 + (-7 + 3*E_2)*M*r0 - 4*r0_2) + 6*a_7*E*L*M*(L_2*(48*M_2 + 4*(-36 + E_2)*M*r0 - 55*r0_2) - 4*r0*(16*(61 + 17*E_2)*M_3 + (569 + 284*E_2)*M_2*r0 + 8*(15 + 4*E_2)*M*r0_2 + r0_3)) + 3*a_8*(L_2*(-96*(2 + E_2)*M_3 + 24*(10 + 3*E_2)*M_2*r0 + (107 - 2*E_2)*M*r0_2 + 9*r0_3) + 8*E_2*M*r0*(488*M_3 + 454*M_2*r0 + 103*M*r0_2 + 27*r0_3)) - 6*a_3*E*L*M*r0_2*(2*L_4*(828*M_2 - 140*M*r0 - 77*r0_2) + L_2*r0*(-1424*M_3 + (2651 + 552*E_2)*M_2*r0 + 2*(483 + 262*E_2)*M*r0_2 - 632*r0_3) + 4*r0_3*(-972*M_3 + (215 + 612*E_2)*M_2*r0 + 8*(9 + 28*E_2)*M*r0_2 + 83*r0_3)) - r0_4*(144*E_2*M*r0_7*(-7*M + 3*r0) + 4*L_6*M*(38*M_2 - 45*M*r0 + 13*r0_2) + 6*L_2*r0_4*(-252*M_3 + (579 - 572*E_2)*M_2*r0 + 2*(-201 + 143*E_2)*M*r0_2 + 86*r0_3) + L_4*r0_2*(590*M_3 + (135 - 1676*E_2)*M_2*r0 + 4*(-161 + 218*E_2)*M*r0_2 + 204*r0_3)) + a_2*r0_2*(72*E_2*M*r0_6*(84*M_2 - 43*M*r0 - 9*r0_2) + 24*L_6*M*(138*M_2 - 67*M*r0 - 3*r0_2) + 3*L_2*r0_3*(-2642*M_4 + (543 + 5692*E_2)*M_3*r0 + (119 + 232*E_2)*M_2*r0_2 - 22*(-27 + 53*E_2)*M*r0_3 - 248*r0_4) + L_4*r0*(-9456*M_4 + 2*(3105 + 3236*E_2)*M_3*r0 + (847 + 3268*E_2)*M_2*r0_2 - 4*(154 + 437*E_2)*M*r0_3 - 228*r0_4)) - 6*a_5*E*L*M*r0*(L_4*(-12*M + 8*r0) + L_2*(3264*M_3 + 4*(793 + 138*E_2)*M_2*r0 + 2*(397 + 128*E_2)*M*r0_2 - 229*r0_3) + 4*r0*(-1776*M_4 + 12*(-25 + 36*E_2)*M_3*r0 + 11*(81 + 76*E_2)*M_2*r0_2 + 2*(109 + 86*E_2)*M*r0_3 - 11*r0_4)) - 3*a_6*(L_4*(32*M_3 + 24*(-7 + E_2)*M_2*r0 - 8*(14 + E_2)*M*r0_2 - 9*r0_3) + 8*E_2*M*r0_2*(888*M_4 + 396*M_3*r0 - 508*M_2*r0_2 - 113*M*r0_3 - 63*r0_4) - L_2*r0*(64*(61 + 102*E_2)*M_4 + 20*(46 + 329*E_2)*M_3*r0 + 8*(10 + 241*E_2)*M_2*r0_2 - (121 + 26*E_2)*M*r0_3 - 5*r0_4)) + 3*a_4*r0*(-8*L_6*M*(M - r0) - 24*E_2*M*r0_4*(180*M_3 - 46*M_2*r0 + 59*M*r0_2 - 9*r0_3) + L_4*(2176*M_4 + 4*(509 + 828*E_2)*M_3*r0 + 4*(-21 + 122*E_2)*M_2*r0_2 - 4*(59 + 71*E_2)*M*r0_3 - 29*r0_4) + L_2*r0*(-7104*M_5 + 16*(48 + 235*E_2)*M_4*r0 + (2593 + 9920*E_2)*M_3*r0_2 + (747 + 1952*E_2)*M_2*r0_3 - 2*(100 + 309*E_2)*M*r0_4 - 90*r0_5)) - 2*a*E*L*M*r0_4*(2*L_4*(752*M_2 + 76*M*r0 - 243*r0_2) + 36*r0_4*(15*M_2 + 2*(-32 + 15*E_2)*M*r0 + 29*r0_2) + 3*L_2*r0_2*(133*M_2 - 102*r0_2 + 88*M*(r0 + 3*E_2*r0))))/(3.*r0_2*expr2_4); A95400 = (r0*(-72*a_8*E_2*M_2 + 36*a_7*E*L*M*(4*M - 15*r0) - 4*a_5*E*L*M*r0*(18*L_2 + 12*(107 + 22*E_2)*M_2 + 6*(-7 + 22*E_2)*M*r0 + 233*r0_2) + 3*a_6*(3*L_2*(-8*M_2 + 4*(15 + E_2)*M*r0 + r0_2) + 8*E_2*M*r0*(107*M_2 + 46*M*r0 + 12*r0_2)) - 12*a*E*L*M*r0_3*(L_2*(8*M_2 + 70*M*r0 - 41*r0_2) + r0_2*(-87*M_2 + 4*(-31 + 9*E_2)*M*r0 + 86*r0_2)) + a_4*r0*(36*L_4*M - 72*E_2*M*r0*(68*M_3 - 6*M_2*r0 - 2*M*r0_2 - 5*r0_3) + L_2*(24*(107 + 132*E_2)*M_3 + 24*(-53 + 25*E_2)*M_2*r0 + 2*(388 - 171*E_2)*M*r0_2 + 23*r0_3)) - 3*r0_3*(24*E_2*M*r0_5*(-7*M + 3*r0) + 2*L_4*M*(64*M_2 - 70*M*r0 + 19*r0_2) + L_2*r0_2*(-28*M_3 + 3*(117 - 68*E_2)*M_2*r0 + 22*(-16 + 5*E_2)*M*r0_2 + 90*r0_3)) - 4*a_3*E*L*M*r0*(3*L_2*(264*M_2 - 32*M*r0 - 35*r0_2) + r0*(-2448*M_3 + 3*(287 + 72*E_2)*M_2*r0 + 2*(61 + 120*E_2)*M*r0_2 + 266*r0_3)) - a_2*r0*(72*E_2*M*r0_4*(-13*M_2 + 14*M*r0 + 2*r0_2) + 6*L_4*M*(-176*M_2 + 76*M*r0 + 13*r0_2) + L_2*r0*(4896*M_4 - 12*(251 + 112*E_2)*M_3*r0 + (991 - 1380*E_2)*M_2*r0_2 + 4*(-181 + 177*E_2)*M*r0_3 + 238*r0_4))))/(12.*expr2_4); A96000 = (4*L_2*r0_6)/expr2_3; A96020 = (2*(72*a_8*E_2*M_2*(2*M + r0) - 96*a_7*E*L*M*(3*M_2 + 5*M*r0 + 2*r0_2) + 8*a*E*L*M*r0_3*(L_4*(4*M - 6*r0) + 8*L_2*(10*M - 3*r0)*r0_2 + 3*r0_4*(7*M + 3*r0)) - 24*a_5*E*L*M*r0*(-64*M_3 - 34*M_2*r0 + 13*M*r0_2 + 19*r0_3 + L_2*(7*M + 9*r0)) + r0_3*(-96*E_2*M*r0_7 + 8*L_6*M*(-2*M + r0) + L_4*r0_2*(3*M_2 + 4*(-9 + 4*E_2)*M*r0 + 12*r0_2) + L_2*r0_4*(43*M_2 - 20*(4 + 5*E_2)*M*r0 + 24*r0_2)) - 8*a_3*E*L*M*r0_2*(6*L_4 + 6*r0_2*(-5*M_2 - 13*M*r0 + 4*r0_2) + L_2*(-136*M_2 - 77*M*r0 + 45*r0_2)) + 3*a_6*(L_2*(48*M_3 + 4*(34 + 7*E_2)*M_2*r0 + 2*(29 + 6*E_2)*M*r0_2 + r0_3) - 8*E_2*M*r0*(32*M_3 + 12*M_2*r0 + 3*M*r0_2 + 4*r0_3)) + a_2*r0_2*(24*L_6*M + 72*E_2*M*(M - 4*r0)*r0_5 - 2*L_4*(272*M_3 + 8*(18 + E_2)*M_2*r0 - (81 + 20*E_2)*M*r0_2 - 36*r0_3) + L_2*r0_2*(158*M_3 - (657 + 364*E_2)*M_2*r0 + 2*(49 - 82*E_2)*M*r0_2 + 84*r0_3)) + a_4*r0*(72*E_2*M*r0_3*(2*M_2 - M*r0 - 4*r0_2) + 3*L_4*(28*M_2 + 4*(15 + 2*E_2)*M*r0 + r0_2) - L_2*(768*M_4 + 16*(33 + 34*E_2)*M_3*r0 + 8*(-4 + 41*E_2)*M_2*r0_2 + 2*(-209 + 14*E_2)*M*r0_3 - 63*r0_4))))/(3.*r0*expr2_4); A96200 = (r0_2*(72*a_6*E_2*M_2 - 24*a_5*E*L*M*(6*M + 7*r0) - 24*a_3*E*L*M*r0*(2*L_2 - 32*M_2 - M*r0 + 11*r0_2) + 8*a*E*L*M*r0_2*(2*L_2*(M - 3*r0) + 3*r0_2*(M + 6*r0)) + 3*a_4*(-16*E_2*M*r0*(8*M_2 - M*r0 + 2*r0_2) + L_2*(24*M_2 + 8*(7 + E_2)*M*r0 + 5*r0_2)) + r0_2*(-96*E_2*M*r0_5 + 4*L_4*M*(-2*M + r0) + L_2*r0_2*(139*M_2 + 4*(-32 + 5*E_2)*M*r0 + 24*r0_2)) + 2*a_2*r0*(12*L_4*M + 12*E_2*M*(11*M - 8*r0)*r0_3 + L_2*(-192*M_3 - 4*(9 + E_2)*M_2*r0 + (29 + 22*E_2)*M*r0_2 + 6*r0_3))))/(6.*expr2_4); A97000 = (2*L*r0_4*(4*a_3*E*M + 12*a*E*M*r0_2 - a_2*L*(4*M + r0) + L*r0_2*(-7*M + 4*r0)))/expr2_4; A97020 = (-24*a_10*E_2*M_2*(25*M + 14*r0) + 12*a_9*E*L*M*(4*(25 + 4*E_2)*M_2 + 12*(8 + E_2)*M*r0 + 33*r0_2) - 4*a*E*L*M*r0_4*(L_4*(300*M_2 - 8*M*r0 - 81*r0_2) + 3*r0_4*(45*M_2 + 8*(-11 + 6*E_2)*M*r0 + 38*r0_2) + L_2*r0_2*(538*M_2 + 2*(-205 + 63*E_2)*M*r0 + 69*r0_2)) + r0_4*(24*E_2*M*(13*M - 5*r0)*r0_7 + 4*L_6*M*(6*M_2 - M*r0 - r0_2) + L_2*r0_4*(611*M_3 + 2*(-517 + 512*E_2)*M_2*r0 + 2*(307 - 253*E_2)*M*r0_2 - 120*r0_3) + L_4*r0_2*(335*M_3 + 24*(-27 + 22*E_2)*M_2*r0 + 2*(221 - 142*E_2)*M*r0_2 - 96*r0_3)) - 4*a_3*E*L*M*r0_2*(L_4*(840*M_2 - 172*M*r0 - 81*r0_2) + 2*L_2*r0*(-176*M_3 + 2*(395 + 72*E_2)*M_2*r0 + (131 + 121*E_2)*M*r0_2 - 246*r0_3) + 2*r0_3*(-1029*M_3 + 2*(299 + 360*E_2)*M_2*r0 + 2*(68 + 73*E_2)*M*r0_2 - 75*r0_3)) - 3*a_8*(L_2*(8*(25 + 24*E_2)*M_3 + 4*(68 + 27*E_2)*M_2*r0 + 2*(53 + 7*E_2)*M*r0_2 - 3*r0_3) - 8*E_2*M*r0*(198*M_3 + 97*M_2*r0 - 12*M*r0_2 + 9*r0_3)) + 8*a_7*E*L*M*(3*L_2*(24*M_2 + (9 + E_2)*M*r0 + 15*r0_2) + r0*(-4*(297 + 74*E_2)*M_3 - 2*(331 + 112*E_2)*M_2*r0 + (149 + 34*E_2)*M*r0_2 + 183*r0_3)) - 4*a_5*E*L*M*r0*(-18*L_4*M + L_2*(1776*M_3 + 2*(751 + 140*E_2)*M_2*r0 + 2*(201 + 55*E_2)*M*r0_2 - 363*r0_3) + r0*(-3648*M_4 + 2*(-19 + 504*E_2)*M_3*r0 + (2517 + 1744*E_2)*M_2*r0_2 + 2*(53 + 58*E_2)*M*r0_3 - 531*r0_4)) + a_2*r0_2*(4*L_6*M*(280*M_2 - 141*M*r0 - 7*r0_2) + 24*E_2*M*r0_6*(102*M_2 - 55*M*r0 - 6*r0_2) + L_2*r0_3*(-2774*M_4 + (1301 + 8284*E_2)*M_3*r0 + (209 - 2152*E_2)*M_2*r0_2 + 8*(11 - 122*E_2)*M*r0_3 - 96*r0_4) + L_4*r0*(-2720*M_4 + 24*(67 + 97*E_2)*M_3*r0 + 5*(111 + 188*E_2)*M_2*r0_2 - 10*(45 + 58*E_2)*M*r0_3 + 12*r0_4)) + a_4*r0*(-24*L_6*M_2 + 24*E_2*M*r0_4*(-162*M_3 + 107*M_2*r0 - 105*M*r0_2 + 12*r0_3) + L_4*(2368*M_4 + 4*(527 + 840*E_2)*M_3*r0 + 4*(230 + 79*E_2)*M_2*r0_2 - (1009 + 296*E_2)*M*r0_3 - 72*r0_4) + L_2*r0*(-7296*M_5 + 8*(41 + 668*E_2)*M_4*r0 + 12*(333 + 974*E_2)*M_3*r0_2 + (1451 - 660*E_2)*M_2*r0_3 - (1171 + 476*E_2)*M*r0_4 - 30*r0_5)) - a_6*(24*E_2*M*r0_2*(304*M_4 + 20*M_3*r0 - 183*M_2*r0_2 + 35*M*r0_3 - 22*r0_4) + L_2*r0*(-48*(99 + 148*E_2)*M_4 - 4*(742 + 1423*E_2)*M_3*r0 + 26*(25 - 16*E_2)*M_2*r0_2 + 3*(459 + 16*E_2)*M*r0_3 + 45*r0_4) + 3*L_4*(64*M_3 + 106*M*r0_2 - 3*r0_3 + 12*M_2*(r0 + 2*E_2*r0))))/(3.*r0_2*expr2_5); A97200 = -(r0*(264*a_8*E_2*M_2 - 12*a_7*E*L*M*((44 + 8*E_2)*M + 13*r0) + 3*a_6*(L_2*((88 + 96*E_2)*M_2 + 4*(13 + 2*E_2)*M*r0 + 3*r0_2) - 8*E_2*M*r0*(90*M_2 - 9*M*r0 + 8*r0_2)) + 4*a*E*L*M*r0_3*(L_2*(196*M_2 - 26*M*r0 - 45*r0_2) + 3*r0_2*(-47*M_2 + 2*(-17 + 6*E_2)*M*r0 + 34*r0_2)) + 4*a_3*E*L*M*r0*(L_2*(600*M_2 - 248*M*r0 - 57*r0_2) + r0*(-1680*M_3 + (881 + 216*E_2)*M_2*r0 + 10*(23 + 4*E_2)*M*r0_2 - 72*r0_3)) + a_4*(24*L_4*M*(4*M + r0) + 24*E_2*M*r0_2*(140*M_3 - 76*M_2*r0 + 36*M*r0_2 - 11*r0_3) + L_2*r0*(-240*(9 + 10*E_2)*M_3 + 8*(-25 + 77*E_2)*M_2*r0 + (281 + 226*E_2)*M*r0_2 + 30*r0_3)) + r0_3*(24*E_2*M*r0_5*(-13*M + 5*r0) + 2*L_4*M*(20*M_2 - 32*M*r0 + 11*r0_2) + L_2*r0_2*(-131*M_3 + (506 - 304*E_2)*M_2*r0 + 10*(-47 + 17*E_2)*M*r0_2 + 120*r0_3)) + a_2*r0*(2*L_4*M*(-400*M_2 + 228*M*r0 + r0_2) + 24*E_2*M*r0_4*(-46*M_2 + 41*M*r0 + 2*r0_2) + L_2*r0*(3360*M_4 - 4*(425 + 422*E_2)*M_3*r0 + (-77 + 8*E_2)*M_2*r0_2 + 12*(-7 + 31*E_2)*M*r0_3 + 96*r0_4)) + 4*a_5*E*L*M*(-12*L_2*(6*M + r0) + r0*(40*(27 + 5*E_2)*M_2 - 123*r0_2 - 4*M*(r0 + 5*E_2*r0)))))/(12.*expr2_5); A98000 = (r0_2*(12*a_6*E_2*M_2 - 12*a_5*E*L*M*(2*M + 3*r0) + 4*a*E*L*M*(2*M - 3*r0)*r0_2*(L_2 - 3*r0_2) - 12*a_3*E*L*M*r0*(L_2 - 8*M_2 + 4*r0_2) + 3*a_4*(-4*E_2*M*r0*(4*M_2 - 2*M*r0 + r0_2) + L_2*(4*M_2 + 2*(6 + E_2)*M*r0 + r0_2)) + r0_2*(-12*E_2*M*r0_5 + 2*L_4*M*(-2*M + r0) + L_2*r0_2*(29*M_2 + 4*(-10 + E_2)*M*r0 + 12*r0_2)) + 2*a_2*r0*(3*L_4*M + 6*E_2*M*(5*M - 2*r0)*r0_3 + L_2*(-24*M_3 - 2*(6 + E_2)*M_2*r0 + (7 + 5*E_2)*M*r0_2 + 3*r0_3))))/(3.*expr2_5); A99000 = -(r0*(60*a_8*E_2*M_2 - 12*a_7*E*L*M*(2*(5 + E_2)*M + 7*r0) + 4*a*E*L*M_2*r0_3*(L_2*(48*M - 26*r0) + 3*r0_2*(-6*M + 5*r0)) + 3*a_6*(L_2*(4*(5 + 6*E_2)*M_2 + (28 + 3*E_2)*M*r0 + r0_2) - 4*E_2*M*r0*(27*M_2 - 12*M*r0 + 2*r0_2)) - M*r0_3*(12*E_2*(3*M - r0)*r0_5 + L_4*(24*M_2 - 22*M*r0 + 5*r0_2) + 2*L_2*r0_2*(9*M_2 + (-5 + 12*E_2)*M*r0 + (1 - 7*E_2)*r0_2)) + 2*a_3*E*L*M*r0*(L_2*(168*M_2 - 110*M*r0 - 9*r0_2) + 2*r0*(-216*M_3 + 4*(37 + 9*E_2)*M_2*r0 + 2*(23 - 5*E_2)*M*r0_2 - 39*r0_3)) + a_4*(3*L_4*M*(8*M + 3*r0) + 12*E_2*M*r0_2*(36*M_3 - 34*M_2*r0 + 18*M*r0_2 - 3*r0_3) + L_2*r0*(-12*(27 + 28*E_2)*M_3 + 2*(-74 + 103*E_2)*M_2*r0 + (127 + 26*E_2)*M*r0_2 + 9*r0_3)) + a_2*M*r0*(36*E_2*M*r0_4*(-5*M + 4*r0) - 2*L_4*(56*M_2 - 39*M*r0 + 4*r0_2) + L_2*r0*(432*M_3 - 8*(23 + 39*E_2)*M_2*r0 + 2*(-45 + 61*E_2)*M*r0_2 + (41 + 31*E_2)*r0_3)) + 2*a_5*E*L*M*(-9*L_2*(4*M + r0) + 2*r0*(2*(81 + 14*E_2)*M_2 - 48*r0_2 + M*(r0 - 16*E_2*r0)))))/(6.*expr2_6); } /* rho */ alpha20 = r0*r0 / (a*a + r0*(r0-2.0*M)); alpha02 = r0*r0; beta = 4.0*(L*L + r0*r0 + a*a*(r0+2.0*M)/r0); } ================================================ FILE: external/Licenses/BlazeCopyright.txt ================================================ Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved https://bitbucket.org/blaze-lib/blaze/src/ ================================================ FILE: external/Licenses/BlazeLicense.txt ================================================ LICENSE OF THE BLAZE LIBRARY 11 November 2013 The Blaze library and headers are licensed under the New (Revised) BSD license. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the {organization} nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: external/Licenses/BoostCopyright.txt ================================================ https://www.boost.org/ ================================================ FILE: external/Licenses/BoostLicense.txt ================================================ Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: external/Licenses/BrigandCopyright.txt ================================================ Copyright Edouard Alligand and Joel Falcou 2015-2017 https://github.com/edouarda/brigand ================================================ FILE: external/Licenses/BrigandLicense.txt ================================================ Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: external/Licenses/Catch2Copyright.txt ================================================ Copyright Catch2 Authors https://github.com/catchorg/Catch2 ================================================ FILE: external/Licenses/Catch2License.txt ================================================ Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: external/Licenses/CharmCopyright.txt ================================================ Copyright (C) 1990-present University of Illinois, Charmworks, Inc. https://github.com/charmplusplus/charm/ ================================================ FILE: external/Licenses/CharmLicense.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --- LLVM Exceptions to the Apache 2.0 License ---- As an exception, if, as a result of your compiling your source code, portions of this Software are embedded into an Object form of such source code, you may redistribute such embedded portions in such Object form without complying with the conditions of Sections 4(a), 4(b) and 4(d) of the License. In addition, if you combine or link compiled forms of this Software with software that is licensed under the GPLv2 ("Combined Software") and if a court of competent jurisdiction determines that the patent provision (Section 3), the indemnity provision (Section 9) or other Section of the License conflicts with the conditions of the GPLv2, you may retroactively and prospectively choose to deem waived or otherwise exclude such Section(s) of the License, but only in their entirety and only with respect to the Combined Software. ================================================ FILE: external/Licenses/GslCopyright.txt ================================================ Copyright (C) 2007 Free Software Foundation, Inc. https://www.gnu.org/software/gsl/ ================================================ FILE: external/Licenses/GslLicense.txt ================================================ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ================================================ FILE: external/Licenses/Hdf5Copyright.txt ================================================ HDF5 (Hierarchical Data Format 5) Software Library and Utilities Copyright 2006 by The HDF Group. NCSA HDF5 (Hierarchical Data Format 5) Software Library and Utilities Copyright 1998-2006 by The Board of Trustees of the University of Illinois. https://github.com/HDFGroup/hdf5 ================================================ FILE: external/Licenses/Hdf5License.txt ================================================ Copyright Notice and License Terms for HDF5 (Hierarchical Data Format 5) Software Library and Utilities ----------------------------------------------------------------------------- HDF5 (Hierarchical Data Format 5) Software Library and Utilities Copyright 2006 by The HDF Group. NCSA HDF5 (Hierarchical Data Format 5) Software Library and Utilities Copyright 1998-2006 by The Board of Trustees of the University of Illinois. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted for any purpose (including commercial purposes) provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or materials provided with the distribution. 3. Neither the name of The HDF Group, the name of the University, nor the name of any Contributor may be used to endorse or promote products derived from this software without specific prior written permission from The HDF Group, the University, or the Contributor, respectively. DISCLAIMER: THIS SOFTWARE IS PROVIDED BY THE HDF GROUP AND THE CONTRIBUTORS "AS IS" WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. IN NO EVENT SHALL THE HDF GROUP OR THE CONTRIBUTORS BE LIABLE FOR ANY DAMAGES SUFFERED BY THE USERS ARISING OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You are under no obligation whatsoever to provide any bug fixes, patches, or upgrades to the features, functionality or performance of the source code ("Enhancements") to anyone; however, if you choose to make your Enhancements available either publicly, or directly to The HDF Group, without imposing a separate written license agreement for such Enhancements, then you hereby grant the following license: a non-exclusive, royalty-free perpetual license to install, use, modify, prepare derivative works, incorporate into other computer software, distribute, and sublicense such enhancements or derivative works thereof, in binary and source code form. ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- Limited portions of HDF5 were developed by Lawrence Berkeley National Laboratory (LBNL). LBNL's Copyright Notice and Licensing Terms can be found here: COPYING_LBNL_HDF5 file in this directory or at https://raw.githubusercontent.com/hdfgroup/hdf5/develop/COPYING_LBNL_HDF5. ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- Contributors: National Center for Supercomputing Applications (NCSA) at the University of Illinois, Fortner Software, Unidata Program Center (netCDF), The Independent JPEG Group (JPEG), Jean-loup Gailly and Mark Adler (gzip), and Digital Equipment Corporation (DEC). ----------------------------------------------------------------------------- Portions of HDF5 were developed with support from the Lawrence Berkeley National Laboratory (LBNL) and the United States Department of Energy under Prime Contract No. DE-AC02-05CH11231. ----------------------------------------------------------------------------- Portions of HDF5 were developed with support from Lawrence Livermore National Laboratory and the United States Department of Energy under Prime Contract No. DE-AC52-07NA27344. ----------------------------------------------------------------------------- Portions of HDF5 were developed with support from the University of California, Lawrence Livermore National Laboratory (UC LLNL). The following statement applies to those portions of the product and must be retained in any redistribution of source code, binaries, documentation, and/or accompanying materials: This work was partially produced at the University of California, Lawrence Livermore National Laboratory (UC LLNL) under contract no. W-7405-ENG-48 (Contract 48) between the U.S. Department of Energy (DOE) and The Regents of the University of California (University) for the operation of UC LLNL. DISCLAIMER: THIS WORK WAS PREPARED AS AN ACCOUNT OF WORK SPONSORED BY AN AGENCY OF THE UNITED STATES GOVERNMENT. NEITHER THE UNITED STATES GOVERNMENT NOR THE UNIVERSITY OF CALIFORNIA NOR ANY OF THEIR EMPLOYEES, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY- OWNED RIGHTS. REFERENCE HEREIN TO ANY SPECIFIC COMMERCIAL PRODUCTS, PROCESS, OR SERVICE BY TRADE NAME, TRADEMARK, MANUFACTURER, OR OTHERWISE, DOES NOT NECESSARILY CONSTITUTE OR IMPLY ITS ENDORSEMENT, RECOMMENDATION, OR FAVORING BY THE UNITED STATES GOVERNMENT OR THE UNIVERSITY OF CALIFORNIA. THE VIEWS AND OPINIONS OF AUTHORS EXPRESSED HEREIN DO NOT NECESSARILY STATE OR REFLECT THOSE OF THE UNITED STATES GOVERNMENT OR THE UNIVERSITY OF CALIFORNIA, AND SHALL NOT BE USED FOR ADVERTISING OR PRODUCT ENDORSEMENT PURPOSES. ----------------------------------------------------------------------------- ================================================ FILE: external/Licenses/JemallocCopyright.txt ================================================ Copyright (C) 2002-present Jason Evans . All rights reserved. Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved. Copyright (C) 2009-present Facebook, Inc. All rights reserved. ================================================ FILE: external/Licenses/JemallocLicense.txt ================================================ Unless otherwise specified, files in the jemalloc source distribution are subject to the following license: -------------------------------------------------------------------------------- Copyright (C) 2002-present Jason Evans . All rights reserved. Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved. Copyright (C) 2009-present Facebook, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice(s), this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice(s), this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- ================================================ FILE: external/Licenses/LibbacktraceCopyright.txt ================================================ Copyright (C) 2012-2024 Free Software Foundation, Inc. ================================================ FILE: external/Licenses/LibbacktraceLicense.txt ================================================ Copyright (C) 2012-2024 Free Software Foundation, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. (3) The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: external/Licenses/LibsharpCopyright.txt ================================================ opyright (C) 2006-2013 Max-Planck-Society https://github.com/Libsharp/libsharp ================================================ FILE: external/Licenses/LibsharpLicense.txt ================================================ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ================================================ FILE: external/Licenses/LibxsmmCopyright.txt ================================================ Copyright (c) 2009-2023, Intel Corporation Copyright (c) 2017-2022, Friedrich Schiller University Jena Copyright (c) 2012-2021, Technische Universitaet Muenchen Copyright (c) 2016-2020, Google Inc. https://github.com/libxsmm/libxsmm ================================================ FILE: external/Licenses/LibxsmmLicense.txt ================================================ BSD 3-Clause License Copyright (c) 2009-2023, Intel Corporation Copyright (c) 2017-2022, Friedrich Schiller University Jena Copyright (c) 2012-2021, Technische Universitaet Muenchen Copyright (c) 2016-2020, Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: external/Licenses/OpenBlasCopyright.txt ================================================ Copyright (c) 2011-2024, The OpenBLAS Project Copyright 2009, 2010 The University of Texas at Austin. https://github.com/OpenMathLib/OpenBLAS ================================================ FILE: external/Licenses/OpenBlasLicense.txt ================================================ Copyright (c) 2011-2014, The OpenBLAS Project All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the OpenBLAS project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: external/Licenses/Pybind11Copyright.txt ================================================ Copyright (c) 2016 Wenzel Jakob , All rights reserved. ================================================ FILE: external/Licenses/Pybind11License.txt ================================================ Copyright (c) 2016 Wenzel Jakob , All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Please also refer to the file .github/CONTRIBUTING.md, which clarifies licensing of external contributions to this project including patches, pull requests, etc. ================================================ FILE: external/Licenses/SpectreGpl3License.txt ================================================ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ================================================ FILE: external/Licenses/XsimdCopyright.txt ================================================ Copyright (c) 2016, Johan Mabille, Sylvain Corlay, Wolf Vollprecht and Martin Renou Copyright (c) 2016, QuantStack Copyright (c) 2018, Serge Guelton https://github.com/xtensor-stack/xsimd ================================================ FILE: external/Licenses/XsimdLicense.txt ================================================ Copyright (c) 2016, Johan Mabille, Sylvain Corlay, Wolf Vollprecht and Martin Renou Copyright (c) 2016, QuantStack Copyright (c) 2018, Serge Guelton All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: external/Licenses/YamlCppCopyright.txt ================================================ Copyright (c) 2008-2015 Jesse Beder. Copyright 2005-2010, 2013, 2015, 2017-2020 Google Inc. Copyright 2007 Neal Norwitz https://github.com/jbeder/yaml-cpp ================================================ FILE: external/Licenses/YamlCppLicense.txt ================================================ Copyright (c) 2008-2015 Jesse Beder. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: external/SPHEREPACK/CMakeLists.txt ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. set(LIBRARY SPHEREPACK) set(LIBRARY_SOURCES alf.f divgs.f gaqd.f gradgs.f hrfft.f shags.f shsgs.f slapgs.f sphcom.f vhags.f vhsgs.f vrtgs.f vtsgs.f ) # Starting in gcc8, gfortran warns about instances of Fortran77 coding style in # certain SPHEREPACK files. The warning is: # Warning: Array reference at ... out of bounds ... in loop beginning ... # # Attempts to silence the warning by use of individual flags were unsuccessful, # so instead we silence all warnings for the problematic files. set(FILES_WITH_ARRAY_REFERENCES alf.f sphcom.f vhags.f vhsgs.f vtsgs.f ) set_source_files_properties(${FILES_WITH_ARRAY_REFERENCES} PROPERTIES COMPILE_FLAGS -w) # Starting in gcc9, gfortran warns about deleted language features in certain # SPHEREPACK files. The warnings are, # * Warning: Fortran 2018 deleted feature: Arithmetic IF statement at ... # * Warning: Fortran 2018 deleted feature: Shared DO termination label at ... # # We silence these warnings too. # An alternative solution would be to specify the compiler flag `-std=legacy`. set(FILES_WITH_DELETED_FEATURES gradgs.f hrfft.f shags.f shsgs.f ) set_source_files_properties(${FILES_WITH_DELETED_FEATURES} PROPERTIES COMPILE_FLAGS -w) add_library(${LIBRARY} ${LIBRARY_SOURCES}) if(SPECTRE_Fortran_STATIC_LIBS) if (NOT $gfortran) find_library(gfortran NAMES libgfortran.a) endif() if (NOT $quadmath) find_library(quadmath NAMES libquadmath.a) endif() target_link_libraries( ${LIBRARY} PRIVATE ${gfortran} ${quadmath} ) endif() target_link_libraries( ${LIBRARY} PRIVATE SpectreFlags ) ================================================ FILE: external/SPHEREPACK/LICENSE.txt ================================================ Copyright © 2004 the University Corporation for Atmospheric Research ("UCAR"). All rights reserved. Developed by NCAR's Computational and Information Systems Laboratory, UCAR, www2.cisl.ucar.edu. Redistribution and use of the Software in source and binary forms, with or without modification, is permitted provided that the following conditions are met: Neither the names of NCAR's Computational and Information Systems Laboratory, the University Corporation for Atmospheric Research, nor the names of its sponsors or contributors may be used to endorse or promote products derived from this Software without specific prior written permission. Redistributions of source code must retain the above copyright notices, this list of conditions, and the disclaimer below. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the disclaimer below in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. SPHEREPACK is a product of the Computational & Information Systems Laboratory at the National Center for Atmospheric Research (NCAR) ================================================ FILE: external/SPHEREPACK/README.txt ================================================ This is a modified version of SPHEREPACK 3.2. The SPHEREPACK 3.2 license can be found in LICENSE.txt. Only 13 FORTRAN files, with the functionality we need for SpECTRE, have been retained here. The unmodified SPHEREPACK contains additional files with more functionality than we need, and we do not include these files, nor do we include the SPHEREPACK makefiles or tests. A summary of the modifications: 1) We have added our own Spherepack.hpp for #including SPHEREPACK subroutines into C/C++. 2) All computations were changed to double precision. 3) divgs, gradgs, shags, shsgs, slapgs, vhags, vhsgs, vrtgs, vtsgs now have the ability to loop over 'offsets' and do multiple computations at once with a single call to a SPHEREPACK function. This is useful if you have a (r,theta,phi) grid, and you need to do spherical transforms on (theta,phi) for multiple values of r. 4) Bugfix in vtsgs.f, where mmax was computed incorrectly if nlon is even. 5) shsgs and shags no longer have limitations on the size of the passed-in coefficient arrays 'a' and 'b'. They also take additional arguments, 'mdabmax, 'ndabmax'. Coefficients that do not fit into the provided storage are ignored / treated as zero / not computed. The same holds for coefficients with indices above {m,n}dabmax. This allows for more efficient implementation of definite integrals, where now one can request computation of the l=0 coefficient only. This also helps in changing resolution, since restriction or prolongation of the coefficient array is no longer (explicitly) needed. 6) Given that we so far do not need to call SPHEREPACK with symmetries (e.g. equatorial symmetry, octant symmetry, etc) enforced, the above changes were not tested with SPHEREPACK's symmetry options turned on. In order to avoid surprises, SPHEREPACK's symmetry options are disabled. If you need symmetries, please test them. ================================================ FILE: external/SPHEREPACK/alf.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c c file alf.f contains subroutines alfk,lfim,lfim1,lfin,lfin1,lfpt c for computing normalized associated legendre polynomials c c subroutine alfk (n,m,cp) c c dimension of real cp(n/2 + 1) c arguments c c purpose routine alfk computes single precision fourier c coefficients in the trigonometric series c representation of the normalized associated c legendre function pbar(n,m,theta) for use by c routines lfp and lfpt in calculating single c precision pbar(n,m,theta). c c first define the normalized associated c legendre functions c c pbar(m,n,theta) = sqrt((2*n+1)*factorial(n-m) c /(2*factorial(n+m)))*sin(theta)**m/(2**n* c factorial(n)) times the (n+m)th derivative of c (x**2-1)**n with respect to x=cos(theta) c c where theta is colatitude. c c then subroutine alfk computes the coefficients c cp(k) in the following trigonometric c expansion of pbar(m,n,theta). c c 1) for n even and m even, pbar(m,n,theta) = c .5*cp(1) plus the sum from k=1 to k=n/2 c of cp(k+1)*cos(2*k*th) c c 2) for n even and m odd, pbar(m,n,theta) = c the sum from k=1 to k=n/2 of c cp(k)*sin(2*k*th) c c 3) for n odd and m even, pbar(m,n,theta) = c the sum from k=1 to k=(n+1)/2 of c cp(k)*cos((2*k-1)*th) c c 4) for n odd and m odd, pbar(m,n,theta) = c the sum from k=1 to k=(n+1)/2 of c cp(k)*sin((2*k-1)*th) c c c usage call alfk(n,m,cp) c c arguments c c on input n c nonnegative integer specifying the degree of c pbar(n,m,theta) c c m c is the order of pbar(n,m,theta). m can be c any integer however cp is computed such that c pbar(n,m,theta) = 0 if abs(m) is greater c than n and pbar(n,m,theta) = (-1)**m* c pbar(n,-m,theta) for negative m. c c on output cp c single precision array of length (n/2)+1 c which contains the fourier coefficients in c the trigonometric series representation of c pbar(n,m,theta) c c c special conditions none c c precision single c c algorithm the highest order coefficient is determined in c closed form and the remainig coefficients are c determined as the solution of a backward c recurrence relation. c c accuracy comparison between routines alfk and double c precision dalfk on the cray1 indicates c greater accuracy for smaller values c of input parameter n. agreement to 14 c places was obtained for n=10 and to 13 c places for n=100. c subroutine alfk (n,m,cp) implicit double precision (a-h,o-z) dimension cp(n/2+1) parameter (sc10=1024.d0) parameter (sc20=sc10*sc10) parameter (sc40=sc20*sc20) c cp(1) = 0.d0 ma = iabs(m) if(ma .gt. n) return if(n-1) 2,3,5 2 cp(1) = dsqrt(2.d0) return 3 if(ma .ne. 0) go to 4 cp(1) = dsqrt(1.5d0) return 4 cp(1) = dsqrt(.75d0) if(m .eq. -1) cp(1) = -cp(1) return 5 if(mod(n+ma,2) .ne. 0) go to 10 nmms2 = (n-ma)/2 fnum = n+ma+1 fnmh = n-ma+1 pm1 = 1.d0 go to 15 10 nmms2 = (n-ma-1)/2 fnum = n+ma+2 fnmh = n-ma+2 pm1 = -1.d0 15 t1 = 1.d0/sc20 nex = 20 fden = 2.d0 if(nmms2 .lt. 1) go to 20 do 18 i=1,nmms2 t1 = fnum*t1/fden if(t1 .gt. sc20) then t1 = t1/sc40 nex = nex+40 end if fnum = fnum+2.d0 fden = fden+2.d0 18 continue 20 t1 = t1/2.d0**(n-1-nex) if(mod(ma/2,2) .ne. 0) t1 = -t1 t2 = 1.d0 if(ma .eq. 0) go to 26 do 25 i=1,ma t2 = fnmh*t2/(fnmh+pm1) fnmh = fnmh+2.d0 25 continue 26 cp2 = t1*dsqrt((n+.5d0)*t2) fnnp1 = n*(n+1) fnmsq = fnnp1-2.d0*ma*ma l = (n+1)/2 if(mod(n,2) .eq. 0 .and. mod(ma,2) .eq. 0) l = l+1 cp(l) = cp2 if(m .ge. 0) go to 29 if(mod(ma,2) .ne. 0) cp(l) = -cp(l) 29 if(l .le. 1) return fk = n a1 = (fk-2.d0)*(fk-1.d0)-fnnp1 b1 = 2.d0*(fk*fk-fnmsq) cp(l-1) = b1*cp(l)/a1 30 l = l-1 if(l .le. 1) return fk = fk-2.d0 a1 = (fk-2.d0)*(fk-1.d0)-fnnp1 b1 = -2.d0*(fk*fk-fnmsq) c1 = (fk+1.d0)*(fk+2.d0)-fnnp1 cp(l-1) = -(b1*cp(l)+c1*cp(l+1))/a1 go to 30 end c subroutine lfim (init,theta,l,n,nm,pb,id,wlfim) c c dimension of theta(l), pb(id,nm+1), wlfim(4*l*(nm+1)) c arguments c c purpose given n and l, routine lfim calculates c the normalized associated legendre functions c pbar(n,m,theta) for m=0,...,n and theta(i) c for i=1,...,l where c c pbar(m,n,theta) = sqrt((2*n+1)*factorial(n-m) c /(2*factorial(n+m)))*sin(theta)**m/(2**n* c factorial(n)) times the (n+m)th derivative of c (x**2-1)**n with respect to x=cos(theta) c c usage call lfim (init,theta,l,n,nm,pb,id,wlfim) c c arguments c on input init c = 0 c initialization only - using parameters c l, nm and array theta, subroutine lfim c initializes array wlfim for subsequent c use in the computation of the associated c legendre functions pb. initialization c does not have to be repeated unless c l, nm, or array theta are changed. c = 1 c subroutine lfim uses the array wlfim that c was computed with init = 0 to compute pb. c c theta c an array that contains the colatitudes c at which the associated legendre functions c will be computed. the colatitudes must be c specified in radians. c c l c the length of the theta array. lfim is c vectorized with vector length l. c c n c nonnegative integer, less than nm, specifying c degree of pbar(n,m,theta). subroutine lfim c must be called starting with n=0. n must be c incremented by one in subsequent calls and c must not exceed nm. c c nm c the maximum value of n and m c c id c the first dimension of the two dimensional c array pb as it appears in the program that c calls lfim. (see output parameter pb) c c wlfim c an array with length 4*l*(nm+1) which c must be initialized by calling lfim c with init=0 (see parameter init) it c must not be altered between calls to c lfim. c c c on output pb c a two dimensional array with first c dimension id in the program that calls c lfim. the second dimension of pb must c be at least nm+1. starting with n=0 c lfim is called repeatedly with n being c increased by one between calls. on each c call, subroutine lfim computes c = pbar(m,n,theta(i)) for m=0,...,n and c i=1,...l. c c wlfim c array containing values which must not c be altered unless l, nm or the array theta c are changed in which case lfim must be c called with init=0 to reinitialize the c wlfim array. c c special conditions n must be increased by one between calls c of lfim in which n is not zero. c c precision single c c c algorithm routine lfim calculates pbar(n,m,theta) using c a four term recurrence relation. (unpublished c notes by paul n. swarztrauber) c subroutine lfim (init,theta,l,n,nm,pb,id,wlfim) implicit double precision (a-h,o-z) dimension theta(1), pb(1) ,wlfim(1) c c total length of wlfim is 4*l*(nm+1) c lnx = l*(nm+1) iw1 = lnx+1 iw2 = iw1+lnx iw3 = iw2+lnx call lfim1(init,theta,l,n,nm,id,pb,wlfim,wlfim(iw1), 1 wlfim(iw2),wlfim(iw3),wlfim(iw2)) return end subroutine lfim1(init,theta,l,n,nm,id,p3,phz,ph1,p1,p2,cp) implicit double precision (a-h,o-z) dimension p1(l,*) ,p2(l,*) ,p3(id,*) ,phz(l,*) , 1 ph1(l,*) ,cp(*) ,theta(*) nmp1 = nm+1 if(init .ne. 0) go to 5 ssqrt2 = 1.d0/dsqrt(2.d0) do 10 i=1,l phz(i,1) = ssqrt2 10 continue do 15 np1=2,nmp1 nh = np1-1 call alfk(nh,0,cp) do 16 i=1,l call lfpt(nh,0,theta(i),cp,phz(i,np1)) 16 continue call alfk(nh,1,cp) do 17 i=1,l call lfpt(nh,1,theta(i),cp,ph1(i,np1)) 17 continue 15 continue return 5 if(n .gt. 2) go to 60 if(n-1)25,30,35 25 do 45 i=1,l p3(i,1)=phz(i,1) 45 continue return 30 do 50 i=1,l p3(i,1) = phz(i,2) p3(i,2) = ph1(i,2) 50 continue return 35 sq5s6 = dsqrt(5.d0/6.d0) sq1s6 = dsqrt(1.d0/6.d0) do 55 i=1,l p3(i,1) = phz(i,3) p3(i,2) = ph1(i,3) p3(i,3) = sq5s6*phz(i,1)-sq1s6*p3(i,1) p1(i,1) = phz(i,2) p1(i,2) = ph1(i,2) p2(i,1) = phz(i,3) p2(i,2) = ph1(i,3) p2(i,3) = p3(i,3) 55 continue return 60 nm1 = n-1 np1 = n+1 fn = dfloat(n) tn = fn+fn cn = (tn+1.d0)/(tn-3.d0) do 65 i=1,l p3(i,1) = phz(i,np1) p3(i,2) = ph1(i,np1) 65 continue if(nm1 .lt. 3) go to 71 do 70 mp1=3,nm1 m = mp1-1 fm = dfloat(m) fnpm = fn+fm fnmm = fn-fm temp = fnpm*(fnpm-1.d0) cc = dsqrt(cn*(fnpm-3.d0)*(fnpm-2.d0)/temp) dd = dsqrt(cn*fnmm*(fnmm-1.d0)/temp) ee = dsqrt((fnmm+1.d0)*(fnmm+2.d0)/temp) do 70 i=1,l p3(i,mp1) = cc*p1(i,mp1-2)+dd*p1(i,mp1)-ee*p3(i,mp1-2) 70 continue 71 fnpm = fn+fn-1.d0 temp = fnpm*(fnpm-1.d0) cc = dsqrt(cn*(fnpm-3.d0)*(fnpm-2.d0)/temp) ee = dsqrt(6.d0/temp) do 75 i=1,l p3(i,n) = cc*p1(i,n-2)-ee*p3(i,n-2) 75 continue fnpm = fn+fn temp = fnpm*(fnpm-1.d0) cc = dsqrt(cn*(fnpm-3.d0)*(fnpm-2.d0)/temp) ee = dsqrt(2.d0/temp) do 80 i=1,l p3(i,n+1) = cc*p1(i,n-1)-ee*p3(i,n-1) 80 continue do 90 mp1=1,np1 do 90 i=1,l p1(i,mp1) = p2(i,mp1) p2(i,mp1) = p3(i,mp1) 90 continue return end c subroutine lfin (init,theta,l,m,nm,pb,id,wlfin) c c dimension of theta(l), pb(id,nm+1), wlfin(4*l*(nm+1)) c arguments c c purpose given m and l, routine lfin calculates c the normalized associated legendre functions c pbar(n,m,theta) for n=m,...,nm and theta(i) c for i=1,...,l where c c pbar(m,n,theta) = sqrt((2*n+1)*factorial(n-m) c /(2*factorial(n+m)))*sin(theta)**m/(2**n* c factorial(n)) times the (n+m)th derivative of c (x**2-1)**n with respect to x=cos(theta) c c usage call lfin (init,theta,l,m,nm,pb,id,wlfin) c c arguments c on input init c = 0 c initialization only - using parameters c l, nm and the array theta, subroutine lfin c initializes the array wlfin for subsequent c use in the computation of the associated c legendre functions pb. initialization does c not have to be repeated unless l, nm or c the array theta are changed. c = 1 c subroutine lfin uses the array wlfin that c was computed with init = 0 to compute pb c c theta c an array that contains the colatitudes c at which the associated legendre functions c will be computed. the colatitudes must be c specified in radians. c c l c the length of the theta array. lfin is c vectorized with vector length l. c c m c nonnegative integer, less than nm, specifying c degree of pbar(n,m,theta). subroutine lfin c must be called starting with n=0. n must be c incremented by one in subsequent calls and c must not exceed nm. c c nm c the maximum value of n and m c c id c the first dimension of the two dimensional c array pb as it appears in the program that c calls lfin. (see output parameter pb) c c wlfin c an array with length 4*l*(nm+1) which c must be initialized by calling lfin c with init=0 (see parameter init) it c must not be altered between calls to c lfin. c c c on output pb c a two dimensional array with first c dimension id in the program that calls c lfin. the second dimension of pb must c be at least nm+1. starting with m=0 c lfin is called repeatedly with m being c increased by one between calls. on each c call, subroutine lfin computes pb(i,n+1) c = pbar(m,n,theta(i)) for n=m,...,nm and c i=1,...l. c c wlfin c array containing values which must not c be altered unless l, nm or the array theta c are changed in which case lfin must be c called with init=0 to reinitialize the c wlfin array. c c special conditions m must be increased by one between calls c of lfin in which m is not zero. c c precision single c c algorithm routine lfin calculates pbar(n,m,theta) using c a four term recurrence relation. (unpublished c notes by paul n. swarztrauber) c subroutine lfin (init,theta,l,m,nm,pb,id,wlfin) implicit double precision (a-h,o-z) dimension theta(1), pb(1) ,wlfin(1) c c total length of wlfin is 4*l*(nm+1) c lnx = l*(nm+1) iw1 = lnx+1 iw2 = iw1+lnx iw3 = iw2+lnx call lfin1(init,theta,l,m,nm,id,pb,wlfin,wlfin(iw1), 1 wlfin(iw2),wlfin(iw3),wlfin(iw2)) return end subroutine lfin1(init,theta,l,m,nm,id,p3,phz,ph1,p1,p2,cp) implicit double precision (a-h,o-z) dimension p1(l,1) ,p2(l,1) ,p3(id,1) ,phz(l,1) , 1 ph1(l,1) ,cp(1) ,theta(1) nmp1 = nm+1 if(init .ne. 0) go to 5 ssqrt2 = 1.d0/dsqrt(2.d0) do 10 i=1,l phz(i,1) = ssqrt2 10 continue do 15 np1=2,nmp1 nh = np1-1 call alfk(nh,0,cp) do 16 i=1,l call lfpt(nh,0,theta(i),cp,phz(i,np1)) 16 continue call alfk(nh,1,cp) do 17 i=1,l call lfpt(nh,1,theta(i),cp,ph1(i,np1)) 17 continue 15 continue return 5 mp1 = m+1 fm = dfloat(m) tm = fm+fm if(m-1)25,30,35 25 do 45 np1=1,nmp1 do 45 i=1,l p3(i,np1) = phz(i,np1) p1(i,np1) = phz(i,np1) 45 continue return 30 do 50 np1=2,nmp1 do 50 i=1,l p3(i,np1) = ph1(i,np1) p2(i,np1) = ph1(i,np1) 50 continue return 35 temp = tm*(tm-1.d0) cc = dsqrt((tm+1.d0)*(tm-2.d0)/temp) ee = dsqrt(2.d0/temp) do 85 i=1,l p3(i,m+1) = cc*p1(i,m-1)-ee*p1(i,m+1) 85 continue if(m .eq. nm) return temp = tm*(tm+1.d0) cc = dsqrt((tm+3.d0)*(tm-2.d0)/temp) ee = dsqrt(6.d0/temp) do 70 i=1,l p3(i,m+2) = cc*p1(i,m)-ee*p1(i,m+2) 70 continue mp3 = m+3 if(nmp1 .lt. mp3) go to 80 do 75 np1=mp3,nmp1 n = np1-1 fn = dfloat(n) tn = fn+fn cn = (tn+1.d0)/(tn-3.d0) fnpm = fn+fm fnmm = fn-fm temp = fnpm*(fnpm-1.d0) cc = dsqrt(cn*(fnpm-3.d0)*(fnpm-2.d0)/temp) dd = dsqrt(cn*fnmm*(fnmm-1.d0)/temp) ee = dsqrt((fnmm+1.d0)*(fnmm+2.d0)/temp) do 75 i=1,l p3(i,np1) = cc*p1(i,np1-2)+dd*p3(i,np1-2)-ee*p1(i,np1) 75 continue 80 do 90 np1=m,nmp1 do 90 i=1,l p1(i,np1) = p2(i,np1) p2(i,np1) = p3(i,np1) 90 continue return end c subroutine lfpt (n,m,theta,cp,pb) c c dimension of c arguments c cp((n/2)+1) c c purpose routine lfpt uses coefficients computed by c routine alfk to compute the single precision c normalized associated legendre function pbar(n, c m,theta) at colatitude theta. c c usage call lfpt(n,m,theta,cp,pb) c c arguments c c on input n c nonnegative integer specifying the degree of c pbar(n,m,theta) c m c is the order of pbar(n,m,theta). m can be c any integer however pbar(n,m,theta) = 0 c if abs(m) is greater than n and c pbar(n,m,theta) = (-1)**m*pbar(n,-m,theta) c for negative m. c c theta c single precision colatitude in radians c c cp c single precision array of length (n/2)+1 c containing coefficients computed by routine c alfk c c on output pb c single precision variable containing c pbar(n,m,theta) c c special conditions calls to routine lfpt must be preceded by an c appropriate call to routine alfk. c c precision single c c algorithm the trigonometric series formula used by c routine lfpt to calculate pbar(n,m,th) at c colatitude th depends on m and n as follows: c c 1) for n even and m even, the formula is c .5*cp(1) plus the sum from k=1 to k=n/2 c of cp(k)*cos(2*k*th) c 2) for n even and m odd. the formula is c the sum from k=1 to k=n/2 of c cp(k)*sin(2*k*th) c 3) for n odd and m even, the formula is c the sum from k=1 to k=(n+1)/2 of c cp(k)*cos((2*k-1)*th) c 4) for n odd and m odd, the formula is c the sum from k=1 to k=(n+1)/2 of c cp(k)*sin((2*k-1)*th) c c accuracy comparison between routines lfpt and double c precision dlfpt on the cray1 indicates greater c accuracy for greater values on input parameter c n. agreement to 13 places was obtained for c n=10 and to 12 places for n=100. c c timing time per call to routine lfpt is dependent on c the input parameter n. c subroutine lfpt (n,m,theta,cp,pb) implicit double precision (a-h,o-z) dimension cp(1) c pb = 0.d0 ma = iabs(m) if(ma .gt. n) return if (n) 10, 10, 30 10 if (ma) 20, 20, 30 20 pb= dsqrt(.5d0) go to 140 30 np1 = n+1 nmod = mod(n,2) mmod = mod(ma,2) if (nmod) 40, 40, 90 40 if (mmod) 50, 50, 70 50 kdo = n/2+1 cdt = dcos(theta+theta) sdt = dsin(theta+theta) ct = 1.d0 st = 0.d0 sum = .5d0*cp(1) do 60 kp1=2,kdo cth = cdt*ct-sdt*st st = sdt*ct+cdt*st ct = cth sum = sum+cp(kp1)*ct 60 continue pb= sum go to 140 70 kdo = n/2 cdt = dcos(theta+theta) sdt = dsin(theta+theta) ct = 1.d0 st = 0.d0 sum = 0.d0 do 80 k=1,kdo cth = cdt*ct-sdt*st st = sdt*ct+cdt*st ct = cth sum = sum+cp(k)*st 80 continue pb= sum go to 140 90 kdo = (n+1)/2 if (mmod) 100,100,120 100 cdt = dcos(theta+theta) sdt = dsin(theta+theta) ct = dcos(theta) st = -dsin(theta) sum = 0.d0 do 110 k=1,kdo cth = cdt*ct-sdt*st st = sdt*ct+cdt*st ct = cth sum = sum+cp(k)*ct 110 continue pb= sum go to 140 120 cdt = dcos(theta+theta) sdt = dsin(theta+theta) ct = dcos(theta) st = -dsin(theta) sum = 0.d0 do 130 k=1,kdo cth = cdt*ct-sdt*st st = sdt*ct+cdt*st ct = cth sum = sum+cp(k)*st 130 continue pb= sum 140 return end ================================================ FILE: external/SPHEREPACK/divgs.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c c c ... file divgs.f c c this file includes documentation and code for c subroutine divgs i c c ... files which must be loaded with divgs.f c c sphcom.f, hrfft.f, vhags.f, shsgs.f, gaqd.f c c c subroutine divgs(nstrg,nstrb,noffsg,noffsb, c nlat,nlon,isym,nt,divg,idiv,jdiv,br,bi,mdb,ndb, c + wshsgs,lshsgs,work,lwork,ierror) c c given the vector spherical harmonic coefficients br and bi, precomputed c by subroutine vhags for a vector field (v,w), subroutine divgs c computes the divergence of the vector field in the scalar array divg. c divg(i,j) is the divergence at the gaussian colatitude point theta(i) c (see nlat as input parameter) and east longitude c c lambda(j) = (j-1)*2*pi/nlon c c on the sphere. i.e. c c dv(i,j) = 1/sint*[ d(sint*v(i,j))/dtheta + d(w(i,j))/dlambda ] c c where sint = sin(theta(i)). w is the east longitudinal and v c is the colatitudinal component of the vector field from which c br,bi were precomputed c c c input parameters c c nstrg,nstrb strides in g,b c noffsg,noffsb offsets in g,b -- must be between 0 and stride-1 c c nlat the number of points in the gaussian colatitude grid on the c full sphere. these lie in the interval (0,pi) and are computed c in radians in theta(1) <...< theta(nlat) by subroutine gaqd. c if nlat is odd the equator will be included as the grid point c theta((nlat+1)/2). if nlat is even the equator will be c excluded as a grid point and will lie half way between c theta(nlat/2) and theta(nlat/2+1). nlat must be at least 3. c note: on the half sphere, the number of grid points in the c colatitudinal direction is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than zero. the axisymmetric case corresponds to nlon=1. c the efficiency of the computation is improved when nlon c is a product of small prime numbers. c c NOTE: this is a modified version of spherepack. Changes from c the original version to the current one have only been c tested for isym==0. For this reason an error code will c be returned if isym!=0. c c c isym a parameter which determines whether the divergence is c computed on the full or half sphere as follows: c c = 0 c c the symmetries/antsymmetries described in isym=1,2 below c do not exist in (v,w) about the equator. in this case the c divergence is neither symmetric nor antisymmetric about c the equator. the divergence is computed on the entire c sphere. i.e., in the array divg(i,j) for i=1,...,nlat and c j=1,...,nlon. c c = 1 c c w is antisymmetric and v is symmetric about the equator. c in this case the divergence is antisymmetyric about c the equator and is computed for the northern hemisphere c only. i.e., if nlat is odd the divergence is computed c in the array divg(i,j) for i=1,...,(nlat+1)/2 and for c j=1,...,nlon. if nlat is even the divergence is computed c in the array divg(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c c = 2 c w is symmetric and v is antisymmetric about the equator c in this case the divergence is symmetyric about the c equator and is computed for the northern hemisphere c only. i.e., if nlat is odd the divergence is computed c in the array divg(i,j) for i=1,...,(nlat+1)/2 and for c j=1,...,nlon. if nlat is even the divergence is computed c in the array divg(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c c c nt nt is the number of scalar and vector fields. some c computational efficiency is obtained for multiple fields. c in the program that calls divgs, the arrays br,bi, and divg c can be three dimensional corresponding to an indexed multiple c vector field. in this case multiple scalar synthesis will c be performed to compute the divergence for each field. the c third index is the synthesis index which assumes the values c k=1,...,nt. for a single synthesis set nt = 1. the c description of the remaining parameters is simplified by c assuming that nt=1 or that all the arrays are two dimensional. c c idiv the first dimension of the array divg as it appears in c the program that calls divgs. if isym = 0 then idiv c must be at least nlat. if isym = 1 or 2 and nlat is c even then idiv must be at least nlat/2. if isym = 1 or 2 c and nlat is odd then idiv must be at least (nlat+1)/2. c c jdiv the second dimension of the array divg as it appears in c the program that calls divgs. jdiv must be at least nlon. c c br,bi two or three dimensional arrays (see input parameter nt) c that contain vector spherical harmonic coefficients c of the vector field (v,w) as computed by subroutine vhags. c *** br and bi must be computed by vhags prior to calling c divgs. c c mdb the first dimension of the arrays br and bi as it c appears in the program that calls divgs. mdb must be at c least min0(nlat,nlon/2) if nlon is even or at least c min0(nlat,(nlon+1)/2) if nlon is odd. c c ndb the second dimension of the arrays br and bi as it c appears in the program that calls divgs. ndb must be at c least nlat. c c c wshsgs an array which must be intialized by subroutine shsgsi. c once initialized, c wshsgs can be used repeatedly by divgs as long as nlon c and nlat remain unchanged. wshsgs must not be altered c between calls of divgs. c c c lshsgs the dimension of the array wshsgs as it appears in the c program that calls divgs. define c c l1 = min0(nlat,(nlon+2)/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lshsgs must be at least c c nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 c c c work a work array that does not have to be saved. c c lwork the dimension of the array work as it appears in the c program that calls divgs. define c c l1 = min0(nlat,(nlon+2)/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c if isym = 0 then lwork must be at least c c nlat*((nt+1)*nlon+2*nt*l1+1) c c if isym > 0 then lwork must be at least c c (nt+1)*l2*nlon+nlat*(2*nt*l1+1) c c ************************************************************** c c output parameters c c c divg a two or three dimensional array (see input parameter nt) c that contains the divergence of the vector field (v,w) c whose coefficients br,bi where computed by subroutine c vhags. divg(i,j) is the divergence at the gaussian colatitude c point theta(i) and longitude point lambda(j) = (j-1)*2*pi/nlon. c the index ranges are defined above at the input parameter c isym. c c c ierror = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of isym c = 4 error in the specification of nt c = 5 error in the specification of idiv c = 6 error in the specification of jdiv c = 7 error in the specification of mdb c = 8 error in the specification of ndb c = 9 error in the specification of lshsgs c = 10 error in the specification of lwork c ********************************************************************** c c subroutine divgs(nstrg,nstrb,noffsg,noffsb, + nlat,nlon,isym,nt,divg,idiv,jdiv,br,bi,mdb,ndb, + wshsgs,lshsgs,work,lwork,ierror) implicit double precision (a-h,o-z) dimension divg(nstrg,idiv,jdiv,nt), + br(nstrb,mdb,ndb,nt),bi(nstrb,mdb,ndb,nt) dimension wshsgs(lshsgs),work(lwork) c c check input parameters c ierror = 1 if(nlat .lt. 3) return ierror = 2 if(nlon .lt. 4) return ierror = 3 c if (isym.lt.0 .or. isym.gt.2) return c see note above about symmeries if(isym.ne.0) return ierror = 4 if(nt .lt. 0) return ierror = 5 imid = (nlat+1)/2 if((isym.eq.0 .and. idiv.lt.nlat) .or. 1 (isym.gt.0 .and. idiv.lt.imid)) return ierror = 6 if(jdiv .lt. nlon) return ierror = 7 if(mdb .lt. min0(nlat,(nlon+1)/2)) return mmax = min0(nlat,(nlon+2)/2) ierror = 8 if(ndb .lt. nlat) return ierror = 9 imid = (nlat+1)/2 lpimn = (imid*mmax*(nlat+nlat-mmax+1))/2 c check permanent work space length l2 = (nlat+1)/2 l1 = min0((nlon+2)/2,nlat) lp=nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 if(lshsgs.lt.lp) return ierror = 10 c c verify unsaved work space (add to what shses requires, file f3) c ls = nlat if(isym .gt. 0) ls = imid nln = nt*ls*nlon c c set first dimension for a,b (as requried by shses) c mab = min0(nlat,nlon/2+1) mn = mab*nlat*nt if(lwork.lt. nln+ls*nlon+2*mn+nlat) return ierror = 11 if((noffsg.lt.0) .or. (noffsg.ge.nstrg)) return if((noffsb.lt.0) .or. (noffsb.ge.nstrb)) return ierror = 0 c c set work space pointers c ia = 1 ib = ia+mn is = ib+mn iwk = is+nlat lwk = lwork-2*mn-nlat call divgs1(nstrg,nstrb,noffsg,noffsb, + nlat,nlon,isym,nt,divg,idiv,jdiv,br,bi,mdb,ndb, +work(ia),work(ib),mab,work(is),wshsgs,lshsgs,work(iwk),lwk, +ierror) return end subroutine divgs1(nstrg,nstrb,noffsg,noffsb, + nlat,nlon,isym,nt,divg,idiv,jdiv,br,bi,mdb,ndb, + a,b,mab,sqnn,wshsgs,lshsgs,wk,lwk,ierror) implicit double precision (a-h,o-z) dimension divg(nstrg,idiv,jdiv,nt), + br(nstrb,mdb,ndb,nt),bi(nstrb,mdb,ndb,nt) dimension a(mab,nlat,nt),b(mab,nlat,nt),sqnn(nlat) dimension wshsgs(lshsgs),wk(lwk) ncb = 1+noffsb c c set coefficient multiplyers c do 1 n=2,nlat fn = dfloat(n-1) sqnn(n) = dsqrt(fn*(fn+1.)) 1 continue c c compute divergence scalar coefficients for each vector field c do 2 k=1,nt do 3 n=1,nlat do 4 m=1,mab a(m,n,k) = 0.0 b(m,n,k) = 0.0 4 continue 3 continue c c compute m=0 coefficients c do 5 n=2,nlat a(1,n,k) = -sqnn(n)*br(ncb,1,n,k) b(1,n,k) = -sqnn(n)*bi(ncb,1,n,k) 5 continue c c compute m>0 coefficients using vector spherepack value for mmax c mmax = min0(nlat,(nlon+1)/2) do 6 m=2,mmax do 7 n=m,nlat a(m,n,k) = -sqnn(n)*br(ncb,m,n,k) b(m,n,k) = -sqnn(n)*bi(ncb,m,n,k) 7 continue 6 continue 2 continue c c synthesize a,b into divg c call shsgs(nstrg,1,noffsg,0,nlat,nlon,isym,nt,divg,idiv,jdiv,a,b, + mab,nlat,mab,nlat,wshsgs,lshsgs,wk,lwk,ierror) return end ================================================ FILE: external/SPHEREPACK/gaqd.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c c This version of gaqd implements the method presented in: c P. N. swarztrauber, Computing the points and weights for c Gauss-Legendre quadrature, SIAM J. Sci. Comput., c 24(2002) pp. 945-954. c c The w and lwork arrays are dummy and included only to c permit a simple pluggable exchange with the c old gaqd in previous versions of SPHEREPACK c c c subroutine gaqd(nlat,theta,wts,w,lwork,ierror) implicit double precision (a-h,o-z) c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c c gauss points and weights are computed using the fourier-newton c described in "on computing the points and weights for c gauss-legendre quadrature", paul n. swarztrauber, siam journal c on scientific computing that has been accepted for publication. c This routine is faster and more accurate than older program c with the same name. c c subroutine gaqd computes the nlat gaussian colatitudes and weights c in double precision. the colatitudes are in radians and lie in the c in the interval (0,pi). c c input parameters c c nlat the number of gaussian colatitudes in the interval (0,pi) c (between the two poles). nlat must be greater than zero. c c w unused double precision variable that permits a simple c exchange with the old routine with the same name c in spherepack. c c lwork unused variable that permits a simple exchange with the c old routine with the same name in spherepack. c c output parameters c c theta a double precision array with length nlat c containing the gaussian colatitudes in c increasing radians on the interval (0,pi). c c wts a double precision array with lenght nlat c containing the gaussian weights. c c ierror = 0 no errors c = 1 if nlat.le.0 c c ***************************************************************** c double precision theta(nlat),wts(nlat),w, 1 x,pi,pis2,dtheta,dthalf,cmax,zprev,zlast,zero, 2 zhold,pb,dpb,dcor,sum,cz c c check work space length c ierror = 1 if (nlat.le.0) return ierror = 0 c c compute weights and points analytically when nlat=1,2 c if (nlat.eq.1) then theta(1) = dacos(0.0d0) wts(1) = 2.0d0 return end if if (nlat.eq.2) then x = dsqrt(1.0d0/3.0d0) theta(1) = dacos(x) theta(2) = dacos(-x) wts(1) = 1.0d0 wts(2) = 1.0d0 return end if eps = dsqrt(dzeps(1.0d0)) eps = eps*dsqrt(eps) pis2 = 2.0d0*datan(1.0d0) pi = pis2+pis2 mnlat = mod(nlat,2) ns2 = nlat/2 nhalf = (nlat+1)/2 idx = ns2+2 c call cpdp (nlat,cz,theta(ns2+1),wts(ns2+1)) c dtheta = pis2/nhalf dthalf = dtheta/2.0d0 cmax = .2d0*dtheta c c estimate first point next to theta = pi/2 c if(mnlat.ne.0) then zero = pis2-dtheta zprev = pis2 nix = nhalf-1 else zero = pis2-dthalf nix = nhalf end if 9 it = 0 10 it = it+1 zlast = zero c c newton iterations c call tpdp (nlat,zero,cz,theta(ns2+1),wts(ns2+1),pb,dpb) dcor = pb/dpb sgnd = 1.0d0 if(dcor .ne. 0.0d0) sgnd = dcor/dabs(dcor) dcor = sgnd*min(dabs(dcor),cmax) zero = zero-dcor if(dabs(zero-zlast).gt.eps*dabs(zero)) go to 10 theta(nix) = zero zhold = zero c wts(nix) = (nlat+nlat+1)/(dpb*dpb) c c yakimiw's formula permits using old pb and dpb c wts(nix) = (nlat+nlat+1)/(dpb+pb*dcos(zlast)/dsin(zlast))**2 nix = nix-1 if(nix.eq.0) go to 30 if(nix.eq.nhalf-1) zero = 3.0d0*zero-pi if(nix.lt.nhalf-1) zero = zero+zero-zprev zprev = zhold go to 9 c c extend points and weights via symmetries c 30 if(mnlat.ne.0) then theta(nhalf) = pis2 call tpdp (nlat,pis2,cz,theta(ns2+1),wts(ns2+1),pb,dpb) wts(nhalf) = (nlat+nlat+1)/(dpb*dpb) end if do i=1,ns2 wts(nlat-i+1) = wts(i) theta(nlat-i+1) = pi-theta(i) end do sum = 0.0d0 do i=1,nlat sum = sum+wts(i) end do do i=1,nlat wts(i) = 2.0d0*wts(i)/sum end do return end subroutine cpdp(n,cz,cp,dcp) implicit double precision (a-h,o-z) c c computes the fourier coefficients of the legendre c polynomial p_n^0 and its derivative. c n is the degree and n/2 or (n+1)/2 c coefficients are returned in cp depending on whether c n is even or odd. The same number of coefficients c are returned in dcp. For n even the constant c coefficient is returned in cz. c double precision cp(n/2+1),dcp(n/2+1), 1 t1,t2,t3,t4,cz ncp = (n+1)/2 t1 = -1.0d0 t2 = n+1.0d0 t3 = 0.0d0 t4 = n+n+1.0d0 if(mod(n,2).eq.0) then cp(ncp) = 1.0d0 do j = ncp,2,-1 t1 = t1+2.0d0 t2 = t2-1.0d0 t3 = t3+1.0d0 t4 = t4-2.0d0 cp(j-1) = (t1*t2)/(t3*t4)*cp(j) end do t1 = t1+2.0d0 t2 = t2-1.0d0 t3 = t3+1.0d0 t4 = t4-2.0d0 cz = (t1*t2)/(t3*t4)*cp(1) do j=1,ncp dcp(j) = (j+j)*cp(j) end do else cp(ncp) = 1.0d0 do j = ncp-1,1,-1 t1 = t1+2.0d0 t2 = t2-1.0d0 t3 = t3+1.0d0 t4 = t4-2.0d0 cp(j) = (t1*t2)/(t3*t4)*cp(j+1) end do do j=1,ncp dcp(j) = (j+j-1)*cp(j) end do end if return end subroutine tpdp (n,theta,cz,cp,dcp,pb,dpb) implicit double precision (a-h,o-z) c c computes pn(theta) and its derivative dpb(theta) with c respect to theta c double precision cp(n/2+1),dcp(n/2+1),cz, 1 pb,dpb,fn,theta,cdt,sdt,cth,sth,chh c fn = n cdt = dcos(theta+theta) sdt = dsin(theta+theta) if(mod(n,2) .eq.0) then c c n even c kdo = n/2 pb = .5d0*cz dpb = 0.0d0 if(n .gt. 0) then cth = cdt sth = sdt do 170 k=1,kdo c pb = pb+cp(k)*cos(2*k*theta) pb = pb+cp(k)*cth c dpb = dpb-(k+k)*cp(k)*sin(2*k*theta) dpb = dpb-dcp(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 170 continue end if else c c n odd c kdo = (n+1)/2 pb = 0.0d0 dpb = 0.0d0 cth = dcos(theta) sth = dsin(theta) do 190 k=1,kdo c pb = pb+cp(k)*cos((2*k-1)*theta) pb = pb+cp(k)*cth c dpb = dpb-(k+k-1)*cp(k)*sin((2*k-1)*theta) dpb = dpb-dcp(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 190 continue end if return end double precision function dzeps (x) implicit double precision (a-h,o-z) double precision x c c estimate unit roundoff in quantities of size x. c double precision a,b,c,eps c c this program should function properly on all systems c satisfying the following two assumptions, c 1. the base used in representing floating point c numbers is not a power of three. c 2. the quantity a in statement 10 is represented to c the accuracy used in floating point variables c that are stored in memory. c the statement number 10 and the go to 10 are intended to c force optimizing compilers to generate code satisfying c assumption 2. c under these assumptions, it should be true that, c a is not exactly equal to four-thirds, c b has a zero for its last bit or digit, c c is not exactly equal to one, c eps measures the separation of 1.0 from c the next larger floating point number. c the developers of eispack would appreciate being informed c about any systems where these assumptions do not hold. c c this version dated 4/6/83. c a = 4.0d0/3.0d0 10 b = a - 1.0d0 c = b + b + b eps = abs(c-1.0d0) if (eps .eq. 0.0d0) go to 10 dzeps = eps*dabs(x) return end ================================================ FILE: external/SPHEREPACK/gradgs.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c ... file gradgs.f c c this file includes documentation and code for c subroutine gradgs i c c ... files which must be loaded with gradgec.f c c sphcom.f, hrfft.f, shags.f,vhsgs.f c c subroutine gradgs(nstrvw,nstrab,noffsvw,noffsab, c nlat,nlon,isym,nt,v,w,idvw,jdvw,a,b,mdab,ndab, c + wvhsgs,lvhsgs,work,lwork,ierror) c c given the scalar spherical harmonic coefficients a and b, precomputed c by subroutine shags for a scalar field sf, subroutine gradgs computes c an irrotational vector field (v,w) such that c c gradient(sf) = (v,w). c c v is the colatitudinal and w is the east longitudinal component c of the gradient. i.e., c c v(i,j) = d(sf(i,j))/dtheta c c and c c w(i,j) = 1/sint*d(sf(i,j))/dlambda c c at the gaussian colatitude point theta(i) (see nlat as input c parameter) and longitude lambda(j) = (j-1)*2*pi/nlon where c sint = sin(theta(i)). c c c input parameters c c nstrvw, nstrab strides of v,w and a,b c noffsvw, noffsab offset of v,w and a,b -- must be between 0 and stride-1 c Alternatively, when the two strides equal, you can set both c to -1 in which case the output will be computed for all c values of offset between 0 and stride-1. c c nlat the number of points in the gaussian colatitude grid on the c full sphere. these lie in the interval (0,pi) and are computed c in radians in theta(1) <...< theta(nlat) by subroutine gaqd. c if nlat is odd the equator will be included as the grid point c theta((nlat+1)/2). if nlat is even the equator will be c excluded as a grid point and will lie half way between c theta(nlat/2) and theta(nlat/2+1). nlat must be at least 3. c note: on the half sphere, the number of grid points in the c colatitudinal direction is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater than c 3. the efficiency of the computation is improved when nlon c is a product of small prime numbers. c c NOTE: this is a modified version of spherepack. Changes from c the original version to the current one have only been c tested for isym==0. For this reason an error code will c be returned if isym!=0. c c c isym this has the same value as the isym that was input to c subroutine shags to compute the arrays a and b from the c scalar field sf. isym determines whether (v,w) are c computed on the full or half sphere as follows: c c = 0 c c sf is not symmetric about the equator. in this case c the vector field (v,w) is computed on the entire sphere. c i.e., in the arrays v(i,j),w(i,j) for i=1,...,nlat and c j=1,...,nlon. c c = 1 c c sf is antisymmetric about the equator. in this case w is c antisymmetric and v is symmetric about the equator. w c and v are computed on the northern hemisphere only. i.e., c if nlat is odd they are computed for i=1,...,(nlat+1)/2 c and j=1,...,nlon. if nlat is even they are computed for c i=1,...,nlat/2 and j=1,...,nlon. c c = 2 c c sf is symmetric about the equator. in this case w is c symmetric and v is antisymmetric about the equator. w c and v are computed on the northern hemisphere only. i.e., c if nlat is odd they are computed for i=1,...,(nlat+1)/2 c and j=1,...,nlon. if nlat is even they are computed for c i=1,...,nlat/2 and j=1,...,nlon. c c c nt nt is the number of scalar and vector fields. some c computational efficiency is obtained for multiple fields. c the arrays a,b,v, and w can be three dimensional corresponding c to an indexed multiple array sf. in this case, multiple c vector synthesis will be performed to compute each vector c field. the third index for a,b,v, and w is the synthesis c index which assumes the values k = 1,...,nt. for a single c synthesis set nt = 1. the description of the remaining c parameters is simplified by assuming that nt=1 or that a,b,v, c and w are two dimensional arrays. c c idvw the first dimension of the arrays v,w as it appears in c the program that calls gradgs. if isym = 0 then idvw c must be at least nlat. if isym = 1 or 2 and nlat is c even then idvw must be at least nlat/2. if isym = 1 or 2 c and nlat is odd then idvw must be at least (nlat+1)/2. c c jdvw the second dimension of the arrays v,w as it appears in c the program that calls gradgs. jdvw must be at least nlon. c c a,b two or three dimensional arrays (see input parameter nt) c that contain scalar spherical harmonic coefficients c of the scalar field array sf as computed by subroutine shags. c *** a,b must be computed by shags prior to calling gradgs. c c mdab the first dimension of the arrays a and b as it appears in c the program that calls gradgs (and shags). mdab must be at c least min0(nlat,(nlon+2)/2) if nlon is even or at least c min0(nlat,(nlon+1)/2) if nlon is odd. c c ndab the second dimension of the arrays a and b as it appears in c the program that calls gradgs (and shags). ndab must be at c least nlat. c c c wvhsgs an array which must be initialized by subroutine vhsgsi. c once initialized, c wvhsgs can be used repeatedly by gradgs as long as nlon c and nlat remain unchanged. wvhsgs must not be altered c between calls of gradgs. c c c lvhsgs the dimension of the array wvhsgs as it appears in the c program that calls grradgs. define c c l1 = min0(nlat,nlon/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lvhsgs must be at least c c l1*l2*(nlat+nlat-l1+1)+nlon+15+2*nlat c c c work a work array that does not have to be saved. c c lwork the dimension of the array work as it appears in the c program that calls gradgs. define c c l1 = min0(nlat,nlon/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c if isym = 0, lwork must be greater than or equal to c c nlat*((2*nt+1)*nlon+2*l1*nt+1). c c if isym = 1 or 2, lwork must be greater than or equal to c c (2*nt+1)*l2*nlon+nlat*(2*l1*nt+1). c c c ************************************************************** c c output parameters c c c v,w two or three dimensional arrays (see input parameter nt) that c contain an irrotational vector field such that the gradient of c the scalar field sf is (v,w). w(i,j) is the east longitude c component and v(i,j) is the colatitudinal component of velocity c at gaussian colatitude and longitude lambda(j) = (j-1)*2*pi/nlon c the indices for v and w are defined at the input parameter c isym. the vorticity of (v,w) is zero. note that any nonzero c vector field on the sphere will be multiple valued at the poles c [reference swarztrauber]. c c c ierror = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of isym c = 4 error in the specification of nt c = 5 error in the specification of idvw c = 6 error in the specification of jdvw c = 7 error in the specification of mdab c = 8 error in the specification of ndab c = 9 error in the specification of lvhsgs c = 10 error in the specification of lwork c ********************************************************************** c c subroutine gradgs(nstrvw,nstrab,noffsvw,noffsab, +nlat,nlon,isym,nt,v,w,idvw,jdvw,a,b,mdab,ndab, +wvhsgs,lvhsgs,work,lwork,ierror) implicit double precision (a-h,o-z) dimension v(nstrvw,idvw,jdvw,nt),w(nstrvw,idvw,jdvw,nt) dimension a(nstrab,mdab,ndab,nt),b(nstrab,mdab,ndab,nt) dimension wvhsgs(lvhsgs),work(lwork) c c check input parameters c ierror = 1 if(nlat .lt. 3) return ierror = 2 if(nlon .lt. 4) return ierror = 3 if(isym.lt.0 .or. isym.gt.2) return c see note above about symmeries if(isym.ne.0) return ierror = 4 if(nt .lt. 0) return ierror = 5 imid = (nlat+1)/2 if((isym.eq.0 .and. idvw.lt.nlat) .or. + (isym.ne.0 .and. idvw.lt.imid)) return ierror = 6 if(jdvw .lt. nlon) return ierror = 7 mmax = min0(nlat,(nlon+1)/2) if(mdab .lt. min0(nlat,(nlon+2)/2)) return ierror = 8 if(ndab .lt. nlat) return ierror = 9 c c verify minimum saved work space length c idz = (mmax*(nlat+nlat-mmax+1))/2 lzimn = idz*imid lgdmin = lzimn+lzimn+nlon+15 if(lvhsgs .lt. lgdmin) return ierror = 10 c c verify minimum unsaved work space length c ng = 1; if(noffsvw.eq.-1 .and. noffsab.eq.-1) ng=nstrvw mn = mmax*nlat*nt*ng idv = nlat if (isym.ne.0) idv = imid lnl = nt*idv*nlon lwkmin = lnl+lnl+idv*nlon+2*mn+nlat if(lwork .lt. lwkmin) return ierror = 11 if((noffsvw.eq.-1) .neqv. (noffsab.eq.-1)) return if((noffsvw.eq.-1) .and. (nstrvw.ne.nstrab)) return if((noffsvw.lt.-1) .or. (noffsvw.ge.nstrvw)) return if((noffsab.lt.-1) .or. (noffsab.ge.nstrab)) return ierror = 0 c c set work space pointers c ibr = 1 ibi = ibr + mn is = ibi + mn iwk = is + nlat liwk = lwork-2*mn-nlat call gradgs1(nstrvw,nstrab,noffsvw,noffsab, +nlat,nlon,isym,nt,v,w,idvw,jdvw,work(ibr),work(ibi),ng, +mmax,work(is),mdab,ndab,a,b,wvhsgs,lvhsgs,work(iwk),liwk, +ierror) return end subroutine gradgs1(nstrvw,nstrab,noffsvw,noffsab, +nlat,nlon,isym,nt,v,w,idvw,jdvw,br,bi,ng,mmax, +sqnn,mdab,ndab,a,b,wvhsgs,lvhsgs,wk,lwk,ierror) implicit double precision (a-h,o-z) dimension v(nstrvw,idvw,jdvw,nt),w(nstrvw,idvw,jdvw,nt) dimension br(ng,mmax,nlat,nt),bi(ng,mmax,nlat,nt),sqnn(nlat) dimension a(nstrab,mdab,ndab,nt),b(nstrab,mdab,ndab,nt) dimension wvhsgs(lvhsgs),wk(lwk) if(noffsab.eq.-1) then ncabmin=1 ncabmax=nstrab else ncabmin=1+noffsab ncabmax=1+noffsab end if c c preset coefficient multiplyers in vector c do 1 n=2,nlat fn = dfloat(n-1) sqnn(n) = dsqrt(fn*(fn+1.d0)) 1 continue c c compute multiple vector fields coefficients c do 2 k=1,nt c c preset br,bi to 0.0 c do 3 n=1,nlat do 4 m=1,mmax do 4 ig=1,ng br(ig,m,n,k) = 0.0d0 bi(ig,m,n,k) = 0.0d0 4 continue 3 continue c c compute m=0 coefficients c do 5 n=2,nlat do 5 ncab=ncabmin,ncabmax ig = ncab-ncabmin+1 br(ig,1,n,k) = sqnn(n)*a(ncab,1,n,k) bi(ig,1,n,k) = sqnn(n)*b(ncab,1,n,k) 5 continue c c compute m>0 coefficients c do 6 m=2,mmax do 7 n=m,nlat do 7 ncab=ncabmin,ncabmax ig = ncab-ncabmin+1 br(ig,m,n,k) = sqnn(n)*a(ncab,m,n,k) bi(ig,m,n,k) = sqnn(n)*b(ncab,m,n,k) 7 continue 6 continue 2 continue c c set ityp for irrotational vector synthesis to compute gradient c if (isym.eq.0) then ityp = 1 else if (isym.eq.1) then ityp = 4 else if (isym.eq.2) then ityp = 7 end if c c vector sythesize br,bi into (v,w) (cr,ci are dummy variables) c call vhsgs(nstrvw,ng,noffsvw,noffsab, + nlat,nlon,ityp,nt,v,w,idvw,jdvw,br,bi,cr,ci, + mmax,nlat,wvhsgs,lvhsgs,wk,lwk,ierror) 200 continue return end ================================================ FILE: external/SPHEREPACK/hrfft.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c ... file hrfft.f c c this file contains a multiple fft package for spherepack. it c includes code and documentation for performing fast fourier c transforms (see subroutines hrffti,hrfftf and hrfftb) c c ********************************************************************** c c subroutine hrffti(n,wsave) c c subroutine hrffti initializes the array wsave which is used in c both hrfftf and hrfftb. the prime factorization of n together c with a tabulation of the trigonometric functions are computed and c stored in wsave. c c input parameter c c n the length of the sequence to be transformed. c c output parameter c c wsave a work array which must be dimensioned at least 2*n+15. c the same work array can be used for both hrfftf and c hrfftb as long as n remains unchanged. different wsave c arrays are required for different values of n. the c contents of wsave must not be changed between calls c of hrfftf or hrfftb. c c ********************************************************************** c c subroutine hrfftf(m,n,r,mdimr,wsave,work) c c subroutine hrfftf computes the fourier coefficients of m real c perodic sequences (fourier analysis); i.e. hrfftf computes the c real fft of m sequences each with length n. the transform is c defined below at output parameter r. c c input parameters c c m the number of sequences. c c n the length of all m sequences. the method is most c efficient when n is a product of small primes. n may c change as long as different work arrays are provided c c r r(m,n) is a two dimensional real array that contains m c sequences each with length n. c c mdimr the first dimension of the r array as it appears c in the program that calls hrfftf. mdimr must be c greater than or equal to m. c c c wsave a work array with at least least 2*n+15 locations c in the program that calls hrfftf. the wsave array must be c initialized by calling subroutine hrffti(n,wsave) and a c different wsave array must be used for each different c value of n. this initialization does not have to be c repeated so long as n remains unchanged thus subsequent c transforms can be obtained faster than the first. c the same wsave array can be used by hrfftf and hrfftb. c c work a real work array with m*n locations. c c c output parameters c c r for all j=1,...,m c c r(j,1) = the sum from i=1 to i=n of r(j,i) c c if n is even set l =n/2 , if n is odd set l = (n+1)/2 c c then for k = 2,...,l c c r(j,2*k-2) = the sum from i = 1 to i = n of c c r(j,i)*cos((k-1)*(i-1)*2*pi/n) c c r(j,2*k-1) = the sum from i = 1 to i = n of c c -r(j,i)*sin((k-1)*(i-1)*2*pi/n) c c if n is even c c r(j,n) = the sum from i = 1 to i = n of c c (-1)**(i-1)*r(j,i) c c ***** note c this transform is unnormalized since a call of hrfftf c followed by a call of hrfftb will multiply the input c sequence by n. c c wsave contains results which must not be destroyed between c calls of hrfftf or hrfftb. c c work a real work array with m*n locations that does c not have to be saved. c c ********************************************************************** c c subroutine hrfftb(m,n,r,mdimr,wsave,work) c c subroutine hrfftb computes the real perodic sequence of m c sequences from their fourier coefficients (fourier synthesis). c the transform is defined below at output parameter r. c c input parameters c c m the number of sequences. c c n the length of all m sequences. the method is most c efficient when n is a product of small primes. n may c change as long as different work arrays are provided c c r r(m,n) is a two dimensional real array that contains c the fourier coefficients of m sequences each with c length n. c c mdimr the first dimension of the r array as it appears c in the program that calls hrfftb. mdimr must be c greater than or equal to m. c c wsave a work array which must be dimensioned at least 2*n+15. c in the program that calls hrfftb. the wsave array must be c initialized by calling subroutine hrffti(n,wsave) and a c different wsave array must be used for each different c value of n. this initialization does not have to be c repeated so long as n remains unchanged thus subsequent c transforms can be obtained faster than the first. c the same wsave array can be used by hrfftf and hrfftb. c c work a real work array with m*n locations. c c c output parameters c c r for all j=1,...,m c c for n even and for i = 1,...,n c c r(j,i) = r(j,1)+(-1)**(i-1)*r(j,n) c c plus the sum from k=2 to k=n/2 of c c 2.*r(j,2*k-2)*cos((k-1)*(i-1)*2*pi/n) c c -2.*r(j,2*k-1)*sin((k-1)*(i-1)*2*pi/n) c c for n odd and for i = 1,...,n c c r(j,i) = r(j,1) plus the sum from k=2 to k=(n+1)/2 of c c 2.*r(j,2*k-2)*cos((k-1)*(i-1)*2*pi/n) c c -2.*r(j,2*k-1)*sin((k-1)*(i-1)*2*pi/n) c c ***** note c this transform is unnormalized since a call of hrfftf c followed by a call of hrfftb will multiply the input c sequence by n. c c wsave contains results which must not be destroyed between c calls of hrfftb or hrfftf. c c work a real work array with m*n locations that does not c have to be saved c c ********************************************************************** c c c subroutine hrffti (n,wsave) implicit double precision (a-h,o-z) dimension wsave(n+15) common /hrf/ tfft tfft = 0.d0 if (n .eq. 1) return call hrfti1 (n,wsave(1),wsave(n+1)) return end subroutine hrfti1 (n,wa,fac) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension wa(n) ,fac(15) ,ntryh(4) double precision tpi,argh,argld,arg data ntryh(1),ntryh(2),ntryh(3),ntryh(4)/4,2,3,5/ nl = n nf = 0 j = 0 101 j = j+1 if (j-4) 102,102,103 102 ntry = ntryh(j) go to 104 103 ntry = ntry+2 104 nq = nl/ntry nr = nl-ntry*nq if (nr) 101,105,101 105 nf = nf+1 fac(nf+2) = ntry nl = nq if (ntry .ne. 2) go to 107 if (nf .eq. 1) go to 107 do 106 i=2,nf ib = nf-i+2 fac(ib+2) = fac(ib+1) 106 continue fac(3) = 2 107 if (nl .ne. 1) go to 104 fac(1) = n fac(2) = nf tpi = 8.d0*datan(1.d0) argh = tpi/dfloat(n) is = 0 nfm1 = nf-1 l1 = 1 if (nfm1 .eq. 0) return do 110 k1=1,nfm1 ip = fac(k1+2) ld = 0 l2 = l1*ip ido = n/l2 ipm = ip-1 do 109 j=1,ipm ld = ld+l1 i = is argld = dfloat(ld)*argh fi = 0.d0 do 108 ii=3,ido,2 i = i+2 fi = fi+1.d0 arg = fi*argld wa(i-1) = dcos(arg) wa(i) = dsin(arg) 108 continue is = is+ido 109 continue l1 = l2 110 continue return end subroutine hrfftf (m,n,r,mdimr,whrfft,work) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension r(mdimr,n) ,work(1) ,whrfft(n+15) common /hrf/ tfft if (n .eq. 1) return c tstart = second(dum) call hrftf1 (m,n,r,mdimr,work,whrfft,whrfft(n+1)) c tfft = tfft+second(dum)-tstart return end subroutine hrftf1 (m,n,c,mdimc,ch,wa,fac) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension ch(m,n) ,c(mdimc,n) ,wa(n) ,fac(15) nf = fac(2) na = 1 l2 = n iw = n do 111 k1=1,nf kh = nf-k1 ip = fac(kh+3) l1 = l2/ip ido = n/l2 idl1 = ido*l1 iw = iw-(ip-1)*ido na = 1-na if (ip .ne. 4) go to 102 ix2 = iw+ido ix3 = ix2+ido if (na .ne. 0) go to 101 call hradf4 (m,ido,l1,c,mdimc,ch,m,wa(iw),wa(ix2),wa(ix3)) go to 110 101 call hradf4 (m,ido,l1,ch,m,c,mdimc,wa(iw),wa(ix2),wa(ix3)) go to 110 102 if (ip .ne. 2) go to 104 if (na .ne. 0) go to 103 call hradf2 (m,ido,l1,c,mdimc,ch,m,wa(iw)) go to 110 103 call hradf2 (m,ido,l1,ch,m,c,mdimc,wa(iw)) go to 110 104 if (ip .ne. 3) go to 106 ix2 = iw+ido if (na .ne. 0) go to 105 call hradf3 (m,ido,l1,c,mdimc,ch,m,wa(iw),wa(ix2)) go to 110 105 call hradf3 (m,ido,l1,ch,m,c,mdimc,wa(iw),wa(ix2)) go to 110 106 if (ip .ne. 5) go to 108 ix2 = iw+ido ix3 = ix2+ido ix4 = ix3+ido if (na .ne. 0) go to 107 call hradf5(m,ido,l1,c,mdimc,ch,m,wa(iw),wa(ix2),wa(ix3),wa(ix4)) go to 110 107 call hradf5(m,ido,l1,ch,m,c,mdimc,wa(iw),wa(ix2),wa(ix3),wa(ix4)) go to 110 108 if (ido .eq. 1) na = 1-na if (na .ne. 0) go to 109 call hradfg (m,ido,ip,l1,idl1,c,c,c,mdimc,ch,ch,m,wa(iw)) na = 1 go to 110 109 call hradfg (m,ido,ip,l1,idl1,ch,ch,ch,m,c,c,mdimc,wa(iw)) na = 0 110 l2 = l1 111 continue if (na .eq. 1) return do 112 j=1,n do 112 i=1,m c(i,j) = ch(i,j) 112 continue return end subroutine hradf4 (mp,ido,l1,cc,mdimcc,ch,mdimch,wa1,wa2,wa3) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension cc(mdimcc,ido,l1,4) ,ch(mdimch,ido,4,l1) , 1 wa1(ido) ,wa2(ido) ,wa3(ido) hsqt2=dsqrt(2.d0)/2.d0 do 101 k=1,l1 do 1001 m=1,mp ch(m,1,1,k) = (cc(m,1,k,2)+cc(m,1,k,4)) 1 +(cc(m,1,k,1)+cc(m,1,k,3)) ch(m,ido,4,k) = (cc(m,1,k,1)+cc(m,1,k,3)) 1 -(cc(m,1,k,2)+cc(m,1,k,4)) ch(m,ido,2,k) = cc(m,1,k,1)-cc(m,1,k,3) ch(m,1,3,k) = cc(m,1,k,4)-cc(m,1,k,2) 1001 continue 101 continue if (ido-2) 107,105,102 102 idp2 = ido+2 do 104 k=1,l1 do 103 i=3,ido,2 ic = idp2-i do 1003 m=1,mp ch(m,i-1,1,k) = ((wa1(i-2)*cc(m,i-1,k,2)+wa1(i-1)* 1 cc(m,i,k,2))+(wa3(i-2)*cc(m,i-1,k,4)+wa3(i-1)* 1 cc(m,i,k,4)))+(cc(m,i-1,k,1)+(wa2(i-2)*cc(m,i-1,k,3)+ 1 wa2(i-1)*cc(m,i,k,3))) ch(m,ic-1,4,k) = (cc(m,i-1,k,1)+(wa2(i-2)*cc(m,i-1,k,3)+ 1 wa2(i-1)*cc(m,i,k,3)))-((wa1(i-2)*cc(m,i-1,k,2)+ 1 wa1(i-1)*cc(m,i,k,2))+(wa3(i-2)*cc(m,i-1,k,4)+ 1 wa3(i-1)*cc(m,i,k,4))) ch(m,i,1,k) = ((wa1(i-2)*cc(m,i,k,2)-wa1(i-1)* 1 cc(m,i-1,k,2))+(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)* 1 cc(m,i-1,k,4)))+(cc(m,i,k,1)+(wa2(i-2)*cc(m,i,k,3)- 1 wa2(i-1)*cc(m,i-1,k,3))) ch(m,ic,4,k) = ((wa1(i-2)*cc(m,i,k,2)-wa1(i-1)* 1 cc(m,i-1,k,2))+(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)* 1 cc(m,i-1,k,4)))-(cc(m,i,k,1)+(wa2(i-2)*cc(m,i,k,3)- 1 wa2(i-1)*cc(m,i-1,k,3))) ch(m,i-1,3,k) = ((wa1(i-2)*cc(m,i,k,2)-wa1(i-1)* 1 cc(m,i-1,k,2))-(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)* 1 cc(m,i-1,k,4)))+(cc(m,i-1,k,1)-(wa2(i-2)*cc(m,i-1,k,3)+ 1 wa2(i-1)*cc(m,i,k,3))) ch(m,ic-1,2,k) = (cc(m,i-1,k,1)-(wa2(i-2)*cc(m,i-1,k,3)+ 1 wa2(i-1)*cc(m,i,k,3)))-((wa1(i-2)*cc(m,i,k,2)-wa1(i-1)* 1 cc(m,i-1,k,2))-(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)* 1 cc(m,i-1,k,4))) ch(m,i,3,k) = ((wa3(i-2)*cc(m,i-1,k,4)+wa3(i-1)* 1 cc(m,i,k,4))-(wa1(i-2)*cc(m,i-1,k,2)+wa1(i-1)* 1 cc(m,i,k,2)))+(cc(m,i,k,1)-(wa2(i-2)*cc(m,i,k,3)- 1 wa2(i-1)*cc(m,i-1,k,3))) ch(m,ic,2,k) = ((wa3(i-2)*cc(m,i-1,k,4)+wa3(i-1)* 1 cc(m,i,k,4))-(wa1(i-2)*cc(m,i-1,k,2)+wa1(i-1)* 1 cc(m,i,k,2)))-(cc(m,i,k,1)-(wa2(i-2)*cc(m,i,k,3)-wa2(i-1)* 1 cc(m,i-1,k,3))) 1003 continue 103 continue 104 continue if (mod(ido,2) .eq. 1) return 105 continue do 106 k=1,l1 do 1006 m=1,mp ch(m,ido,1,k) = (hsqt2*(cc(m,ido,k,2)-cc(m,ido,k,4)))+ 1 cc(m,ido,k,1) ch(m,ido,3,k) = cc(m,ido,k,1)-(hsqt2*(cc(m,ido,k,2)- 1 cc(m,ido,k,4))) ch(m,1,2,k) = (-hsqt2*(cc(m,ido,k,2)+cc(m,ido,k,4)))- 1 cc(m,ido,k,3) ch(m,1,4,k) = (-hsqt2*(cc(m,ido,k,2)+cc(m,ido,k,4)))+ 1 cc(m,ido,k,3) 1006 continue 106 continue 107 return end subroutine hradf2 (mp,ido,l1,cc,mdimcc,ch,mdimch,wa1) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension ch(mdimch,ido,2,l1) ,cc(mdimcc,ido,l1,2) , 1 wa1(ido) do 101 k=1,l1 do 1001 m=1,mp ch(m,1,1,k) = cc(m,1,k,1)+cc(m,1,k,2) ch(m,ido,2,k) = cc(m,1,k,1)-cc(m,1,k,2) 1001 continue 101 continue if (ido-2) 107,105,102 102 idp2 = ido+2 do 104 k=1,l1 do 103 i=3,ido,2 ic = idp2-i do 1003 m=1,mp ch(m,i,1,k) = cc(m,i,k,1)+(wa1(i-2)*cc(m,i,k,2)- 1 wa1(i-1)*cc(m,i-1,k,2)) ch(m,ic,2,k) = (wa1(i-2)*cc(m,i,k,2)-wa1(i-1)* 1 cc(m,i-1,k,2))-cc(m,i,k,1) ch(m,i-1,1,k) = cc(m,i-1,k,1)+(wa1(i-2)*cc(m,i-1,k,2)+ 1 wa1(i-1)*cc(m,i,k,2)) ch(m,ic-1,2,k) = cc(m,i-1,k,1)-(wa1(i-2)*cc(m,i-1,k,2)+ 1 wa1(i-1)*cc(m,i,k,2)) 1003 continue 103 continue 104 continue if (mod(ido,2) .eq. 1) return 105 do 106 k=1,l1 do 1006 m=1,mp ch(m,1,2,k) = -cc(m,ido,k,2) ch(m,ido,1,k) = cc(m,ido,k,1) 1006 continue 106 continue 107 return end subroutine hradf3 (mp,ido,l1,cc,mdimcc,ch,mdimch,wa1,wa2) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension ch(mdimch,ido,3,l1) ,cc(mdimcc,ido,l1,3) , 1 wa1(ido) ,wa2(ido) arg=2.d0*pimach()/3.d0 taur=dcos(arg) taui=dsin(arg) do 101 k=1,l1 do 1001 m=1,mp ch(m,1,1,k) = cc(m,1,k,1)+(cc(m,1,k,2)+cc(m,1,k,3)) ch(m,1,3,k) = taui*(cc(m,1,k,3)-cc(m,1,k,2)) ch(m,ido,2,k) = cc(m,1,k,1)+taur* 1 (cc(m,1,k,2)+cc(m,1,k,3)) 1001 continue 101 continue if (ido .eq. 1) return idp2 = ido+2 do 103 k=1,l1 do 102 i=3,ido,2 ic = idp2-i do 1002 m=1,mp ch(m,i-1,1,k) = cc(m,i-1,k,1)+((wa1(i-2)*cc(m,i-1,k,2)+ 1 wa1(i-1)*cc(m,i,k,2))+(wa2(i-2)*cc(m,i-1,k,3)+wa2(i-1)* 1 cc(m,i,k,3))) ch(m,i,1,k) = cc(m,i,k,1)+((wa1(i-2)*cc(m,i,k,2)-wa1(i-1)* 1 cc(m,i-1,k,2))+(wa2(i-2)*cc(m,i,k,3)-wa2(i-1)* 1 cc(m,i-1,k,3))) ch(m,i-1,3,k) = (cc(m,i-1,k,1)+taur*((wa1(i-2)* 1 cc(m,i-1,k,2)+wa1(i-1)*cc(m,i,k,2))+(wa2(i-2)* 1 cc(m,i-1,k,3)+wa2(i-1)*cc(m,i,k,3))))+(taui*((wa1(i-2)* 1 cc(m,i,k,2)-wa1(i-1)*cc(m,i-1,k,2))-(wa2(i-2)* 1 cc(m,i,k,3)-wa2(i-1)*cc(m,i-1,k,3)))) ch(m,ic-1,2,k) = (cc(m,i-1,k,1)+taur*((wa1(i-2)* 1 cc(m,i-1,k,2)+wa1(i-1)*cc(m,i,k,2))+(wa2(i-2)* 1 cc(m,i-1,k,3)+wa2(i-1)*cc(m,i,k,3))))-(taui*((wa1(i-2)* 1 cc(m,i,k,2)-wa1(i-1)*cc(m,i-1,k,2))-(wa2(i-2)* 1 cc(m,i,k,3)-wa2(i-1)*cc(m,i-1,k,3)))) ch(m,i,3,k) = (cc(m,i,k,1)+taur*((wa1(i-2)*cc(m,i,k,2)- 1 wa1(i-1)*cc(m,i-1,k,2))+(wa2(i-2)*cc(m,i,k,3)-wa2(i-1)* 1 cc(m,i-1,k,3))))+(taui*((wa2(i-2)*cc(m,i-1,k,3)+wa2(i-1)* 1 cc(m,i,k,3))-(wa1(i-2)*cc(m,i-1,k,2)+wa1(i-1)* 1 cc(m,i,k,2)))) ch(m,ic,2,k) = (taui*((wa2(i-2)*cc(m,i-1,k,3)+wa2(i-1)* 1 cc(m,i,k,3))-(wa1(i-2)*cc(m,i-1,k,2)+wa1(i-1)* 1 cc(m,i,k,2))))-(cc(m,i,k,1)+taur*((wa1(i-2)*cc(m,i,k,2)- 1 wa1(i-1)*cc(m,i-1,k,2))+(wa2(i-2)*cc(m,i,k,3)-wa2(i-1)* 1 cc(m,i-1,k,3)))) 1002 continue 102 continue 103 continue return end subroutine hradf5 (mp,ido,l1,cc,mdimcc,ch,mdimch, 1 wa1,wa2,wa3,wa4) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension cc(mdimcc,ido,l1,5) ,ch(mdimch,ido,5,l1) , 1 wa1(ido) ,wa2(ido) ,wa3(ido) ,wa4(ido) arg=2.d0*pimach()/5.d0 tr11=dcos(arg) ti11=dsin(arg) tr12=dcos(2.d0*arg) ti12=dsin(2.d0*arg) do 101 k=1,l1 do 1001 m=1,mp ch(m,1,1,k) = cc(m,1,k,1)+(cc(m,1,k,5)+cc(m,1,k,2))+ 1 (cc(m,1,k,4)+cc(m,1,k,3)) ch(m,ido,2,k) = cc(m,1,k,1)+tr11*(cc(m,1,k,5)+cc(m,1,k,2))+ 1 tr12*(cc(m,1,k,4)+cc(m,1,k,3)) ch(m,1,3,k) = ti11*(cc(m,1,k,5)-cc(m,1,k,2))+ti12* 1 (cc(m,1,k,4)-cc(m,1,k,3)) ch(m,ido,4,k) = cc(m,1,k,1)+tr12*(cc(m,1,k,5)+cc(m,1,k,2))+ 1 tr11*(cc(m,1,k,4)+cc(m,1,k,3)) ch(m,1,5,k) = ti12*(cc(m,1,k,5)-cc(m,1,k,2))-ti11* 1 (cc(m,1,k,4)-cc(m,1,k,3)) 1001 continue 101 continue if (ido .eq. 1) return idp2 = ido+2 do 103 k=1,l1 do 102 i=3,ido,2 ic = idp2-i do 1002 m=1,mp ch(m,i-1,1,k) = cc(m,i-1,k,1)+((wa1(i-2)*cc(m,i-1,k,2)+ 1 wa1(i-1)*cc(m,i,k,2))+(wa4(i-2)*cc(m,i-1,k,5)+wa4(i-1)* 1 cc(m,i,k,5)))+((wa2(i-2)*cc(m,i-1,k,3)+wa2(i-1)* 1 cc(m,i,k,3))+(wa3(i-2)*cc(m,i-1,k,4)+wa3(i-1)*cc(m,i,k,4))) ch(m,i,1,k) = cc(m,i,k,1)+((wa1(i-2)*cc(m,i,k,2)-wa1(i-1)* 1 cc(m,i-1,k,2))+(wa4(i-2)*cc(m,i,k,5)-wa4(i-1)* 1 cc(m,i-1,k,5)))+((wa2(i-2)*cc(m,i,k,3)-wa2(i-1)* 1 cc(m,i-1,k,3))+(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)* 1 cc(m,i-1,k,4))) ch(m,i-1,3,k) = cc(m,i-1,k,1)+tr11* 1 ( wa1(i-2)*cc(m,i-1,k,2)+wa1(i-1)*cc(m,i,k,2) 1 +wa4(i-2)*cc(m,i-1,k,5)+wa4(i-1)*cc(m,i,k,5))+tr12* 1 ( wa2(i-2)*cc(m,i-1,k,3)+wa2(i-1)*cc(m,i,k,3) 1 +wa3(i-2)*cc(m,i-1,k,4)+wa3(i-1)*cc(m,i,k,4))+ti11* 1 ( wa1(i-2)*cc(m,i,k,2)-wa1(i-1)*cc(m,i-1,k,2) 1 -(wa4(i-2)*cc(m,i,k,5)-wa4(i-1)*cc(m,i-1,k,5)))+ti12* 1 ( wa2(i-2)*cc(m,i,k,3)-wa2(i-1)*cc(m,i-1,k,3) 1 -(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)*cc(m,i-1,k,4))) ch(m,ic-1,2,k) = cc(m,i-1,k,1)+tr11* 1 ( wa1(i-2)*cc(m,i-1,k,2)+wa1(i-1)*cc(m,i,k,2) 1 +wa4(i-2)*cc(m,i-1,k,5)+wa4(i-1)*cc(m,i,k,5))+tr12* 1 ( wa2(i-2)*cc(m,i-1,k,3)+wa2(i-1)*cc(m,i,k,3) 1 +wa3(i-2)*cc(m,i-1,k,4)+wa3(i-1)*cc(m,i,k,4))-(ti11* 1 ( wa1(i-2)*cc(m,i,k,2)-wa1(i-1)*cc(m,i-1,k,2) 1 -(wa4(i-2)*cc(m,i,k,5)-wa4(i-1)*cc(m,i-1,k,5)))+ti12* 1 ( wa2(i-2)*cc(m,i,k,3)-wa2(i-1)*cc(m,i-1,k,3) 1 -(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)*cc(m,i-1,k,4)))) ch(m,i,3,k) = (cc(m,i,k,1)+tr11*((wa1(i-2)*cc(m,i,k,2)- 1 wa1(i-1)*cc(m,i-1,k,2))+(wa4(i-2)*cc(m,i,k,5)-wa4(i-1)* 1 cc(m,i-1,k,5)))+tr12*((wa2(i-2)*cc(m,i,k,3)-wa2(i-1)* 1 cc(m,i-1,k,3))+(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)* 1 cc(m,i-1,k,4))))+(ti11*((wa4(i-2)*cc(m,i-1,k,5)+ 1 wa4(i-1)*cc(m,i,k,5))-(wa1(i-2)*cc(m,i-1,k,2)+wa1(i-1)* 1 cc(m,i,k,2)))+ti12*((wa3(i-2)*cc(m,i-1,k,4)+wa3(i-1)* 1 cc(m,i,k,4))-(wa2(i-2)*cc(m,i-1,k,3)+wa2(i-1)* 1 cc(m,i,k,3)))) ch(m,ic,2,k) = (ti11*((wa4(i-2)*cc(m,i-1,k,5)+wa4(i-1)* 1 cc(m,i,k,5))-(wa1(i-2)*cc(m,i-1,k,2)+wa1(i-1)* 1 cc(m,i,k,2)))+ti12*((wa3(i-2)*cc(m,i-1,k,4)+wa3(i-1)* 1 cc(m,i,k,4))-(wa2(i-2)*cc(m,i-1,k,3)+wa2(i-1)* 1 cc(m,i,k,3))))-(cc(m,i,k,1)+tr11*((wa1(i-2)*cc(m,i,k,2)- 1 wa1(i-1)*cc(m,i-1,k,2))+(wa4(i-2)*cc(m,i,k,5)-wa4(i-1)* 1 cc(m,i-1,k,5)))+tr12*((wa2(i-2)*cc(m,i,k,3)-wa2(i-1)* 1 cc(m,i-1,k,3))+(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)* 1 cc(m,i-1,k,4)))) ch(m,i-1,5,k) = (cc(m,i-1,k,1)+tr12*((wa1(i-2)* 1 cc(m,i-1,k,2)+wa1(i-1)*cc(m,i,k,2))+(wa4(i-2)* 1 cc(m,i-1,k,5)+wa4(i-1)*cc(m,i,k,5)))+tr11*((wa2(i-2)* 1 cc(m,i-1,k,3)+wa2(i-1)*cc(m,i,k,3))+(wa3(i-2)* 1 cc(m,i-1,k,4)+wa3(i-1)*cc(m,i,k,4))))+(ti12*((wa1(i-2)* 1 cc(m,i,k,2)-wa1(i-1)*cc(m,i-1,k,2))-(wa4(i-2)*cc(m,i,k,5)- 1 wa4(i-1)*cc(m,i-1,k,5)))-ti11*((wa2(i-2)*cc(m,i,k,3)- 1 wa2(i-1)*cc(m,i-1,k,3))-(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)* 1 cc(m,i-1,k,4)))) ch(m,ic-1,4,k) = (cc(m,i-1,k,1)+tr12*((wa1(i-2)* 1 cc(m,i-1,k,2)+wa1(i-1)*cc(m,i,k,2))+(wa4(i-2)* 1 cc(m,i-1,k,5)+wa4(i-1)*cc(m,i,k,5)))+tr11*((wa2(i-2)* 1 cc(m,i-1,k,3)+wa2(i-1)*cc(m,i,k,3))+(wa3(i-2)* 1 cc(m,i-1,k,4)+wa3(i-1)*cc(m,i,k,4))))-(ti12*((wa1(i-2)* 1 cc(m,i,k,2)-wa1(i-1)*cc(m,i-1,k,2))-(wa4(i-2)*cc(m,i,k,5)- 1 wa4(i-1)*cc(m,i-1,k,5)))-ti11*((wa2(i-2)*cc(m,i,k,3)- 1 wa2(i-1)*cc(m,i-1,k,3))-(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)* 1 cc(m,i-1,k,4)))) ch(m,i,5,k) = (cc(m,i,k,1)+tr12*((wa1(i-2)*cc(m,i,k,2)- 1 wa1(i-1)*cc(m,i-1,k,2))+(wa4(i-2)*cc(m,i,k,5)-wa4(i-1)* 1 cc(m,i-1,k,5)))+tr11*((wa2(i-2)*cc(m,i,k,3)-wa2(i-1)* 1 cc(m,i-1,k,3))+(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)* 1 cc(m,i-1,k,4))))+(ti12*((wa4(i-2)*cc(m,i-1,k,5)+ 1 wa4(i-1)*cc(m,i,k,5))-(wa1(i-2)*cc(m,i-1,k,2)+wa1(i-1)* 1 cc(m,i,k,2)))-ti11*((wa3(i-2)*cc(m,i-1,k,4)+wa3(i-1)* 1 cc(m,i,k,4))-(wa2(i-2)*cc(m,i-1,k,3)+wa2(i-1)* 1 cc(m,i,k,3)))) ch(m,ic,4,k) = (ti12*((wa4(i-2)*cc(m,i-1,k,5)+wa4(i-1)* 1 cc(m,i,k,5))-(wa1(i-2)*cc(m,i-1,k,2)+wa1(i-1)* 1 cc(m,i,k,2)))-ti11*((wa3(i-2)*cc(m,i-1,k,4)+wa3(i-1)* 1 cc(m,i,k,4))-(wa2(i-2)*cc(m,i-1,k,3)+wa2(i-1)* 1 cc(m,i,k,3))))-(cc(m,i,k,1)+tr12*((wa1(i-2)*cc(m,i,k,2)- 1 wa1(i-1)*cc(m,i-1,k,2))+(wa4(i-2)*cc(m,i,k,5)-wa4(i-1)* 1 cc(m,i-1,k,5)))+tr11*((wa2(i-2)*cc(m,i,k,3)-wa2(i-1)* 1 cc(m,i-1,k,3))+(wa3(i-2)*cc(m,i,k,4)-wa3(i-1)* 1 cc(m,i-1,k,4)))) 1002 continue 102 continue 103 continue return end subroutine hradfg (mp,ido,ip,l1,idl1,cc,c1,c2,mdimcc, 1 ch,ch2,mdimch,wa) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension ch(mdimch,ido,l1,ip) ,cc(mdimcc,ido,ip,l1) , 1 c1(mdimcc,ido,l1,ip) ,c2(mdimcc,idl1,ip), 2 ch2(mdimch,idl1,ip) ,wa(ido) tpi=2.d0*pimach() arg = tpi/dfloat(ip) dcp = dcos(arg) dsp = dsin(arg) ipph = (ip+1)/2 ipp2 = ip+2 idp2 = ido+2 nbd = (ido-1)/2 if (ido .eq. 1) go to 119 do 101 ik=1,idl1 do 1001 m=1,mp ch2(m,ik,1) = c2(m,ik,1) 1001 continue 101 continue do 103 j=2,ip do 102 k=1,l1 do 1002 m=1,mp ch(m,1,k,j) = c1(m,1,k,j) 1002 continue 102 continue 103 continue if (nbd .gt. l1) go to 107 is = -ido do 106 j=2,ip is = is+ido idij = is do 105 i=3,ido,2 idij = idij+2 do 104 k=1,l1 do 1004 m=1,mp ch(m,i-1,k,j) = wa(idij-1)*c1(m,i-1,k,j)+wa(idij) 1 *c1(m,i,k,j) ch(m,i,k,j) = wa(idij-1)*c1(m,i,k,j)-wa(idij) 1 *c1(m,i-1,k,j) 1004 continue 104 continue 105 continue 106 continue go to 111 107 is = -ido do 110 j=2,ip is = is+ido do 109 k=1,l1 idij = is do 108 i=3,ido,2 idij = idij+2 do 1008 m=1,mp ch(m,i-1,k,j) = wa(idij-1)*c1(m,i-1,k,j)+wa(idij) 1 *c1(m,i,k,j) ch(m,i,k,j) = wa(idij-1)*c1(m,i,k,j)-wa(idij) 1 *c1(m,i-1,k,j) 1008 continue 108 continue 109 continue 110 continue 111 if (nbd .lt. l1) go to 115 do 114 j=2,ipph jc = ipp2-j do 113 k=1,l1 do 112 i=3,ido,2 do 1012 m=1,mp c1(m,i-1,k,j) = ch(m,i-1,k,j)+ch(m,i-1,k,jc) c1(m,i-1,k,jc) = ch(m,i,k,j)-ch(m,i,k,jc) c1(m,i,k,j) = ch(m,i,k,j)+ch(m,i,k,jc) c1(m,i,k,jc) = ch(m,i-1,k,jc)-ch(m,i-1,k,j) 1012 continue 112 continue 113 continue 114 continue go to 121 115 do 118 j=2,ipph jc = ipp2-j do 117 i=3,ido,2 do 116 k=1,l1 do 1016 m=1,mp c1(m,i-1,k,j) = ch(m,i-1,k,j)+ch(m,i-1,k,jc) c1(m,i-1,k,jc) = ch(m,i,k,j)-ch(m,i,k,jc) c1(m,i,k,j) = ch(m,i,k,j)+ch(m,i,k,jc) c1(m,i,k,jc) = ch(m,i-1,k,jc)-ch(m,i-1,k,j) 1016 continue 116 continue 117 continue 118 continue go to 121 119 do 120 ik=1,idl1 do 1020 m=1,mp c2(m,ik,1) = ch2(m,ik,1) 1020 continue 120 continue 121 do 123 j=2,ipph jc = ipp2-j do 122 k=1,l1 do 1022 m=1,mp c1(m,1,k,j) = ch(m,1,k,j)+ch(m,1,k,jc) c1(m,1,k,jc) = ch(m,1,k,jc)-ch(m,1,k,j) 1022 continue 122 continue 123 continue c ar1 = 1.d0 ai1 = 0.d0 do 127 l=2,ipph lc = ipp2-l ar1h = dcp*ar1-dsp*ai1 ai1 = dcp*ai1+dsp*ar1 ar1 = ar1h do 124 ik=1,idl1 do 1024 m=1,mp ch2(m,ik,l) = c2(m,ik,1)+ar1*c2(m,ik,2) ch2(m,ik,lc) = ai1*c2(m,ik,ip) 1024 continue 124 continue dc2 = ar1 ds2 = ai1 ar2 = ar1 ai2 = ai1 do 126 j=3,ipph jc = ipp2-j ar2h = dc2*ar2-ds2*ai2 ai2 = dc2*ai2+ds2*ar2 ar2 = ar2h do 125 ik=1,idl1 do 1025 m=1,mp ch2(m,ik,l) = ch2(m,ik,l)+ar2*c2(m,ik,j) ch2(m,ik,lc) = ch2(m,ik,lc)+ai2*c2(m,ik,jc) 1025 continue 125 continue 126 continue 127 continue do 129 j=2,ipph do 128 ik=1,idl1 do 1028 m=1,mp ch2(m,ik,1) = ch2(m,ik,1)+c2(m,ik,j) 1028 continue 128 continue 129 continue c if (ido .lt. l1) go to 132 do 131 k=1,l1 do 130 i=1,ido do 1030 m=1,mp cc(m,i,1,k) = ch(m,i,k,1) 1030 continue 130 continue 131 continue go to 135 132 do 134 i=1,ido do 133 k=1,l1 do 1033 m=1,mp cc(m,i,1,k) = ch(m,i,k,1) 1033 continue 133 continue 134 continue 135 do 137 j=2,ipph jc = ipp2-j j2 = j+j do 136 k=1,l1 do 1036 m=1,mp cc(m,ido,j2-2,k) = ch(m,1,k,j) cc(m,1,j2-1,k) = ch(m,1,k,jc) 1036 continue 136 continue 137 continue if (ido .eq. 1) return if (nbd .lt. l1) go to 141 do 140 j=2,ipph jc = ipp2-j j2 = j+j do 139 k=1,l1 do 138 i=3,ido,2 ic = idp2-i do 1038 m=1,mp cc(m,i-1,j2-1,k) = ch(m,i-1,k,j)+ch(m,i-1,k,jc) cc(m,ic-1,j2-2,k) = ch(m,i-1,k,j)-ch(m,i-1,k,jc) cc(m,i,j2-1,k) = ch(m,i,k,j)+ch(m,i,k,jc) cc(m,ic,j2-2,k) = ch(m,i,k,jc)-ch(m,i,k,j) 1038 continue 138 continue 139 continue 140 continue return 141 do 144 j=2,ipph jc = ipp2-j j2 = j+j do 143 i=3,ido,2 ic = idp2-i do 142 k=1,l1 do 1042 m=1,mp cc(m,i-1,j2-1,k) = ch(m,i-1,k,j)+ch(m,i-1,k,jc) cc(m,ic-1,j2-2,k) = ch(m,i-1,k,j)-ch(m,i-1,k,jc) cc(m,i,j2-1,k) = ch(m,i,k,j)+ch(m,i,k,jc) cc(m,ic,j2-2,k) = ch(m,i,k,jc)-ch(m,i,k,j) 1042 continue 142 continue 143 continue 144 continue return end double precision function pimach() implicit double precision (a-h,o-z) pimach=3.14159265358979323846264338328d0 return end subroutine hrfftb(m,n,r,mdimr,whrfft,work) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension r(mdimr,n) ,work(1) ,whrfft(n+15) common /hrf/ tfft if (n .eq. 1) return c tstart = second(dum) call hrftb1 (m,n,r,mdimr,work,whrfft,whrfft(n+1)) c tfft = tfft+second(dum)-tstart return end subroutine hrftb1 (m,n,c,mdimc,ch,wa,fac) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension ch(m,n), c(mdimc,n), wa(n) ,fac(15) nf = fac(2) na = 0 l1 = 1 iw = 1 do 116 k1=1,nf ip = fac(k1+2) l2 = ip*l1 ido = n/l2 idl1 = ido*l1 if (ip .ne. 4) go to 103 ix2 = iw+ido ix3 = ix2+ido if (na .ne. 0) go to 101 call hradb4 (m,ido,l1,c,mdimc,ch,m,wa(iw),wa(ix2),wa(ix3)) go to 102 101 call hradb4 (m,ido,l1,ch,m,c,mdimc,wa(iw),wa(ix2),wa(ix3)) 102 na = 1-na go to 115 103 if (ip .ne. 2) go to 106 if (na .ne. 0) go to 104 call hradb2 (m,ido,l1,c,mdimc,ch,m,wa(iw)) go to 105 104 call hradb2 (m,ido,l1,ch,m,c,mdimc,wa(iw)) 105 na = 1-na go to 115 106 if (ip .ne. 3) go to 109 ix2 = iw+ido if (na .ne. 0) go to 107 call hradb3 (m,ido,l1,c,mdimc,ch,m,wa(iw),wa(ix2)) go to 108 107 call hradb3 (m,ido,l1,ch,m,c,mdimc,wa(iw),wa(ix2)) 108 na = 1-na go to 115 109 if (ip .ne. 5) go to 112 ix2 = iw+ido ix3 = ix2+ido ix4 = ix3+ido if (na .ne. 0) go to 110 call hradb5 (m,ido,l1,c,mdimc,ch,m,wa(iw),wa(ix2),wa(ix3),wa(ix4)) go to 111 110 call hradb5 (m,ido,l1,ch,m,c,mdimc,wa(iw),wa(ix2),wa(ix3),wa(ix4)) 111 na = 1-na go to 115 112 if (na .ne. 0) go to 113 call hradbg (m,ido,ip,l1,idl1,c,c,c,mdimc,ch,ch,m,wa(iw)) go to 114 113 call hradbg (m,ido,ip,l1,idl1,ch,ch,ch,m,c,c,mdimc,wa(iw)) 114 if (ido .eq. 1) na = 1-na 115 l1 = l2 iw = iw+(ip-1)*ido 116 continue if (na .eq. 0) return do 117 j=1,n do 117 i=1,m c(i,j) = ch(i,j) 117 continue return end subroutine hradbg (mp,ido,ip,l1,idl1,cc,c1,c2,mdimcc, 1 ch,ch2,mdimch,wa) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension ch(mdimch,ido,l1,ip) ,cc(mdimcc,ido,ip,l1) , 1 c1(mdimcc,ido,l1,ip) ,c2(mdimcc,idl1,ip), 2 ch2(mdimch,idl1,ip) ,wa(ido) tpi=2.d0*pimach() arg = tpi/dfloat(ip) dcp = dcos(arg) dsp = dsin(arg) idp2 = ido+2 nbd = (ido-1)/2 ipp2 = ip+2 ipph = (ip+1)/2 if (ido .lt. l1) go to 103 do 102 k=1,l1 do 101 i=1,ido do 1001 m=1,mp ch(m,i,k,1) = cc(m,i,1,k) 1001 continue 101 continue 102 continue go to 106 103 do 105 i=1,ido do 104 k=1,l1 do 1004 m=1,mp ch(m,i,k,1) = cc(m,i,1,k) 1004 continue 104 continue 105 continue 106 do 108 j=2,ipph jc = ipp2-j j2 = j+j do 107 k=1,l1 do 1007 m=1,mp ch(m,1,k,j) = cc(m,ido,j2-2,k)+cc(m,ido,j2-2,k) ch(m,1,k,jc) = cc(m,1,j2-1,k)+cc(m,1,j2-1,k) 1007 continue 107 continue 108 continue if (ido .eq. 1) go to 116 if (nbd .lt. l1) go to 112 do 111 j=2,ipph jc = ipp2-j do 110 k=1,l1 do 109 i=3,ido,2 ic = idp2-i do 1009 m=1,mp ch(m,i-1,k,j) = cc(m,i-1,2*j-1,k)+cc(m,ic-1,2*j-2,k) ch(m,i-1,k,jc) = cc(m,i-1,2*j-1,k)-cc(m,ic-1,2*j-2,k) ch(m,i,k,j) = cc(m,i,2*j-1,k)-cc(m,ic,2*j-2,k) ch(m,i,k,jc) = cc(m,i,2*j-1,k)+cc(m,ic,2*j-2,k) 1009 continue 109 continue 110 continue 111 continue go to 116 112 do 115 j=2,ipph jc = ipp2-j do 114 i=3,ido,2 ic = idp2-i do 113 k=1,l1 do 1013 m=1,mp ch(m,i-1,k,j) = cc(m,i-1,2*j-1,k)+cc(m,ic-1,2*j-2,k) ch(m,i-1,k,jc) = cc(m,i-1,2*j-1,k)-cc(m,ic-1,2*j-2,k) ch(m,i,k,j) = cc(m,i,2*j-1,k)-cc(m,ic,2*j-2,k) ch(m,i,k,jc) = cc(m,i,2*j-1,k)+cc(m,ic,2*j-2,k) 1013 continue 113 continue 114 continue 115 continue 116 ar1 = 1.d0 ai1 = 0.d0 do 120 l=2,ipph lc = ipp2-l ar1h = dcp*ar1-dsp*ai1 ai1 = dcp*ai1+dsp*ar1 ar1 = ar1h do 117 ik=1,idl1 do 1017 m=1,mp c2(m,ik,l) = ch2(m,ik,1)+ar1*ch2(m,ik,2) c2(m,ik,lc) = ai1*ch2(m,ik,ip) 1017 continue 117 continue dc2 = ar1 ds2 = ai1 ar2 = ar1 ai2 = ai1 do 119 j=3,ipph jc = ipp2-j ar2h = dc2*ar2-ds2*ai2 ai2 = dc2*ai2+ds2*ar2 ar2 = ar2h do 118 ik=1,idl1 do 1018 m=1,mp c2(m,ik,l) = c2(m,ik,l)+ar2*ch2(m,ik,j) c2(m,ik,lc) = c2(m,ik,lc)+ai2*ch2(m,ik,jc) 1018 continue 118 continue 119 continue 120 continue do 122 j=2,ipph do 121 ik=1,idl1 do 1021 m=1,mp ch2(m,ik,1) = ch2(m,ik,1)+ch2(m,ik,j) 1021 continue 121 continue 122 continue do 124 j=2,ipph jc = ipp2-j do 123 k=1,l1 do 1023 m=1,mp ch(m,1,k,j) = c1(m,1,k,j)-c1(m,1,k,jc) ch(m,1,k,jc) = c1(m,1,k,j)+c1(m,1,k,jc) 1023 continue 123 continue 124 continue if (ido .eq. 1) go to 132 if (nbd .lt. l1) go to 128 do 127 j=2,ipph jc = ipp2-j do 126 k=1,l1 do 125 i=3,ido,2 do 1025 m=1,mp ch(m,i-1,k,j) = c1(m,i-1,k,j)-c1(m,i,k,jc) ch(m,i-1,k,jc) = c1(m,i-1,k,j)+c1(m,i,k,jc) ch(m,i,k,j) = c1(m,i,k,j)+c1(m,i-1,k,jc) ch(m,i,k,jc) = c1(m,i,k,j)-c1(m,i-1,k,jc) 1025 continue 125 continue 126 continue 127 continue go to 132 128 do 131 j=2,ipph jc = ipp2-j do 130 i=3,ido,2 do 129 k=1,l1 do 1029 m=1,mp ch(m,i-1,k,j) = c1(m,i-1,k,j)-c1(m,i,k,jc) ch(m,i-1,k,jc) = c1(m,i-1,k,j)+c1(m,i,k,jc) ch(m,i,k,j) = c1(m,i,k,j)+c1(m,i-1,k,jc) ch(m,i,k,jc) = c1(m,i,k,j)-c1(m,i-1,k,jc) 1029 continue 129 continue 130 continue 131 continue 132 continue if (ido .eq. 1) return do 133 ik=1,idl1 do 1033 m=1,mp c2(m,ik,1) = ch2(m,ik,1) 1033 continue 133 continue do 135 j=2,ip do 134 k=1,l1 do 1034 m=1,mp c1(m,1,k,j) = ch(m,1,k,j) 1034 continue 134 continue 135 continue if (nbd .gt. l1) go to 139 is = -ido do 138 j=2,ip is = is+ido idij = is do 137 i=3,ido,2 idij = idij+2 do 136 k=1,l1 do 1036 m=1,mp c1(m,i-1,k,j) = wa(idij-1)*ch(m,i-1,k,j)-wa(idij)* 1 ch(m,i,k,j) c1(m,i,k,j) = wa(idij-1)*ch(m,i,k,j)+wa(idij)* 1 ch(m,i-1,k,j) 1036 continue 136 continue 137 continue 138 continue go to 143 139 is = -ido do 142 j=2,ip is = is+ido do 141 k=1,l1 idij = is do 140 i=3,ido,2 idij = idij+2 do 1040 m=1,mp c1(m,i-1,k,j) = wa(idij-1)*ch(m,i-1,k,j)-wa(idij)* 1 ch(m,i,k,j) c1(m,i,k,j) = wa(idij-1)*ch(m,i,k,j)+wa(idij)* 1 ch(m,i-1,k,j) 1040 continue 140 continue 141 continue 142 continue 143 return end subroutine hradb4 (mp,ido,l1,cc,mdimcc,ch,mdimch,wa1,wa2,wa3) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension cc(mdimcc,ido,4,l1) ,ch(mdimch,ido,l1,4) , 1 wa1(ido) ,wa2(ido) ,wa3(ido) sqrt2=dsqrt(2.d0) do 101 k=1,l1 do 1001 m=1,mp ch(m,1,k,3) = (cc(m,1,1,k)+cc(m,ido,4,k)) 1 -(cc(m,ido,2,k)+cc(m,ido,2,k)) ch(m,1,k,1) = (cc(m,1,1,k)+cc(m,ido,4,k)) 1 +(cc(m,ido,2,k)+cc(m,ido,2,k)) ch(m,1,k,4) = (cc(m,1,1,k)-cc(m,ido,4,k)) 1 +(cc(m,1,3,k)+cc(m,1,3,k)) ch(m,1,k,2) = (cc(m,1,1,k)-cc(m,ido,4,k)) 1 -(cc(m,1,3,k)+cc(m,1,3,k)) 1001 continue 101 continue if (ido-2) 107,105,102 102 idp2 = ido+2 do 104 k=1,l1 do 103 i=3,ido,2 ic = idp2-i do 1002 m=1,mp ch(m,i-1,k,1) = (cc(m,i-1,1,k)+cc(m,ic-1,4,k)) 1 +(cc(m,i-1,3,k)+cc(m,ic-1,2,k)) ch(m,i,k,1) = (cc(m,i,1,k)-cc(m,ic,4,k)) 1 +(cc(m,i,3,k)-cc(m,ic,2,k)) ch(m,i-1,k,2)=wa1(i-2)*((cc(m,i-1,1,k)-cc(m,ic-1,4,k)) 1 -(cc(m,i,3,k)+cc(m,ic,2,k)))-wa1(i-1) 1 *((cc(m,i,1,k)+cc(m,ic,4,k))+(cc(m,i-1,3,k)-cc(m,ic-1,2,k))) ch(m,i,k,2)=wa1(i-2)*((cc(m,i,1,k)+cc(m,ic,4,k)) 1 +(cc(m,i-1,3,k)-cc(m,ic-1,2,k)))+wa1(i-1) 1 *((cc(m,i-1,1,k)-cc(m,ic-1,4,k))-(cc(m,i,3,k)+cc(m,ic,2,k))) ch(m,i-1,k,3)=wa2(i-2)*((cc(m,i-1,1,k)+cc(m,ic-1,4,k)) 1 -(cc(m,i-1,3,k)+cc(m,ic-1,2,k)))-wa2(i-1) 1 *((cc(m,i,1,k)-cc(m,ic,4,k))-(cc(m,i,3,k)-cc(m,ic,2,k))) ch(m,i,k,3)=wa2(i-2)*((cc(m,i,1,k)-cc(m,ic,4,k)) 1 -(cc(m,i,3,k)-cc(m,ic,2,k)))+wa2(i-1) 1 *((cc(m,i-1,1,k)+cc(m,ic-1,4,k))-(cc(m,i-1,3,k) 1 +cc(m,ic-1,2,k))) ch(m,i-1,k,4)=wa3(i-2)*((cc(m,i-1,1,k)-cc(m,ic-1,4,k)) 1 +(cc(m,i,3,k)+cc(m,ic,2,k)))-wa3(i-1) 1 *((cc(m,i,1,k)+cc(m,ic,4,k))-(cc(m,i-1,3,k)-cc(m,ic-1,2,k))) ch(m,i,k,4)=wa3(i-2)*((cc(m,i,1,k)+cc(m,ic,4,k)) 1 -(cc(m,i-1,3,k)-cc(m,ic-1,2,k)))+wa3(i-1) 1 *((cc(m,i-1,1,k)-cc(m,ic-1,4,k))+(cc(m,i,3,k)+cc(m,ic,2,k))) 1002 continue 103 continue 104 continue if (mod(ido,2) .eq. 1) return 105 continue do 106 k=1,l1 do 1003 m=1,mp ch(m,ido,k,1) = (cc(m,ido,1,k)+cc(m,ido,3,k)) 1 +(cc(m,ido,1,k)+cc(m,ido,3,k)) ch(m,ido,k,2) = sqrt2*((cc(m,ido,1,k)-cc(m,ido,3,k)) 1 -(cc(m,1,2,k)+cc(m,1,4,k))) ch(m,ido,k,3) = (cc(m,1,4,k)-cc(m,1,2,k)) 1 +(cc(m,1,4,k)-cc(m,1,2,k)) ch(m,ido,k,4) = -sqrt2*((cc(m,ido,1,k)-cc(m,ido,3,k)) 1 +(cc(m,1,2,k)+cc(m,1,4,k))) 1003 continue 106 continue 107 return end subroutine hradb2 (mp,ido,l1,cc,mdimcc,ch,mdimch,wa1) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension cc(mdimcc,ido,2,l1) ,ch(mdimch,ido,l1,2), 1 wa1(ido) do 101 k=1,l1 do 1001 m=1,mp ch(m,1,k,1) = cc(m,1,1,k)+cc(m,ido,2,k) ch(m,1,k,2) = cc(m,1,1,k)-cc(m,ido,2,k) 1001 continue 101 continue if (ido-2) 107,105,102 102 idp2 = ido+2 do 104 k=1,l1 do 103 i=3,ido,2 ic = idp2-i do 1002 m=1,mp ch(m,i-1,k,1) = cc(m,i-1,1,k)+cc(m,ic-1,2,k) ch(m,i,k,1) = cc(m,i,1,k)-cc(m,ic,2,k) ch(m,i-1,k,2) = wa1(i-2)*(cc(m,i-1,1,k)-cc(m,ic-1,2,k)) 1 -wa1(i-1)*(cc(m,i,1,k)+cc(m,ic,2,k)) ch(m,i,k,2) = wa1(i-2)*(cc(m,i,1,k)+cc(m,ic,2,k))+wa1(i-1) 1 *(cc(m,i-1,1,k)-cc(m,ic-1,2,k)) 1002 continue 103 continue 104 continue if (mod(ido,2) .eq. 1) return 105 do 106 k=1,l1 do 1003 m=1,mp ch(m,ido,k,1) = cc(m,ido,1,k)+cc(m,ido,1,k) ch(m,ido,k,2) = -(cc(m,1,2,k)+cc(m,1,2,k)) 1003 continue 106 continue 107 return end subroutine hradb3 (mp,ido,l1,cc,mdimcc,ch,mdimch,wa1,wa2) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension cc(mdimcc,ido,3,l1) ,ch(mdimch,ido,l1,3), 1 wa1(ido) ,wa2(ido) arg=2.d0*pimach()/3.d0 taur=dcos(arg) taui=dsin(arg) do 101 k=1,l1 do 1001 m=1,mp ch(m,1,k,1) = cc(m,1,1,k)+2.d0*cc(m,ido,2,k) ch(m,1,k,2) = cc(m,1,1,k)+(2.d0*taur)*cc(m,ido,2,k) 1 -(2.d0*taui)*cc(m,1,3,k) ch(m,1,k,3) = cc(m,1,1,k)+(2.d0*taur)*cc(m,ido,2,k) 1 +2.d0*taui*cc(m,1,3,k) 1001 continue 101 continue if (ido .eq. 1) return idp2 = ido+2 do 103 k=1,l1 do 102 i=3,ido,2 ic = idp2-i do 1002 m=1,mp ch(m,i-1,k,1) = cc(m,i-1,1,k)+(cc(m,i-1,3,k)+cc(m,ic-1,2,k)) ch(m,i,k,1) = cc(m,i,1,k)+(cc(m,i,3,k)-cc(m,ic,2,k)) ch(m,i-1,k,2) = wa1(i-2)* 1 ((cc(m,i-1,1,k)+taur*(cc(m,i-1,3,k)+cc(m,ic-1,2,k)))- * (taui*(cc(m,i,3,k)+cc(m,ic,2,k)))) 2 -wa1(i-1)* 3 ((cc(m,i,1,k)+taur*(cc(m,i,3,k)-cc(m,ic,2,k)))+ * (taui*(cc(m,i-1,3,k)-cc(m,ic-1,2,k)))) ch(m,i,k,2) = wa1(i-2)* 4 ((cc(m,i,1,k)+taur*(cc(m,i,3,k)-cc(m,ic,2,k)))+ 8 (taui*(cc(m,i-1,3,k)-cc(m,ic-1,2,k)))) 5 +wa1(i-1)* 6 ((cc(m,i-1,1,k)+taur*(cc(m,i-1,3,k)+cc(m,ic-1,2,k)))- 8 (taui*(cc(m,i,3,k)+cc(m,ic,2,k)))) ch(m,i-1,k,3) = wa2(i-2)* 7 ((cc(m,i-1,1,k)+taur*(cc(m,i-1,3,k)+cc(m,ic-1,2,k)))+ 8 (taui*(cc(m,i,3,k)+cc(m,ic,2,k)))) 8 -wa2(i-1)* 9 ((cc(m,i,1,k)+taur*(cc(m,i,3,k)-cc(m,ic,2,k)))- 8 (taui*(cc(m,i-1,3,k)-cc(m,ic-1,2,k)))) ch(m,i,k,3) = wa2(i-2)* 1 ((cc(m,i,1,k)+taur*(cc(m,i,3,k)-cc(m,ic,2,k)))- 8 (taui*(cc(m,i-1,3,k)-cc(m,ic-1,2,k)))) 2 +wa2(i-1)* 3 ((cc(m,i-1,1,k)+taur*(cc(m,i-1,3,k)+cc(m,ic-1,2,k)))+ 8 (taui*(cc(m,i,3,k)+cc(m,ic,2,k)))) 1002 continue 102 continue 103 continue return end subroutine hradb5 (mp,ido,l1,cc,mdimcc,ch,mdimch, 1 wa1,wa2,wa3,wa4) implicit double precision (a-h,o-z) c c a multiple fft package for spherepack c dimension cc(mdimcc,ido,5,l1) ,ch(mdimch,ido,l1,5), 1 wa1(ido) ,wa2(ido) ,wa3(ido) ,wa4(ido) arg=2.d0*pimach()/5.d0 tr11=dcos(arg) ti11=dsin(arg) tr12=dcos(2.d0*arg) ti12=dsin(2.d0*arg) do 101 k=1,l1 do 1001 m=1,mp ch(m,1,k,1) = cc(m,1,1,k)+2.d0*cc(m,ido,2,k)+2.d0*cc(m,ido,4,k) ch(m,1,k,2) = (cc(m,1,1,k)+tr11*2.d0*cc(m,ido,2,k) 1 +tr12*2.d0*cc(m,ido,4,k))-(ti11*2.d0*cc(m,1,3,k) 1 +ti12*2.d0*cc(m,1,5,k)) ch(m,1,k,3) = (cc(m,1,1,k)+tr12*2.d0*cc(m,ido,2,k) 1 +tr11*2.d0*cc(m,ido,4,k))-(ti12*2.d0*cc(m,1,3,k) 1 -ti11*2.d0*cc(m,1,5,k)) ch(m,1,k,4) = (cc(m,1,1,k)+tr12*2.d0*cc(m,ido,2,k) 1 +tr11*2.d0*cc(m,ido,4,k))+(ti12*2.d0*cc(m,1,3,k) 1 -ti11*2.d0*cc(m,1,5,k)) ch(m,1,k,5) = (cc(m,1,1,k)+tr11*2.d0*cc(m,ido,2,k) 1 +tr12*2.d0*cc(m,ido,4,k))+(ti11*2.d0*cc(m,1,3,k) 1 +ti12*2.d0*cc(m,1,5,k)) 1001 continue 101 continue if (ido .eq. 1) return idp2 = ido+2 do 103 k=1,l1 do 102 i=3,ido,2 ic = idp2-i do 1002 m=1,mp ch(m,i-1,k,1) = cc(m,i-1,1,k)+(cc(m,i-1,3,k)+cc(m,ic-1,2,k)) 1 +(cc(m,i-1,5,k)+cc(m,ic-1,4,k)) ch(m,i,k,1) = cc(m,i,1,k)+(cc(m,i,3,k)-cc(m,ic,2,k)) 1 +(cc(m,i,5,k)-cc(m,ic,4,k)) ch(m,i-1,k,2) = wa1(i-2)*((cc(m,i-1,1,k)+tr11* 1 (cc(m,i-1,3,k)+cc(m,ic-1,2,k))+tr12 1 *(cc(m,i-1,5,k)+cc(m,ic-1,4,k)))-(ti11*(cc(m,i,3,k) 1 +cc(m,ic,2,k))+ti12*(cc(m,i,5,k)+cc(m,ic,4,k)))) 1 -wa1(i-1)*((cc(m,i,1,k)+tr11*(cc(m,i,3,k)-cc(m,ic,2,k)) 1 +tr12*(cc(m,i,5,k)-cc(m,ic,4,k)))+(ti11*(cc(m,i-1,3,k) 1 -cc(m,ic-1,2,k))+ti12*(cc(m,i-1,5,k)-cc(m,ic-1,4,k)))) ch(m,i,k,2) = wa1(i-2)*((cc(m,i,1,k)+tr11*(cc(m,i,3,k) 1 -cc(m,ic,2,k))+tr12*(cc(m,i,5,k)-cc(m,ic,4,k))) 1 +(ti11*(cc(m,i-1,3,k)-cc(m,ic-1,2,k))+ti12 1 *(cc(m,i-1,5,k)-cc(m,ic-1,4,k))))+wa1(i-1) 1 *((cc(m,i-1,1,k)+tr11*(cc(m,i-1,3,k) 1 +cc(m,ic-1,2,k))+tr12*(cc(m,i-1,5,k)+cc(m,ic-1,4,k))) 1 -(ti11*(cc(m,i,3,k)+cc(m,ic,2,k))+ti12 1 *(cc(m,i,5,k)+cc(m,ic,4,k)))) ch(m,i-1,k,3) = wa2(i-2) 1 *((cc(m,i-1,1,k)+tr12*(cc(m,i-1,3,k)+cc(m,ic-1,2,k)) 1 +tr11*(cc(m,i-1,5,k)+cc(m,ic-1,4,k)))-(ti12*(cc(m,i,3,k) 1 +cc(m,ic,2,k))-ti11*(cc(m,i,5,k)+cc(m,ic,4,k)))) 1 -wa2(i-1) 1 *((cc(m,i,1,k)+tr12*(cc(m,i,3,k)- 1 cc(m,ic,2,k))+tr11*(cc(m,i,5,k)-cc(m,ic,4,k))) 1 +(ti12*(cc(m,i-1,3,k)-cc(m,ic-1,2,k))-ti11 1 *(cc(m,i-1,5,k)-cc(m,ic-1,4,k)))) ch(m,i,k,3) = wa2(i-2) 1 *((cc(m,i,1,k)+tr12*(cc(m,i,3,k)- 1 cc(m,ic,2,k))+tr11*(cc(m,i,5,k)-cc(m,ic,4,k))) 1 +(ti12*(cc(m,i-1,3,k)-cc(m,ic-1,2,k))-ti11 1 *(cc(m,i-1,5,k)-cc(m,ic-1,4,k)))) 1 +wa2(i-1) 1 *((cc(m,i-1,1,k)+tr12*(cc(m,i-1,3,k)+cc(m,ic-1,2,k)) 1 +tr11*(cc(m,i-1,5,k)+cc(m,ic-1,4,k)))-(ti12*(cc(m,i,3,k) 1 +cc(m,ic,2,k))-ti11*(cc(m,i,5,k)+cc(m,ic,4,k)))) ch(m,i-1,k,4) = wa3(i-2) 1 *((cc(m,i-1,1,k)+tr12*(cc(m,i-1,3,k)+cc(m,ic-1,2,k)) 1 +tr11*(cc(m,i-1,5,k)+cc(m,ic-1,4,k)))+(ti12*(cc(m,i,3,k) 1 +cc(m,ic,2,k))-ti11*(cc(m,i,5,k)+cc(m,ic,4,k)))) 1 -wa3(i-1) 1 *((cc(m,i,1,k)+tr12*(cc(m,i,3,k)- 1 cc(m,ic,2,k))+tr11*(cc(m,i,5,k)-cc(m,ic,4,k))) 1 -(ti12*(cc(m,i-1,3,k)-cc(m,ic-1,2,k))-ti11 1 *(cc(m,i-1,5,k)-cc(m,ic-1,4,k)))) ch(m,i,k,4) = wa3(i-2) 1 *((cc(m,i,1,k)+tr12*(cc(m,i,3,k)- 1 cc(m,ic,2,k))+tr11*(cc(m,i,5,k)-cc(m,ic,4,k))) 1 -(ti12*(cc(m,i-1,3,k)-cc(m,ic-1,2,k))-ti11 1 *(cc(m,i-1,5,k)-cc(m,ic-1,4,k)))) 1 +wa3(i-1) 1 *((cc(m,i-1,1,k)+tr12*(cc(m,i-1,3,k)+cc(m,ic-1,2,k)) 1 +tr11*(cc(m,i-1,5,k)+cc(m,ic-1,4,k)))+(ti12*(cc(m,i,3,k) 1 +cc(m,ic,2,k))-ti11*(cc(m,i,5,k)+cc(m,ic,4,k)))) ch(m,i-1,k,5) = wa4(i-2) 1 *((cc(m,i-1,1,k)+tr11*(cc(m,i-1,3,k)+cc(m,ic-1,2,k)) 1 +tr12*(cc(m,i-1,5,k)+cc(m,ic-1,4,k)))+(ti11*(cc(m,i,3,k) 1 +cc(m,ic,2,k))+ti12*(cc(m,i,5,k)+cc(m,ic,4,k)))) 1 -wa4(i-1) 1 *((cc(m,i,1,k)+tr11*(cc(m,i,3,k)-cc(m,ic,2,k)) 1 +tr12*(cc(m,i,5,k)-cc(m,ic,4,k)))-(ti11*(cc(m,i-1,3,k) 1 -cc(m,ic-1,2,k))+ti12*(cc(m,i-1,5,k)-cc(m,ic-1,4,k)))) ch(m,i,k,5) = wa4(i-2) 1 *((cc(m,i,1,k)+tr11*(cc(m,i,3,k)-cc(m,ic,2,k)) 1 +tr12*(cc(m,i,5,k)-cc(m,ic,4,k)))-(ti11*(cc(m,i-1,3,k) 1 -cc(m,ic-1,2,k))+ti12*(cc(m,i-1,5,k)-cc(m,ic-1,4,k)))) 1 +wa4(i-1) 1 *((cc(m,i-1,1,k)+tr11*(cc(m,i-1,3,k)+cc(m,ic-1,2,k)) 1 +tr12*(cc(m,i-1,5,k)+cc(m,ic-1,4,k)))+(ti11*(cc(m,i,3,k) 1 +cc(m,ic,2,k))+ti12*(cc(m,i,5,k)+cc(m,ic,4,k)))) 1002 continue 102 continue 103 continue return end ================================================ FILE: external/SPHEREPACK/shags.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c c ... file shags.f c c this file contains code and documentation for subroutines c shags and shagsi c c ... files which must be loaded with shags.f c c sphcom.f, hrfft.f, gaqd.f c c subroutine shags(nstrg,nstrab,noffsg,noffsab, c nlat,nlon,isym,nt,g,idg,jdg,a,b,mdab,ndab, c 1 mdabmax,ndabmax, c 1 wshags,lshags,work,lwork,ierror) c c subroutine shags performs the spherical harmonic analysis c on the array g and stores the result in the arrays a and b. c the analysis is performed on a gaussian grid in colatitude c and an equally spaced grid in longitude. the associated c legendre functions are stored rather than recomputed as they c are in subroutine shagc. the analysis is described below c at output parameters a,b. c c input parameters c c nstrg,nstrab strides of g,a,b c noffsg,noffsab offset of g,a,b -- must be between 0 and stride-1 c Alternatively, when the two strides equal, you can set both c to -1 in which case the output will be computed for all c values of offset between 0 and stride-1. c c nlat the number of points in the gaussian colatitude grid on the c full sphere. these lie in the interval (0,pi) and are compu c in radians in theta(1),...,theta(nlat) by subroutine gaqd. c if nlat is odd the equator will be included as the grid poi c theta((nlat+1)/2). if nlat is even the equator will be c excluded as a grid point and will lie half way between c theta(nlat/2) and theta(nlat/2+1). nlat must be at least 3. c note: on the half sphere, the number of grid points in the c colatitudinal direction is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than or equal to 4. the efficiency of the computation is c improved when nlon is a product of small prime numbers. c c NOTE: this is a modified version of spherepack. Changes from c the original version to the current one have only been c tested for isym==0. For this reason an error code will c be returned if isym!=0. c c isym = 0 no symmetries exist about the equator. the analysis c is performed on the entire sphere. i.e. on the c array g(i,j) for i=1,...,nlat and j=1,...,nlon. c (see description of g below) c c = 1 g is antisymmetric about the equator. the analysis c is performed on the northern hemisphere only. i.e. c if nlat is odd the analysis is performed on the c array g(i,j) for i=1,...,(nlat+1)/2 and j=1,...,nlon. c if nlat is even the analysis is performed on the c array g(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c c c = 2 g is symmetric about the equator. the analysis is c performed on the northern hemisphere only. i.e. c if nlat is odd the analysis is performed on the c array g(i,j) for i=1,...,(nlat+1)/2 and j=1,...,nlon. c if nlat is even the analysis is performed on the c array g(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c c nt the number of analyses. in the program that calls shags, c the arrays g,a and b can be three dimensional in which c case multiple analyses will be performed. the third c index is the analysis index which assumes the values c k=1,...,nt. for a single analysis set nt=1. the c discription of the remaining parameters is simplified c by assuming that nt=1 or that the arrays g,a and b c have only two dimensions. c c g a two or three dimensional array (see input parameter c nt) that contains the discrete function to be analyzed. c g(i,j) contains the value of the function at the gaussian c point theta(i) and longitude point phi(j) = (j-1)*2*pi/nlon c the index ranges are defined above at the input parameter c isym. c c idg the first dimension of the array g as it appears in the c program that calls shags. if isym equals zero then idg c must be at least nlat. if isym is nonzero then idg must c be at least nlat/2 if nlat is even or at least (nlat+1)/2 c if nlat is odd. c c jdg the second dimension of the array g as it appears in the c program that calls shags. jdg must be at least nlon. c c mdab the first dimension of the arrays a and b as it appears c in the program that calls shags. if mdab is at least c min0((nlon+2)/2,nlat) if nlon is even or at least c min0((nlon+1)/2,nlat) if nlon is odd, the output will c contain all coefficients. Otherwise it will be truncated. c c ndab the second dimension of the arrays a and b as it appears c in the program that calls shags. If ndab is at least nlat, c the the output will contain all coefficients. Otherwise c it will be truncated. c c mdabmax, ndabmax -- will only compute coefficients a,b up to these c c wshags an array which must be initialized by subroutine shagsi. c once initialized, wshags can be used repeatedly by shags c as long as nlat and nlon remain unchanged. wshags must c not be altered between calls of shags. c c lshags the dimension of the array wshags as it appears in the c program that calls shags. define c c l1 = min0(nlat,(nlon+2)/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lshags must be at least c c nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 c c work a real work space which need not be saved c c c lwork the dimension of the array work as it appears in the c program that calls shags. define c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c c if isym is zero then lwork must be at least c c nlat*nlon*(nt+1) c c if isym is nonzero then lwork must be at least c c l2*nlon*(nt+1) c c ************************************************************** c c output parameters c c a,b both a,b are two or three dimensional arrays (see input c parameter nt) that contain the spherical harmonic c coefficients in the representation of g(i,j) given in the c discription of subroutine shags. for isym=0, a(m,n) and c b(m,n) are given by the equations listed below. symmetric c versions are used when isym is greater than zero. c c definitions c c 1. the normalized associated legendre functions c c pbar(m,n,theta) = dsqrt((2*n+1)*factorial(n-m)/(2*factorial(n+m))) c *sin(theta)**m/(2**n*factorial(n)) times the c (n+m)th derivative of (x**2-1)**n with respect c to x=cos(theta). c c 2. the fourier transform of g(i,j). c c c(m,i) = 2/nlon times the sum from j=1 to j=nlon of c g(i,j)*cos((m-1)*(j-1)*2*pi/nlon) c (the first and last terms in this sum c are divided by 2) c c s(m,i) = 2/nlon times the sum from j=2 to j=nlon of c g(i,j)*sin((m-1)*(j-1)*2*pi/nlon) c c c 3. the gaussian points and weights on the sphere c (computed by subroutine gaqd). c c theta(1),...,theta(nlat) (gaussian pts in radians) c wts(1),...,wts(nlat) (corresponding gaussian weights) c c c 4. the maximum (plus one) longitudinal wave number c c mmax = min0(nlat,(nlon+2)/2) if nlon is even or c mmax = min0(nlat,(nlon+1)/2) if nlon is odd. c c c then for m=0,...,mmax-1 and n=m,...,nlat-1 the arrays a,b c are given by c c a(m+1,n+1) = the sum from i=1 to i=nlat of c c(m+1,i)*wts(i)*pbar(m,n,theta(i)) c c b(m+1,n+1) = the sum from i=1 to nlat of c s(m+1,i)*wts(i)*pbar(m,n,theta(i)) c c ierror = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of isym c = 4 error in the specification of nt c = 5 error in the specification of idg c = 6 error in the specification of jdg c = 9 error in the specification of lshags c = 10 error in the specification of lwork c c c **************************************************************** c c subroutine shagsi(nlat,nlon,wshags,lshags,work,lwork,dwork,ldwork, c + ierror) c c subroutine shagsi initializes the array wshags which can then c be used repeatedly by subroutines shags. it precomputes c and stores in wshags quantities such as gaussian weights, c legendre polynomial coefficients, and fft trigonometric tables. c c input parameters c c nlat the number of points in the gaussian colatitude grid on the c full sphere. these lie in the interval (0,pi) and are compu c in radians in theta(1),...,theta(nlat) by subroutine gaqd. c if nlat is odd the equator will be included as the grid poi c theta((nlat+1)/2). if nlat is even the equator will be c excluded as a grid point and will lie half way between c theta(nlat/2) and theta(nlat/2+1). nlat must be at least 3. c note: on the half sphere, the number of grid points in the c colatitudinal direction is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than or equal to 4. the efficiency of the computation is c improved when nlon is a product of small prime numbers. c c wshags an array which must be initialized by subroutine shagsi. c once initialized, wshags can be used repeatedly by shags c as long as nlat and nlon remain unchanged. wshags must c not be altered between calls of shags. c c lshags the dimension of the array wshags as it appears in the c program that calls shags. define c c l1 = min0(nlat,(nlon+2)/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lshags must be at least c c nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 c c work a real work space which need not be saved c c lwork the dimension of the array work as it appears in the c program that calls shagsi. lwork must be at least c 4*nlat*(nlat+2)+2 in the routine calling shagsi c c dwork a double precision work array that does not have to be saved. c c ldwork the length of dwork in the calling routine. ldwork must c be at least nlat*(nlat+4) c c output parameter c c wshags an array which must be initialized before calling shags or c once initialized, wshags can be used repeatedly by shags or c as long as nlat and nlon remain unchanged. wshags must not c altered between calls of shasc. c c ierror = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of lshags c = 4 error in the specification of lwork c = 5 error in the specification of ldwork c = 6 failure in gaqd to compute gaussian points c (due to failure in eigenvalue routine) c c c **************************************************************** subroutine shags(nstrg,nstrab,noffsg,noffsab, 1 nlat,nlon,mode,nt,g,idg,jdg,a,b,mdab,ndab, 1 mdabmax,ndabmax,wshags,lshags,work,lwork,ierror) implicit double precision (a-h,o-z) c subroutine shags performs the spherical harmonic analysis on c a gaussian grid on the array(s) in g and returns the coefficients c in array(s) a,b. the necessary legendre polynomials are fully c stored in this version. c dimension g(nstrg,idg,jdg,1),a(nstrab,mdab,ndab,1), 1 b(nstrab,mdab,ndab,1),wshags(lshags),work(lwork) c check input parameters ierror = 1 if (nlat.lt.3) return ierror = 2 if (nlon.lt.4) return ierror = 3 c if (mode.lt.0 .or.mode.gt.2) return c see note about isym above if (mode.ne.0) return c set m limit for pmn l = min0((nlon+2)/2,nlat) c set gaussian point nearest equator pointer late = (nlat+mod(nlat,2))/2 c set number of grid points for analysis/synthesis lat = nlat if (mode.ne.0) lat = late ierror = 4 if (nt.lt.1) return ierror = 5 if (idg.lt.lat) return ierror = 6 if (jdg.lt.nlon) return c note that there are no requirements on the minimum values of c mdab, ndab c ierror = 7 c if(mdab .lt. l) return c ierror = 8 c if(ndab .lt. nlat) return l1 = l l2 = late ierror = 9 c check permanent work space length c lp= nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 if(lshags.lt.lp) return ng = 1; if(noffsg.eq.-1 .and. noffsab.eq.-1) ng=nstrg ierror = 10 c check temporary work space length if (mode.eq.0 .and. lwork.lt.ng*nlat*nlon*(nt+1)) return if (mode.ne.0 .and. lwork.lt.ng*l2*nlon*(nt+1)) return ierror = 11 if((noffsg.eq.-1) .neqv. (noffsab.eq.-1)) return if((noffsg.eq.-1) .and. (nstrg.ne.nstrab)) return if((noffsg.lt.-1) .or. (noffsg.ge.nstrg)) return if((noffsab.lt.-1) .or. (noffsab.ge.nstrab)) return ierror = 0 c set starting address for gaussian wts ,fft values, c and fully stored legendre polys in wshags iwts = 1 ifft = nlat+2*nlat*late+3*(l*(l-1)/2+(nlat-l)*(l-1))+1 ipmn = ifft+nlon+15 c set pointer for internal storage of g iw = ng*lat*nlon*nt+1 call shags1(nstrg,nstrab,noffsg,noffsab,nlat, 1nlon,l,lat,mode,g,idg,jdg,nt,a,b,mdab,ndab,mdabmax,ndabmax, 1wshags(iwts),wshags(ifft),wshags(ipmn),late,work,ng,work(iw)) return end subroutine shags1(nstrgs,nstrab,noffsg,noffsab, 1 nlat,nlon,l,lat,mode,gs,idg,jdg,nt,a,b,mdab, 1 ndab,mdabmax,ndabmax,wts,wfft,pmn,late,g,ng,work) implicit double precision (a-h,o-z) dimension gs(nstrgs,idg,jdg,nt),a(nstrab,mdab,ndab,nt), 1 b(nstrab,mdab,ndab,nt),g(ng,lat,nlon,nt) dimension wfft(1),pmn(late,1),wts(nlat),work(1) nlatmax=min0(nlat,ndabmax) if(noffsg.eq.-1) then ioffset0=2 ioffset1=1+nstrgs else ioffset0=1 ioffset1=1 end if c set gs array internally in shags1 do 100 k=1,nt do 100 j=1,nlon do 100 i=1,lat do 100 ioffset=ioffset0,ioffset1 ig=ioffset-ioffset0+1 ncgs=noffsg+ioffset g(ig,i,j,k) = gs(ncgs,i,j,k) 100 continue c do fourier transform do 101 k=1,nt call hrfftf(ng*lat,nlon,g(1,1,1,k),ng*lat,wfft,work) 101 continue c scale result sfn = 2.0d0/dfloat(nlon) do 102 k=1,nt do 102 j=1,nlon do 102 i=1,lat do 102 ig=1,ng g(ig,i,j,k) = sfn*g(ig,i,j,k) 102 continue c compute using gaussian quadrature c a(n,m) = s (ga(theta,m)*pnm(theta)*sin(theta)*dtheta) c b(n,m) = s (gb(theta,m)*pnm(theta)*sin(theta)*dtheta) c here ga,gb are the cos(phi),sin(phi) coefficients of c the fourier expansion of g(theta,phi) in phi. as a result c of the above fourier transform they are stored in array c g as follows: c for each theta(i) and k= l-1 c ga(0),ga(1),gb(1),ga(2),gb(2),...,ga(k-1),gb(k-1),ga(k) c correspond to c g(i,1),g(i,2),g(i,3),g(i,4),g(i,5),...,g(i,2l-4),g(i,2l-3),g(i,2l-2) c whenever 2*l-2 = nlon exactly c initialize coefficients to zero c do 103 k=1,nt c do 103 np1=1,nlat c do 103 mp1=1,l c do 103 ioffset=ioffset0,ioffset1 c ncab=noffsab+ioffset c a(ncab,mp1,np1,k) = 0.0d0 c b(ncab,mp1,np1,k) = 0.0d0 c 103 continue if(noffsab.eq.-1) then a=0.0d0 b=0.0d0 else a(1+noffsab,:,:,:)=0.0d0 b(1+noffsab,:,:,:)=0.0d0 end if c set mp1 limit on b(mp1) calculation lm1 = l if (nlon .eq. l+l-2) lm1 = l-1 mp1max=min0(lm1,mdabmax) if (mode.eq.0) then c for full sphere (mode=0) and even/odd reduction: c overwrite g(i) with (g(i)+g(nlat-i+1))*wts(i) c overwrite g(nlat-i+1) with (g(i)-g(nlat-i+1))*wts(i) nl2 = nlat/2 do 104 k=1,nt do 104 j=1,nlon do 105 i=1,nl2 do 105 ig=1,ng is = nlat-i+1 t1 = g(ig,i,j,k) t2 = g(ig,is,j,k) g(ig,i,j,k) = wts(i)*(t1+t2) g(ig,is,j,k) = wts(i)*(t1-t2) 105 continue c adjust equator if necessary(nlat odd) do 104 ig=1,ng if (mod(nlat,2).ne.0) g(ig,late,j,k) = wts(late)*g(ig,late,j,k) 104 continue c do 201 ioffset=ioffset0,ioffset1 c ig=ioffset-ioffset0+1 c ncab=noffsab+ioffset c set m = 0 coefficients first mp1 = 1 m = 0 mml1 = m*(2*nlat-m-1)/2 do 106 k=1,nt do 106 i=1,late is = nlat-i+1 do 107 np1=1,nlatmax,2 do 107 ioffset=ioffset0,ioffset1 ig=ioffset-ioffset0+1 ncab=noffsab+ioffset c n even a(ncab,1,np1,k) = a(ncab,1,np1,k) 1 +g(ig,i,1,k)*pmn(i,mml1+np1) 107 continue if(nlatmax.ge.2) then do 108 np1=2,nlatmax,2 do 108 ioffset=ioffset0,ioffset1 ig=ioffset-ioffset0+1 ncab=noffsab+ioffset c n odd a(ncab,1,np1,k) = a(ncab,1,np1,k) 1 +g(ig,is,1,k)*pmn(i,mml1+np1) 108 continue end if 106 continue c compute m.ge.1 coefficients next if(mp1max.ge.2) then do 109 mp1=2,mp1max m = mp1-1 mml1 = m*(2*nlat-m-1)/2 mp2 = mp1+1 do 110 k=1,nt do 111 i=1,late is = nlat-i+1 c n-m even if(nlatmax.ge.mp1) then do 112 np1=mp1,nlatmax,2 do 112 ioffset=ioffset0,ioffset1 ig=ioffset-ioffset0+1 ncab=noffsab+ioffset a(ncab,mp1,np1,k) = a(ncab,mp1,np1,k) 1 +g(ig,i,2*m,k)*pmn(i,mml1+np1) b(ncab,mp1,np1,k) = b(ncab,mp1,np1,k) 1 +g(ig,i,2*m+1,k)*pmn(i,mml1+np1) 112 continue end if c n-m odd if(nlatmax.ge.mp2) then do 113 np1=mp2,nlatmax,2 do 113 ioffset=ioffset0,ioffset1 ig=ioffset-ioffset0+1 ncab=noffsab+ioffset a(ncab,mp1,np1,k) = a(ncab,mp1,np1,k) 1 +g(ig,is,2*m,k)*pmn(i,mml1+np1) b(ncab,mp1,np1,k) = b(ncab,mp1,np1,k) 1 +g(ig,is,2*m+1,k)*pmn(i,mml1+np1) 113 continue end if 111 continue 110 continue 109 continue end if if (nlon .eq. l+l-2) then if(l.le.mdabmax) then c compute m=l-1, n=l-1,l,...,nlat-1 coefficients m = l-1 mml1 = m*(2*nlat-m-1)/2 do 114 k=1,nt do 114 i=1,late is = nlat-i+1 if(nlatmax.ge.l) then do 124 np1=l,nlatmax,2 mn = mml1+np1 do 124 ioffset=ioffset0,ioffset1 ig=ioffset-ioffset0+1 ncab=noffsab+ioffset a(ncab,l,np1,k) = a(ncab,l,np1,k)+0.5d0*g(ig,i,nlon,k)*pmn(i,mn) 124 continue end if c n-m odd lp1 = l+1 if(nlatmax.ge.lp1) then do 125 np1=lp1,nlatmax,2 mn = mml1+np1 do 125 ioffset=ioffset0,ioffset1 ig=ioffset-ioffset0+1 ncab=noffsab+ioffset a(ncab,l,np1,k) = a(ncab,l,np1,k)+0.5d0*g(ig,is,nlon,k)*pmn(i,mn) 125 continue end if 114 continue end if end if c 201 continue else c do 202 ioffset=ioffset0,ioffset1 c ig=ioffset-ioffset0+1 c ncab=noffsab+ioffset c half sphere c overwrite g(i) with wts(i)*(g(i)+g(i)) for i=1,...,nlate/2 nl2 = nlat/2 do 116 k=1,nt do 116 j=1,nlon do 115 i=1,nl2 do 115 ig=1,ng g(ig,i,j,k) = wts(i)*(g(ig,i,j,k)+g(ig,i,j,k)) 115 continue c adjust equator separately if a grid point do 116 ig=1,ng if (nl2.lt.late) g(ig,late,j,k) = wts(late)*g(ig,late,j,k) 116 continue c set m = 0 coefficients first mp1 = 1 m = 0 mml1 = m*(2*nlat-m-1)/2 ms = 1 if (mode.eq.1) ms = 2 do 117 k=1,nt do 117 i=1,late do 117 np1=ms,nlatmax,2 do 117 ioffset=ioffset0,ioffset1 ig=ioffset-ioffset0+1 ncab=noffsab+ioffset a(ncab,1,np1,k) = a(ncab,1,np1,k) 1 +g(ig,i,1,k)*pmn(i,mml1+np1) 117 continue c compute m.ge.1 coefficients next if(mp1max.ge.2) then do 118 mp1=2,mp1max m = mp1-1 mml1 = m*(2*nlat-m-1)/2 ms = mp1 if (mode.eq.1) ms = mp1+1 if(nlatmax.ge.ms) then do 119 k=1,nt do 119 i=1,late do 119 np1=ms,nlatmax,2 do 119 ioffset=ioffset0,ioffset1 ig=ioffset-ioffset0+1 ncab=noffsab+ioffset a(ncab,mp1,np1,k) = a(ncab,mp1,np1,k) 1 +g(ig,i,2*m,k)*pmn(i,mml1+np1) b(ncab,mp1,np1,k) = b(ncab,mp1,np1,k) 1 +g(ig,i,2*m+1,k)*pmn(i,mml1+np1) 119 continue end if 118 continue end if if (nlon.eq.l+l-2 .and. l.le.mdabmax) then c compute n=m=l-1 coefficients last m = l-1 mml1 = m*(2*nlat-m-1)/2 c set starting n for mode even ns = l c set starting n for mode odd if (mode.eq.1) ns = l+1 if(nlatmax.ge.ns) then do 120 k=1,nt do 120 i=1,late do 120 np1=ns,nlatmax,2 mn = mml1+np1 do 120 ioffset=ioffset0,ioffset1 ig=ioffset-ioffset0+1 ncab=noffsab+ioffset a(ncab,l,np1,k) = a(ncab,l,np1,k)+0.5d0*g(ig,i,nlon,k)*pmn(i,mn) 120 continue end if end if c 202 continue end if return end subroutine shagsi(nlat,nlon,wshags,lshags,work,lwork,dwork,ldwork, + ierror) implicit double precision (a-h,o-z) c c this subroutine must be called before calling shags or shsgs with c fixed nlat,nlon. it precomputes the gaussian weights, points c and all necessary legendre polys and stores them in wshags. c these quantities must be preserved when calling shags or shsgs c repeatedly with fixed nlat,nlon. dwork must be of length at c least nlat*(nlat+4) in the routine calling shagsi. This is c not checked. undetectable errors will result if dwork is c smaller than nlat*(nlat+4). c dimension wshags(lshags),work(lwork) double precision dwork(ldwork) ierror = 1 if (nlat.lt.3) return ierror = 2 if (nlon.lt.4) return c set triangular truncation limit for spherical harmonic basis l = min0((nlon+2)/2,nlat) c set equator or nearest point (if excluded) pointer late = (nlat+1)/2 l1 = l l2 = late c check permanent work space length ierror = 3 lp=nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 if(lshags.lt.lp) return ierror = 4 c check temporary work space if (lwork.lt.4*nlat*(nlat+2)+2) return ierror = 5 c check double precision temporary space if (ldwork .lt. nlat*(nlat+4)) return ierror = 0 c set preliminary quantites needed to compute and store legendre polys ldw = nlat*(nlat+4) call shagsp(nlat,nlon,wshags,lshags,dwork,ldwork,ierror) if (ierror.ne.0) return c set legendre poly pointer in wshags ipmnf = nlat+2*nlat*late+3*(l*(l-1)/2+(nlat-l)*(l-1))+nlon+16 call shagss1(nlat,l,late,wshags,work,wshags(ipmnf)) return end subroutine shagss1(nlat,l,late,w,pmn,pmnf) implicit double precision (a-h,o-z) dimension w(1),pmn(nlat,late,3),pmnf(late,1) c compute and store legendre polys for i=1,...,late,m=0,...,l-1 c and n=m,...,l-1 do i=1,nlat do j=1,late do k=1,3 pmn(i,j,k) = 0.0d0 end do end do end do km0=1 km1=2 km2=3 do 100 mp1=1,l m = mp1-1 mml1 = m*(2*nlat-m-1)/2 c compute pmn for n=m,...,nlat-1 and i=1,...,(l+1)/2 mode = 0 call legin(mode,l,nlat,m,w,pmn,km,km0,km1,km2) c store above in pmnf do 101 np1=mp1,nlat mn = mml1+np1 do 102 i=1,late pmnf(i,mn) = pmn(np1,i,km) 102 continue 101 continue 100 continue return end subroutine shagsp(nlat,nlon,wshags,lshags,dwork,ldwork,ierror) implicit double precision (a-h,o-z) dimension wshags(lshags) double precision dwork(ldwork) ierror = 1 if (nlat.lt.3) return ierror = 2 if (nlon.lt.4) return c set triangular truncation limit for spherical harmonic basis l = min0((nlon+2)/2,nlat) c set equator or nearest point (if excluded) pointer late = (nlat+mod(nlat,2))/2 l1 = l l2 = late ierror = 3 c check permanent work space length if (lshags .lt. nlat*(2*l2+3*l1-2)+3*l1*(1-l1)/2+nlon+15)return ierror = 4 c if (lwork.lt.4*nlat*(nlat+2)+2) return if (ldwork.lt.nlat*(nlat+4))return ierror = 0 c set pointers i1 = 1 i2 = i1+nlat i3 = i2+nlat*late i4 = i3+nlat*late i5 = i4+l*(l-1)/2 +(nlat-l)*(l-1) i6 = i5+l*(l-1)/2 +(nlat-l)*(l-1) i7 = i6+l*(l-1)/2 +(nlat-l)*(l-1) c set indices in temp work for double precision gaussian wts and pts idth = 1 c idwts = idth+2*nlat c iw = idwts+2*nlat idwts = idth+nlat iw = idwts+nlat call shagsp1(nlat,nlon,l,late,wshags(i1),wshags(i2),wshags(i3), 1wshags(i4),wshags(i5),wshags(i6),wshags(i7),dwork(idth), 2dwork(idwts),dwork(iw),ierror) if (ierror.ne.0) ierror = 6 return end subroutine shagsp1(nlat,nlon,l,late,wts,p0n,p1n,abel,bbel,cbel, + wfft,dtheta,dwts,work,ier) implicit double precision (a-h,o-z) dimension wts(nlat),p0n(nlat,late),p1n(nlat,late),abel(1),bbel(1), 1 cbel(1),wfft(1),dtheta(nlat),dwts(nlat) double precision pb,dtheta,dwts,work(*) indx(m,n) = (n-1)*(n-2)/2+m-1 imndx(m,n) = l*(l-1)/2+(n-l-1)*(l-1)+m-1 call hrffti(nlon,wfft) c compute double precision gaussian points and weights c lw = 4*nlat*(nlat+2) lw = nlat*(nlat+2) call gaqd(nlat,dtheta,dwts,work,lw,ier) if (ier.ne.0) return c store gaussian weights single precision to save computation c in inner loops in analysis do 100 i=1,nlat wts(i) = dwts(i) 100 continue c initialize p0n,p1n using double precision dnlfk,dnlft do 101 np1=1,nlat do 101 i=1,late p0n(np1,i) = 0.0d0 p1n(np1,i) = 0.0d0 101 continue c compute m=n=0 legendre polynomials for all theta(i) np1 = 1 n = 0 m = 0 call dnlfk(m,n,work) do 103 i=1,late call dnlft(m,n,dtheta(i),work,pb) p0n(1,i) = pb 103 continue c compute p0n,p1n for all theta(i) when n.gt.0 do 104 np1=2,nlat n = np1-1 m = 0 call dnlfk(m,n,work) do 105 i=1,late call dnlft(m,n,dtheta(i),work,pb) p0n(np1,i) = pb 105 continue c compute m=1 legendre polynomials for all n and theta(i) m = 1 call dnlfk(m,n,work) do 106 i=1,late call dnlft(m,n,dtheta(i),work,pb) p1n(np1,i) = pb 106 continue 104 continue c c compute and store swarztrauber recursion coefficients c for 2.le.m.le.n and 2.le.n.le.nlat in abel,bbel,cbel do 107 n=2,nlat mlim = min0(n,l) do 107 m=2,mlim imn = indx(m,n) if (n.ge.l) imn = imndx(m,n) abel(imn)=dsqrt(dfloat((2*n+1)*(m+n-2)*(m+n-3))/ 1 dfloat(((2*n-3)*(m+n-1)*(m+n)))) bbel(imn)=dsqrt(dfloat((2*n+1)*(n-m-1)*(n-m))/ 1 dfloat(((2*n-3)*(m+n-1)*(m+n)))) cbel(imn)=dsqrt(dfloat((n-m+1)*(n-m+2))/ 1 dfloat(((n+m-1)*(n+m)))) 107 continue return end ================================================ FILE: external/SPHEREPACK/shsgs.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c c ... file shsgs.f c c this file contains code and documentation for subroutines c shsgs and shsgsi c c ... files which must be loaded with shsgs.f c c sphcom.f, hrfft.f, gaqd.f c c subroutine shsgs(nstrg,nstrab,noffsg,noffsab, c nlat,nlon,isym,nt,g,idg,jdg,a,b,mdab,ndab, c 1 mdabmax,ndabmax, c 1 wshsgs,lshsgs,work,lwork,ierror) c c subroutine shsgs performs the spherical harmonic synthesis c on the arrays a and b and stores the result in the array g. c the synthesis is performed on an equally spaced longitude grid c and a gaussian colatitude grid. the associated legendre functions c are stored rather than recomputed as they are in subroutine c shsgc. the synthesis is described below at output parameter c g. c c c input parameters c c nstrg,nstrab stride in g,a,b c noffsg,noffsab offset in g,a,b -- must be between 0 and stride-1 c Alternatively, when the two strides equal, you can set both c to -1 in which case the output will be computed for all c values of offset between 0 and stride-1. c c nlat the number of points in the gaussian colatitude grid on the c full sphere. these lie in the interval (0,pi) and are compu c in radians in theta(1),...,theta(nlat) by subroutine gaqd. c if nlat is odd the equator will be included as the grid poi c theta((nlat+1)/2). if nlat is even the equator will be c excluded as a grid point and will lie half way between c theta(nlat/2) and theta(nlat/2+1). nlat must be at least 3. c note: on the half sphere, the number of grid points in the c colatitudinal direction is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than or equal to 4. the efficiency of the computation is c improved when nlon is a product of small prime numbers. c c NOTE: this is a modified version of spherepack. Changes from c the original version to the current one have only been c tested for isym==0. For this reason an error code will c be returned if isym!=0. c c isym = 0 no symmetries exist about the equator. the synthesis c is performed on the entire sphere. i.e. on the c array g(i,j) for i=1,...,nlat and j=1,...,nlon. c (see description of g below) c c = 1 g is antisymmetric about the equator. the synthesis c is performed on the northern hemisphere only. i.e. c if nlat is odd the synthesis is performed on the c array g(i,j) for i=1,...,(nlat+1)/2 and j=1,...,nlon. c if nlat is even the synthesis is performed on the c array g(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c c c = 2 g is symmetric about the equator. the synthesis is c performed on the northern hemisphere only. i.e. c if nlat is odd the synthesis is performed on the c array g(i,j) for i=1,...,(nlat+1)/2 and j=1,...,nlon. c if nlat is even the synthesis is performed on the c array g(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c c nt the number of syntheses. in the program that calls shsgs, c the arrays g,a and b can be three dimensional in which c case multiple synthesis will be performed. the third c index is the synthesis index which assumes the values c k=1,...,nt. for a single synthesis set nt=1. the c discription of the remaining parameters is simplified c by assuming that nt=1 or that the arrays g,a and b c have only two dimensions. c c idg the first dimension of the array g as it appears in the c program that calls shagc. if isym equals zero then idg c must be at least nlat. if isym is nonzero then idg must c be at least nlat/2 if nlat is even or at least (nlat+1)/2 c if nlat is odd. c c jdg the second dimension of the array g as it appears in the c program that calls shagc. jdg must be at least nlon. c c a,b two or three dimensional arrays (see the input parameter c nt) that contain the coefficients in the spherical harmonic c expansion of g(i,j) given below at the definition of the c output parameter g. a(m,n) and b(m,n) are defined for c indices m=1,...,mmax and n=m,...,nlat where mmax is the c maximum (plus one) longitudinal wave number given by c mmax = min0(nlat,(nlon+2)/2) if nlon is even or c mmax = min0(nlat,(nlon+1)/2) if nlon is odd. c c mdab the first dimension of the arrays a and b as it appears c in the program that calls shsgs. mdab must be at least c min0((nlon+2)/2,nlat) if nlon is even or at least c min0((nlon+1)/2,nlat) if nlon is odd IF IT CONTAINS c ALL COEFFICIENTS. If smaller, the higher coefficients c are ignored (i.e., treated as if they were zero). c c ndab the second dimension of the arrays a and b as it appears c in the program that calls shsgs. ndab must be at least nlat c IF IT CONTAINS ALL COEFFICIENTS. Otherwise the higher coefs c are ignored (i.e., treated as if they were zero). c c mdabmax, ndabmax -- will ignore coefficients a,b with index higher c than these c c wshsgs an array which must be initialized by subroutine shsgsi. c once initialized, wshsgs can be used repeatedly by shsgs c as long as nlat and nlon remain unchanged. wshsgs must c not be altered between calls of shsgs. c c lshsgs the dimension of the array wshsgs as it appears in the c program that calls shsgs. define c c l1 = min0(nlat,(nlon+2)/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lshsgs must be at least c c nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 c c c lwork the dimension of the array work as it appears in the c program that calls shsgs. define c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c c if isym is zero then lwork must be at least c c nlat*nlon*(nt+1) c c if isym is nonzero then lwork must be at least c c l2*nlon*(nt+1) c c c ************************************************************** c c output parameters c c g a two or three dimensional array (see input parameter nt) c that contains the discrete function which is synthesized. c g(i,j) contains the value of the function at the gaussian c colatitude point theta(i) and longitude point c phi(j) = (j-1)*2*pi/nlon. the index ranges are defined c above at the input parameter isym. for isym=0, g(i,j) c is given by the the equations listed below. symmetric c versions are used when isym is greater than zero. c c the normalized associated legendre functions are given by c c pbar(m,n,theta) = dsqrt((2*n+1)*factorial(n-m)/(2*factorial(n+m))) c *sin(theta)**m/(2**n*factorial(n)) times the c (n+m)th derivative of (x**2-1)**n with respect c to x=cos(theta) c c define the maximum (plus one) longitudinal wave number c as mmax = min0(nlat,(nlon+2)/2) if nlon is even or c mmax = min0(nlat,(nlon+1)/2) if nlon is odd. c c then g(i,j) = the sum from n=0 to n=nlat-1 of c c .5*pbar(0,n,theta(i))*a(1,n+1) c c plus the sum from m=1 to m=mmax-1 of c c the sum from n=m to n=nlat-1 of c c pbar(m,n,theta(i))*(a(m+1,n+1)*cos(m*phi(j)) c -b(m+1,n+1)*sin(m*phi(j))) c c c ierror = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of isym c = 4 error in the specification of nt c = 5 error in the specification of idg c = 6 error in the specification of jdg c = 9 error in the specification of lshsgs c = 10 error in the specification of lwork c c c **************************************************************** c c subroutine shsgsi(nlat,nlon,wshsgs,lshsgs,work,lwork,dwork,ldwork, c + ierror) c c subroutine shsgsi initializes the array wshsgs which can then c be used repeatedly by subroutines shsgs. it precomputes c and stores in wshsgs quantities such as gaussian weights, c legendre polynomial coefficients, and fft trigonometric tables. c c input parameters c c nlat the number of points in the gaussian colatitude grid on the c full sphere. these lie in the interval (0,pi) and are compu c in radians in theta(1),...,theta(nlat) by subroutine gaqd. c if nlat is odd the equator will be included as the grid poi c theta((nlat+1)/2). if nlat is even the equator will be c excluded as a grid point and will lie half way between c theta(nlat/2) and theta(nlat/2+1). nlat must be at least 3. c note: on the half sphere, the number of grid points in the c colatitudinal direction is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than or equal to 4. the efficiency of the computation is c improved when nlon is a product of small prime numbers. c c wshsgs an array which must be initialized by subroutine shsgsi. c once initialized, wshsgs can be used repeatedly by shsgs c as long as nlat and nlon remain unchanged. wshsgs must c not be altered between calls of shsgs. c c lshsgs the dimension of the array wshsgs as it appears in the c program that calls shsgs. define c c l1 = min0(nlat,(nlon+2)/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lshsgs must be at least c c nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 c c work a real work space which need not be saved c c lwork the dimension of the array work as it appears in the c program that calls shsgsi. lwork must be at least c 4*nlat*(nlat+2)+2 in the routine calling shsgsi c c dwork a double precision work array that does not have to be saved. c c ldwork the length of dwork in the calling routine. ldwork must c be at least nlat*(nlat+4) c c output parameter c c wshsgs an array which must be initialized before calling shsgs or c once initialized, wshsgs can be used repeatedly by shsgs or c as long as nlat and nlon remain unchanged. wshsgs must not c altered between calls of shsgs. c c ierror = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of lshsgs c = 4 error in the specification of lwork c = 5 error in the specification of ldwork c = 5 failure in gaqd to compute gaussian points c (due to failure in eigenvalue routine) c c subroutine shsgs(nstrg,nstrab,noffsg,noffsab, 1 nlat,nlon,mode,nt,g,idg,jdg,a,b,mdab,ndab, 1 mdabmax,ndabmax,wshsgs,lshsgs,work,lwork,ierror) implicit double precision (a-h,o-z) dimension g(nstrg,idg,jdg,1),a(nstrab,mdab,ndab,1), 1 b(nstrab,mdab,ndab,1),wshsgs(lshsgs),work(lwork) c check input parameters ierror = 1 if (nlat.lt.3) return ierror = 2 if (nlon.lt.4) return ierror = 3 c if (mode.lt.0 .or.mode.gt.2) return c see note about isym above if (mode.ne.0) return ierror = 4 if (nt.lt.1) return c set limit on m subscript l = min0((nlon+2)/2,nlat) c set gaussian point nearest equator pointer late = (nlat+mod(nlat,2))/2 c set number of grid points for analysis/synthesis lat = nlat if (mode.ne.0) lat = late ierror = 5 if (idg.lt.lat) return ierror = 6 if (jdg.lt.nlon) return c ierror = 7 c if(mdab .lt. l) return c ierror = 8 c if(ndab .lt. nlat) return l1 = l l2 = late ierror = 9 c check permanent work space length lp=nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 if(lshsgs.lt.lp) return c check temporary work space length ng = 1; if(noffsg.eq.-1 .and. noffsab.eq.-1) ng=nstrg ierror = 10 if (mode.eq.0 .and. lwork.lt.ng*nlat*nlon*(nt+1)) return if (mode.ne.0 .and. lwork.lt.ng*l2*nlon*(nt+1)) return ierror = 11 if((noffsg.eq.-1) .neqv. (noffsab.eq.-1)) return if((noffsg.eq.-1) .and. (nstrg.ne.nstrab)) return if((noffsg.lt.-1) .or. (noffsg.ge.nstrg)) return if((noffsab.lt.-1) .or. (noffsab.ge.nstrab)) return ierror = 0 c starting address for fft values and legendre polys in wshsgs ifft = nlat+2*nlat*late+3*(l*(l-1)/2+(nlat-l)*(l-1))+1 ipmn = ifft+nlon+15 c set pointer for internal storage of g iw = ng*lat*nlon*nt+1 call shsgs1(nstrg,nstrab,noffsg,noffsab, 1 nlat,nlon,l,lat,mode,g,idg,jdg,nt,a,b,mdab,ndab, 1 mdabmax,ndabmax, 1 wshsgs(ifft),wshsgs(ipmn),late,work,ng,work(iw)) return end subroutine shsgs1(nstrgs,nstrab,noffsgs,noffsab, 1 nlat,nlon,l,lat,mode,gs,idg,jdg,nt,a,b,mdab, 1 ndab,mdabmax,ndabmax,wfft,pmn,late,g,ng,work) implicit double precision (a-h,o-z) dimension gs(nstrgs,idg,jdg,nt), 1 a(nstrab,mdab,ndab,nt),b(nstrab,mdab,ndab,nt) dimension wfft(1),pmn(late,1),g(ng,lat,nlon,nt),work(1) nlatmax=min0(nlat,ndabmax) c ncgs=1+noffsgs c ncab=1+noffsab if(noffsgs.eq.-1) then ioffset0=2 ioffset1=nstrgs+1 else ioffset0=1 ioffset1=1 end if c reconstruct fourier coefficients in g on gaussian grid c using coefficients in a,b c initialize to zero do 100 k=1,nt do 100 j=1,nlon do 100 i=1,lat do 100 ig=1,ng g(ig,i,j,k) = 0.0d0 100 continue lm1 = l if (nlon .eq. l+l-2) lm1 = l-1 mp1max = min0(lm1,mdabmax) if (mode.eq.0) then c do 201 ioffset=ioffset0,ioffset1 c ncab=noffsab+ioffset c ig=ioffset-ioffset0+1 c set first column in g m = 0 mml1 = m*(2*nlat-m-1)/2 do 101 k=1,nt c n even do 102 np1=1,nlatmax,2 mn = mml1+np1 do 102 i=1,late do 102 ioffset=ioffset0,ioffset1 ncab=noffsab+ioffset ig=ioffset-ioffset0+1 g(ig,i,1,k) = g(ig,i,1,k)+a(ncab,1,np1,k)*pmn(i,mn) 102 continue c n odd nl2 = nlat/2 if(nlatmax.ge.2) then do 103 np1=2,nlatmax,2 mn = mml1+np1 do 103 i=1,nl2 is = nlat-i+1 do 103 ioffset=ioffset0,ioffset1 ncab=noffsab+ioffset ig=ioffset-ioffset0+1 g(ig,is,1,k) = g(ig,is,1,k)+a(ncab,1,np1,k)*pmn(i,mn) 103 continue end if 101 continue c restore m=0 coefficients from odd/even do 112 k=1,nt do 112 i=1,nl2 do 112 ig=1,ng is = nlat-i+1 t1 = g(ig,i,1,k) t3 = g(ig,is,1,k) g(ig,i,1,k) = t1+t3 g(ig,is,1,k) = t1-t3 112 continue c sweep interior columns of g if(mp1max.ge.2) then do 104 mp1=2,mp1max m = mp1-1 mml1 = m*(2*nlat-m-1)/2 mp2 = m+2 do 105 k=1,nt c for n-m even store (g(i,p,k)+g(nlat-i+1,p,k))/2 in g(i,p,k) p=2*m,2*m+1 c for i=1,...,late if(nlatmax.ge.mp1) then do 106 np1=mp1,nlatmax,2 mn = mml1+np1 do 107 i=1,late do 107 ioffset=ioffset0,ioffset1 ncab=noffsab+ioffset ig=ioffset-ioffset0+1 g(ig,i,2*m,k) = g(ig,i,2*m,k)+a(ncab,mp1,np1,k)*pmn(i,mn) g(ig,i,2*m+1,k) = g(ig,i,2*m+1,k)+b(ncab,mp1,np1,k)*pmn(i,mn) 107 continue 106 continue end if c for n-m odd store g(i,p,k)-g(nlat-i+1,p,k) in g(nlat-i+1,p,k) c for i=1,...,nlat/2 (p=2*m,p=2*m+1) if(nlatmax.ge.mp2) then do 108 np1=mp2,nlatmax,2 mn = mml1+np1 do 109 i=1,nl2 is = nlat-i+1 do 109 ioffset=ioffset0,ioffset1 ncab=noffsab+ioffset ig=ioffset-ioffset0+1 g(ig,is,2*m,k) = g(ig,is,2*m,k)+a(ncab,mp1,np1,k)*pmn(i,mn) g(ig,is,2*m+1,k) = g(ig,is,2*m+1,k)+b(ncab,mp1,np1,k)*pmn(i,mn) 109 continue 108 continue end if c now set fourier coefficients using even-odd reduction above do 110 i=1,nl2 do 110 ig=1,ng is = nlat-i+1 t1 = g(ig,i,2*m,k) t2 = g(ig,i,2*m+1,k) t3 = g(ig,is,2*m,k) t4 = g(ig,is,2*m+1,k) g(ig,i,2*m,k) = t1+t3 g(ig,i,2*m+1,k) = t2+t4 g(ig,is,2*m,k) = t1-t3 g(ig,is,2*m+1,k) = t2-t4 110 continue 105 continue 104 continue end if c set last column (using a only) if necessary if (nlon.eq. l+l-2) then if (l.le.mdabmax) then m = l-1 mml1 = m*(2*nlat-m-1)/2 do 111 k=1,nt c n-m even if(nlatmax.ge.l) then do 131 np1=l,nlatmax,2 mn = mml1+np1 do 131 i=1,late do 131 ioffset=ioffset0,ioffset1 ncab=noffsab+ioffset ig=ioffset-ioffset0+1 g(ig,i,nlon,k) = g(ig,i,nlon,k)+2.0d0*a(ncab,l,np1,k)*pmn(i,mn) 131 continue end if lp1 = l+1 c n-m odd if(nlatmax.ge.lp1) then do 132 np1=lp1,nlatmax,2 mn = mml1+np1 do 132 i=1,nl2 is = nlat-i+1 do 132 ioffset=ioffset0,ioffset1 ncab=noffsab+ioffset ig=ioffset-ioffset0+1 g(ig,is,nlon,k) = g(ig,is,nlon,k)+2.0d0*a(ncab,l,np1,k)*pmn(i,mn) 132 continue end if do 133 i=1,nl2 do 133 ig=1,ng is = nlat-i+1 t1 = g(ig,i,nlon,k) t3 = g(ig,is,nlon,k) g(ig,i,nlon,k)= t1+t3 g(ig,is,nlon,k)= t1-t3 133 continue 111 continue end if end if 201 continue else c half sphere (mode.ne.0) c set first column in g m = 0 mml1 = m*(2*nlat-m-1)/2 meo = 1 if (mode.eq.1) meo = 2 ms = m+meo if(nlatmax.ge.ms) then do 113 k=1,nt do 113 np1=ms,nlatmax,2 mn = mml1+np1 do 113 i=1,late do 113 ioffset=ioffset0,ioffset1 ncab=noffsab+ioffset ig=ioffset-ioffset0+1 g(ig,i,1,k) = g(ig,i,1,k)+a(ncab,1,np1,k)*pmn(i,mn) 113 continue end if c sweep interior columns of g if(mp1max.ge.2) then do 114 mp1=2,mp1max m = mp1-1 mml1 = m*(2*nlat-m-1)/2 ms = m+meo if(nlatmax.ge.ms) then do 115 k=1,nt do 115 np1=ms,nlatmax,2 mn = mml1+np1 do 115 i=1,late do 115 ioffset=ioffset0,ioffset1 ncab=noffsab+ioffset ig=ioffset-ioffset0+1 g(ig,i,2*m,k) = g(ig,i,2*m,k)+a(ncab,mp1,np1,k)*pmn(i,mn) g(ig,i,2*m+1,k) = g(ig,i,2*m+1,k)+b(ncab,mp1,np1,k)*pmn(i,mn) 115 continue end if 114 continue end if if (nlon.eq.l+l-2 .and. l.le.mdabmax) then c set last column m = l-1 mml1 = m*(2*nlat-m-1)/2 ns = l if (mode.eq.1) ns = l+1 if(nlatmax.ge.ns) then do 116 k=1,nt do 116 np1=ns,nlatmax,2 mn = mml1+np1 do 116 i=1,late do 116 ioffset=ioffset0,ioffset1 ncab=noffsab+ioffset ig=ioffset-ioffset0+1 g(ig,i,nlon,k) = g(ig,i,nlon,k)+2.0d0*a(ncab,l,np1,k)*pmn(i,mn) 116 continue end if end if 202 continue end if c do inverse fourier transform do 120 k=1,nt call hrfftb(ng*lat,nlon,g(1,1,1,k),ng*lat,wfft,work) 120 continue c scale output in gs do 122 k=1,nt do 122 j=1,nlon do 122 i=1,lat do 122 ioffset=ioffset0,ioffset1 ncgs=noffsgs+ioffset ig=ioffset-ioffset0+1 gs(ncgs,i,j,k) = 0.5d0*g(ig,i,j,k) 122 continue return end subroutine shsgsi(nlat,nlon,wshsgs,lshsgs,work,lwork,dwork,ldwork, + ierror) implicit double precision (a-h,o-z) c c this subroutine must be called before calling shags or shsgs with c fixed nlat,nlon. it precomputes the gaussian weights, points c and all necessary legendre polys and stores them in wshsgs. c these quantities must be preserved when calling shsgs c repeatedly with fixed nlat,nlon. c dimension wshsgs(lshsgs),work(lwork) double precision dwork(ldwork) ierror = 1 if (nlat.lt.3) return ierror = 2 if (nlon.lt.4) return c set triangular truncation limit for spherical harmonic basis l = min0((nlon+2)/2,nlat) c set equator or nearest point (if excluded) pointer late = (nlat+1)/2 l1 = l l2 = late c check permanent work space length ierror = 3 lp=nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 if(lshsgs.lt.lp) return ierror = 4 c check temporary work space if (lwork.lt.4*nlat*(nlat+2)+2) return ierror = 5 if (ldwork .lt. nlat*(nlat+4)) return ierror = 0 c set preliminary quantites needed to compute and store legendre polys ldw = nlat*(nlat+4) call shsgsp(nlat,nlon,wshsgs,lshsgs,dwork,ldwork,ierror) if (ierror.ne.0) return c set legendre poly pointer in wshsgs ipmnf = nlat+2*nlat*late+3*(l*(l-1)/2+(nlat-l)*(l-1))+nlon+16 call shsgss1(nlat,l,late,wshsgs,work,wshsgs(ipmnf)) return end subroutine shsgss1(nlat,l,late,w,pmn,pmnf) implicit double precision (a-h,o-z) dimension w(1),pmn(nlat,late,3),pmnf(late,1) c compute and store legendre polys for i=1,...,late,m=0,...,l-1 c and n=m,...,l-1 do i=1,nlat do j=1,late do k=1,3 pmn(i,j,k) = 0.0d0 end do end do end do km0=1 km1=2 km2=3 do 100 mp1=1,l m = mp1-1 mml1 = m*(2*nlat-m-1)/2 c compute pmn for n=m,...,nlat-1 and i=1,...,(l+1)/2 mode = 0 call legin(mode,l,nlat,m,w,pmn,km,km0,km1,km2) c store above in pmnf do 101 np1=mp1,nlat mn = mml1+np1 do 102 i=1,late pmnf(i,mn) = pmn(np1,i,km) 102 continue 101 continue 100 continue return end subroutine shsgsp(nlat,nlon,wshsgs,lshsgs,dwork,ldwork,ierror) implicit double precision (a-h,o-z) dimension wshsgs(lshsgs) double precision dwork(ldwork) ierror = 1 if (nlat.lt.3) return ierror = 2 if (nlon.lt.4) return c set triangular truncation limit for spherical harmonic basis l = min0((nlon+2)/2,nlat) c set equator or nearest point (if excluded) pointer late = (nlat+mod(nlat,2))/2 l1 = l l2 = late ierror = 3 c check permanent work space length if (lshsgs .lt. nlat*(2*l2+3*l1-2)+3*l1*(1-l1)/2+nlon+15)return ierror = 4 c if (lwork.lt.4*nlat*(nlat+2)+2) return if (ldwork .lt. nlat*(nlat+4)) return ierror = 0 c set pointers i1 = 1 i2 = i1+nlat i3 = i2+nlat*late i4 = i3+nlat*late i5 = i4+l*(l-1)/2 +(nlat-l)*(l-1) i6 = i5+l*(l-1)/2 +(nlat-l)*(l-1) i7 = i6+l*(l-1)/2 +(nlat-l)*(l-1) c set indices in temp work for double precision gaussian wts and pts idth = 1 c idwts = idth+2*nlat c iw = idwts+2*nlat idwts = idth+nlat iw = idwts+nlat call shsgsp1(nlat,nlon,l,late,wshsgs(i1),wshsgs(i2),wshsgs(i3), 1wshsgs(i4),wshsgs(i5),wshsgs(i6),wshsgs(i7),dwork(idth), 2dwork(idwts),dwork(iw),ierror) if (ierror.ne.0) ierror = 6 return end subroutine shsgsp1(nlat,nlon,l,late,wts,p0n,p1n,abel,bbel,cbel, + wfft,dtheta,dwts,work,ier) implicit double precision (a-h,o-z) dimension wts(nlat),p0n(nlat,late),p1n(nlat,late),abel(1),bbel(1), 1 cbel(1),wfft(1),dtheta(nlat),dwts(nlat) double precision pb,dtheta,dwts,work(*) indx(m,n) = (n-1)*(n-2)/2+m-1 imndx(m,n) = l*(l-1)/2+(n-l-1)*(l-1)+m-1 call hrffti(nlon,wfft) c c compute double precision gaussian points and weights c lw = nlat*(nlat+2) call gaqd(nlat,dtheta,dwts,work,lw,ier) if (ier.ne.0) return c store gaussian weights single precision to save computation c in inner loops in analysis do 100 i=1,nlat wts(i) = dwts(i) 100 continue c initialize p0n,p1n using double precision dnlfk,dnlft do 101 np1=1,nlat do 101 i=1,late p0n(np1,i) = 0.0d0 p1n(np1,i) = 0.0d0 101 continue c compute m=n=0 legendre polynomials for all theta(i) np1 = 1 n = 0 m = 0 call dnlfk(m,n,work) do 103 i=1,late call dnlft(m,n,dtheta(i),work,pb) p0n(1,i) = pb 103 continue c compute p0n,p1n for all theta(i) when n.gt.0 do 104 np1=2,nlat n = np1-1 m = 0 call dnlfk(m,n,work) do 105 i=1,late call dnlft(m,n,dtheta(i),work,pb) p0n(np1,i) = pb 105 continue c compute m=1 legendre polynomials for all n and theta(i) m = 1 call dnlfk(m,n,work) do 106 i=1,late call dnlft(m,n,dtheta(i),work,pb) p1n(np1,i) = pb 106 continue 104 continue c c compute and store swarztrauber recursion coefficients c for 2.le.m.le.n and 2.le.n.le.nlat in abel,bbel,cbel do 107 n=2,nlat mlim = min0(n,l) do 107 m=2,mlim imn = indx(m,n) if (n.ge.l) imn = imndx(m,n) abel(imn)=dsqrt(dfloat((2*n+1)*(m+n-2)*(m+n-3))/ 1 dfloat(((2*n-3)*(m+n-1)*(m+n)))) bbel(imn)=dsqrt(dfloat((2*n+1)*(n-m-1)*(n-m))/ 1 dfloat(((2*n-3)*(m+n-1)*(m+n)))) cbel(imn)=dsqrt(dfloat((n-m+1)*(n-m+2))/ 1 dfloat(((n+m-1)*(n+m)))) 107 continue return end ================================================ FILE: external/SPHEREPACK/slapgs.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c c c ... file slapgs.f c c this file includes documentation and code for c subroutine slapgs i c c ... files which must be loaded with slapgs.f c c sphcom.f, hrfft.f, shags.f, shsgs.f c c c c subroutine slapgs(nstrlap,nstrab,noffslap,noffsab, c nlat,nlon,isym,nt,slap,ids,jds,a,b, c +mdab,ndab,wshsgs,lshsgs,work,lwork,ierror) c c c given the scalar spherical harmonic coefficients a and b, precomputed c by subroutine shags for a scalar field sf, subroutine slapgs computes c the laplacian of sf in the scalar array slap. slap(i,j) is the c laplacian of sf at the gaussian colatitude theta(i) (see nlat as c an input parameter) and east longitude lambda(j) = (j-1)*2*pi/nlon c on the sphere. i.e. c c slap(i,j) = c c 2 2 c [1/sint*d (sf(i,j)/dlambda + d(sint*d(sf(i,j))/dtheta)/dtheta]/sint c c c where sint = sin(theta(i)). the scalar laplacian in slap has the c same symmetry or absence of symmetry about the equator as the scalar c field sf. the input parameters isym,nt,mdab,ndab must have the c same values used by shags to compute a and b for sf. the associated c legendre functions are stored rather than recomputed as they are c in subroutine slapgc. c c input parameters c c nstrlap, nstrab strides in lap,a,b, c noffslap, noffsab offset in lap,a,b, -- must be between 0 and stride-1 c c nlat the number of points in the gaussian colatitude grid on the c full sphere. these lie in the interval (0,pi) and are computed c in radians in theta(1) <...< theta(nlat) by subroutine gaqd. c if nlat is odd the equator will be included as the grid point c theta((nlat+1)/2). if nlat is even the equator will be c excluded as a grid point and will lie half way between c theta(nlat/2) and theta(nlat/2+1). nlat must be at least 3. c note: on the half sphere, the number of grid points in the c colatitudinal direction is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct longitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than zero. the axisymmetric case corresponds to nlon=1. c the efficiency of the computation is improved when nlon c is a product of small prime numbers. c c NOTE: this is a modified version of spherepack. Changes from c the original version to the current one have only been c tested for isym==0. For this reason an error code will c be returned if isym!=0. c c isym this parameter should have the same value input to subroutine c shags to compute the coefficients a and b for the scalar field c sf. isym is set as follows: c c = 0 no symmetries exist in sf about the equator. scalar c synthesis is used to compute slap on the entire sphere. c i.e., in the array slap(i,j) for i=1,...,nlat and c j=1,...,nlon. c c = 1 sf and slap are antisymmetric about the equator. the c synthesis used to compute slap is performed on the c northern hemisphere only. if nlat is odd, slap(i,j) is c computed for i=1,...,(nlat+1)/2 and j=1,...,nlon. if c nlat is even, slap(i,j) is computed for i=1,...,nlat/2 c and j=1,...,nlon. c c c = 2 sf and slap are symmetric about the equator. the c synthesis used to compute slap is performed on the c northern hemisphere only. if nlat is odd, slap(i,j) is c computed for i=1,...,(nlat+1)/2 and j=1,...,nlon. if c nlat is even, slap(i,j) is computed for i=1,...,nlat/2 c and j=1,...,nlon. c c c nt the number of analyses. in the program that calls slapgs c the arrays slap,a, and b can be three dimensional in which c case multiple synthesis will be performed. the third index c is the synthesis index which assumes the values k=1,...,nt. c for a single analysis set nt=1. the description of the c remaining parameters is simplified by assuming that nt=1 c or that all the arrays are two dimensional. c c ids the first dimension of the array slap as it appears in the c program that calls slapgs. if isym = 0 then ids must be at c least nlat. if isym > 0 and nlat is even then ids must be c at least nlat/2. if isym > 0 and nlat is odd then ids must c be at least (nlat+1)/2. c c jds the second dimension of the array slap as it appears in the c program that calls slapgs. jds must be at least nlon. c c c a,b two or three dimensional arrays (see input parameter nt) c that contain scalar spherical harmonic coefficients c of the scalar field sf as computed by subroutine shags. c *** a,b must be computed by shags prior to calling slapgs. c c c mdab the first dimension of the arrays a and b as it appears c in the program that calls slapgs. mdab must be at c least min0(nlat,(nlon+2)/2) if nlon is even or at least c min0(nlat,(nlon+1)/2) if nlon is odd. c c ndab the second dimension of the arrays a and b as it appears c in the program that calls slapgs. ndbc must be at least c least nlat. c c mdab,ndab should have the same values input to shags to c compute the coefficients a and b. c c c wshsgs an array which must be initialized by subroutine slapgsi c (or equivalently by shsgsi). once initialized, wshsgs c can be used repeatedly by slapgs as long as nlat and nlon c remain unchanged. wshsgs must not be altered between calls c of slapgs. c c lshsgs the dimension of the array wshsgs as it appears in the c program that calls slapgs. let c c l1 = min0(nlat,(nlon+2)/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lshsgs must be at least c c nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 c c c work a work array that does not have to be saved. c c lwork the dimension of the array work as it appears in the c program that calls slapgs. define c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c l1 = min0(nlat,(nlon+2)/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c if isym is zero then lwork must be at least c c (nt+1)*nlat*nlon + nlat*(2*nt*l1+1) c c if isym is nonzero lwork must be at least c c (nt+1)*l2*nlon + nlat*(2*nt*l1+1) c c c ************************************************************** c c output parameters c c c slap a two or three dimensional arrays (see input parameter nt) that c contain the scalar laplacian of the scalar field sf. slap(i,j) c is the scalar laplacian at the gaussian colatitude theta(i) c and longitude lambda(j) = (j-1)*2*pi/nlon for i=1,...,nlat c and j=1,...,nlon. c c c ierror a parameter which flags errors in input parameters as follows: c c = 0 no errors detected c c = 1 error in the specification of nlat c c = 2 error in the specification of nlon c c = 3 error in the specification of ityp c c = 4 error in the specification of nt c c = 5 error in the specification of ids c c = 6 error in the specification of jds c c = 7 error in the specification of mdbc c c = 8 error in the specification of ndbc c c = 9 error in the specification of lshsgs c c = 10 error in the specification of lwork c c c ********************************************************************** c c end of documentation for slapgs c c ********************************************************************** c c subroutine slapgs(nstrlap,nstrab,noffslap,noffsab, + nlat,nlon,isym,nt,slap,ids,jds,a,b,mdab,ndab, + wshsgs,lshsgs,work,lwork,ierror) implicit double precision (a-h,o-z) dimension slap(nstrlap,ids,jds,nt), + a(nstrab,mdab,ndab,nt),b(nstrab,mdab,ndab,nt) dimension wshsgs(lshsgs),work(lwork) c c check input parameters c ierror = 1 if(nlat .lt. 3) return ierror = 2 if(nlon .lt. 4) return ierror = 3 c if (isym.lt.0 .or. isym.gt.2) return c see note above about symmeries if(isym.ne.0) return ierror = 4 if(nt .lt. 0) return ierror = 5 imid = (nlat+1)/2 if((isym.eq.0 .and. ids.lt.nlat) .or. 1 (isym.gt.0 .and. ids.lt.imid)) return ierror = 6 if(jds .lt. nlon) return ierror = 7 mmax = min0(nlat,nlon/2+1) if(mdab .lt. mmax) return ierror = 8 if(ndab .lt. nlat) return ierror = 9 c c set and verify saved work space length c imid = (nlat+1)/2 l2 = (nlat+mod(nlat,2))/2 l1 = min0((nlon+2)/2,nlat) lp=nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 if(lshsgs.lt.lp) return ierror = 10 c c set and verify unsaved work space length c ls = nlat if(isym .gt. 0) ls = imid nln = nt*ls*nlon mn = mmax*nlat*nt c lwkmin = nln+ls*nlon+2*mn+nlat c if (lwork .lt. lwkmin) return l2 = (nlat+1)/2 l1 = min0(nlat,nlon/2+1) if (isym.eq.0) then lwkmin = (nt+1)*nlat*nlon + nlat*(2*nt*l1+1) else lwkmin = (nt+1)*l2*nlon + nlat*(2*nt*l1+1) end if if (lwork .lt. lwkmin) return ierror = 11 if((noffslap.lt.0) .or. (noffslap.ge.nstrlap)) return if((noffsab.lt.0) .or. (noffsab.ge.nstrab)) return ierror = 0 c c set work space pointers c ia = 1 ib = ia+mn ifn = ib+mn iwk = ifn+nlat lwk = lwork-2*mn-nlat call slapgs1(nstrlap,nstrab,noffslap,noffsab, +nlat,nlon,isym,nt,slap,ids,jds,a,b,mdab,ndab, +work(ia),work(ib),mmax,work(ifn),wshsgs,lshsgs,work(iwk),lwk, +ierror) return end subroutine slapgs1(nstrlap,nstrab,noffslap,noffsab, + nlat,nlon,isym,nt,slap,ids,jds,a,b,mdab,ndab, + alap,blap,mmax,fnn,wsave,lsave,wk,lwk,ierror) implicit double precision (a-h,o-z) dimension slap(nstrlap,ids,jds,nt), + a(nstrab,mdab,ndab,nt),b(nstrab,mdab,ndab,nt) dimension alap(mmax,nlat,nt),blap(mmax,nlat,nt),fnn(nlat) dimension wsave(lsave),wk(lwk) ncab=1+noffsab c c set coefficient multiplyers c do 1 n=2,nlat fn = dfloat(n-1) fnn(n) = fn*(fn+1.d0) 1 continue c c compute scalar laplacian coefficients for each vector field c do 2 k=1,nt do 3 n=1,nlat do 4 m=1,mmax alap(m,n,k) = 0.0d0 blap(m,n,k) = 0.0d0 4 continue 3 continue c c compute m=0 coefficients c do 5 n=2,nlat alap(1,n,k) = -fnn(n)*a(ncab,1,n,k) blap(1,n,k) = -fnn(n)*b(ncab,1,n,k) 5 continue c c compute m>0 coefficients c do 6 m=2,mmax do 7 n=m,nlat alap(m,n,k) = -fnn(n)*a(ncab,m,n,k) blap(m,n,k) = -fnn(n)*b(ncab,m,n,k) 7 continue 6 continue 2 continue c c synthesize alap,blap into slap c call shsgs(nstrlap,1,noffslap,0, + nlat,nlon,isym,nt,slap,ids,jds,alap,blap, + mmax,nlat,mmax,nlat,wsave,lsave,wk,lwk,ierror) return end ================================================ FILE: external/SPHEREPACK/sphcom.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c ... file sphcom.f c c this file must be loaded with all main program files c in spherepack. it includes undocumented subroutines c called by some or all of main programs c subroutine dnlfk (m,n,cp) implicit double precision (a-h,o-z) c c cp requires n/2+1 double precision locations c double precision cp,fnum,fden,fnmh,a1,b1,c1,cp2,fnnp1,fnmsq,fk, 1 t1,t2,pm1,sc10,sc20,sc40 dimension cp(1) parameter (sc10=1024.d0) parameter (sc20=sc10*sc10) parameter (sc40=sc20*sc20) c cp(1) = 0.d0 ma = iabs(m) if(ma .gt. n) return if(n-1) 2,3,5 2 cp(1) = dsqrt(2.d0) return 3 if(ma .ne. 0) go to 4 cp(1) = dsqrt(1.5d0) return 4 cp(1) = dsqrt(.75d0) if(m .eq. -1) cp(1) = -cp(1) return 5 if(mod(n+ma,2) .ne. 0) go to 10 nmms2 = (n-ma)/2 fnum = n+ma+1 fnmh = n-ma+1 pm1 = 1.d0 go to 15 10 nmms2 = (n-ma-1)/2 fnum = n+ma+2 fnmh = n-ma+2 pm1 = -1.d0 c t1 = 1. c t1 = 2.d0**(n-1) c t1 = 1.d0/t1 15 t1 = 1.d0/sc20 nex = 20 fden = 2.d0 if(nmms2 .lt. 1) go to 20 do 18 i=1,nmms2 t1 = fnum*t1/fden if(t1 .gt. sc20) then t1 = t1/sc40 nex = nex+40 end if fnum = fnum+2.d0 fden = fden+2.d0 18 continue 20 t1 = t1/2.d0**(n-1-nex) if(mod(ma/2,2) .ne. 0) t1 = -t1 t2 = 1.d0 if(ma .eq. 0) go to 26 do 25 i=1,ma t2 = fnmh*t2/(fnmh+pm1) fnmh = fnmh+2.d0 25 continue 26 cp2 = t1*dsqrt((n+.5d0)*t2) fnnp1 = n*(n+1) fnmsq = fnnp1-2.d0*ma*ma l = (n+1)/2 if(mod(n,2) .eq. 0 .and. mod(ma,2) .eq. 0) l = l+1 cp(l) = cp2 if(m .ge. 0) go to 29 if(mod(ma,2) .ne. 0) cp(l) = -cp(l) 29 if(l .le. 1) return fk = n a1 = (fk-2.d0)*(fk-1.d0)-fnnp1 b1 = 2.d0*(fk*fk-fnmsq) cp(l-1) = b1*cp(l)/a1 30 l = l-1 if(l .le. 1) return fk = fk-2.d0 a1 = (fk-2.d0)*(fk-1.d0)-fnnp1 b1 = -2.d0*(fk*fk-fnmsq) c1 = (fk+1.d0)*(fk+2.d0)-fnnp1 cp(l-1) = -(b1*cp(l)+c1*cp(l+1))/a1 go to 30 end subroutine dnlft (m,n,theta,cp,pb) implicit double precision (a-h,o-z) double precision cp(*),pb,theta,cdt,sdt,cth,sth,chh cdt = dcos(theta+theta) sdt = dsin(theta+theta) nmod=mod(n,2) mmod=mod(m,2) if(nmod)1,1,2 1 if(mmod)3,3,4 c c n even, m even c 3 kdo=n/2 pb = .5d0*cp(1) if(n .eq. 0) return cth = cdt sth = sdt do 170 k=1,kdo c pb = pb+cp(k+1)*dcos(2*k*theta) pb = pb+cp(k+1)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 170 continue return c c n even, m odd c 4 kdo = n/2 pb = 0.d0 cth = cdt sth = sdt do 180 k=1,kdo c pb = pb+cp(k)*dsin(2*k*theta) pb = pb+cp(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 180 continue return 2 if(mmod)13,13,14 c c n odd, m even c 13 kdo = (n+1)/2 pb = 0.d0 cth = dcos(theta) sth = dsin(theta) do 190 k=1,kdo c pb = pb+cp(k)*dcos((2*k-1)*theta) pb = pb+cp(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 190 continue return c c n odd, m odd c 14 kdo = (n+1)/2 pb = 0.d0 cth = dcos(theta) sth = dsin(theta) do 200 k=1,kdo c pb = pb+cp(k)*dsin((2*k-1)*theta) pb = pb+cp(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 200 continue return end subroutine dnlftd (m,n,theta,cp,pb) implicit double precision (a-h,o-z) c c computes the derivative of pmn(theta) with respect to theta c dimension cp(1) double precision cp,pb,theta,cdt,sdt,cth,sth,chh cdt = dcos(theta+theta) sdt = dsin(theta+theta) nmod=mod(n,2) mmod=mod(abs(m),2) if(nmod)1,1,2 1 if(mmod)3,3,4 c c n even, m even c 3 kdo=n/2 pb = 0.d0 if(n .eq. 0) return cth = cdt sth = sdt do 170 k=1,kdo c pb = pb+cp(k+1)*dcos(2*k*theta) pb = pb-2.d0*k*cp(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 170 continue return c c n even, m odd c 4 kdo = n/2 pb = 0.d0 cth = cdt sth = sdt do 180 k=1,kdo c pb = pb+cp(k)*dsin(2*k*theta) pb = pb+2.d0*k*cp(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 180 continue return 2 if(mmod)13,13,14 c c n odd, m even c 13 kdo = (n+1)/2 pb = 0.d0 cth = dcos(theta) sth = dsin(theta) do 190 k=1,kdo c pb = pb+cp(k)*dcos((2*k-1)*theta) pb = pb-(2.d0*k-1)*cp(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 190 continue return c c n odd, m odd c 14 kdo = (n+1)/2 pb = 0.d0 cth = dcos(theta) sth = dsin(theta) do 200 k=1,kdo c pb = pb+cp(k)*dsin((2*k-1)*theta) pb = pb+(2.d0*k-1)*cp(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 200 continue return end subroutine legin(mode,l,nlat,m,w,pmn,km,km0,km1,km2) implicit double precision (a-h,o-z) c this subroutine computes legendre polynomials for n=m,...,l-1 c and i=1,...,late (late=((nlat+mod(nlat,2))/2)gaussian grid c in pmn(n+1,i,km) using swarztrauber's recursion formula. c the vector w contains quantities precomputed in shigc. c legin must be called in the order m=0,1,...,l-1 c (e.g., if m=10 is sought it must be preceded by calls with c m=0,1,2,...,9 in that order) dimension w(1),pmn(1) c set size of pole to equator gaussian grid late = (nlat+mod(nlat,2))/2 c partition w (set pointers for p0n,p1n,abel,bbel,cbel,pmn) i1 = 1+nlat i2 = i1+nlat*late i3 = i2+nlat*late i4 = i3+(2*nlat-l)*(l-1)/2 i5 = i4+(2*nlat-l)*(l-1)/2 call legin1(mode,l,nlat,late,m,w(i1),w(i2),w(i3),w(i4), 1 w(i5),pmn,km,km0,km1,km2) return end subroutine legin1(mode,l,nlat,late,m,p0n,p1n,abel,bbel,cbel, 1 pmn,km,km0,km1,km2) implicit double precision (a-h,o-z) dimension p0n(nlat,late),p1n(nlat,late) dimension abel(1),bbel(1),cbel(1),pmn(nlat,late,3) c define index function used in storing triangular c arrays for recursion coefficients (functions of (m,n)) c for 2.le.m.le.n-1 and 2.le.n.le.l-1 indx(m,n) = (n-1)*(n-2)/2+m-1 c for l.le.n.le.nlat and 2.le.m.le.l imndx(m,n) = l*(l-1)/2+(n-l-1)*(l-1)+m-1 c set do loop indices for full or half sphere ms = m+1 ninc = 1 if (mode.eq.1) then c only compute pmn for n-m odd ms = m+2 ninc = 2 else if (mode.eq.2) then c only compute pmn for n-m even ms = m+1 ninc = 2 end if if (m.gt.1) then do 100 np1=ms,nlat,ninc n = np1-1 imn = indx(m,n) if (n.ge.l) imn = imndx(m,n) do 100 i=1,late pmn(np1,i,km0) = abel(imn)*pmn(n-1,i,km2) 1 +bbel(imn)*pmn(n-1,i,km0) 2 -cbel(imn)*pmn(np1,i,km2) 100 continue else if (m.eq.0) then do 101 np1=ms,nlat,ninc do 101 i=1,late pmn(np1,i,km0) = p0n(np1,i) 101 continue else if (m.eq.1) then do 102 np1=ms,nlat,ninc do 102 i=1,late pmn(np1,i,km0) = p1n(np1,i) 102 continue end if c permute column indices c km0,km1,km2 store m,m-1,m-2 columns kmt = km0 km0 = km2 km2 = km1 km1 = kmt c set current m index in output param km km = kmt return end c$$$ subroutine zfin (isym,nlat,nlon,m,z,i3,wzfin) c$$$ implicit double precision (a-h,o-z) c$$$ dimension z(1) ,wzfin(1) c$$$ imid = (nlat+1)/2 c$$$ lim = nlat*imid c$$$ mmax = min0(nlat,nlon/2+1) c$$$ labc = ((mmax-2)*(nlat+nlat-mmax-1))/2 c$$$ iw1 = lim+1 c$$$ iw2 = iw1+lim c$$$ iw3 = iw2+labc c$$$ iw4 = iw3+labc c$$$c c$$$c the length of wzfin is 2*lim+3*labc c$$$c c$$$ call zfin1 (isym,nlat,m,z,imid,i3,wzfin,wzfin(iw1),wzfin(iw2), c$$$ 1 wzfin(iw3),wzfin(iw4)) c$$$ return c$$$ end c$$$ subroutine zfin1 (isym,nlat,m,z,imid,i3,zz,z1,a,b,c) c$$$ implicit double precision (a-h,o-z) c$$$ dimension z(imid,nlat,3),zz(imid,1),z1(imid,1), c$$$ 1 a(1),b(1),c(1) c$$$ save i1,i2 c$$$ ihold = i1 c$$$ i1 = i2 c$$$ i2 = i3 c$$$ i3 = ihold c$$$ if(m-1)25,30,35 c$$$ 25 i1 = 1 c$$$ i2 = 2 c$$$ i3 = 3 c$$$ do 45 np1=1,nlat c$$$ do 45 i=1,imid c$$$ z(i,np1,i3) = zz(i,np1) c$$$ 45 continue c$$$ return c$$$ 30 do 50 np1=2,nlat c$$$ do 50 i=1,imid c$$$ z(i,np1,i3) = z1(i,np1) c$$$ 50 continue c$$$ return c$$$ 35 ns = ((m-2)*(nlat+nlat-m-1))/2+1 c$$$ if(isym .eq. 1) go to 36 c$$$ do 85 i=1,imid c$$$ z(i,m+1,i3) = a(ns)*z(i,m-1,i1)-c(ns)*z(i,m+1,i1) c$$$ 85 continue c$$$ 36 if(m .eq. nlat-1) return c$$$ if(isym .eq. 2) go to 71 c$$$ ns = ns+1 c$$$ do 70 i=1,imid c$$$ z(i,m+2,i3) = a(ns)*z(i,m,i1)-c(ns)*z(i,m+2,i1) c$$$ 70 continue c$$$ 71 nstrt = m+3 c$$$ if(isym .eq. 1) nstrt = m+4 c$$$ if(nstrt .gt. nlat) go to 80 c$$$ nstp = 2 c$$$ if(isym .eq. 0) nstp = 1 c$$$ do 75 np1=nstrt,nlat,nstp c$$$ ns = ns+nstp c$$$ do 75 i=1,imid c$$$ z(i,np1,i3) = a(ns)*z(i,np1-2,i1)+b(ns)*z(i,np1-2,i3) c$$$ 1 -c(ns)*z(i,np1,i1) c$$$ 75 continue c$$$ 80 return c$$$ end subroutine zfinit (nlat,nlon,wzfin,dwork) implicit double precision (a-h,o-z) dimension wzfin(*) double precision dwork(*) imid = (nlat+1)/2 iw1 = 2*nlat*imid+1 c c the length of wzfin is 3*((l-3)*l+2)/2 + 2*l*imid c the length of dwork is nlat+2 c call zfini1 (nlat,nlon,imid,wzfin,wzfin(iw1),dwork, 1 dwork(nlat/2+1)) return end subroutine zfini1 (nlat,nlon,imid,z,abc,cz,work) implicit double precision (a-h,o-z) c c abc must have 3*((mmax-2)*(nlat+nlat-mmax-1))/2 locations c where mmax = min0(nlat,nlon/2+1) c cz and work must each have nlat+1 locations c dimension z(imid,nlat,2),abc(1) double precision pi,dt,th,zh,cz(*),work(*) pi = 4.d0*datan(1.d0) dt = pi/(nlat-1) do 160 mp1=1,2 m = mp1-1 do 160 np1=mp1,nlat n = np1-1 call dnzfk(nlat,m,n,cz,work) do 165 i=1,imid th = (i-1)*dt call dnzft(nlat,m,n,th,cz,zh) z(i,np1,mp1) = zh 165 continue z(1,np1,mp1) = .5d0*z(1,np1,mp1) 160 continue call rabcp(nlat,nlon,abc) return end subroutine dnzfk(nlat,m,n,cz,work) implicit double precision (a-h,o-z) c c dnzfk computes the coefficients in the trigonometric c expansion of the z functions that are used in spherical c harmonic analysis. c dimension cz(1),work(1) c c cz and work must both have nlat/2+1 locations c double precision sum,sc1,t1,t2,work,cz lc = (nlat+1)/2 sc1 = 2.d0/dfloat(nlat-1) call dnlfk(m,n,work) nmod = mod(n,2) mmod = mod(m,2) if(nmod)1,1,2 1 if(mmod)3,3,4 c c n even, m even c 3 kdo = n/2+1 do 5 idx=1,lc i = idx+idx-2 sum = work(1)/(1.d0-i*i) if(kdo.lt.2) go to 29 do 6 kp1=2,kdo k = kp1-1 t1 = 1.d0-(k+k+i)**2 t2 = 1.d0-(k+k-i)**2 8 sum = sum+work(kp1)*(t1+t2)/(t1*t2) 6 continue 29 cz(idx) = sc1*sum 5 continue return c c n even, m odd c 4 kdo = n/2 do 9 idx=1,lc i = idx+idx-2 sum = 0.d0 do 101 k=1,kdo t1 = 1.d0-(k+k+i)**2 t2 = 1.d0-(k+k-i)**2 12 sum=sum+work(k)*(t1-t2)/(t1*t2) 101 continue cz(idx) = sc1*sum 9 continue return 2 if(mmod)13,13,14 c c n odd, m even c 13 kdo = (n+1)/2 do 15 idx=1,lc i = idx+idx-1 sum = 0.d0 do 16 k=1,kdo t1 = 1.d0-(k+k-1+i)**2 t2 = 1.d0-(k+k-1-i)**2 18 sum=sum+work(k)*(t1+t2)/(t1*t2) 16 continue cz(idx)=sc1*sum 15 continue return c c n odd, m odd c 14 kdo = (n+1)/2 do 19 idx=1,lc i = idx+idx-3 sum=0.d0 do 20 k=1,kdo t1 = 1.d0-(k+k-1+i)**2 t2 = 1.d0-(k+k-1-i)**2 22 sum=sum+work(k)*(t1-t2)/(t1*t2) 20 continue cz(idx)=sc1*sum 19 continue return end subroutine dnzft(nlat,m,n,th,cz,zh) implicit double precision (a-h,o-z) dimension cz(1) double precision cz,zh,th,cdt,sdt,cth,sth,chh zh = 0.d0 cdt = dcos(th+th) sdt = dsin(th+th) lmod = mod(nlat,2) mmod = mod(m,2) nmod = mod(n,2) if(lmod)20,20,10 10 lc = (nlat+1)/2 lq = lc-1 ls = lc-2 if(nmod)1,1,2 1 if(mmod)3,3,4 c c nlat odd n even m even c 3 zh = .5d0*(cz(1)+cz(lc)*dcos(2*lq*th)) cth = cdt sth = sdt do 201 k=2,lq c zh = zh+cz(k)*dcos(2*(k-1)*th) zh = zh+cz(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 201 continue return c c nlat odd n even m odd c 4 cth = cdt sth = sdt do 202 k=1,ls c zh = zh+cz(k+1)*dsin(2*k*th) zh = zh+cz(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 202 continue return c c nlat odd n odd, m even c 2 if(mmod)5,5,6 5 cth = dcos(th) sth = dsin(th) do 203 k=1,lq c zh = zh+cz(k)*dcos((2*k-1)*th) zh = zh+cz(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 203 continue return c c nlat odd n odd m odd c 6 cth = dcos(th) sth = dsin(th) do 204 k=1,lq c zh = zh+cz(k+1)*dsin((2*k-1)*th) zh = zh+cz(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 204 continue return 20 lc = nlat/2 lq = lc-1 if(nmod)30,30,80 30 if(mmod)40,40,60 c c nlat even n even m even c 40 zh = .5d0*cz(1) cth = cdt sth = sdt do 50 k=2,lc c zh = zh+cz(k)*dcos(2*(k-1)*th) zh = zh+cz(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 50 continue return c c nlat even n even m odd c 60 cth = cdt sth = sdt do 70 k=1,lq c zh = zh+cz(k+1)*dsin(2*k*th) zh = zh+cz(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 70 continue return c c nlat even n odd m even c 80 if(mmod)90,90,110 90 zh = .5d0*cz(lc)*dcos((nlat-1)*th) cth = dcos(th) sth = dsin(th) do 100 k=1,lq c zh = zh+cz(k)*dcos((2*k-1)*th) zh = zh+cz(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 100 continue return c c nlat even n odd m odd c 110 cth = dcos(th) sth = dsin(th) do 120 k=1,lq c zh = zh+cz(k+1)*dsin((2*k-1)*th) zh = zh+cz(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 120 continue return end c$$$ subroutine alin (isym,nlat,nlon,m,p,i3,walin) c$$$ implicit double precision (a-h,o-z) c$$$ dimension p(1) ,walin(1) c$$$ imid = (nlat+1)/2 c$$$ lim = nlat*imid c$$$ mmax = min0(nlat,nlon/2+1) c$$$ labc = ((mmax-2)*(nlat+nlat-mmax-1))/2 c$$$ iw1 = lim+1 c$$$ iw2 = iw1+lim c$$$ iw3 = iw2+labc c$$$ iw4 = iw3+labc c$$$c c$$$c the length of walin is ((5*l-7)*l+6)/2 c$$$c c$$$ call alin1 (isym,nlat,m,p,imid,i3,walin,walin(iw1),walin(iw2), c$$$ 1 walin(iw3),walin(iw4)) c$$$ return c$$$ end c$$$ subroutine alin1 (isym,nlat,m,p,imid,i3,pz,p1,a,b,c) c$$$ implicit double precision (a-h,o-z) c$$$ dimension p(imid,nlat,3),pz(imid,1),p1(imid,1), c$$$ 1 a(1),b(1),c(1) c$$$ save i1,i2 c$$$ ihold = i1 c$$$ i1 = i2 c$$$ i2 = i3 c$$$ i3 = ihold c$$$ if(m-1)25,30,35 c$$$ 25 i1 = 1 c$$$ i2 = 2 c$$$ i3 = 3 c$$$ do 45 np1=1,nlat c$$$ do 45 i=1,imid c$$$ p(i,np1,i3) = pz(i,np1) c$$$ 45 continue c$$$ return c$$$ 30 do 50 np1=2,nlat c$$$ do 50 i=1,imid c$$$ p(i,np1,i3) = p1(i,np1) c$$$ 50 continue c$$$ return c$$$ 35 ns = ((m-2)*(nlat+nlat-m-1))/2+1 c$$$ if(isym .eq. 1) go to 36 c$$$ do 85 i=1,imid c$$$ p(i,m+1,i3) = a(ns)*p(i,m-1,i1)-c(ns)*p(i,m+1,i1) c$$$ 85 continue c$$$ 36 if(m .eq. nlat-1) return c$$$ if(isym .eq. 2) go to 71 c$$$ ns = ns+1 c$$$ do 70 i=1,imid c$$$ p(i,m+2,i3) = a(ns)*p(i,m,i1)-c(ns)*p(i,m+2,i1) c$$$ 70 continue c$$$ 71 nstrt = m+3 c$$$ if(isym .eq. 1) nstrt = m+4 c$$$ if(nstrt .gt. nlat) go to 80 c$$$ nstp = 2 c$$$ if(isym .eq. 0) nstp = 1 c$$$ do 75 np1=nstrt,nlat,nstp c$$$ ns = ns+nstp c$$$ do 75 i=1,imid c$$$ p(i,np1,i3) = a(ns)*p(i,np1-2,i1)+b(ns)*p(i,np1-2,i3) c$$$ 1 -c(ns)*p(i,np1,i1) c$$$ 75 continue c$$$ 80 return c$$$ end subroutine alinit (nlat,nlon,walin,dwork) implicit double precision (a-h,o-z) dimension walin(*) double precision dwork(*) imid = (nlat+1)/2 iw1 = 2*nlat*imid+1 c c the length of walin is 3*((l-3)*l+2)/2 + 2*l*imid c the length of work is nlat+1 c call alini1 (nlat,nlon,imid,walin,walin(iw1),dwork) return end subroutine alini1 (nlat,nlon,imid,p,abc,cp) implicit double precision (a-h,o-z) dimension p(imid,nlat,2),abc(1),cp(1) double precision pi,dt,th,cp,ph pi = 4.d0*datan(1.d0) dt = pi/(nlat-1) do 160 mp1=1,2 m = mp1-1 do 160 np1=mp1,nlat n = np1-1 call dnlfk (m,n,cp) do 160 i=1,imid th = (i-1)*dt call dnlft (m,n,th,cp,ph) p(i,np1,mp1) = ph 160 continue call rabcp(nlat,nlon,abc) return end subroutine rabcp(nlat,nlon,abc) implicit double precision (a-h,o-z) c c subroutine rabcp computes the coefficients in the recurrence c relation for the associated legendre fuctions. array abc c must have 3*((mmax-2)*(nlat+nlat-mmax-1))/2 locations. c dimension abc(1) mmax = min0(nlat,nlon/2+1) labc = ((mmax-2)*(nlat+nlat-mmax-1))/2 iw1 = labc+1 iw2 = iw1+labc call rabcp1(nlat,nlon,abc,abc(iw1),abc(iw2)) return end subroutine rabcp1(nlat,nlon,a,b,c) implicit double precision (a-h,o-z) c c coefficients a, b, and c for computing pbar(m,n,theta) are c stored in location ((m-2)*(nlat+nlat-m-1))/2+n+1 c dimension a(1),b(1),c(1) mmax = min0(nlat,nlon/2+1) do 215 mp1=3,mmax m = mp1-1 ns = ((m-2)*(nlat+nlat-m-1))/2+1 fm = dfloat(m) tm = fm+fm temp = tm*(tm-1.d0) a(ns) = dsqrt((tm+1.d0)*(tm-2.d0)/temp) c(ns) = dsqrt(2.d0/temp) if(m .eq. nlat-1) go to 215 ns = ns+1 temp = tm*(tm+1.d0) a(ns) = dsqrt((tm+3.d0)*(tm-2.d0)/temp) c(ns) = dsqrt(6.d0/temp) mp3 = m+3 if(mp3 .gt. nlat) go to 215 do 210 np1=mp3,nlat n = np1-1 ns = ns+1 fn = dfloat(n) tn = fn+fn cn = (tn+1.d0)/(tn-3.d0) fnpm = fn+fm fnmm = fn-fm temp = fnpm*(fnpm-1.d0) a(ns) = dsqrt(cn*(fnpm-3.d0)*(fnpm-2.d0)/temp) b(ns) = dsqrt(cn*fnmm*(fnmm-1.d0)/temp) c(ns) = dsqrt((fnmm+1.d0)*(fnmm+2.d0)/temp) 210 continue 215 continue return end c$$$ subroutine sea1(nlat,nlon,imid,z,idz,zin,wzfin,dwork) c$$$ implicit double precision (a-h,o-z) c$$$ dimension z(idz,*),zin(imid,nlat,3),wzfin(*) c$$$ double precision dwork(*) c$$$ call zfinit(nlat,nlon,wzfin,dwork) c$$$ mmax = min0(nlat,nlon/2+1) c$$$ do 33 mp1=1,mmax c$$$ m = mp1-1 c$$$ call zfin (0,nlat,nlon,m,zin,i3,wzfin) c$$$ do 33 np1=mp1,nlat c$$$ mn = m*(nlat-1)-(m*(m-1))/2+np1 c$$$ do 33 i=1,imid c$$$ z(mn,i) = zin(i,np1,i3) c$$$ 33 continue c$$$ return c$$$ end c$$$ subroutine ses1(nlat,nlon,imid,p,pin,walin,dwork) c$$$ implicit double precision (a-h,o-z) c$$$ dimension p(imid,*),pin(imid,nlat,3),walin(*) c$$$ double precision dwork(*) c$$$ call alinit (nlat,nlon,walin,dwork) c$$$ mmax = min0(nlat,nlon/2+1) c$$$ do 10 mp1=1,mmax c$$$ m = mp1-1 c$$$ call alin(0,nlat,nlon,m,pin,i3,walin) c$$$ do 10 np1=mp1,nlat c$$$ mn = m*(nlat-1)-(m*(m-1))/2+np1 c$$$ do 10 i=1,imid c$$$ p(i,mn) = pin(i,np1,i3) c$$$ 10 continue c$$$ return c$$$ end subroutine zvinit (nlat,nlon,wzvin,dwork) implicit double precision (a-h,o-z) dimension wzvin(1) double precision dwork(*) imid = (nlat+1)/2 iw1 = 2*nlat*imid+1 c c the length of wzvin is c 2*nlat*imid +3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 c the length of dwork is nlat+2 c call zvini1 (nlat,nlon,imid,wzvin,wzvin(iw1),dwork, 1 dwork(nlat/2+2)) return end subroutine zvini1 (nlat,nlon,imid,zv,abc,czv,work) implicit double precision (a-h,o-z) c c abc must have 3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 c locations where mmax = min0(nlat,(nlon+1)/2) c czv and work must each have nlat/2+1 locations c dimension zv(imid,nlat,2),abc(1) double precision pi,dt,czv(1),zvh,th,work(1) pi = 4.d0*datan(1.d0) dt = pi/(nlat-1) mdo = min0(2,nlat,(nlon+1)/2) do 160 mp1=1,mdo m = mp1-1 do 160 np1=mp1,nlat n = np1-1 call dzvk(nlat,m,n,czv,work) do 165 i=1,imid th = (i-1)*dt call dzvt(nlat,m,n,th,czv,zvh) zv(i,np1,mp1) = zvh 165 continue zv(1,np1,mp1) = .5d0*zv(1,np1,mp1) 160 continue call rabcv(nlat,nlon,abc) return end subroutine zwinit (nlat,nlon,wzwin,dwork) implicit double precision (a-h,o-z) dimension wzwin(1) double precision dwork(*) imid = (nlat+1)/2 iw1 = 2*nlat*imid+1 c c the length of wzvin is 2*nlat*imid+3*((nlat-3)*nlat+2)/2 c the length of dwork is nlat+2 c call zwini1 (nlat,nlon,imid,wzwin,wzwin(iw1),dwork, 1 dwork(nlat/2+2)) return end subroutine zwini1 (nlat,nlon,imid,zw,abc,czw,work) implicit double precision (a-h,o-z) c c abc must have 3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 c locations where mmax = min0(nlat,(nlon+1)/2) c czw and work must each have nlat+1 locations c dimension zw(imid,nlat,2),abc(1) double precision pi,dt,czw(1),zwh,th,work(1) pi = 4.d0*datan(1.d0) dt = pi/(nlat-1) mdo = min0(3,nlat,(nlon+1)/2) if(mdo .lt. 2) return do 160 mp1=2,mdo m = mp1-1 do 160 np1=mp1,nlat n = np1-1 call dzwk(nlat,m,n,czw,work) do 165 i=1,imid th = (i-1)*dt call dzwt(nlat,m,n,th,czw,zwh) zw(i,np1,m) = zwh 165 continue zw(1,np1,m) = .5d0*zw(1,np1,m) 160 continue call rabcw(nlat,nlon,abc) return end c$$$ subroutine zvin (ityp,nlat,nlon,m,zv,i3,wzvin) c$$$ implicit double precision (a-h,o-z) c$$$ dimension zv(1) ,wzvin(1) c$$$ imid = (nlat+1)/2 c$$$ lim = nlat*imid c$$$ mmax = min0(nlat,(nlon+1)/2) c$$$ labc = (max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 c$$$ iw1 = lim+1 c$$$ iw2 = iw1+lim c$$$ iw3 = iw2+labc c$$$ iw4 = iw3+labc c$$$c c$$$c the length of wzvin is 2*lim+3*labc c$$$c c$$$ call zvin1 (ityp,nlat,m,zv,imid,i3,wzvin,wzvin(iw1),wzvin(iw2), c$$$ 1 wzvin(iw3),wzvin(iw4)) c$$$ return c$$$ end c$$$ subroutine zvin1 (ityp,nlat,m,zv,imid,i3,zvz,zv1,a,b,c) c$$$ implicit double precision (a-h,o-z) c$$$ dimension zv(imid,nlat,3),zvz(imid,1),zv1(imid,1), c$$$ 1 a(1),b(1),c(1) c$$$ save i1,i2 c$$$ ihold = i1 c$$$ i1 = i2 c$$$ i2 = i3 c$$$ i3 = ihold c$$$ if(m-1)25,30,35 c$$$ 25 i1 = 1 c$$$ i2 = 2 c$$$ i3 = 3 c$$$ do 45 np1=1,nlat c$$$ do 45 i=1,imid c$$$ zv(i,np1,i3) = zvz(i,np1) c$$$ 45 continue c$$$ return c$$$ 30 do 50 np1=2,nlat c$$$ do 50 i=1,imid c$$$ zv(i,np1,i3) = zv1(i,np1) c$$$ 50 continue c$$$ return c$$$ 35 ns = ((m-2)*(nlat+nlat-m-1))/2+1 c$$$ if(ityp .eq. 1) go to 36 c$$$ do 85 i=1,imid c$$$ zv(i,m+1,i3) = a(ns)*zv(i,m-1,i1)-c(ns)*zv(i,m+1,i1) c$$$ 85 continue c$$$ 36 if(m .eq. nlat-1) return c$$$ if(ityp .eq. 2) go to 71 c$$$ ns = ns+1 c$$$ do 70 i=1,imid c$$$ zv(i,m+2,i3) = a(ns)*zv(i,m,i1)-c(ns)*zv(i,m+2,i1) c$$$ 70 continue c$$$ 71 nstrt = m+3 c$$$ if(ityp .eq. 1) nstrt = m+4 c$$$ if(nstrt .gt. nlat) go to 80 c$$$ nstp = 2 c$$$ if(ityp .eq. 0) nstp = 1 c$$$ do 75 np1=nstrt,nlat,nstp c$$$ ns = ns+nstp c$$$ do 75 i=1,imid c$$$ zv(i,np1,i3) = a(ns)*zv(i,np1-2,i1)+b(ns)*zv(i,np1-2,i3) c$$$ 1 -c(ns)*zv(i,np1,i1) c$$$ 75 continue c$$$ 80 return c$$$ end c$$$ subroutine zwin (ityp,nlat,nlon,m,zw,i3,wzwin) c$$$ implicit double precision (a-h,o-z) c$$$ dimension zw(1) ,wzwin(1) c$$$ imid = (nlat+1)/2 c$$$ lim = nlat*imid c$$$ mmax = min0(nlat,(nlon+1)/2) c$$$ labc = (max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 c$$$ iw1 = lim+1 c$$$ iw2 = iw1+lim c$$$ iw3 = iw2+labc c$$$ iw4 = iw3+labc c$$$c c$$$c the length of wzwin is 2*lim+3*labc c$$$c c$$$ call zwin1 (ityp,nlat,m,zw,imid,i3,wzwin,wzwin(iw1),wzwin(iw2), c$$$ 1 wzwin(iw3),wzwin(iw4)) c$$$ return c$$$ end c$$$ subroutine zwin1 (ityp,nlat,m,zw,imid,i3,zw1,zw2,a,b,c) c$$$ implicit double precision (a-h,o-z) c$$$ dimension zw(imid,nlat,3),zw1(imid,1),zw2(imid,1), c$$$ 1 a(1),b(1),c(1) c$$$ save i1,i2 c$$$ ihold = i1 c$$$ i1 = i2 c$$$ i2 = i3 c$$$ i3 = ihold c$$$ if(m-2)25,30,35 c$$$ 25 i1 = 1 c$$$ i2 = 2 c$$$ i3 = 3 c$$$ do 45 np1=2,nlat c$$$ do 45 i=1,imid c$$$ zw(i,np1,i3) = zw1(i,np1) c$$$ 45 continue c$$$ return c$$$ 30 do 50 np1=3,nlat c$$$ do 50 i=1,imid c$$$ zw(i,np1,i3) = zw2(i,np1) c$$$ 50 continue c$$$ return c$$$ 35 ns = ((m-2)*(nlat+nlat-m-1))/2+1 c$$$ if(ityp .eq. 1) go to 36 c$$$ do 85 i=1,imid c$$$ zw(i,m+1,i3) = a(ns)*zw(i,m-1,i1)-c(ns)*zw(i,m+1,i1) c$$$ 85 continue c$$$ 36 if(m .eq. nlat-1) return c$$$ if(ityp .eq. 2) go to 71 c$$$ ns = ns+1 c$$$ do 70 i=1,imid c$$$ zw(i,m+2,i3) = a(ns)*zw(i,m,i1)-c(ns)*zw(i,m+2,i1) c$$$ 70 continue c$$$ 71 nstrt = m+3 c$$$ if(ityp .eq. 1) nstrt = m+4 c$$$ if(nstrt .gt. nlat) go to 80 c$$$ nstp = 2 c$$$ if(ityp .eq. 0) nstp = 1 c$$$ do 75 np1=nstrt,nlat,nstp c$$$ ns = ns+nstp c$$$ do 75 i=1,imid c$$$ zw(i,np1,i3) = a(ns)*zw(i,np1-2,i1)+b(ns)*zw(i,np1-2,i3) c$$$ 1 -c(ns)*zw(i,np1,i1) c$$$ 75 continue c$$$ 80 return c$$$ end subroutine vbinit (nlat,nlon,wvbin,dwork) implicit double precision (a-h,o-z) dimension wvbin(1) double precision dwork(*) imid = (nlat+1)/2 iw1 = 2*nlat*imid+1 c c the length of wvbin is 2*nlat*imid+3*((nlat-3)*nlat+2)/2 c the length of dwork is nlat+2 c call vbini1 (nlat,nlon,imid,wvbin,wvbin(iw1),dwork, 1 dwork(nlat/2+2)) return end subroutine vbini1 (nlat,nlon,imid,vb,abc,cvb,work) implicit double precision (a-h,o-z) c c abc must have 3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 c locations where mmax = min0(nlat,(nlon+1)/2) c cvb and work must each have nlat+1 locations c dimension vb(imid,nlat,2),abc(1) double precision pi,dt,cvb(1),th,vbh,work(1) pi = 4.d0*datan(1.d0) dt = pi/(nlat-1) mdo = min0(2,nlat,(nlon+1)/2) do 160 mp1=1,mdo m = mp1-1 do 160 np1=mp1,nlat n = np1-1 call dvbk(m,n,cvb,work) do 165 i=1,imid th = (i-1)*dt call dvbt(m,n,th,cvb,vbh) vb(i,np1,mp1) = vbh 165 continue 160 continue call rabcv(nlat,nlon,abc) return end subroutine wbinit (nlat,nlon,wwbin,dwork) implicit double precision (a-h,o-z) dimension wwbin(1) double precision dwork(*) imid = (nlat+1)/2 iw1 = 2*nlat*imid+1 c c the length of wwbin is 2*nlat*imid+3*((nlat-3)*nlat+2)/2 c the length of dwork is nlat+2 c call wbini1 (nlat,nlon,imid,wwbin,wwbin(iw1),dwork, 1 dwork(nlat/2+2)) return end subroutine wbini1 (nlat,nlon,imid,wb,abc,cwb,work) implicit double precision (a-h,o-z) c c abc must have 3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 c locations where mmax = min0(nlat,(nlon+1)/2) c cwb and work must each have nlat/2+1 locations c dimension wb(imid,nlat,2),abc(1) double precision pi,dt,cwb(1),wbh,th,work(1) pi = 4.d0*datan(1.d0) dt = pi/(nlat-1) mdo = min0(3,nlat,(nlon+1)/2) if(mdo .lt. 2) return do 160 mp1=2,mdo m = mp1-1 do 160 np1=mp1,nlat n = np1-1 call dwbk(m,n,cwb,work) do 165 i=1,imid th = (i-1)*dt call dwbt(m,n,th,cwb,wbh) wb(i,np1,m) = wbh 165 continue 160 continue call rabcw(nlat,nlon,abc) return end subroutine vbin (ityp,nlat,nlon,m,vb,i3,wvbin,i1,i2) implicit double precision (a-h,o-z) dimension vb(1) ,wvbin(1) imid = (nlat+1)/2 lim = nlat*imid mmax = min0(nlat,(nlon+1)/2) labc = (max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 iw1 = lim+1 iw2 = iw1+lim iw3 = iw2+labc iw4 = iw3+labc c c the length of wvbin is 2*lim+3*labc c call vbin1 (ityp,nlat,m,vb,imid,i3,wvbin,wvbin(iw1),wvbin(iw2), 1 wvbin(iw3),wvbin(iw4),i1,i2) return end subroutine vbin1 (ityp,nlat,m,vb,imid,i3,vbz,vb1,a,b,c,i1,i2) implicit double precision (a-h,o-z) dimension vb(imid,nlat,3),vbz(imid,1),vb1(imid,1), 1 a(1),b(1),c(1) ihold = i1 i1 = i2 i2 = i3 i3 = ihold if(m-1)25,30,35 25 i1 = 1 i2 = 2 i3 = 3 do 45 np1=1,nlat do 45 i=1,imid vb(i,np1,i3) = vbz(i,np1) 45 continue return 30 do 50 np1=2,nlat do 50 i=1,imid vb(i,np1,i3) = vb1(i,np1) 50 continue return 35 ns = ((m-2)*(nlat+nlat-m-1))/2+1 if(ityp .eq. 1) go to 36 do 85 i=1,imid vb(i,m+1,i3) = a(ns)*vb(i,m-1,i1)-c(ns)*vb(i,m+1,i1) 85 continue 36 if(m .eq. nlat-1) return if(ityp .eq. 2) go to 71 ns = ns+1 do 70 i=1,imid vb(i,m+2,i3) = a(ns)*vb(i,m,i1)-c(ns)*vb(i,m+2,i1) 70 continue 71 nstrt = m+3 if(ityp .eq. 1) nstrt = m+4 if(nstrt .gt. nlat) go to 80 nstp = 2 if(ityp .eq. 0) nstp = 1 do 75 np1=nstrt,nlat,nstp ns = ns+nstp do 75 i=1,imid vb(i,np1,i3) = a(ns)*vb(i,np1-2,i1)+b(ns)*vb(i,np1-2,i3) 1 -c(ns)*vb(i,np1,i1) 75 continue 80 return end subroutine wbin (ityp,nlat,nlon,m,wb,i3,wwbin,i1,i2) implicit double precision (a-h,o-z) dimension wb(1) ,wwbin(1) imid = (nlat+1)/2 lim = nlat*imid mmax = min0(nlat,(nlon+1)/2) labc = (max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 iw1 = lim+1 iw2 = iw1+lim iw3 = iw2+labc iw4 = iw3+labc c c the length of wwbin is 2*lim+3*labc c call wbin1 (ityp,nlat,m,wb,imid,i3,wwbin,wwbin(iw1),wwbin(iw2), 1 wwbin(iw3),wwbin(iw4),i1,i2) return end subroutine wbin1 (ityp,nlat,m,wb,imid,i3,wb1,wb2,a,b,c,i1,i2) implicit double precision (a-h,o-z) dimension wb(imid,nlat,3),wb1(imid,1),wb2(imid,1), 1 a(1),b(1),c(1) ihold = i1 i1 = i2 i2 = i3 i3 = ihold if(m-2)25,30,35 25 i1 = 1 i2 = 2 i3 = 3 do 45 np1=2,nlat do 45 i=1,imid wb(i,np1,i3) = wb1(i,np1) 45 continue return 30 do 50 np1=3,nlat do 50 i=1,imid wb(i,np1,i3) = wb2(i,np1) 50 continue return 35 ns = ((m-2)*(nlat+nlat-m-1))/2+1 if(ityp .eq. 1) go to 36 do 85 i=1,imid wb(i,m+1,i3) = a(ns)*wb(i,m-1,i1)-c(ns)*wb(i,m+1,i1) 85 continue 36 if(m .eq. nlat-1) return if(ityp .eq. 2) go to 71 ns = ns+1 do 70 i=1,imid wb(i,m+2,i3) = a(ns)*wb(i,m,i1)-c(ns)*wb(i,m+2,i1) 70 continue 71 nstrt = m+3 if(ityp .eq. 1) nstrt = m+4 if(nstrt .gt. nlat) go to 80 nstp = 2 if(ityp .eq. 0) nstp = 1 do 75 np1=nstrt,nlat,nstp ns = ns+nstp do 75 i=1,imid wb(i,np1,i3) = a(ns)*wb(i,np1-2,i1)+b(ns)*wb(i,np1-2,i3) 1 -c(ns)*wb(i,np1,i1) 75 continue 80 return end subroutine dzvk(nlat,m,n,czv,work) implicit double precision (a-h,o-z) c c subroutine dzvk computes the coefficients in the trigonometric c expansion of the quadrature function zvbar(n,m,theta) c c input parameters c c nlat the number of colatitudes including the poles. c c n the degree (subscript) of wbarv(n,m,theta) c c m the order (superscript) of wbarv(n,m,theta) c c work a work array with at least nlat/2+1 locations c c output parameter c c czv the fourier coefficients of zvbar(n,m,theta). c dimension czv(1),work(1) double precision czv,sc1,sum,work,t1,t2 if(n .le. 0) return lc = (nlat+1)/2 sc1 = 2.d0/dfloat(nlat-1) call dvbk(m,n,work,czv) nmod = mod(n,2) mmod = mod(m,2) if(nmod .ne. 0) go to 1 if(mmod .ne. 0) go to 2 c c n even, m even c kdo = n/2 do 9 id=1,lc i = id+id-2 sum = 0.d0 do 10 k=1,kdo t1 = 1.d0-(k+k+i)**2 t2 = 1.d0-(k+k-i)**2 sum = sum+work(k)*(t1-t2)/(t1*t2) 10 continue czv(id) = sc1*sum 9 continue return c c n even, m odd c 2 kdo = n/2 do 5 id=1,lc i = id+id-2 sum = 0.d0 do 6 k=1,kdo t1 = 1.d0-(k+k+i)**2 t2 = 1.d0-(k+k-i)**2 sum = sum+work(k)*(t1+t2)/(t1*t2) 6 continue czv(id) = sc1*sum 5 continue return 1 if(mmod .ne. 0) go to 3 c c n odd, m even c kdo = (n+1)/2 do 19 id=1,lc i = id+id-3 sum = 0.d0 do 20 k=1,kdo t1 = 1.d0-(k+k-1+i)**2 t2 = 1.d0-(k+k-1-i)**2 sum = sum+work(k)*(t1-t2)/(t1*t2) 20 continue czv(id) = sc1*sum 19 continue return c c n odd, m odd c 3 kdo = (n+1)/2 do 15 id=1,lc i = id+id-1 sum = 0.d0 do 16 k=1,kdo t1 = 1.d0-(k+k-1+i)**2 t2 = 1.d0-(k+k-1-i)**2 sum = sum+work(k)*(t1+t2)/(t1*t2) 16 continue czv(id) = sc1*sum 15 continue return end subroutine dzvt(nlat,m,n,th,czv,zvh) implicit double precision (a-h,o-z) c c subroutine dzvt tabulates the function zvbar(n,m,theta) c at theta = th in double precision c c input parameters c c nlat the number of colatitudes including the poles. c c n the degree (subscript) of zvbar(n,m,theta) c c m the order (superscript) of zvbar(n,m,theta) c c czv the fourier coefficients of zvbar(n,m,theta) c as computed by subroutine zwk. c c output parameter c c zvh zvbar(m,n,theta) evaluated at theta = th c dimension czv(1) double precision th,czv,zvh,cth,sth,cdt,sdt,chh zvh = 0.d0 if(n .le. 0) return lc = (nlat+1)/2 lq = lc-1 ls = lc-2 cth = dcos(th) sth = dsin(th) cdt = cth*cth-sth*sth sdt = 2.d0*sth*cth lmod = mod(nlat,2) mmod = mod(m,2) nmod = mod(n,2) if(lmod .eq. 0) go to 50 if(nmod .ne. 0) go to 1 cth = cdt sth = sdt if(mmod .ne. 0) go to 2 c c nlat odd n even m even c do 10 k=1,ls zvh = zvh+czv(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 10 continue return c c nlat odd n even m odd c 2 zvh = .5d0*czv(1) do 20 k=2,lq zvh = zvh+czv(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 20 continue zvh = zvh+.5d0*czv(lc)*dcos((nlat-1)*th) return 1 if(mmod .ne. 0) go to 3 c c nlat odd n odd m even c do 30 k=1,lq zvh = zvh+czv(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 30 continue return c c nlat odd n odd m odd c 3 do 40 k=1,lq zvh = zvh+czv(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 40 continue return 50 if(nmod .ne. 0) go to 51 cth = cdt sth = sdt if(mmod .ne. 0) go to 52 c c nlat even n even m even c do 55 k=1,lq zvh = zvh+czv(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 55 continue return c c nlat even n even m odd c 52 zvh = .5d0*czv(1) do 57 k=2,lc zvh = zvh+czv(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 57 continue return 51 if(mmod .ne. 0) go to 53 c c nlat even n odd m even c do 58 k=1,lq zvh = zvh+czv(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 58 continue return c c nlat even n odd m odd c 53 zvh = .5d0*czv(lc)*dcos((nlat-1)*th) do 60 k=1,lq zvh = zvh+czv(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 60 continue return end subroutine dzwk(nlat,m,n,czw,work) implicit double precision (a-h,o-z) c c subroutine dzwk computes the coefficients in the trigonometric c expansion of the quadrature function zwbar(n,m,theta) c c input parameters c c nlat the number of colatitudes including the poles. c c n the degree (subscript) of zwbar(n,m,theta) c c m the order (superscript) of zwbar(n,m,theta) c c work a work array with at least nlat/2+1 locations c c output parameter c c czw the fourier coefficients of zwbar(n,m,theta). c dimension czw(1),work(1) double precision czw,work,sc1,sum,t1,t2 if(n .le. 0) return lc = (nlat+1)/2 sc1 = 2.d0/dfloat(nlat-1) call dwbk(m,n,work,czw) nmod = mod(n,2) mmod = mod(m,2) if(nmod .ne. 0) go to 1 if(mmod .ne. 0) go to 2 c c n even, m even c kdo = n/2 do 19 id=1,lc i = id+id-3 sum = 0.d0 do 20 k=1,kdo t1 = 1.d0-(k+k-1+i)**2 t2 = 1.d0-(k+k-1-i)**2 sum = sum+work(k)*(t1-t2)/(t1*t2) 20 continue czw(id) = sc1*sum 19 continue return c c n even, m odd c 2 kdo = n/2 do 15 id=1,lc i = id+id-1 sum = 0.d0 do 16 k=1,kdo t1 = 1.d0-(k+k-1+i)**2 t2 = 1.d0-(k+k-1-i)**2 sum = sum+work(k)*(t1+t2)/(t1*t2) 16 continue czw(id) = sc1*sum 15 continue return 1 if(mmod .ne. 0) go to 3 c c n odd, m even c kdo = (n-1)/2 do 9 id=1,lc i = id+id-2 sum = 0.d0 do 10 k=1,kdo t1 = 1.d0-(k+k+i)**2 t2 = 1.d0-(k+k-i)**2 sum = sum+work(k)*(t1-t2)/(t1*t2) 10 continue czw(id) = sc1*sum 9 continue return c c n odd, m odd c 3 kdo = (n+1)/2 do 5 id=1,lc i = id+id-2 sum = work(1)/(1.d0-i*i) if(kdo .lt. 2) go to 29 do 6 kp1=2,kdo k = kp1-1 t1 = 1.d0-(k+k+i)**2 t2 = 1.d0-(k+k-i)**2 sum = sum+work(kp1)*(t1+t2)/(t1*t2) 6 continue 29 czw(id) = sc1*sum 5 continue return end subroutine dzwt(nlat,m,n,th,czw,zwh) implicit double precision (a-h,o-z) c c subroutine dzwt tabulates the function zwbar(n,m,theta) c at theta = th in double precision c c input parameters c c nlat the number of colatitudes including the poles. c nlat must be an odd integer c c n the degree (subscript) of zwbar(n,m,theta) c c m the order (superscript) of zwbar(n,m,theta) c c czw the fourier coefficients of zwbar(n,m,theta) c as computed by subroutine zwk. c c output parameter c c zwh zwbar(m,n,theta) evaluated at theta = th c dimension czw(1) double precision czw,zwh,th,cth,sth,cdt,sdt,chh zwh = 0.d0 if(n .le. 0) return lc = (nlat+1)/2 lq = lc-1 ls = lc-2 cth = dcos(th) sth = dsin(th) cdt = cth*cth-sth*sth sdt = 2.d0*sth*cth lmod = mod(nlat,2) mmod = mod(m,2) nmod = mod(n,2) if(lmod .eq. 0) go to 50 if(nmod .ne. 0) go to 1 if(mmod .ne. 0) go to 2 c c nlat odd n even m even c do 30 k=1,lq zwh = zwh+czw(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 30 continue return c c nlat odd n even m odd c 2 do 40 k=1,lq zwh = zwh+czw(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 40 continue return 1 cth = cdt sth = sdt if(mmod .ne. 0) go to 3 c c nlat odd n odd m even c do 10 k=1,ls zwh = zwh+czw(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 10 continue return c c nlat odd n odd m odd c 3 zwh = .5d0*czw(1) do 20 k=2,lq zwh = zwh+czw(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 20 continue zwh = zwh+.5d0*czw(lc)*dcos((nlat-1)*th) return 50 if(nmod .ne. 0) go to 51 if(mmod .ne. 0) go to 52 c c nlat even n even m even c do 55 k=1,lq zwh = zwh+czw(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 55 continue return c c nlat even n even m odd c 52 zwh = .5d0*czw(lc)*dcos((nlat-1)*th) do 60 k=1,lq zwh = zwh+czw(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 60 continue return 51 cth = cdt sth = sdt if(mmod .ne. 0) go to 53 c c nlat even n odd m even c do 65 k=1,lq zwh = zwh+czw(k+1)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 65 continue return c c nlat even n odd m odd c 53 zwh = .5d0*czw(1) do 70 k=2,lc zwh = zwh+czw(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 70 continue return end subroutine dvbk(m,n,cv,work) implicit double precision (a-h,o-z) double precision cv(1),work(1),fn,fk,cf cv(1) = 0.d0 if(n .le. 0) return fn = n srnp1 = dsqrt(fn*(fn+1.d0)) cf = 2.d0*m/srnp1 modn = mod(n,2) modm = mod(m,2) call dnlfk(m,n,work) if(modn .ne. 0) go to 70 ncv = n/2 if(ncv .eq. 0) return fk = 0.d0 if(modm .ne. 0) go to 60 c c n even m even c do 55 l=1,ncv fk = fk+2.d0 cv(l) = -fk*work(l+1)/srnp1 55 continue return c c n even m odd c 60 do 65 l=1,ncv fk = fk+2.d0 cv(l) = fk*work(l)/srnp1 65 continue return 70 ncv = (n+1)/2 fk = -1.d0 if(modm .ne. 0) go to 80 c c n odd m even c do 75 l=1,ncv fk = fk+2.d0 cv(l) = -fk*work(l)/srnp1 75 continue return c c n odd m odd c 80 do 85 l=1,ncv fk = fk+2.d0 cv(l) = fk*work(l)/srnp1 85 continue return end subroutine dwbk(m,n,cw,work) implicit double precision (a-h,o-z) double precision cw(1),work(1),fn,cf,srnp1 cw(1) = 0.d0 if(n.le.0 .or. m.le.0) return fn = n srnp1 = dsqrt(fn*(fn+1.d0)) cf = 2.d0*m/srnp1 modn = mod(n,2) modm = mod(m,2) call dnlfk(m,n,work) if(m .eq. 0) go to 50 if(modn .ne. 0) go to 30 l = n/2 if(l .eq. 0) go to 50 if(modm .ne. 0) go to 20 c c n even m even c cw(l) = -cf*work(l+1) 10 l = l-1 if(l .le. 0) go to 50 cw(l) = cw(l+1)-cf*work(l+1) go to 10 c c n even m odd c 20 cw(l) = cf*work(l) 25 l = l-1 if(l .le. 0) go to 50 cw(l) = cw(l+1)+cf*work(l) go to 25 30 if(modm .ne. 0) go to 40 l = (n-1)/2 if(l .eq. 0) go to 50 c c n odd m even c cw(l) = -cf*work(l+1) 35 l = l-1 if(l .le. 0) go to 50 cw(l) = cw(l+1)-cf*work(l+1) go to 35 c c n odd m odd c 40 l = (n+1)/2 cw(l) = cf*work(l) 45 l = l-1 if(l .le. 0) go to 50 cw(l) = cw(l+1)+cf*work(l) go to 45 50 return end subroutine dvbt(m,n,theta,cv,vh) implicit double precision (a-h,o-z) dimension cv(1) double precision cv,vh,theta,cth,sth,cdt,sdt,chh vh = 0.d0 if(n.eq.0) return cth = dcos(theta) sth = dsin(theta) cdt = cth*cth-sth*sth sdt = 2.d0*sth*cth mmod = mod(m,2) nmod = mod(n,2) if(nmod .ne. 0) go to 1 cth = cdt sth = sdt if(mmod .ne. 0) go to 2 c c n even m even c ncv = n/2 do 10 k=1,ncv vh = vh+cv(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 10 continue return c c n even m odd c 2 ncv = n/2 do 15 k=1,ncv vh = vh+cv(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 15 continue return 1 if(mmod .ne. 0) go to 3 c c n odd m even c ncv = (n+1)/2 do 20 k=1,ncv vh = vh+cv(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 20 continue return c c case m odd and n odd c 3 ncv = (n+1)/2 do 25 k=1,ncv vh = vh+cv(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 25 continue return end subroutine dwbt(m,n,theta,cw,wh) implicit double precision (a-h,o-z) dimension cw(1) double precision theta,cw,wh,cth,sth,cdt,sdt,chh wh = 0.d0 if(n.le.0 .or. m.le.0) return cth = dcos(theta) sth = dsin(theta) cdt = cth*cth-sth*sth sdt = 2.d0*sth*cth mmod=mod(m,2) nmod=mod(n,2) if(nmod .ne. 0) go to 1 if(mmod .ne. 0) go to 2 c c n even m even c ncw = n/2 do 10 k=1,ncw wh = wh+cw(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 10 continue return c c n even m odd c 2 ncw = n/2 do 8 k=1,ncw wh = wh+cw(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 8 continue return 1 cth = cdt sth = sdt if(mmod .ne. 0) go to 3 c c n odd m even c ncw = (n-1)/2 do 20 k=1,ncw wh = wh+cw(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 20 continue return c c case m odd and n odd c 3 ncw = (n+1)/2 wh = .5d0*cw(1) if(ncw.lt.2) return do 25 k=2,ncw wh = wh+cw(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 25 continue return end subroutine rabcv(nlat,nlon,abc) implicit double precision (a-h,o-z) c c subroutine rabcp computes the coefficients in the recurrence c relation for the functions vbar(m,n,theta). array abc c must have 3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 locations. c dimension abc(1) mmax = min0(nlat,(nlon+1)/2) labc = (max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 iw1 = labc+1 iw2 = iw1+labc call rabcv1(nlat,nlon,abc,abc(iw1),abc(iw2)) return end subroutine rabcv1(nlat,nlon,a,b,c) implicit double precision (a-h,o-z) c c coefficients a, b, and c for computing vbar(m,n,theta) are c stored in location ((m-2)*(nlat+nlat-m-1))/2+n+1 c dimension a(1),b(1),c(1) mmax = min0(nlat,(nlon+1)/2) if(mmax .lt. 3) return do 215 mp1=3,mmax m = mp1-1 ns = ((m-2)*(nlat+nlat-m-1))/2+1 fm = dfloat(m) tm = fm+fm temp = tm*(tm-1.d0) tpn = (fm-2.d0)*(fm-1.d0)/(fm*(fm+1.d0)) a(ns) = dsqrt(tpn*(tm+1.d0)*(tm-2.d0)/temp) c(ns) = dsqrt(2.d0/temp) if(m .eq. nlat-1) go to 215 ns = ns+1 temp = tm*(tm+1.d0) tpn = (fm-1.d0)*fm/((fm+1.d0)*(fm+2.d0)) a(ns) = dsqrt(tpn*(tm+3.d0)*(tm-2.d0)/temp) c(ns) = dsqrt(6.d0/temp) mp3 = m+3 if(mp3 .gt. nlat) go to 215 do 210 np1=mp3,nlat n = np1-1 ns = ns+1 fn = dfloat(n) tn = fn+fn cn = (tn+1.d0)/(tn-3.d0) tpn = (fn-2.d0)*(fn-1.d0)/(fn*(fn+1.d0)) fnpm = fn+fm fnmm = fn-fm temp = fnpm*(fnpm-1.d0) a(ns) = dsqrt(tpn*cn*(fnpm-3.d0)*(fnpm-2.d0)/temp) b(ns) = dsqrt(tpn*cn*fnmm*(fnmm-1.d0)/temp) c(ns) = dsqrt((fnmm+1.d0)*(fnmm+2.d0)/temp) 210 continue 215 continue return end subroutine rabcw(nlat,nlon,abc) implicit double precision (a-h,o-z) c c subroutine rabcw computes the coefficients in the recurrence c relation for the functions wbar(m,n,theta). array abc c must have 3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 locations. c dimension abc(1) mmax = min0(nlat,(nlon+1)/2) labc = (max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 iw1 = labc+1 iw2 = iw1+labc call rabcw1(nlat,nlon,abc,abc(iw1),abc(iw2)) return end subroutine rabcw1(nlat,nlon,a,b,c) implicit double precision (a-h,o-z) c c coefficients a, b, and c for computing wbar(m,n,theta) are c stored in location ((m-2)*(nlat+nlat-m-1))/2+n+1 c dimension a(1),b(1),c(1) mmax = min0(nlat,(nlon+1)/2) if(mmax .lt. 4) return do 215 mp1=4,mmax m = mp1-1 ns = ((m-2)*(nlat+nlat-m-1))/2+1 fm = dfloat(m) tm = fm+fm temp = tm*(tm-1.d0) tpn = (fm-2.d0)*(fm-1.d0)/(fm*(fm+1.d0)) tph = fm/(fm-2.d0) a(ns) = tph*dsqrt(tpn*(tm+1.d0)*(tm-2.d0)/temp) c(ns) = tph*dsqrt(2.d0/temp) if(m .eq. nlat-1) go to 215 ns = ns+1 temp = tm*(tm+1.d0) tpn = (fm-1.d0)*fm/((fm+1.d0)*(fm+2.d0)) tph = fm/(fm-2.d0) a(ns) = tph*dsqrt(tpn*(tm+3.d0)*(tm-2.d0)/temp) c(ns) = tph*dsqrt(6.d0/temp) mp3 = m+3 if(mp3 .gt. nlat) go to 215 do 210 np1=mp3,nlat n = np1-1 ns = ns+1 fn = dfloat(n) tn = fn+fn cn = (tn+1.d0)/(tn-3.d0) fnpm = fn+fm fnmm = fn-fm temp = fnpm*(fnpm-1.d0) tpn = (fn-2.d0)*(fn-1.d0)/(fn*(fn+1.d0)) tph = fm/(fm-2.d0) a(ns) = tph*dsqrt(tpn*cn*(fnpm-3.d0)*(fnpm-2.d0)/temp) b(ns) = dsqrt(tpn*cn*fnmm*(fnmm-1.d0)/temp) c(ns) = tph*dsqrt((fnmm+1.d0)*(fnmm+2.d0)/temp) 210 continue 215 continue return end subroutine vtinit (nlat,nlon,wvbin,dwork) implicit double precision (a-h,o-z) dimension wvbin(*) double precision dwork(*) imid = (nlat+1)/2 iw1 = 2*nlat*imid+1 c c the length of wvbin is 2*nlat*imid+3*((nlat-3)*nlat+2)/2 c the length of dwork is nlat+2 c call vtini1 (nlat,nlon,imid,wvbin,wvbin(iw1),dwork, 1 dwork(nlat/2+2)) return end subroutine vtini1 (nlat,nlon,imid,vb,abc,cvb,work) implicit double precision (a-h,o-z) c c abc must have 3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 c locations where mmax = min0(nlat,(nlon+1)/2) c cvb and work must each have nlat/2+1 locations c dimension vb(imid,nlat,2),abc(1),cvb(1) double precision pi,dt,cvb,th,vbh,work(*) pi = 4.d0*datan(1.d0) dt = pi/(nlat-1) mdo = min0(2,nlat,(nlon+1)/2) do 160 mp1=1,mdo m = mp1-1 do 160 np1=mp1,nlat n = np1-1 call dvtk(m,n,cvb,work) do 165 i=1,imid th = (i-1)*dt call dvtt(m,n,th,cvb,vbh) vb(i,np1,mp1) = vbh 165 continue 160 continue call rabcv(nlat,nlon,abc) return end subroutine wtinit (nlat,nlon,wwbin,dwork) implicit double precision (a-h,o-z) dimension wwbin(1) double precision dwork(*) imid = (nlat+1)/2 iw1 = 2*nlat*imid+1 c c the length of wwbin is 2*nlat*imid+3*((nlat-3)*nlat+2)/2 c the length of dwork is nlat+2 c call wtini1 (nlat,nlon,imid,wwbin,wwbin(iw1),dwork, 1 dwork(nlat/2+2)) return end subroutine wtini1 (nlat,nlon,imid,wb,abc,cwb,work) implicit double precision (a-h,o-z) c c abc must have 3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 c locations where mmax = min0(nlat,(nlon+1)/2) c cwb and work must each have nlat/2+1 locations c dimension wb(imid,nlat,2),abc(1) double precision pi,dt,cwb(*),wbh,th,work(*) pi = 4.d0*datan(1.d0) dt = pi/(nlat-1) mdo = min0(3,nlat,(nlon+1)/2) if(mdo .lt. 2) return do 160 mp1=2,mdo m = mp1-1 do 160 np1=mp1,nlat n = np1-1 call dwtk(m,n,cwb,work) do 165 i=1,imid th = (i-1)*dt call dwtt(m,n,th,cwb,wbh) wb(i,np1,m) = wbh 165 continue 160 continue call rabcw(nlat,nlon,abc) return end subroutine vtgint (nlat,nlon,theta,wvbin,work) implicit double precision (a-h,o-z) dimension wvbin(*) double precision theta(*), work(*) imid = (nlat+1)/2 iw1 = 2*nlat*imid+1 c c theta is a double precision array with (nlat+1)/2 locations c nlat is the maximum value of n+1 c the length of wvbin is 2*nlat*imid+3*((nlat-3)*nlat+2)/2 c the length of work is nlat+2 c call vtgit1 (nlat,nlon,imid,theta,wvbin,wvbin(iw1), + work,work(nlat/2+2)) return end subroutine vtgit1 (nlat,nlon,imid,theta,vb,abc,cvb,work) implicit double precision (a-h,o-z) c c abc must have 3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 c locations where mmax = min0(nlat,(nlon+1)/2) c cvb and work must each have nlat/2+1 locations c dimension vb(imid,nlat,2),abc(*) double precision theta(*),cvb(*),work(*),vbh mdo = min0(2,nlat,(nlon+1)/2) do 160 mp1=1,mdo m = mp1-1 do 160 np1=mp1,nlat n = np1-1 call dvtk(m,n,cvb,work) do 165 i=1,imid call dvtt(m,n,theta(i),cvb,vbh) vb(i,np1,mp1) = vbh 165 continue 160 continue call rabcv(nlat,nlon,abc) return end subroutine wtgint (nlat,nlon,theta,wwbin,work) implicit double precision (a-h,o-z) dimension wwbin(*) double precision theta(*), work(*) imid = (nlat+1)/2 iw1 = 2*nlat*imid+1 c c theta is a double precision array with (nlat+1)/2 locations c nlat is the maximum value of n+1 c the length of wwbin is 2*nlat*imid+3*((nlat-3)*nlat+2)/2 c the length of work is nlat+2 c call wtgit1 (nlat,nlon,imid,theta,wwbin,wwbin(iw1), 1 work,work(nlat/2+2)) return end subroutine wtgit1 (nlat,nlon,imid,theta,wb,abc,cwb,work) implicit double precision (a-h,o-z) c c abc must have 3*((nlat-3)*nlat+2)/2 locations c cwb and work must each have nlat/2+1 locations c dimension wb(imid,nlat,2),abc(1) double precision theta(*), cwb(*), work(*), wbh mdo = min0(3,nlat,(nlon+1)/2) if(mdo .lt. 2) return do 160 mp1=2,mdo m = mp1-1 do 160 np1=mp1,nlat n = np1-1 call dwtk(m,n,cwb,work) do 165 i=1,imid call dwtt(m,n,theta(i),cwb,wbh) wb(i,np1,m) = wbh 165 continue 160 continue call rabcw(nlat,nlon,abc) return end subroutine dvtk(m,n,cv,work) implicit double precision (a-h,o-z) double precision cv(*),work(*),fn,fk,cf,srnp1 cv(1) = 0.d0 if(n .le. 0) return fn = n srnp1 = dsqrt(fn*(fn+1.d0)) cf = 2.d0*m/srnp1 modn = mod(n,2) modm = mod(m,2) call dnlfk(m,n,work) if(modn .ne. 0) go to 70 ncv = n/2 if(ncv .eq. 0) return fk = 0.d0 if(modm .ne. 0) go to 60 c c n even m even c do 55 l=1,ncv fk = fk+2.d0 cv(l) = -fk*fk*work(l+1)/srnp1 55 continue return c c n even m odd c 60 do 65 l=1,ncv fk = fk+2.d0 cv(l) = -fk*fk*work(l)/srnp1 65 continue return 70 ncv = (n+1)/2 fk = -1.d0 if(modm .ne. 0) go to 80 c c n odd m even c do 75 l=1,ncv fk = fk+2.d0 cv(l) = -fk*fk*work(l)/srnp1 75 continue return c c n odd m odd c 80 do 85 l=1,ncv fk = fk+2.d0 cv(l) = -fk*fk*work(l)/srnp1 85 continue return end subroutine dwtk(m,n,cw,work) implicit double precision (a-h,o-z) double precision cw(*),work(*),fn,cf,srnp1 cw(1) = 0.d0 if(n.le.0 .or. m.le.0) return fn = n srnp1 = dsqrt(fn*(fn+1.d0)) cf = 2.d0*m/srnp1 modn = mod(n,2) modm = mod(m,2) call dnlfk(m,n,work) if(m .eq. 0) go to 50 if(modn .ne. 0) go to 30 l = n/2 if(l .eq. 0) go to 50 if(modm .ne. 0) go to 20 c c n even m even c cw(l) = -cf*work(l+1) 10 l = l-1 if(l .le. 0) go to 50 cw(l) = cw(l+1)-cf*work(l+1) cw(l+1) = (l+l+1)*cw(l+1) go to 10 c c n even m odd c 20 cw(l) = cf*work(l) 25 l = l-1 if(l) 50,27,26 26 cw(l) = cw(l+1)+cf*work(l) 27 cw(l+1) = -(l+l+1)*cw(l+1) go to 25 30 if(modm .ne. 0) go to 40 l = (n-1)/2 if(l .eq. 0) go to 50 c c n odd m even c cw(l) = -cf*work(l+1) 35 l = l-1 if(l) 50,37,36 36 cw(l) = cw(l+1)-cf*work(l+1) 37 cw(l+1) = (l+l+2)*cw(l+1) go to 35 c c n odd m odd c 40 l = (n+1)/2 cw(l) = cf*work(l) 45 l = l-1 if(l) 50,47,46 46 cw(l) = cw(l+1)+cf*work(l) 47 cw(l+1) = -(l+l)*cw(l+1) go to 45 50 return end subroutine dvtt(m,n,theta,cv,vh) implicit double precision (a-h,o-z) dimension cv(1) double precision cv,vh,theta,cth,sth,cdt,sdt,chh vh = 0.d0 if(n.eq.0) return cth = dcos(theta) sth = dsin(theta) cdt = cth*cth-sth*sth sdt = 2.d0*sth*cth mmod = mod(m,2) nmod = mod(n,2) if(nmod .ne. 0) go to 1 cth = cdt sth = sdt if(mmod .ne. 0) go to 2 c c n even m even c ncv = n/2 do 10 k=1,ncv vh = vh+cv(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 10 continue return c c n even m odd c 2 ncv = n/2 do 15 k=1,ncv vh = vh+cv(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 15 continue return 1 if(mmod .ne. 0) go to 3 c c n odd m even c ncv = (n+1)/2 do 20 k=1,ncv vh = vh+cv(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 20 continue return c c case m odd and n odd c 3 ncv = (n+1)/2 do 25 k=1,ncv vh = vh+cv(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 25 continue return end subroutine dwtt(m,n,theta,cw,wh) implicit double precision (a-h,o-z) dimension cw(1) double precision theta,cw,wh,cth,sth,cdt,sdt,chh wh = 0.d0 if(n.le.0 .or. m.le.0) return cth = dcos(theta) sth = dsin(theta) cdt = cth*cth-sth*sth sdt = 2.d0*sth*cth mmod=mod(m,2) nmod=mod(n,2) if(nmod .ne. 0) go to 1 if(mmod .ne. 0) go to 2 c c n even m even c ncw = n/2 do 10 k=1,ncw wh = wh+cw(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 10 continue return c c n even m odd c 2 ncw = n/2 do 8 k=1,ncw wh = wh+cw(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 8 continue return 1 cth = cdt sth = sdt if(mmod .ne. 0) go to 3 c c n odd m even c ncw = (n-1)/2 do 20 k=1,ncw wh = wh+cw(k)*cth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 20 continue return c c case m odd and n odd c 3 ncw = (n+1)/2 wh = 0.d0 if(ncw.lt.2) return do 25 k=2,ncw wh = wh+cw(k)*sth chh = cdt*cth-sdt*sth sth = sdt*cth+cdt*sth cth = chh 25 continue return end subroutine vbgint (nlat,nlon,theta,wvbin,work) implicit double precision (a-h,o-z) dimension wvbin(1) double precision theta(*),work(*) imid = (nlat+1)/2 iw1 = 2*nlat*imid+1 c c theta is a double precision array with (nlat+1)/2 locations c nlat is the maximum value of n+1 c the length of wvbin is 2*nlat*imid+3*((nlat-3)*nlat+2)/2 c the length of work is nlat+2 c call vbgit1 (nlat,nlon,imid,theta,wvbin,wvbin(iw1), + work,work(nlat/2+2)) return end subroutine vbgit1 (nlat,nlon,imid,theta,vb,abc,cvb,work) implicit double precision (a-h,o-z) c c abc must have 3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 c locations where mmax = min0(nlat,(nlon+1)/2) c cvb and work must each have nlat/2+1 locations c dimension vb(imid,nlat,2),abc(1) double precision cvb(1),theta(1),vbh,work(1) mdo = min0(2,nlat,(nlon+1)/2) do 160 mp1=1,mdo m = mp1-1 do 160 np1=mp1,nlat n = np1-1 call dvbk(m,n,cvb,work) do 165 i=1,imid call dvbt(m,n,theta(i),cvb,vbh) vb(i,np1,mp1) = vbh 165 continue 160 continue call rabcv(nlat,nlon,abc) return end subroutine wbgint (nlat,nlon,theta,wwbin,work) implicit double precision (a-h,o-z) dimension wwbin(1) double precision work(*),theta(*) imid = (nlat+1)/2 iw1 = 2*nlat*imid+1 c c theta is a double precision array with (nlat+1)/2 locations c nlat is the maximum value of n+1 c the length of wwbin is 2*nlat*imid+3*((nlat-3)*nlat+2)/2 c the length of work is nlat+2 c call wbgit1 (nlat,nlon,imid,theta,wwbin,wwbin(iw1), + work,work(nlat/2+2)) return end subroutine wbgit1 (nlat,nlon,imid,theta,wb,abc,cwb,work) implicit double precision (a-h,o-z) c c abc must have 3*((nlat-3)*nlat+2)/2 locations c cwb and work must each have nlat/2+1 locations c dimension wb(imid,nlat,2),abc(1) double precision cwb(1),theta(1),wbh,work(1) mdo = min0(3,nlat,(nlon+1)/2) if(mdo .lt. 2) return do 160 mp1=2,mdo m = mp1-1 do 160 np1=mp1,nlat n = np1-1 call dwbk(m,n,cwb,work) do 165 i=1,imid call dwbt(m,n,theta(i),cwb,wbh) wb(i,np1,m) = wbh 165 continue 160 continue call rabcw(nlat,nlon,abc) return end ================================================ FILE: external/SPHEREPACK/vhags.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c c ... file vhags.f c c this file contains code and documentation for subroutines c vhags and vhagsi c c ... files which must be loaded with vhags.f c c sphcom.f, hrfft.f, gaqd.f c c subroutine vhags(nstrvw,nstrbc,noffsvw,noffsbc, c nlat,nlon,ityp,nt,v,w,idvw,jdvw,br,bi,cr,ci, c + mdab,ndab,wvhags,lvhags,work,lwork,ierror) c c subroutine vhags performs the vector spherical harmonic analysis c on the vector field (v,w) and stores the result in the arrays c br, bi, cr, and ci. v(i,j) and w(i,j) are the colatitudinal c (measured from the north pole) and east longitudinal components c respectively, located at the gaussian colatitude point theta(i) c and longitude phi(j) = (j-1)*2*pi/nlon. the spectral c representation of (v,w) is given at output parameters v,w in c subroutine vhses. c c input parameters c c nstrvw,nstrbc the strides in v,w and br,bi,cr,ci c noffsvw,noffsbc the offset in v,w and br,bi,cr,ci c -- must be between 0 and stride-1 c nlat the number of points in the gaussian colatitude grid on the c full sphere. these lie in the interval (0,pi) and are computed c in radians in theta(1) <...< theta(nlat) by subroutine gaqd. c if nlat is odd the equator will be included as the grid point c theta((nlat+1)/2). if nlat is even the equator will be c excluded as a grid point and will lie half way between c theta(nlat/2) and theta(nlat/2+1). nlat must be at least 3. c note: on the half sphere, the number of grid points in the c colatitudinal direction is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than zero. the axisymmetric case corresponds to nlon=1. c the efficiency of the computation is improved when nlon c is a product of small prime numbers. c c NOTE: this is a modified version of spherepack. Changes from c the original version to the current one have only been c tested for ityp=0,1,2. For this reason an error code will c be returned if ityp>2. c c ityp = 0 no symmetries exist about the equator. the analysis c is performed on the entire sphere. i.e. on the c arrays v(i,j),w(i,j) for i=1,...,nlat and c j=1,...,nlon. c c = 1 no symmetries exist about the equator. the analysis c is performed on the entire sphere. i.e. on the c arrays v(i,j),w(i,j) for i=1,...,nlat and c j=1,...,nlon. the curl of (v,w) is zero. that is, c (d/dtheta (sin(theta) w) - dv/dphi)/sin(theta) = 0. c the coefficients cr and ci are zero. c c = 2 no symmetries exist about the equator. the analysis c is performed on the entire sphere. i.e. on the c arrays v(i,j),w(i,j) for i=1,...,nlat and c j=1,...,nlon. the divergence of (v,w) is zero. i.e., c (d/dtheta (sin(theta) v) + dw/dphi)/sin(theta) = 0. c the coefficients br and bi are zero. c c = 3 v is symmetric and w is antisymmetric about the c equator. the analysis is performed on the northern c hemisphere only. i.e., if nlat is odd the analysis c is performed on the arrays v(i,j),w(i,j) for c i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the analysis is performed on the the arrays c v(i,j),w(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c c = 4 v is symmetric and w is antisymmetric about the c equator. the analysis is performed on the northern c hemisphere only. i.e., if nlat is odd the analysis c is performed on the arrays v(i,j),w(i,j) for c i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the analysis is performed on the the arrays c v(i,j),w(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c the curl of (v,w) is zero. that is, c (d/dtheta (sin(theta) w) - dv/dphi)/sin(theta) = 0. c the coefficients cr and ci are zero. c c = 5 v is symmetric and w is antisymmetric about the c equator. the analysis is performed on the northern c hemisphere only. i.e., if nlat is odd the analysis c is performed on the arrays v(i,j),w(i,j) for c i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the analysis is performed on the the arrays c v(i,j),w(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c the divergence of (v,w) is zero. i.e., c (d/dtheta (sin(theta) v) + dw/dphi)/sin(theta) = 0. c the coefficients br and bi are zero. c c = 6 v is antisymmetric and w is symmetric about the c equator. the analysis is performed on the northern c hemisphere only. i.e., if nlat is odd the analysis c is performed on the arrays v(i,j),w(i,j) for c i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the analysis is performed on the the arrays c v(i,j),w(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c c = 7 v is antisymmetric and w is symmetric about the c equator. the analysis is performed on the northern c hemisphere only. i.e., if nlat is odd the analysis c is performed on the arrays v(i,j),w(i,j) for c i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the analysis is performed on the the arrays c v(i,j),w(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c the curl of (v,w) is zero. that is, c (d/dtheta (sin(theta) w) - dv/dphi)/sin(theta) = 0. c the coefficients cr and ci are zero. c c = 8 v is antisymmetric and w is symmetric about the c equator. the analysis is performed on the northern c hemisphere only. i.e., if nlat is odd the analysis c is performed on the arrays v(i,j),w(i,j) for c i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the analysis is performed on the the arrays c v(i,j),w(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c the divergence of (v,w) is zero. i.e., c (d/dtheta (sin(theta) v) + dw/dphi)/sin(theta) = 0. c the coefficients br and bi are zero. c c c nt the number of analyses. in the program that calls vhags, c the arrays v,w,br,bi,cr, and ci can be three dimensional c in which case multiple analyses will be performed. c the third index is the analysis index which assumes the c values k=1,...,nt. for a single analysis set nt=1. the c discription of the remaining parameters is simplified c by assuming that nt=1 or that all the arrays are two c dimensional. c c v,w two or three dimensional arrays (see input parameter nt) c that contain the vector function to be analyzed. c v is the colatitudnal component and w is the east c longitudinal component. v(i,j),w(i,j) contain the c components at the gaussian colatitude point theta(i) c and longitude phi(j) = (j-1)*2*pi/nlon. the index ranges c are defined above at the input parameter ityp. c c idvw the first dimension of the arrays v,w as it appears in c the program that calls vhags. if ityp .le. 2 then idvw c must be at least nlat. if ityp .gt. 2 and nlat is c even then idvw must be at least nlat/2. if ityp .gt. 2 c and nlat is odd then idvw must be at least (nlat+1)/2. c c jdvw the second dimension of the arrays v,w as it appears in c the program that calls vhags. jdvw must be at least nlon. c c mdab the first dimension of the arrays br,bi,cr, and ci as it c appears in the program that calls vhags. mdab must be at c least min0(nlat,nlon/2) if nlon is even or at least c min0(nlat,(nlon+1)/2) if nlon is odd. c c ndab the second dimension of the arrays br,bi,cr, and ci as it c appears in the program that calls vhags. ndab must be at c least nlat. c c wvhags an array which must be initialized by subroutine vhgsi. c once initialized, wvhags can be used repeatedly by vhags c as long as nlon and nlat remain unchanged. wvhags must c not be altered between calls of vhags. c c lvhags the dimension of the array wvhags as it appears in the c program that calls vhags. define c c l1 = min0(nlat,nlon/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lvhags must be at least c c l1*l2(nlat+nlat-l1+1)+nlon+15 c c ??? (nlat+1)*(nlat+1)*nlat/2 + nlon + 15 c c c c work a work array that does not have to be saved. c c lwork the dimension of the array work as it appears in the c program that calls vhags. define c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c if ityp .le. 2 then lwork must be at least c the larger of the two quantities c c 3*nlat*(nlat+1)+2 (required by vhagsi) c c and c c (2*nt+1)*nlat*nlon c c if ityp .gt. 2 then lwork must be at least c the larger of the two quantities c c 3*nlat*(nlat+1)+2 (required by vhagsi) c c and c c (2*nt+1)*l2*nlon c c c ************************************************************** c c output parameters c c br,bi two or three dimensional arrays (see input parameter nt) c cr,ci that contain the vector spherical harmonic coefficients c in the spectral representation of v(i,j) and w(i,j) given c in the discription of subroutine vhses. br(mp1,np1), c bi(mp1,np1),cr(mp1,np1), and ci(mp1,np1) are computed c for mp1=1,...,mmax and np1=mp1,...,nlat except for np1=nlat c and odd mp1. mmax=min0(nlat,nlon/2) if nlon is even or c mmax=min0(nlat,(nlon+1)/2) if nlon is odd. c c ierror = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of ityp c = 4 error in the specification of nt c = 5 error in the specification of idvw c = 6 error in the specification of jdvw c = 7 error in the specification of mdab c = 8 error in the specification of ndab c = 9 error in the specification of lvhags c = 10 error in the specification of lwork c c c subroutine vhagsi(nlat,nlon,wvhags,lvhags,work,lwork,ierror) c c subroutine vhagsi initializes the array wvhags which can then be c used repeatedly by subroutine vhags until nlat or nlon is changed. c c input parameters c c nlat the number of points in the gaussian colatitude grid on the c full sphere. these lie in the interval (0,pi) and are computed c in radians in theta(1) <...< theta(nlat) by subroutine gaqd. c if nlat is odd the equator will be included as the grid point c theta((nlat+1)/2). if nlat is even the equator will be c excluded as a grid point and will lie half way between c theta(nlat/2) and theta(nlat/2+1). nlat must be at least 3. c note: on the half sphere, the number of grid points in the c colatitudinal direction is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than zero. the axisymmetric case corresponds to nlon=1. c the efficiency of the computation is improved when nlon c is a product of small prime numbers. c c lvhags the dimension of the array wvhags as it appears in the c program that calls vhagsi. define c c l1 = min0(nlat,nlon/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lvhags must be at least c c 3*nlat*(nlat+1)+2 (required by vhagsi) c c dwork a double precision work space that does not need to be saved c c ldwork the dimension of the array dwork as it appears in the c program that calls vhagsi. ldwork must be at least c c (3*nlat*(nlat+3)+2)/2 c c ************************************************************** c c output parameters c c wvhags an array which is initialized for use by subroutine vhags. c once initialized, wvhags can be used repeatedly by vhags c as long as nlat and nlon remain unchanged. wvhags must not c be altered between calls of vhags. c c c ierror = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of lvhags c = 4 error in the specification of ldwork c subroutine vhags(nstrvw,nstrbc,noffsvw,noffsbc, 1 nlat,nlon,ityp,nt,v,w,idvw,jdvw,br,bi,cr,ci, 1 mdab,ndab,wvhags,lvhags,work,lwork,ierror) implicit double precision (a-h,o-z) dimension v(nstrvw,idvw,jdvw,1),w(nstrvw,idvw,jdvw,1), 1 br(nstrbc,mdab,ndab,1),bi(nstrbc,mdab,ndab,1), 1 cr(nstrbc,mdab,ndab,1),ci(nstrbc,mdab,ndab,1), 2 work(1),wvhags(1) ierror = 1 if(nlat .lt. 3) return ierror = 2 if(nlon .lt. 1) return ierror = 3 if(ityp.lt.0 .or. ityp.gt.8) return c see note above about symmetries if(ityp.gt.2) return ierror = 4 if(nt .lt. 0) return ierror = 5 imid = (nlat+1)/2 if((ityp.le.2 .and. idvw.lt.nlat) .or. 1 (ityp.gt.2 .and. idvw.lt.imid)) return ierror = 6 if(jdvw .lt. nlon) return ierror = 7 mmax = min0(nlat,(nlon+1)/2) if(mdab .lt. mmax) return ierror = 8 if(ndab .lt. nlat) return ierror = 9 idz = (mmax*(nlat+nlat-mmax+1))/2 lzimn = idz*imid if(lvhags .lt. lzimn+lzimn+nlon+15) return ierror = 10 idv = nlat if(ityp .gt. 2) idv = imid lnl = nt*idv*nlon if(lwork .lt. lnl+lnl+idv*nlon) return ierror = 11 if((noffsvw.lt.0).or.(noffsvw.ge.nstrvw)) return if((noffsbc.lt.0).or.(noffsbc.ge.nstrbc)) return ierror = 0 ist = 0 if(ityp .le. 2) ist = imid c c set wvhags pointers c lmn = nlat*(nlat+1)/2 jw1 = 1 jw2 = jw1+imid*lmn jw3 = jw2+imid*lmn c c set work pointers c iw1 = ist+1 iw2 = lnl+1 iw3 = iw2+ist iw4 = iw2+lnl call vhags1(nstrvw,nstrbc,noffsvw,noffsbc, + nlat,nlon,ityp,nt,imid,idvw,jdvw,v,w,mdab,ndab, + br,bi,cr,ci,idv,work,work(iw1),work(iw2),work(iw3), + work(iw4),idz,wvhags(jw1),wvhags(jw2),wvhags(jw3)) return end subroutine vhags1(nstrvw,nstrbc,noffsvw,noffsbc, +nlat,nlon,ityp,nt,imid,idvw,jdvw,v,w,mdab, +ndab,br,bi,cr,ci,idv,ve,vo,we,wo,work,idz,vb,wb,wrfft) implicit double precision (a-h,o-z) dimension v(nstrvw,idvw,jdvw,1),w(nstrvw,idvw,jdvw,1), 1 br(nstrbc,mdab,ndab,1),bi(nstrbc,mdab,ndab,1), 1 cr(nstrbc,mdab,ndab,1),ci(nstrbc,mdab,ndab,1), 2 ve(idv,nlon,1),vo(idv,nlon,1),we(idv,nlon,1), 3 wo(idv,nlon,1),work(1), 4 vb(imid,1),wb(imid,1),wrfft(1) ncvw=1+noffsvw ncbc=1+noffsbc nlp1 = nlat+1 tsn = 2.d0/nlon fsn = 4.d0/nlon mlat = mod(nlat,2) mlon = mod(nlon,2) mmax = min0(nlat,(nlon+1)/2) imm1 = imid if(mlat .ne. 0) imm1 = imid-1 if(ityp .gt. 2) go to 3 do 5 k=1,nt do 5 i=1,imm1 do 5 j=1,nlon ve(i,j,k) = tsn*(v(ncvw,i,j,k)+v(ncvw,nlp1-i,j,k)) vo(i,j,k) = tsn*(v(ncvw,i,j,k)-v(ncvw,nlp1-i,j,k)) we(i,j,k) = tsn*(w(ncvw,i,j,k)+w(ncvw,nlp1-i,j,k)) wo(i,j,k) = tsn*(w(ncvw,i,j,k)-w(ncvw,nlp1-i,j,k)) 5 continue go to 2 3 do 8 k=1,nt do 8 i=1,imm1 do 8 j=1,nlon ve(i,j,k) = fsn*v(ncvw,i,j,k) vo(i,j,k) = fsn*v(ncvw,i,j,k) we(i,j,k) = fsn*w(ncvw,i,j,k) wo(i,j,k) = fsn*w(ncvw,i,j,k) 8 continue 2 if(mlat .eq. 0) go to 7 do 6 k=1,nt do 6 j=1,nlon ve(imid,j,k) = tsn*v(ncvw,imid,j,k) we(imid,j,k) = tsn*w(ncvw,imid,j,k) 6 continue 7 do 9 k=1,nt call hrfftf(idv,nlon,ve(1,1,k),idv,wrfft,work) call hrfftf(idv,nlon,we(1,1,k),idv,wrfft,work) 9 continue ndo1 = nlat ndo2 = nlat if(mlat .ne. 0) ndo1 = nlat-1 if(mlat .eq. 0) ndo2 = nlat-1 if(ityp.eq.2 .or. ityp.eq.5 .or. ityp.eq.8) go to 11 do 10 k=1,nt do 10 mp1=1,mmax do 10 np1=mp1,nlat br(1,mp1,np1,k)=0.d0 bi(1,mp1,np1,k)=0.d0 10 continue 11 if(ityp.eq.1 .or. ityp.eq.4 .or. ityp.eq.7) go to 13 do 12 k=1,nt do 12 mp1=1,mmax do 12 np1=mp1,nlat cr(ncbc,mp1,np1,k)=0.d0 ci(ncbc,mp1,np1,k)=0.d0 12 continue 13 itypp = ityp+1 go to (1,100,200,300,400,500,600,700,800),itypp c c case ityp=0 , no symmetries c c case m=0 c 1 do 15 k=1,nt do 15 i=1,imid do 15 np1=2,ndo2,2 br(1,1,np1,k) = br(1,1,np1,k)+vb(i,np1)*ve(i,1,k) cr(ncbc,1,np1,k) = cr(ncbc,1,np1,k)-vb(i,np1)*we(i,1,k) 15 continue do 16 k=1,nt do 16 i=1,imm1 do 16 np1=3,ndo1,2 br(1,1,np1,k) = br(1,1,np1,k)+vb(i,np1)*vo(i,1,k) cr(ncbc,1,np1,k) = cr(ncbc,1,np1,k)-vb(i,np1)*wo(i,1,k) 16 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) return do 20 mp1=2,mmax m = mp1-1 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 17 do 23 k=1,nt do 23 i=1,imm1 do 23 np1=mp1,ndo1,2 br(1,mp1,np1,k) = br(1,mp1,np1,k)+vb(i,np1+mb)*vo(i,2*mp1-2,k) 1 +wb(i,np1+mb)*we(i,2*mp1-1,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k)+vb(i,np1+mb)*vo(i,2*mp1-1,k) 1 -wb(i,np1+mb)*we(i,2*mp1-2,k) cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*wo(i,2*mp1-2,k) 1 +wb(i,np1+mb)*ve(i,2*mp1-1,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*wo(i,2*mp1-1,k) 1 -wb(i,np1+mb)*ve(i,2*mp1-2,k) 23 continue if(mlat .eq. 0) go to 17 do 24 k=1,nt do 24 np1=mp1,ndo1,2 br(1,mp1,np1,k) = br(1,mp1,np1,k) 1 +wb(imid,np1+mb)*we(imid,2*mp1-1,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k) 1 -wb(imid,np1+mb)*we(imid,2*mp1-2,k) cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 +wb(imid,np1+mb)*ve(imid,2*mp1-1,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -wb(imid,np1+mb)*ve(imid,2*mp1-2,k) 24 continue 17 if(mp2 .gt. ndo2) go to 20 do 21 k=1,nt do 21 i=1,imm1 do 21 np1=mp2,ndo2,2 br(1,mp1,np1,k) = br(1,mp1,np1,k)+vb(i,np1+mb)*ve(i,2*mp1-2,k) 1 +wb(i,np1+mb)*wo(i,2*mp1-1,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k)+vb(i,np1+mb)*ve(i,2*mp1-1,k) 1 -wb(i,np1+mb)*wo(i,2*mp1-2,k) cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*we(i,2*mp1-2,k) 1 +wb(i,np1+mb)*vo(i,2*mp1-1,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*we(i,2*mp1-1,k) 1 -wb(i,np1+mb)*vo(i,2*mp1-2,k) 21 continue if(mlat .eq. 0) go to 20 do 22 k=1,nt do 22 np1=mp2,ndo2,2 br(1,mp1,np1,k) = br(1,mp1,np1,k) 1 +vb(imid,np1+mb)*ve(imid,2*mp1-2,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k) 1 +vb(imid,np1+mb)*ve(imid,2*mp1-1,k) cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 -vb(imid,np1+mb)*we(imid,2*mp1-2,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -vb(imid,np1+mb)*we(imid,2*mp1-1,k) 22 continue 20 continue return c c case ityp=1 , no symmetries but cr and ci equal zero c c case m=0 c 100 do 115 k=1,nt do 115 i=1,imid do 115 np1=2,ndo2,2 br(1,1,np1,k) = br(1,1,np1,k)+vb(i,np1)*ve(i,1,k) 115 continue do 116 k=1,nt do 116 i=1,imm1 do 116 np1=3,ndo1,2 br(1,1,np1,k) = br(1,1,np1,k)+vb(i,np1)*vo(i,1,k) 116 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) return do 120 mp1=2,mmax m = mp1-1 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 117 do 123 k=1,nt do 123 i=1,imm1 do 123 np1=mp1,ndo1,2 br(1,mp1,np1,k) = br(1,mp1,np1,k)+vb(i,np1+mb)*vo(i,2*mp1-2,k) 1 +wb(i,np1+mb)*we(i,2*mp1-1,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k)+vb(i,np1+mb)*vo(i,2*mp1-1,k) 1 -wb(i,np1+mb)*we(i,2*mp1-2,k) 123 continue if(mlat .eq. 0) go to 117 do 124 k=1,nt do 124 np1=mp1,ndo1,2 br(1,mp1,np1,k) = br(1,mp1,np1,k) 1 +wb(imid,np1+mb)*we(imid,2*mp1-1,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k) 1 -wb(imid,np1+mb)*we(imid,2*mp1-2,k) 124 continue 117 if(mp2 .gt. ndo2) go to 120 do 121 k=1,nt do 121 i=1,imm1 do 121 np1=mp2,ndo2,2 br(1,mp1,np1,k) = br(1,mp1,np1,k)+vb(i,np1+mb)*ve(i,2*mp1-2,k) 1 +wb(i,np1+mb)*wo(i,2*mp1-1,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k)+vb(i,np1+mb)*ve(i,2*mp1-1,k) 1 -wb(i,np1+mb)*wo(i,2*mp1-2,k) 121 continue if(mlat .eq. 0) go to 120 do 122 k=1,nt do 122 np1=mp2,ndo2,2 br(1,mp1,np1,k) = br(1,mp1,np1,k) 1 +vb(imid,np1+mb)*ve(imid,2*mp1-2,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k) 1 +vb(imid,np1+mb)*ve(imid,2*mp1-1,k) 122 continue 120 continue return c c case ityp=2 , no symmetries but br and bi equal zero c c case m=0 c 200 do 215 k=1,nt do 215 i=1,imid do 215 np1=2,ndo2,2 cr(ncbc,1,np1,k) = cr(ncbc,1,np1,k)-vb(i,np1)*we(i,1,k) 215 continue do 216 k=1,nt do 216 i=1,imm1 do 216 np1=3,ndo1,2 cr(ncbc,1,np1,k) = cr(ncbc,1,np1,k)-vb(i,np1)*wo(i,1,k) 216 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) return do 220 mp1=2,mmax m = mp1-1 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 217 do 223 k=1,nt do 223 i=1,imm1 do 223 np1=mp1,ndo1,2 cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*wo(i,2*mp1-2,k) 1 +wb(i,np1+mb)*ve(i,2*mp1-1,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*wo(i,2*mp1-1,k) 1 -wb(i,np1+mb)*ve(i,2*mp1-2,k) 223 continue if(mlat .eq. 0) go to 217 do 224 k=1,nt do 224 np1=mp1,ndo1,2 cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 +wb(imid,np1+mb)*ve(imid,2*mp1-1,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -wb(imid,np1+mb)*ve(imid,2*mp1-2,k) 224 continue 217 if(mp2 .gt. ndo2) go to 220 do 221 k=1,nt do 221 i=1,imm1 do 221 np1=mp2,ndo2,2 cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*we(i,2*mp1-2,k) 1 +wb(i,np1+mb)*vo(i,2*mp1-1,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*we(i,2*mp1-1,k) 1 -wb(i,np1+mb)*vo(i,2*mp1-2,k) 221 continue if(mlat .eq. 0) go to 220 do 222 k=1,nt do 222 np1=mp2,ndo2,2 cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 -vb(imid,np1+mb)*we(imid,2*mp1-2,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -vb(imid,np1+mb)*we(imid,2*mp1-1,k) 222 continue 220 continue return c c case ityp=3 , v even , w odd c c case m=0 c 300 do 315 k=1,nt do 315 i=1,imid do 315 np1=2,ndo2,2 br(1,1,np1,k) = br(1,1,np1,k)+vb(i,np1)*ve(i,1,k) 315 continue do 316 k=1,nt do 316 i=1,imm1 do 316 np1=3,ndo1,2 cr(ncbc,1,np1,k) = cr(ncbc,1,np1,k)-vb(i,np1)*wo(i,1,k) 316 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) return do 320 mp1=2,mmax m = mp1-1 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 317 do 323 k=1,nt do 323 i=1,imm1 do 323 np1=mp1,ndo1,2 cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*wo(i,2*mp1-2,k) 1 +wb(i,np1+mb)*ve(i,2*mp1-1,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*wo(i,2*mp1-1,k) 1 -wb(i,np1+mb)*ve(i,2*mp1-2,k) 323 continue if(mlat .eq. 0) go to 317 do 324 k=1,nt do 324 np1=mp1,ndo1,2 cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 +wb(imid,np1+mb)*ve(imid,2*mp1-1,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -wb(imid,np1+mb)*ve(imid,2*mp1-2,k) 324 continue 317 if(mp2 .gt. ndo2) go to 320 do 321 k=1,nt do 321 i=1,imm1 do 321 np1=mp2,ndo2,2 br(1,mp1,np1,k) = br(1,mp1,np1,k)+vb(i,np1+mb)*ve(i,2*mp1-2,k) 1 +wb(i,np1+mb)*wo(i,2*mp1-1,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k)+vb(i,np1+mb)*ve(i,2*mp1-1,k) 1 -wb(i,np1+mb)*wo(i,2*mp1-2,k) 321 continue if(mlat .eq. 0) go to 320 do 322 k=1,nt do 322 np1=mp2,ndo2,2 br(1,mp1,np1,k) = br(1,mp1,np1,k) 1 +vb(imid,np1+mb)*ve(imid,2*mp1-2,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k) 1 +vb(imid,np1+mb)*ve(imid,2*mp1-1,k) 322 continue 320 continue return c c case ityp=4 , v even, w odd, and cr and ci equal 0. c c case m=0 c 400 do 415 k=1,nt do 415 i=1,imid do 415 np1=2,ndo2,2 br(1,1,np1,k) = br(1,1,np1,k)+vb(i,np1)*ve(i,1,k) 415 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) return do 420 mp1=2,mmax m = mp1-1 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp2 .gt. ndo2) go to 420 do 421 k=1,nt do 421 i=1,imm1 do 421 np1=mp2,ndo2,2 br(1,mp1,np1,k) = br(1,mp1,np1,k)+vb(i,np1+mb)*ve(i,2*mp1-2,k) 1 +wb(i,np1+mb)*wo(i,2*mp1-1,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k)+vb(i,np1+mb)*ve(i,2*mp1-1,k) 1 -wb(i,np1+mb)*wo(i,2*mp1-2,k) 421 continue if(mlat .eq. 0) go to 420 do 422 k=1,nt do 422 np1=mp2,ndo2,2 br(1,mp1,np1,k) = br(1,mp1,np1,k) 1 +vb(imid,np1+mb)*ve(imid,2*mp1-2,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k) 1 +vb(imid,np1+mb)*ve(imid,2*mp1-1,k) 422 continue 420 continue return c c case ityp=5 v even, w odd, and br and bi equal zero c c case m=0 c 500 do 516 k=1,nt do 516 i=1,imm1 do 516 np1=3,ndo1,2 cr(ncbc,1,np1,k) = cr(ncbc,1,np1,k)-vb(i,np1)*wo(i,1,k) 516 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) return do 520 mp1=2,mmax m = mp1-1 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 520 do 523 k=1,nt do 523 i=1,imm1 do 523 np1=mp1,ndo1,2 cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*wo(i,2*mp1-2,k) 1 +wb(i,np1+mb)*ve(i,2*mp1-1,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*wo(i,2*mp1-1,k) 1 -wb(i,np1+mb)*ve(i,2*mp1-2,k) 523 continue if(mlat .eq. 0) go to 520 do 524 k=1,nt do 524 np1=mp1,ndo1,2 cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 +wb(imid,np1+mb)*ve(imid,2*mp1-1,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -wb(imid,np1+mb)*ve(imid,2*mp1-2,k) 524 continue 520 continue return c c case ityp=6 , v odd , w even c c case m=0 c 600 do 615 k=1,nt do 615 i=1,imid do 615 np1=2,ndo2,2 cr(ncbc,1,np1,k) = cr(ncbc,1,np1,k)-vb(i,np1)*we(i,1,k) 615 continue do 616 k=1,nt do 616 i=1,imm1 do 616 np1=3,ndo1,2 br(1,1,np1,k) = br(1,1,np1,k)+vb(i,np1)*vo(i,1,k) 616 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) return do 620 mp1=2,mmax m = mp1-1 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 617 do 623 k=1,nt do 623 i=1,imm1 do 623 np1=mp1,ndo1,2 br(1,mp1,np1,k) = br(1,mp1,np1,k)+vb(i,np1+mb)*vo(i,2*mp1-2,k) 1 +wb(i,np1+mb)*we(i,2*mp1-1,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k)+vb(i,np1+mb)*vo(i,2*mp1-1,k) 1 -wb(i,np1+mb)*we(i,2*mp1-2,k) 623 continue if(mlat .eq. 0) go to 617 do 624 k=1,nt do 624 np1=mp1,ndo1,2 br(1,mp1,np1,k) = br(1,mp1,np1,k) 1 +wb(imid,np1+mb)*we(imid,2*mp1-1,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k) 1 -wb(imid,np1+mb)*we(imid,2*mp1-2,k) 624 continue 617 if(mp2 .gt. ndo2) go to 620 do 621 k=1,nt do 621 i=1,imm1 do 621 np1=mp2,ndo2,2 cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*we(i,2*mp1-2,k) 1 +wb(i,np1+mb)*vo(i,2*mp1-1,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*we(i,2*mp1-1,k) 1 -wb(i,np1+mb)*vo(i,2*mp1-2,k) 621 continue if(mlat .eq. 0) go to 620 do 622 k=1,nt do 622 np1=mp2,ndo2,2 cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 -vb(imid,np1+mb)*we(imid,2*mp1-2,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -vb(imid,np1+mb)*we(imid,2*mp1-1,k) 622 continue 620 continue return c c case ityp=7 v odd, w even, and cr and ci equal zero c c case m=0 c 700 do 716 k=1,nt do 716 i=1,imm1 do 716 np1=3,ndo1,2 br(1,1,np1,k) = br(1,1,np1,k)+vb(i,np1)*vo(i,1,k) 716 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) return do 720 mp1=2,mmax m = mp1-1 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 720 do 723 k=1,nt do 723 i=1,imm1 do 723 np1=mp1,ndo1,2 br(1,mp1,np1,k) = br(1,mp1,np1,k)+vb(i,np1+mb)*vo(i,2*mp1-2,k) 1 +wb(i,np1+mb)*we(i,2*mp1-1,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k)+vb(i,np1+mb)*vo(i,2*mp1-1,k) 1 -wb(i,np1+mb)*we(i,2*mp1-2,k) 723 continue if(mlat .eq. 0) go to 720 do 724 k=1,nt do 724 np1=mp1,ndo1,2 br(1,mp1,np1,k) = br(1,mp1,np1,k) 1 +wb(imid,np1+mb)*we(imid,2*mp1-1,k) bi(1,mp1,np1,k) = bi(1,mp1,np1,k) 1 -wb(imid,np1+mb)*we(imid,2*mp1-2,k) 724 continue 720 continue return c c case ityp=8 v odd, w even, and both br and bi equal zero c c case m=0 c 800 do 815 k=1,nt do 815 i=1,imid do 815 np1=2,ndo2,2 cr(ncbc,1,np1,k) = cr(ncbc,1,np1,k)-vb(i,np1)*we(i,1,k) 815 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) return do 820 mp1=2,mmax m = mp1-1 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp2 .gt. ndo2) go to 820 do 821 k=1,nt do 821 i=1,imm1 do 821 np1=mp2,ndo2,2 cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*we(i,2*mp1-2,k) 1 +wb(i,np1+mb)*vo(i,2*mp1-1,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -vb(i,np1+mb)*we(i,2*mp1-1,k) 1 -wb(i,np1+mb)*vo(i,2*mp1-2,k) 821 continue if(mlat .eq. 0) go to 820 do 822 k=1,nt do 822 np1=mp2,ndo2,2 cr(ncbc,mp1,np1,k) = cr(ncbc,mp1,np1,k) 1 -vb(imid,np1+mb)*we(imid,2*mp1-2,k) ci(ncbc,mp1,np1,k) = ci(ncbc,mp1,np1,k) 1 -vb(imid,np1+mb)*we(imid,2*mp1-1,k) 822 continue 820 continue return end subroutine vhagsi(nlat,nlon,wvhags,lvhags,dwork,ldwork,ierror) implicit double precision (a-h,o-z) dimension wvhags(lvhags) double precision dwork(ldwork) ierror = 1 if(nlat .lt. 3) return ierror = 2 if(nlon .lt. 1) return ierror = 3 imid = (nlat+1)/2 lmn = (nlat*(nlat+1))/2 if(lvhags .lt. 2*(imid*lmn)+nlon+15) return ierror = 4 c if (ldwork.lt.nlat*(3*nlat+9)+2) return if (ldwork.lt.(nlat*(3*nlat+9)+2)/2) return ierror = 0 jw1 = 1 jw2 = jw1+imid*lmn jw3 = jw2+imid*lmn iw1 = 1 iw2 = iw1+nlat iw3 = iw2+nlat iw4 = iw3+3*imid*nlat c iw2 = iw1+nlat+nlat c iw3 = iw2+nlat+nlat c iw4 = iw3+6*imid*nlat call vhgai1(nlat,imid,wvhags(jw1),wvhags(jw2), +dwork(iw1),dwork(iw2),dwork(iw3),dwork(iw4)) call hrffti(nlon,wvhags(jw3)) return end subroutine vhgai1(nlat,imid,vb,wb,dthet,dwts,dpbar,work) implicit double precision (a-h,o-z) dimension vb(imid,*),wb(imid,*) double precision abel,bbel,cbel,ssqr2,dcf double precision dpbar(imid,nlat,3), dthet(*),dwts(*),work(*) c lwk = 4*nlat*(nlat+2) lwk = nlat*(nlat+2) call gaqd(nlat,dthet,dwts,dpbar,lwk,ierror) c c compute associated legendre functions c c compute m=n=0 legendre polynomials for all theta(i) c ssqr2 = 1.d0/dsqrt(2.d0) do 90 i=1,imid dpbar(i,1,1) = ssqr2 vb(i,1) = 0.d0 wb(i,1) = 0.d0 90 continue c c main loop for remaining vb, and wb c do 100 n=1,nlat-1 nm = mod(n-2,3)+1 nz = mod(n-1,3)+1 np = mod(n,3)+1 c c compute dpbar for m=0 c call dnlfk(0,n,work) mn = indx(0,n,nlat) do 105 i=1,imid call dnlft(0,n,dthet(i),work,dpbar(i,1,np)) 105 continue c c compute dpbar for m=1 c call dnlfk(1,n,work) mn = indx(1,n,nlat) do 106 i=1,imid call dnlft(1,n,dthet(i),work,dpbar(i,2,np)) c pbar(i,mn) = dpbar(i,2,np) 106 continue 104 continue c c compute and store dpbar for m=2,n c if(n.lt.2) go to 108 do 107 m=2,n abel = dsqrt(dfloat((2*n+1)*(m+n-2)*(m+n-3))/ 1 dfloat((2*n-3)*(m+n-1)*(m+n))) bbel = dsqrt(dfloat((2*n+1)*(n-m-1)*(n-m))/ 1 dfloat((2*n-3)*(m+n-1)*(m+n))) cbel = dsqrt(dfloat((n-m+1)*(n-m+2))/ 1 dfloat((m+n-1)*(m+n))) id = indx(m,n,nlat) if (m.ge.n-1) go to 102 do 103 i=1,imid dpbar(i,m+1,np) = abel*dpbar(i,m-1,nm)+bbel*dpbar(i,m+1,nm) 1 -cbel*dpbar(i,m-1,np) 103 continue go to 107 102 do 101 i=1,imid dpbar(i,m+1,np) = abel*dpbar(i,m-1,nm)-cbel*dpbar(i,m-1,np) 101 continue 107 continue c c compute the derivative of the functions c 108 continue ix = indx(0,n,nlat) iy = indx(n,n,nlat) do 125 i=1,imid vb(i,ix) = -dpbar(i,2,np)*dwts(i) vb(i,iy) = dpbar(i,n,np)/dsqrt(dfloat(2*(n+1)))*dwts(i) 125 continue c if(n.eq.1) go to 131 dcf = dsqrt(dfloat(4*n*(n+1))) do 130 m=1,n-1 ix = indx(m,n,nlat) abel = dsqrt(dfloat((n+m)*(n-m+1)))/dcf bbel = dsqrt(dfloat((n-m)*(n+m+1)))/dcf do 130 i=1,imid vb(i,ix) = (abel*dpbar(i,m,np)-bbel*dpbar(i,m+2,np))*dwts(i) 130 continue c c compute the vector harmonic w(theta) = m*pbar/cos(theta) c c set wb=0 for m=0 c 131 continue ix = indx(0,n,nlat) do 220 i=1,imid wb(i,ix) = 0.d0 220 continue c c compute wb for m=1,n c dcf = dsqrt(dfloat(n+n+1)/dfloat(4*n*(n+1)*(n+n-1))) do 230 m=1,n ix = indx(m,n,nlat) abel = dcf*dsqrt(dfloat((n+m)*(n+m-1))) bbel = dcf*dsqrt(dfloat((n-m)*(n-m-1))) if(m.ge.n-1) go to 231 do 229 i=1,imid wb(i,ix) = (abel*dpbar(i,m,nz) + bbel*dpbar(i,m+2,nz))*dwts(i) 229 continue go to 230 231 do 228 i=1,imid wb(i,ix) = abel*dpbar(i,m,nz)*dwts(i) 228 continue 230 continue 100 continue return end function indx(m,n,nlat) implicit double precision (a-h,o-z) integer indx indx = m*nlat-(m*(m+1))/2+n+1 return end ================================================ FILE: external/SPHEREPACK/vhsgs.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c c ... file vhsgs.f c c this file contains code and documentation for subroutines c vhsgs and vhsgsi c c ... files which must be loaded with vhsgs.f c c sphcom.f, hrfft.f, gaqd.f c c subroutine vhsgs(nstrvw,nstrbc,noffsvw,noffsbc, c nlat,nlon,ityp,nt,v,w,idvw,jdvw,br,bi,cr,ci, c + mdab,ndab,wvhsgs,lvhsgs,work,lwork,ierror) c c c subroutine vhsgs performs the vector spherical harmonic synthesis c of the arrays br, bi, cr, and ci and stores the result in the c arrays v and w. the synthesis is performed on an equally spaced c longitude grid and a gaussian colatitude grid (measured from c the north pole). v(i,j) and w(i,j) are the colatitudinal and c east longitudinal components respectively, located at the i(th) c colatitude gaussian point (see nlat below) and longitude c phi(j) = (j-1)*2*pi/nlon. the spectral respresentation of (v,w) c is given below at output parameters v,w. c c input parameters c c nstrvw, nstrbc strides in v,w and in br,bi,cr,ci c noffsvw, noffsbc offset in v,w and in br,bi,cr,ci c -- must be between 0 and stride-1 c Alternatively, when the two strides equal, you can set both c to -1 in which case the output will be computed for all c values of offset between 0 and stride-1. c c nlat the number of points in the gaussian colatitude grid on the c full sphere. these lie in the interval (0,pi) and are computed c in radians in theta(1) <...< theta(nlat) by subroutine gaqd. c if nlat is odd the equator will be included as the grid point c theta((nlat+1)/2). if nlat is even the equator will be c excluded as a grid point and will lie half way between c theta(nlat/2) and theta(nlat/2+1). nlat must be at least 3. c note: on the half sphere, the number of grid points in the c colatitudinal direction is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than zero. the axisymmetric case corresponds to nlon=1. c the efficiency of the computation is improved when nlon c is a product of small prime numbers. c c NOTE: this is a modified version of spherepack. Changes from c the original version to the current one have only been c tested for ityp=0,1,2. For this reason an error code will c be returned if ityp>2. c c ityp = 0 no symmetries exist about the equator. the synthesis c is performed on the entire sphere. i.e. on the c arrays v(i,j),w(i,j) for i=1,...,nlat and c j=1,...,nlon. c c = 1 no symmetries exist about the equator. the synthesis c is performed on the entire sphere. i.e. on the c arrays v(i,j),w(i,j) for i=1,...,nlat and c j=1,...,nlon. the curl of (v,w) is zero. that is, c (d/dtheta (sin(theta) w) - dv/dphi)/sin(theta) = 0. c the coefficients cr and ci are zero. c c = 2 no symmetries exist about the equator. the synthesis c is performed on the entire sphere. i.e. on the c arrays v(i,j),w(i,j) for i=1,...,nlat and c j=1,...,nlon. the divergence of (v,w) is zero. i.e., c (d/dtheta (sin(theta) v) + dw/dphi)/sin(theta) = 0. c the coefficients br and bi are zero. c c = 3 v is symmetric and w is antisymmetric about the c equator. the synthesis is performed on the northern c hemisphere only. i.e., if nlat is odd the synthesis c is performed on the arrays v(i,j),w(i,j) for c i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the synthesis is performed on the the arrays c v(i,j),w(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c c = 4 v is symmetric and w is antisymmetric about the c equator. the synthesis is performed on the northern c hemisphere only. i.e., if nlat is odd the synthesis c is performed on the arrays v(i,j),w(i,j) for c i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the synthesis is performed on the the arrays c v(i,j),w(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c the curl of (v,w) is zero. that is, c (d/dtheta (sin(theta) w) - dv/dphi)/sin(theta) = 0. c the coefficients cr and ci are zero. c c = 5 v is symmetric and w is antisymmetric about the c equator. the synthesis is performed on the northern c hemisphere only. i.e., if nlat is odd the synthesis c is performed on the arrays v(i,j),w(i,j) for c i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the synthesis is performed on the the arrays c v(i,j),w(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c the divergence of (v,w) is zero. i.e., c (d/dtheta (sin(theta) v) + dw/dphi)/sin(theta) = 0. c the coefficients br and bi are zero. c c = 6 v is antisymmetric and w is symmetric about the c equator. the synthesis is performed on the northern c hemisphere only. i.e., if nlat is odd the synthesis c is performed on the arrays v(i,j),w(i,j) for c i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the synthesis is performed on the the arrays c v(i,j),w(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c c = 7 v is antisymmetric and w is symmetric about the c equator. the synthesis is performed on the northern c hemisphere only. i.e., if nlat is odd the synthesis c is performed on the arrays v(i,j),w(i,j) for c i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the synthesis is performed on the the arrays c v(i,j),w(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c the curl of (v,w) is zero. that is, c (d/dtheta (sin(theta) w) - dv/dphi)/sin(theta) = 0. c the coefficients cr and ci are zero. c c = 8 v is antisymmetric and w is symmetric about the c equator. the synthesis is performed on the northern c hemisphere only. i.e., if nlat is odd the synthesis c is performed on the arrays v(i,j),w(i,j) for c i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the synthesis is performed on the the arrays c v(i,j),w(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c the divergence of (v,w) is zero. i.e., c (d/dtheta (sin(theta) v) + dw/dphi)/sin(theta) = 0. c the coefficients br and bi are zero. c c c nt the number of syntheses. in the program that calls vhsgs, c the arrays v,w,br,bi,cr, and ci can be three dimensional c in which case multiple syntheses will be performed. c the third index is the synthesis index which assumes the c values k=1,...,nt. for a single synthesis set nt=1. the c discription of the remaining parameters is simplified c by assuming that nt=1 or that all the arrays are two c dimensional. c c idvw the first dimension of the arrays v,w as it appears in c the program that calls vhags. if ityp .le. 2 then idvw c must be at least nlat. if ityp .gt. 2 and nlat is c even then idvw must be at least nlat/2. if ityp .gt. 2 c and nlat is odd then idvw must be at least (nlat+1)/2. c c jdvw the second dimension of the arrays v,w as it appears in c the program that calls vhsgs. jdvw must be at least nlon. c c br,bi two or three dimensional arrays (see input parameter nt) c cr,ci that contain the vector spherical harmonic coefficients c in the spectral representation of v(i,j) and w(i,j) given c below at the discription of output parameters v and w. c c mdab the first dimension of the arrays br,bi,cr, and ci as it c appears in the program that calls vhsgs. mdab must be at c least min0(nlat,nlon/2) if nlon is even or at least c min0(nlat,(nlon+1)/2) if nlon is odd. c c ndab the second dimension of the arrays br,bi,cr, and ci as it c appears in the program that calls vhsgs. ndab must be at c least nlat. c c wvhsgs an array which must be initialized by subroutine vhsgsi. c once initialized, wvhsgs can be used repeatedly by vhsgs c as long as nlon and nlat remain unchanged. wvhsgs must c not be altered between calls of vhsgs. c c lvhsgs the dimension of the array wvhsgs as it appears in the c program that calls vhsgs. define c c l1 = min0(nlat,nlon/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lvhsgs must be at least c c l1*l2*(nlat+nlat-l1+1)+nlon+15+2*nlat c c c work a work array that does not have to be saved. c c lwork the dimension of the array work as it appears in the c program that calls vhsgs. define c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c if ityp .le. 2 then lwork must be at least c c (2*nt+1)*nlat*nlon c c if ityp .gt. 2 then lwork must be at least c c (2*nt+1)*l2*nlon c c ************************************************************** c c output parameters c c v,w two or three dimensional arrays (see input parameter nt) c in which the synthesis is stored. v is the colatitudinal c component and w is the east longitudinal component. c v(i,j),w(i,j) contain the components at the guassian colatitude c point theta(i) and longitude phi(j) = (j-1)*2*pi/nlon. c the index ranges are defined above at the input parameter c ityp. v and w are computed from the formulas given below. c c c define c c 1. theta is colatitude and phi is east longitude c c 2. the normalized associated legendre funnctions c c pbar(m,n,theta) = sqrt((2*n+1)*factorial(n-m) c /(2*factorial(n+m)))*sin(theta)**m/(2**n* c factorial(n)) times the (n+m)th derivative c of (x**2-1)**n with respect to x=cos(theta) c c 3. vbar(m,n,theta) = the derivative of pbar(m,n,theta) with c respect to theta divided by the square c root of n(n+1). c c vbar(m,n,theta) is more easily computed in the form c c vbar(m,n,theta) = (sqrt((n+m)*(n-m+1))*pbar(m-1,n,theta) c -sqrt((n-m)*(n+m+1))*pbar(m+1,n,theta))/(2*sqrt(n*(n+1))) c c 4. wbar(m,n,theta) = m/(sin(theta))*pbar(m,n,theta) divided c by the square root of n(n+1). c c wbar(m,n,theta) is more easily computed in the form c c wbar(m,n,theta) = sqrt((2n+1)/(2n-1))*(sqrt((n+m)*(n+m-1)) c *pbar(m-1,n-1,theta)+sqrt((n-m)*(n-m-1))*pbar(m+1,n-1,theta)) c /(2*sqrt(n*(n+1))) c c c the colatitudnal dependence of the normalized surface vector c spherical harmonics are defined by c c 5. bbar(m,n,theta) = (vbar(m,n,theta),i*wbar(m,n,theta)) c c 6. cbar(m,n,theta) = (i*wbar(m,n,theta),-vbar(m,n,theta)) c c c the coordinate to index mappings c c 7. theta(i) = i(th) gaussian grid point and phi(j) = (j-1)*2*pi/nlon c c c the maximum (plus one) longitudinal wave number c c 8. mmax = min0(nlat,nlon/2) if nlon is even or c mmax = min0(nlat,(nlon+1)/2) if nlon is odd. c c if we further define the output vector as c c 9. h(i,j) = (v(i,j),w(i,j)) c c and the complex coefficients c c 10. b(m,n) = cmplx(br(m+1,n+1),bi(m+1,n+1)) c c 11. c(m,n) = cmplx(cr(m+1,n+1),ci(m+1,n+1)) c c c then for i=1,...,nlat and j=1,...,nlon c c the expansion for real h(i,j) takes the form c c h(i,j) = the sum from n=1 to n=nlat-1 of the real part of c c .5*(b(0,n)*bbar(0,n,theta(i))+c(0,n)*cbar(0,n,theta(i))) c c plus the sum from m=1 to m=mmax-1 of the sum from n=m to c n=nlat-1 of the real part of c c b(m,n)*bbar(m,n,theta(i))*exp(i*m*phi(j)) c +c(m,n)*cbar(m,n,theta(i))*exp(i*m*phi(j)) c c ************************************************************* c c in terms of real variables this expansion takes the form c c for i=1,...,nlat and j=1,...,nlon c c v(i,j) = the sum from n=1 to n=nlat-1 of c c .5*br(ncbc,n+1)*vbar(0,n,theta(i)) c c plus the sum from m=1 to m=mmax-1 of the sum from n=m to c n=nlat-1 of the real part of c c (br(m+1,n+1)*vbar(m,n,theta(i))-ci(m+1,n+1)*wbar(m,n,theta(i))) c *cos(m*phi(j)) c -(bi(m+1,n+1)*vbar(m,n,theta(i))+cr(m+1,n+1)*wbar(m,n,theta(i))) c *sin(m*phi(j)) c c and for i=1,...,nlat and j=1,...,nlon c c w(i,j) = the sum from n=1 to n=nlat-1 of c c -.5*cr(1,n+1)*vbar(0,n,theta(i)) c c plus the sum from m=1 to m=mmax-1 of the sum from n=m to c n=nlat-1 of the real part of c c -(cr(m+1,n+1)*vbar(m,n,theta(i))+bi(m+1,n+1)*wbar(m,n,theta(i))) c *cos(m*phi(j)) c +(ci(m+1,n+1)*vbar(m,n,theta(i))-br(m+1,n+1)*wbar(m,n,theta(i))) c *sin(m*phi(j)) c c c br(m+1,nlat),bi(m+1,nlat),cr(m+1,nlat), and ci(m+1,nlat) are c assumed zero for m even. c c c ierror = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of ityp c = 4 error in the specification of nt c = 5 error in the specification of idvw c = 6 error in the specification of jdvw c = 7 error in the specification of mdab c = 8 error in the specification of ndab c = 9 error in the specification of lvhsgs c = 10 error in the specification of lwork c c c subroutine vhsgsi(nlat,nlon,wvhsgs,lvhsgs,dwork,ldwork,ierror) c c subroutine vhsgsi initializes the array wvhsgs which can then be c used repeatedly by subroutine vhsgs until nlat or nlon is changed. c c input parameters c c nlat the number of points in the gaussian colatitude grid on the c full sphere. these lie in the interval (0,pi) and are computed c in radians in theta(1) <...< theta(nlat) by subroutine gaqd. c if nlat is odd the equator will be included as the grid point c theta((nlat+1)/2). if nlat is even the equator will be c excluded as a grid point and will lie half way between c theta(nlat/2) and theta(nlat/2+1). nlat must be at least 3. c note: on the half sphere, the number of grid points in the c colatitudinal direction is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than zero. the axisymmetric case corresponds to nlon=1. c the efficiency of the computation is improved when nlon c is a product of small prime numbers. c c lvhsgs the dimension of the array wvhsgs as it appears in the c program that calls vhsgs. define c c l1 = min0(nlat,nlon/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lvhsgs must be at least c c l1*l2*(nlat+nlat-l1+1)+nlon+15+2*nlat c c dwork a double precision work array that does not need to be saved c c ldwork the dimension of the array dwork as it appears in the c program that calls vhsgsi. ldwork must be at least c c (3*nlat*(nlat+3)+2)/2 c c ************************************************************** c c output parameters c c wvhsgs an array which is initialized for use by subroutine vhsgs. c once initialized, wvhsgs can be used repeatedly by vhsgs c as long as nlat and nlon remain unchanged. wvhsgs must not c be altered between calls of vhsgs. c c c ierror = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of lvhsgs c = 4 error in the specification of lwork c subroutine vhsgs(nstrvw,nstrbc,noffsvw,noffsbc, + nlat,nlon,ityp,nt,v,w,idvw,jdvw,br,bi,cr,ci, + mdab,ndab,wvhsgs,lvhsgs,work,lwork,ierror) implicit double precision (a-h,o-z) dimension v(nstrvw,idvw,jdvw,1),w(nstrvw,idvw,jdvw,1), 1 br(nstrbc,mdab,ndab,1),bi(nstrbc,mdab,ndab,1), 1 cr(nstrbc,mdab,ndab,1),ci(nstrbc,mdab,ndab,1), 2 work(1),wvhsgs(1) ierror = 1 if(nlat .lt. 3) return ierror = 2 if(nlon .lt. 1) return ierror = 3 if(ityp.lt.0 .or. ityp.gt.8) return c see note above about symmetries if(ityp.gt.2) return ierror = 4 if(nt .lt. 0) return ierror = 5 imid = (nlat+1)/2 if((ityp.le.2 .and. idvw.lt.nlat) .or. 1 (ityp.gt.2 .and. idvw.lt.imid)) return ierror = 6 if(jdvw .lt. nlon) return ierror = 7 mmax = min0(nlat,(nlon+1)/2) if(mdab .lt. mmax) return ierror = 8 if(ndab .lt. nlat) return ierror = 9 idz = (mmax*(nlat+nlat-mmax+1))/2 lzimn = idz*imid if(lvhsgs .lt. lzimn+lzimn+nlon+15) return ierror = 10 idv = nlat if(ityp .gt. 2) idv = imid lnl = nt*idv*nlon ng=1 if(noffsvw.eq.-1) ng=nstrvw if(lwork .lt. ng*(lnl+lnl+idv*nlon)) return ierror = 11 if((noffsvw.eq.-1) .neqv. (noffsbc.eq.-1)) return if((noffsvw.eq.-1) .and. (nstrvw.ne.nstrbc)) return if((noffsvw.lt.-1) .or. (noffsvw.ge.nstrvw)) return if((noffsbc.lt.-1) .or. (noffsbc.ge.nstrbc)) return ierror = 0 ist = 0 if(ityp .le. 2) ist = imid c c set wvhsgs pointers c lmn = nlat*(nlat+1)/2 jw1 = 1 jw2 = jw1+imid*lmn jw3 = jw2+imid*lmn c c set work pointers c iw1 = ng*ist+1 iw2 = ng*lnl+1 iw3 = iw2+ist*ng iw4 = iw2+lnl*ng call vhsgs1(nstrvw,nstrbc,noffsvw,noffsbc, + nlat,nlon,ityp,nt,imid,idvw,jdvw,v,w,mdab,ndab, + br,bi,cr,ci,ng,idv,work,work(iw1),work(iw2),work(iw3), + work(iw4),idz,wvhsgs(jw1),wvhsgs(jw2),wvhsgs(jw3)) return end subroutine vhsgs1(nstrvw,nstrbc,noffsvw,noffsbc, + nlat,nlon,ityp,nt,imid,idvw,jdvw,v,w,mdab, 1 ndab,br,bi,cr,ci,ng,idv,ve,vo,we,wo,work,idz,vb,wb,wrfft) implicit double precision (a-h,o-z) dimension v(nstrvw,idvw,jdvw,1),w(nstrvw,idvw,jdvw,1), 1 br(nstrbc,mdab,ndab,1),bi(nstrbc,mdab,ndab,1), 1 cr(nstrbc,mdab,ndab,1),ci(nstrbc,mdab,ndab,1), 2 ve(ng,idv,nlon,1),vo(ng,idv,nlon,1),we(ng,idv,nlon,1), 3 wo(ng,idv,nlon,1),work(1),wrfft(1), 4 vb(imid,1),wb(imid,1) ncvwdiff=noffsvw-noffsbc if(noffsbc.eq.-1) then ncbcmin=1 ncbcmax=nstrbc else ncbcmin=1+noffsbc ncbcmax=1+noffsbc end if c do 234 ncbc=ncbcmin,ncbcmax c ncvw=ncvwdiff+ncbc c ig=ncbc-ncbcmin+1 c ig=1 nlp1 = nlat+1 mlat = mod(nlat,2) mlon = mod(nlon,2) mmax = min0(nlat,(nlon+1)/2) imm1 = imid if(mlat .ne. 0) imm1 = imid-1 do 10 k=1,nt do 10 j=1,nlon do 10 i=1,idv do 10 ig=1,ng ve(ig,i,j,k) = 0.d0 we(ig,i,j,k) = 0.d0 10 continue ndo1 = nlat ndo2 = nlat if(mlat .ne. 0) ndo1 = nlat-1 if(mlat .eq. 0) ndo2 = nlat-1 18 itypp = ityp+1 go to (1,100,200,300,400,500,600,700,800),itypp c c case ityp=0 no symmetries c c case m = 0 c 1 continue do 15 k=1,nt do 15 np1=2,ndo2,2 do 15 i=1,imid do 15 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,i,1,k)=ve(ig,i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) we(ig,i,1,k)=we(ig,i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 15 continue do 16 k=1,nt do 16 np1=3,ndo1,2 do 16 i=1,imm1 do 16 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 vo(ig,i,1,k)=vo(ig,i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) wo(ig,i,1,k)=wo(ig,i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 16 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 30 mp1=2,mmax m = mp1-1 c mb = m*(nlat-1)-(m*(m-1))/2 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 26 do 25 k=1,nt do 24 np1=mp1,ndo1,2 mn = mb+np1 do 23 i=1,imm1 do 23 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 vo(ig,i,2*mp1-2,k)=vo(ig,i,2*mp1-2,k)+br(ncbc,mp1,np1,k)*vb(i,mn) ve(ig,i,2*mp1-2,k)=ve(ig,i,2*mp1-2,k)-ci(ncbc,mp1,np1,k)*wb(i,mn) vo(ig,i,2*mp1-1,k)=vo(ig,i,2*mp1-1,k)+bi(ncbc,mp1,np1,k)*vb(i,mn) ve(ig,i,2*mp1-1,k)=ve(ig,i,2*mp1-1,k)+cr(ncbc,mp1,np1,k)*wb(i,mn) wo(ig,i,2*mp1-2,k)=wo(ig,i,2*mp1-2,k)-cr(ncbc,mp1,np1,k)*vb(i,mn) we(ig,i,2*mp1-2,k)=we(ig,i,2*mp1-2,k)-bi(ncbc,mp1,np1,k)*wb(i,mn) wo(ig,i,2*mp1-1,k)=wo(ig,i,2*mp1-1,k)-ci(ncbc,mp1,np1,k)*vb(i,mn) we(ig,i,2*mp1-1,k)=we(ig,i,2*mp1-1,k)+br(ncbc,mp1,np1,k)*wb(i,mn) 23 continue if(mlat .eq. 0) go to 24 do 924 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,imid,2*mp1-2,k) = ve(ig,imid,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(imid,mn) ve(ig,imid,2*mp1-1,k) = ve(ig,imid,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(imid,mn) we(ig,imid,2*mp1-2,k) = we(ig,imid,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(imid,mn) we(ig,imid,2*mp1-1,k) = we(ig,imid,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(imid,mn) 924 continue 24 continue 25 continue 26 if(mp2 .gt. ndo2) go to 30 do 29 k=1,nt do 28 np1=mp2,ndo2,2 mn = mb+np1 do 27 i=1,imm1 do 27 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,i,2*mp1-2,k)=ve(ig,i,2*mp1-2,k)+br(ncbc,mp1,np1,k)*vb(i,mn) vo(ig,i,2*mp1-2,k)=vo(ig,i,2*mp1-2,k)-ci(ncbc,mp1,np1,k)*wb(i,mn) ve(ig,i,2*mp1-1,k)=ve(ig,i,2*mp1-1,k)+bi(ncbc,mp1,np1,k)*vb(i,mn) vo(ig,i,2*mp1-1,k)=vo(ig,i,2*mp1-1,k)+cr(ncbc,mp1,np1,k)*wb(i,mn) we(ig,i,2*mp1-2,k)=we(ig,i,2*mp1-2,k)-cr(ncbc,mp1,np1,k)*vb(i,mn) wo(ig,i,2*mp1-2,k)=wo(ig,i,2*mp1-2,k)-bi(ncbc,mp1,np1,k)*wb(i,mn) we(ig,i,2*mp1-1,k)=we(ig,i,2*mp1-1,k)-ci(ncbc,mp1,np1,k)*vb(i,mn) wo(ig,i,2*mp1-1,k)=wo(ig,i,2*mp1-1,k)+br(ncbc,mp1,np1,k)*wb(i,mn) 27 continue if(mlat .eq. 0) go to 28 do 928 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,imid,2*mp1-2,k) = ve(ig,imid,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(imid,mn) ve(ig,imid,2*mp1-1,k) = ve(ig,imid,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(imid,mn) we(ig,imid,2*mp1-2,k) = we(ig,imid,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(imid,mn) we(ig,imid,2*mp1-1,k) = we(ig,imid,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(imid,mn) 928 continue 28 continue 29 continue 30 continue go to 950 c c case ityp=1 no symmetries, cr and ci equal zero c c case m = 0 c 100 continue do 115 k=1,nt do 115 np1=2,ndo2,2 do 115 i=1,imid do 115 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,i,1,k)=ve(ig,i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) 115 continue do 116 k=1,nt do 116 np1=3,ndo1,2 do 116 i=1,imm1 do 116 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 vo(ig,i,1,k)=vo(ig,i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) 116 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 130 mp1=2,mmax m = mp1-1 c mb = m*(nlat-1)-(m*(m-1))/2 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 126 do 125 k=1,nt do 124 np1=mp1,ndo1,2 mn = mb+np1 do 123 i=1,imm1 do 123 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 vo(ig,i,2*mp1-2,k)=vo(ig,i,2*mp1-2,k)+br(ncbc,mp1,np1,k)*vb(i,mn) vo(ig,i,2*mp1-1,k)=vo(ig,i,2*mp1-1,k)+bi(ncbc,mp1,np1,k)*vb(i,mn) we(ig,i,2*mp1-2,k)=we(ig,i,2*mp1-2,k)-bi(ncbc,mp1,np1,k)*wb(i,mn) we(ig,i,2*mp1-1,k)=we(ig,i,2*mp1-1,k)+br(ncbc,mp1,np1,k)*wb(i,mn) 123 continue if(mlat .eq. 0) go to 124 do 9124 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 we(ig,imid,2*mp1-2,k) = we(ig,imid,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(imid,mn) we(ig,imid,2*mp1-1,k) = we(ig,imid,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(imid,mn) 9124 continue 124 continue 125 continue 126 if(mp2 .gt. ndo2) go to 130 do 129 k=1,nt do 128 np1=mp2,ndo2,2 mn = mb+np1 do 127 i=1,imm1 do 127 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,i,2*mp1-2,k)=ve(ig,i,2*mp1-2,k)+br(ncbc,mp1,np1,k)*vb(i,mn) ve(ig,i,2*mp1-1,k)=ve(ig,i,2*mp1-1,k)+bi(ncbc,mp1,np1,k)*vb(i,mn) wo(ig,i,2*mp1-2,k)=wo(ig,i,2*mp1-2,k)-bi(ncbc,mp1,np1,k)*wb(i,mn) wo(ig,i,2*mp1-1,k)=wo(ig,i,2*mp1-1,k)+br(ncbc,mp1,np1,k)*wb(i,mn) 127 continue if(mlat .eq. 0) go to 128 do 9128 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,imid,2*mp1-2,k) = ve(ig,imid,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(imid,mn) ve(ig,imid,2*mp1-1,k) = ve(ig,imid,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(imid,mn) 9128 continue 128 continue 129 continue 130 continue go to 950 c c case ityp=2 no symmetries, br and bi are equal to zero c c case m = 0 c 200 do 215 k=1,nt do 215 np1=2,ndo2,2 do 215 i=1,imid do 215 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 we(ig,i,1,k)=we(ig,i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 215 continue do 216 k=1,nt do 216 np1=3,ndo1,2 do 216 i=1,imm1 do 9216 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 wo(ig,i,1,k)=wo(ig,i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 9216 continue 216 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 230 mp1=2,mmax m = mp1-1 c mb = m*(nlat-1)-(m*(m-1))/2 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 226 do 225 k=1,nt do 224 np1=mp1,ndo1,2 mn = mb+np1 do 223 i=1,imm1 do 223 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,i,2*mp1-2,k)=ve(ig,i,2*mp1-2,k)-ci(ncbc,mp1,np1,k)*wb(i,mn) ve(ig,i,2*mp1-1,k)=ve(ig,i,2*mp1-1,k)+cr(ncbc,mp1,np1,k)*wb(i,mn) wo(ig,i,2*mp1-2,k)=wo(ig,i,2*mp1-2,k)-cr(ncbc,mp1,np1,k)*vb(i,mn) wo(ig,i,2*mp1-1,k)=wo(ig,i,2*mp1-1,k)-ci(ncbc,mp1,np1,k)*vb(i,mn) 223 continue if(mlat .eq. 0) go to 224 do 9224 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,imid,2*mp1-2,k) = ve(ig,imid,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(imid,mn) ve(ig,imid,2*mp1-1,k) = ve(ig,imid,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(imid,mn) 9224 continue 224 continue 225 continue 226 if(mp2 .gt. ndo2) go to 230 do 229 k=1,nt do 228 np1=mp2,ndo2,2 mn = mb+np1 do 227 i=1,imm1 do 227 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 vo(ig,i,2*mp1-2,k)=vo(ig,i,2*mp1-2,k)-ci(ncbc,mp1,np1,k)*wb(i,mn) vo(ig,i,2*mp1-1,k)=vo(ig,i,2*mp1-1,k)+cr(ncbc,mp1,np1,k)*wb(i,mn) we(ig,i,2*mp1-2,k)=we(ig,i,2*mp1-2,k)-cr(ncbc,mp1,np1,k)*vb(i,mn) we(ig,i,2*mp1-1,k)=we(ig,i,2*mp1-1,k)-ci(ncbc,mp1,np1,k)*vb(i,mn) 227 continue if(mlat .eq. 0) go to 228 do 9228 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 we(ig,imid,2*mp1-2,k) = we(ig,imid,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(imid,mn) we(ig,imid,2*mp1-1,k) = we(ig,imid,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(imid,mn) 9228 continue 228 continue 229 continue 230 continue go to 950 c c case ityp=3 v even, w odd c c case m = 0 c 300 do 315 k=1,nt do 315 np1=2,ndo2,2 do 315 i=1,imid do 315 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,i,1,k)=ve(ig,i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) 315 continue do 316 k=1,nt do 316 np1=3,ndo1,2 do 316 i=1,imm1 do 316 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 wo(ig,i,1,k)=wo(ig,i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 316 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 330 mp1=2,mmax m = mp1-1 c mb = m*(nlat-1)-(m*(m-1))/2 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 326 do 325 k=1,nt do 324 np1=mp1,ndo1,2 mn = mb+np1 do 323 i=1,imm1 do 323 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,i,2*mp1-2,k)=ve(ig,i,2*mp1-2,k)-ci(ncbc,mp1,np1,k)*wb(i,mn) ve(ig,i,2*mp1-1,k)=ve(ig,i,2*mp1-1,k)+cr(ncbc,mp1,np1,k)*wb(i,mn) wo(ig,i,2*mp1-2,k)=wo(ig,i,2*mp1-2,k)-cr(ncbc,mp1,np1,k)*vb(i,mn) wo(ig,i,2*mp1-1,k)=wo(ig,i,2*mp1-1,k)-ci(ncbc,mp1,np1,k)*vb(i,mn) 323 continue if(mlat .eq. 0) go to 324 do 9324 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,imid,2*mp1-2,k) = ve(ig,imid,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(imid,mn) ve(ig,imid,2*mp1-1,k) = ve(ig,imid,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(imid,mn) 9324 continue 324 continue 325 continue 326 if(mp2 .gt. ndo2) go to 330 do 329 k=1,nt do 328 np1=mp2,ndo2,2 mn = mb+np1 do 327 i=1,imm1 do 327 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,i,2*mp1-2,k)=ve(ig,i,2*mp1-2,k)+br(ncbc,mp1,np1,k)*vb(i,mn) ve(ig,i,2*mp1-1,k)=ve(ig,i,2*mp1-1,k)+bi(ncbc,mp1,np1,k)*vb(i,mn) wo(ig,i,2*mp1-2,k)=wo(ig,i,2*mp1-2,k)-bi(ncbc,mp1,np1,k)*wb(i,mn) wo(ig,i,2*mp1-1,k)=wo(ig,i,2*mp1-1,k)+br(ncbc,mp1,np1,k)*wb(i,mn) 327 continue if(mlat .eq. 0) go to 328 do 9328 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,imid,2*mp1-2,k) = ve(ig,imid,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(imid,mn) ve(ig,imid,2*mp1-1,k) = ve(ig,imid,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(imid,mn) 9328 continue 328 continue 329 continue 330 continue go to 950 c c case ityp=4 v even, w odd, and both cr and ci equal zero c c case m = 0 c 400 do 415 k=1,nt do 415 np1=2,ndo2,2 do 415 i=1,imid do 415 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,i,1,k)=ve(ig,i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) 415 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 430 mp1=2,mmax m = mp1-1 c mb = m*(nlat-1)-(m*(m-1))/2 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp2 .gt. ndo2) go to 430 do 429 k=1,nt do 428 np1=mp2,ndo2,2 mn = mb+np1 do 427 i=1,imm1 do 427 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,i,2*mp1-2,k)=ve(ig,i,2*mp1-2,k)+br(ncbc,mp1,np1,k)*vb(i,mn) ve(ig,i,2*mp1-1,k)=ve(ig,i,2*mp1-1,k)+bi(ncbc,mp1,np1,k)*vb(i,mn) wo(ig,i,2*mp1-2,k)=wo(ig,i,2*mp1-2,k)-bi(ncbc,mp1,np1,k)*wb(i,mn) wo(ig,i,2*mp1-1,k)=wo(ig,i,2*mp1-1,k)+br(ncbc,mp1,np1,k)*wb(i,mn) 427 continue if(mlat .eq. 0) go to 428 do 9428 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,imid,2*mp1-2,k) = ve(ig,imid,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(imid,mn) ve(ig,imid,2*mp1-1,k) = ve(ig,imid,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(imid,mn) 9428 continue 428 continue 429 continue 430 continue go to 950 c c case ityp=5 v even, w odd, br and bi equal zero c c case m = 0 c 500 do 516 k=1,nt do 516 np1=3,ndo1,2 do 516 i=1,imm1 do 516 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 wo(ig,i,1,k)=wo(ig,i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 516 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 530 mp1=2,mmax m = mp1-1 c mb = m*(nlat-1)-(m*(m-1))/2 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 530 do 525 k=1,nt do 524 np1=mp1,ndo1,2 mn = mb+np1 do 523 i=1,imm1 do 523 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,i,2*mp1-2,k)=ve(ig,i,2*mp1-2,k)-ci(ncbc,mp1,np1,k)*wb(i,mn) ve(ig,i,2*mp1-1,k)=ve(ig,i,2*mp1-1,k)+cr(ncbc,mp1,np1,k)*wb(i,mn) wo(ig,i,2*mp1-2,k)=wo(ig,i,2*mp1-2,k)-cr(ncbc,mp1,np1,k)*vb(i,mn) wo(ig,i,2*mp1-1,k)=wo(ig,i,2*mp1-1,k)-ci(ncbc,mp1,np1,k)*vb(i,mn) 523 continue if(mlat .eq. 0) go to 524 do 9524 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ve(ig,imid,2*mp1-2,k) = ve(ig,imid,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(imid,mn) ve(ig,imid,2*mp1-1,k) = ve(ig,imid,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(imid,mn) 9524 continue 524 continue 525 continue 530 continue go to 950 c c case ityp=6 v odd , w even c c case m = 0 c 600 do 615 k=1,nt do 615 np1=2,ndo2,2 do 615 i=1,imid do 615 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 we(ig,i,1,k)=we(ig,i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 615 continue do 616 k=1,nt do 616 np1=3,ndo1,2 do 616 i=1,imm1 do 616 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 vo(ig,i,1,k)=vo(ig,i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) 616 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 630 mp1=2,mmax m = mp1-1 c mb = m*(nlat-1)-(m*(m-1))/2 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 626 do 625 k=1,nt do 624 np1=mp1,ndo1,2 mn = mb+np1 do 623 i=1,imm1 do 623 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 vo(ig,i,2*mp1-2,k)=vo(ig,i,2*mp1-2,k)+br(ncbc,mp1,np1,k)*vb(i,mn) vo(ig,i,2*mp1-1,k)=vo(ig,i,2*mp1-1,k)+bi(ncbc,mp1,np1,k)*vb(i,mn) we(ig,i,2*mp1-2,k)=we(ig,i,2*mp1-2,k)-bi(ncbc,mp1,np1,k)*wb(i,mn) we(ig,i,2*mp1-1,k)=we(ig,i,2*mp1-1,k)+br(ncbc,mp1,np1,k)*wb(i,mn) 623 continue if(mlat .eq. 0) go to 624 do 9624 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 we(ig,imid,2*mp1-2,k) = we(ig,imid,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(imid,mn) we(ig,imid,2*mp1-1,k) = we(ig,imid,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(imid,mn) 9624 continue 624 continue 625 continue 626 if(mp2 .gt. ndo2) go to 630 do 629 k=1,nt do 628 np1=mp2,ndo2,2 mn = mb+np1 do 627 i=1,imm1 do 627 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 vo(ig,i,2*mp1-2,k)=vo(ig,i,2*mp1-2,k)-ci(ncbc,mp1,np1,k)*wb(i,mn) vo(ig,i,2*mp1-1,k)=vo(ig,i,2*mp1-1,k)+cr(ncbc,mp1,np1,k)*wb(i,mn) we(ig,i,2*mp1-2,k)=we(ig,i,2*mp1-2,k)-cr(ncbc,mp1,np1,k)*vb(i,mn) we(ig,i,2*mp1-1,k)=we(ig,i,2*mp1-1,k)-ci(ncbc,mp1,np1,k)*vb(i,mn) 627 continue if(mlat .eq. 0) go to 628 do 9628 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 we(ig,imid,2*mp1-2,k) = we(ig,imid,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(imid,mn) we(ig,imid,2*mp1-1,k) = we(ig,imid,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(imid,mn) 9628 continue 628 continue 629 continue 630 continue go to 950 c c case ityp=7 v odd, w even cr and ci equal zero c c case m = 0 c 700 do 716 k=1,nt do 716 np1=3,ndo1,2 do 716 i=1,imm1 do 716 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 vo(ig,i,1,k)=vo(ig,i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) 716 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 730 mp1=2,mmax m = mp1-1 c mb = m*(nlat-1)-(m*(m-1))/2 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 730 do 725 k=1,nt do 724 np1=mp1,ndo1,2 mn = mb+np1 do 723 i=1,imm1 do 723 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 vo(ig,i,2*mp1-2,k)=vo(ig,i,2*mp1-2,k)+br(ncbc,mp1,np1,k)*vb(i,mn) vo(ig,i,2*mp1-1,k)=vo(ig,i,2*mp1-1,k)+bi(ncbc,mp1,np1,k)*vb(i,mn) we(ig,i,2*mp1-2,k)=we(ig,i,2*mp1-2,k)-bi(ncbc,mp1,np1,k)*wb(i,mn) we(ig,i,2*mp1-1,k)=we(ig,i,2*mp1-1,k)+br(ncbc,mp1,np1,k)*wb(i,mn) 723 continue if(mlat .eq. 0) go to 724 do 9724 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 we(ig,imid,2*mp1-2,k) = we(ig,imid,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(imid,mn) we(ig,imid,2*mp1-1,k) = we(ig,imid,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(imid,mn) 9724 continue 724 continue 725 continue 730 continue go to 950 c c case ityp=8 v odd, w even br and bi equal zero c c case m = 0 c 800 do 815 k=1,nt do 815 np1=2,ndo2,2 do 815 i=1,imid do 815 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 we(ig,i,1,k)=we(ig,i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 815 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 830 mp1=2,mmax m = mp1-1 c mb = m*(nlat-1)-(m*(m-1))/2 mb = m*nlat-(m*(m+1))/2 mp2 = mp1+1 if(mp2 .gt. ndo2) go to 830 do 829 k=1,nt do 828 np1=mp2,ndo2,2 mn = mb+np1 do 827 i=1,imm1 do 827 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 vo(ig,i,2*mp1-2,k)=vo(ig,i,2*mp1-2,k)-ci(ncbc,mp1,np1,k)*wb(i,mn) vo(ig,i,2*mp1-1,k)=vo(ig,i,2*mp1-1,k)+cr(ncbc,mp1,np1,k)*wb(i,mn) we(ig,i,2*mp1-2,k)=we(ig,i,2*mp1-2,k)-cr(ncbc,mp1,np1,k)*vb(i,mn) we(ig,i,2*mp1-1,k)=we(ig,i,2*mp1-1,k)-ci(ncbc,mp1,np1,k)*vb(i,mn) 827 continue if(mlat .eq. 0) go to 828 we(ig,imid,2*mp1-2,k) = we(ig,imid,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(imid,mn) we(ig,imid,2*mp1-1,k) = we(ig,imid,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(imid,mn) 828 continue 829 continue 830 continue 950 continue do 14 k=1,nt c do 14 ig=1,ng call hrfftb(ng*idv,nlon,ve(1,1,1,k),ng*idv,wrfft,work) call hrfftb(ng*idv,nlon,we(1,1,1,k),ng*idv,wrfft,work) 14 continue if(ityp .gt. 2) go to 12 do 60 k=1,nt do 60 j=1,nlon do 60 i=1,imm1 do 60 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ncvw=ncvwdiff+ncbc v(ncvw,i,j,k) = .5d0*(ve(ig,i,j,k)+vo(ig,i,j,k)) w(ncvw,i,j,k) = .5d0*(we(ig,i,j,k)+wo(ig,i,j,k)) v(ncvw,nlp1-i,j,k) = .5d0*(ve(ig,i,j,k)-vo(ig,i,j,k)) w(ncvw,nlp1-i,j,k) = .5d0*(we(ig,i,j,k)-wo(ig,i,j,k)) 60 continue go to 13 12 do 11 k=1,nt do 11 j=1,nlon do 11 i=1,imm1 do 11 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ncvw=ncvwdiff+ncbc v(ncvw,i,j,k) = .5d0*ve(ig,i,j,k) w(ncvw,i,j,k) = .5d0*we(ig,i,j,k) 11 continue 13 if(mlat .ne. 0) then do 65 k=1,nt do 65 j=1,nlon do 65 ncbc=ncbcmin,ncbcmax ig=ncbc-ncbcmin+1 ncvw=ncvwdiff+ncbc ncvw=ncvwdiff+ncbc v(ncvw,imid,j,k) = .5d0*ve(ig,imid,j,k) w(ncvw,imid,j,k) = .5d0*we(ig,imid,j,k) 65 continue end if 234 continue return end subroutine vhsgsi(nlat,nlon,wvhsgs,lvhsgs,dwork,ldwork,ierror) implicit double precision (a-h,o-z) c c subroutine vhsfsi computes the gaussian points theta, gauss c weights wts, and the components vb and wb of the vector c harmonics. all quantities are computed internally in double c precision but returned in single precision and are therfore c accurate to single precision. c c set imid = (nlat+1)/2 and lmn=(nlat*(nlat+1))/2 then c wvhsgs must have 2*(imid*lmn+nlat)+nlon+15 locations c c double precision array dwork must have c 3*nlat*(nlat+1)+5*nlat+1 = nlat*(3*nlat+8)+1 c locations which is determined by the size of dthet, c dwts, dwork, and dpbar in vhsgs1 c dimension wvhsgs(*) double precision dwork(*) ierror = 1 if(nlat .lt. 3) return ierror = 2 if(nlon .lt. 1) return ierror = 3 imid = (nlat+1)/2 lmn = (nlat*(nlat+1))/2 if(lvhsgs .lt. 2*(imid*lmn)+nlon+15) return ierror = 4 if (ldwork .lt. (nlat*3*(nlat+3)+2)/2) return ierror = 0 c c set saved work space pointers c jw1 = 1 jw2 = jw1+imid*lmn jw3 = jw2+imid*lmn c c set unsaved work space pointers c iw1 = 1 iw2 = iw1+nlat iw3 = iw2+nlat iw4 = iw3+3*imid*nlat c iw2 = iw1+nlat+nlat c iw3 = iw2+nlat+nlat c iw4 = iw3+6*imid*nlat call vhgsi1(nlat,imid,wvhsgs(jw1),wvhsgs(jw2), +dwork(iw1),dwork(iw2),dwork(iw3),dwork(iw4)) call hrffti(nlon,wvhsgs(jw3)) return end subroutine vhgsi1(nlat,imid,vb,wb,dthet,dwts,dpbar,work) implicit double precision (a-h,o-z) dimension vb(imid,*),wb(imid,*) double precision abel,bbel,cbel,ssqr2,dcf double precision dthet(*),dwts(*),dpbar(imid,nlat,3),work(*) c c compute gauss points and weights c use dpbar (length 3*nnlat*(nnlat+1)) as work space for gaqd c lwk = nlat*(nlat+2) call gaqd(nlat,dthet,dwts,dpbar,lwk,ierror) c c compute associated legendre functions c c compute m=n=0 legendre polynomials for all theta(i) c ssqr2 = 1.d0/dsqrt(2.d0) do 90 i=1,imid dpbar(i,1,1) = ssqr2 vb(i,1) = 0.d0 wb(i,1) = 0.d0 90 continue c c main loop for remaining vb, and wb c do 100 n=1,nlat-1 nm = mod(n-2,3)+1 nz = mod(n-1,3)+1 np = mod(n,3)+1 c c compute dpbar for m=0 c call dnlfk(0,n,work) mn = indx(0,n,nlat) do 105 i=1,imid call dnlft(0,n,dthet(i),work,dpbar(i,1,np)) c pbar(i,mn) = dpbar(i,1,np) 105 continue c c compute dpbar for m=1 c call dnlfk(1,n,work) mn = indx(1,n,nlat) do 106 i=1,imid call dnlft(1,n,dthet(i),work,dpbar(i,2,np)) c pbar(i,mn) = dpbar(i,2,np) 106 continue 104 continue c c compute and store dpbar for m=2,n c if(n.lt.2) go to 108 do 107 m=2,n abel = dsqrt(dfloat((2*n+1)*(m+n-2)*(m+n-3))/ 1 dfloat((2*n-3)*(m+n-1)*(m+n))) bbel = dsqrt(dfloat((2*n+1)*(n-m-1)*(n-m))/ 1 dfloat((2*n-3)*(m+n-1)*(m+n))) cbel = dsqrt(dfloat((n-m+1)*(n-m+2))/ 1 dfloat((m+n-1)*(m+n))) id = indx(m,n,nlat) if (m.ge.n-1) go to 102 do 103 i=1,imid dpbar(i,m+1,np) = abel*dpbar(i,m-1,nm)+bbel*dpbar(i,m+1,nm) 1 -cbel*dpbar(i,m-1,np) c pbar(i,id) = dpbar(i,m+1,np) 103 continue go to 107 102 do 101 i=1,imid dpbar(i,m+1,np) = abel*dpbar(i,m-1,nm)-cbel*dpbar(i,m-1,np) c pbar(i,id) = dpbar(i,m+1,np) 101 continue 107 continue c c compute the derivative of the functions c 108 ix = indx(0,n,nlat) iy = indx(n,n,nlat) do 125 i=1,imid vb(i,ix) = -dpbar(i,2,np) vb(i,iy) = dpbar(i,n,np)/dsqrt(dfloat(2*(n+1))) 125 continue c if(n.eq.1) go to 131 dcf = dsqrt(dfloat(4*n*(n+1))) do 130 m=1,n-1 ix = indx(m,n,nlat) abel = dsqrt(dfloat((n+m)*(n-m+1)))/dcf bbel = dsqrt(dfloat((n-m)*(n+m+1)))/dcf do 130 i=1,imid vb(i,ix) = abel*dpbar(i,m,np)-bbel*dpbar(i,m+2,np) 130 continue c c compute the vector harmonic w(theta) = m*pbar/cos(theta) c c set wb=0 for m=0 c 131 ix = indx(0,n,nlat) do 220 i=1,imid wb(i,ix) = 0.d0 220 continue c c compute wb for m=1,n c dcf = dsqrt(dfloat(n+n+1)/dfloat(4*n*(n+1)*(n+n-1))) do 230 m=1,n ix = indx(m,n,nlat) abel = dcf*dsqrt(dfloat((n+m)*(n+m-1))) bbel = dcf*dsqrt(dfloat((n-m)*(n-m-1))) if(m.ge.n-1) go to 231 do 229 i=1,imid wb(i,ix) = abel*dpbar(i,m,nz) + bbel*dpbar(i,m+2,nz) 229 continue go to 230 231 do 228 i=1,imid wb(i,ix) = abel*dpbar(i,m,nz) 228 continue 230 continue 100 continue return end ================================================ FILE: external/SPHEREPACK/vrtgs.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c c ... file vrtgs.f c c this file includes documentation and code for c subroutine divgs i c c ... files which must be loaded with vrtgs.f c c sphcom.f, hrfft.f, vhgsc.f, shsgs.f, gaqd.f c c subroutine vrtgs(nstrv,nstrc,noffsv,noffsc, c nlat,nlon,isym,nt,vort,ivrt,jvrt,cr,ci,mdc,ndc, c + wshsgs,lshsgs,work,lwork,ierror) c c given the vector spherical harmonic coefficients cr and ci, precomputed c by subroutine vhags for a vector field (v,w), subroutine vrtgs c computes the vorticity of the vector field in the scalar array c vort. vort(i,j) is the vorticity at the gaussian colatitude c theta(i) (see nlat as input parameter) and longitude c lambda(j) = (j-1)*2*pi/nlon on the sphere. i.e., c c vort(i,j) = [-dv/dlambda + d(sint*w)/dtheta]/sint c c where sint = sin(theta(i)). w is the east longitudinal and v c is the colatitudinal component of the vector field from which c cr,ci were precomputed. required associated legendre polynomials c are stored rather than recomputed as they are in subroutine vrtgc. c c c input parameters c c nstrv the stride in vort c nstrc the stride in ci,cr c c noffsv the offset in vort c noffsc the offset in ci,cr c -- must be between 0 and stride-1 c c nlat the number of points in the gaussian colatitude grid on the c full sphere. these lie in the interval (0,pi) and are computed c in radians in theta(1) <...< theta(nlat) by subroutine gaqd. c if nlat is odd the equator will be included as the grid point c theta((nlat+1)/2). if nlat is even the equator will be c excluded as a grid point and will lie half way between c theta(nlat/2) and theta(nlat/2+1). nlat must be at least 3. c note: on the half sphere, the number of grid points in the c colatitudinal direction is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than 3. the axisymmetric case corresponds to nlon=1. c the efficiency of the computation is improved when nlon c is a product of small prime numbers. c c NOTE: this is a modified version of spherepack. Changes from c the original version to the current one have only been c tested for isym==0. For this reason an error code will c be returned if isym!=0. c c c isym a parameter which determines whether the vorticity is c computed on the full or half sphere as follows: c c = 0 c the symmetries/antsymmetries described in isym=1,2 below c do not exist in (v,w) about the equator. in this case the c vorticity is neither symmetric nor antisymmetric about c the equator. the vorticity is computed on the entire c sphere. i.e., in the array vort(i,j) for i=1,...,nlat and c j=1,...,nlon. c c = 1 c w is antisymmetric and v is symmetric about the equator. c in this case the vorticity is symmetyric about the c equator and is computed for the northern hemisphere c only. i.e., if nlat is odd the vorticity is computed c in the array vort(i,j) for i=1,...,(nlat+1)/2 and for c j=1,...,nlon. if nlat is even the vorticity is computed c in the array vort(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c c = 2 c w is symmetric and v is antisymmetric about the equator c in this case the vorticity is antisymmetric about the c equator and is computed for the northern hemisphere c only. i.e., if nlat is odd the vorticity is computed c in the array vort(i,j) for i=1,...,(nlat+1)/2 and for c j=1,...,nlon. if nlat is even the vorticity is computed c in the array vort(i,j) for i=1,...,nlat/2 and j=1,...,nlon. c c c nt nt is the number of scalar and vector fields. some c computational efficiency is obtained for multiple fields. c in the program that calls vrtgs, the arrays cr,ci, and vort c can be three dimensional corresponding to an indexed multiple c vector field. in this case multiple scalar synthesis will c be performed to compute the vorticity for each field. the c third index is the synthesis index which assumes the values c k=1,...,nt. for a single synthesis set nt = 1. the c description of the remaining parameters is simplified by c assuming that nt=1 or that all the arrays are two dimensional. c c ivrt the first dimension of the array vort as it appears in c the program that calls vrtgs. if isym = 0 then ivrt c must be at least nlat. if isym = 1 or 2 and nlat is c even then ivrt must be at least nlat/2. if isym = 1 or 2 c and nlat is odd then ivrt must be at least (nlat+1)/2. c c jvrt the second dimension of the array vort as it appears in c the program that calls vrtgs. jvrt must be at least nlon. c c cr,ci two or three dimensional arrays (see input parameter nt) c that contain vector spherical harmonic coefficients c of the vector field (v,w) as computed by subroutine vhags. c *** cr and ci must be computed by vhags prior to calling c vrtgs. c c mdc the first dimension of the arrays cr and ci as it c appears in the program that calls vrtgs. mdc must be at c least min0(nlat,nlon/2) if nlon is even or at least c min0(nlat,(nlon+1)/2) if nlon is odd. c c ndc the second dimension of the arrays cr and ci as it c appears in the program that calls vrtgs. ndc must be at c least nlat. c c wshsgs an array which must be initialized by subroutine shsgsi. c once initialized, c wshsgs can be used repeatedly by vrtgs as long as nlon c and nlat remain unchanged. wshsgs must not be altered c between calls of vrtgs c c lshsgs the dimension of the array wshsgs as it appears in the c program that calls vrtgs. define c c l1 = min0(nlat,(nlon+2)/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lshsgs must be at least c c nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 c c work a work array that does not have to be saved. c c lwork the dimension of the array work as it appears in the c program that calls vrtgs. define c c l1 = min0(nlat,nlon/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd. c c if isym = 0 then lwork must be at least c c nlat*((nt+1)*nlon+2*nt*l1+1) c c if isym > 0 then lwork must be at least c c (nt+1)*l2*nlon+nlat*(2*nt*l1+1) c c c ************************************************************** c c output parameters c c c vort a two or three dimensional array (see input parameter nt) c that contains the vorticity of the vector field (v,w) c whose coefficients cr,ci where computed by subroutine vhags. c vort(i,j) is the vorticity at the gaussian colatitude point c theta(i) and longitude point lambda(j) = (j-1)*2*pi/nlon. c the index ranges are defined above at the input parameter c isym. c c c ierror an error parameter which indicates fatal errors with input c parameters when returned positive. c = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of isym c = 4 error in the specification of nt c = 5 error in the specification of ivrt c = 6 error in the specification of jvrt c = 7 error in the specification of mdc c = 8 error in the specification of ndc c = 9 error in the specification of lshsgs c = 10 error in the specification of lwork c ********************************************************************** c c subroutine vrtgs(nstrv,nstrc,noffsv,noffsc, + nlat,nlon,isym,nt,vort,ivrt,jvrt,cr,ci,mdc,ndc, + wshsgs,lshsgs,work,lwork,ierror) implicit double precision (a-h,o-z) dimension vort(nstrv,ivrt,jvrt,nt), + cr(nstrc,mdc,ndc,nt),ci(nstrc,mdc,ndc,nt) dimension wshsgs(lshsgs),work(lwork) c c check input parameters c ierror = 1 if(nlat .lt. 3) return ierror = 2 if(nlon .lt. 4) return ierror = 3 c if (isym.lt.0 .or. isym.gt.2) return c see note above about symmetries if(isym.ne.0) return ierror = 4 if(nt .lt. 0) return ierror = 5 imid = (nlat+1)/2 if((isym.eq.0 .and. ivrt.lt.nlat) .or. 1 (isym.gt.0 .and. ivrt.lt.imid)) return ierror = 6 if(jvrt .lt. nlon) return ierror = 7 if(mdc .lt. min0(nlat,(nlon+1)/2)) return mmax = min0(nlat,(nlon+2)/2) ierror = 8 if(ndc .lt. nlat) return ierror = 9 imid = (nlat+1)/2 lpimn = (imid*mmax*(nlat+nlat-mmax+1))/2 l2 = (nlat+mod(nlat,2))/2 l1 = min0((nlon+2)/2,nlat) lp=nlat*(3*(l1+l2)-2)+(l1-1)*(l2*(2*nlat-l1)-3*l1)/2+nlon+15 if(lshsgs.lt.lp) return ierror = 10 c c verify unsaved work space (add to what shses requires, file f3) c c c set first dimension for a,b (as requried by shses) c mab = min0(nlat,nlon/2+1) mn = mab*nlat*nt ls = nlat if(isym .gt. 0) ls = imid nln = nt*ls*nlon if(lwork.lt. nln+ls*nlon+2*mn+nlat) return ierror = 11 if((noffsv.lt.0).or.(noffsv.ge.nstrv)) return if((noffsc.lt.0).or.(noffsc.ge.nstrc)) return ierror = 0 c c set work space pointers c ia = 1 ib = ia+mn is = ib+mn iwk = is+nlat lwk = lwork-2*mn-nlat call vrtgs1(nstrv,nstrc,noffsv,noffsc, 1 nlat,nlon,isym,nt,vort,ivrt,jvrt,cr,ci,mdc,ndc, +work(ia),work(ib),mab,work(is),wshsgs,lshsgs,work(iwk),lwk, +ierror) return end subroutine vrtgs1(nstrv,nstrc,noffsv,noffsc, + nlat,nlon,isym,nt,vort,ivrt,jvrt,cr,ci,mdc,ndc, + a,b,mab,sqnn,wsav,lwsav,wk,lwk,ierror) implicit double precision (a-h,o-z) dimension vort(nstrv,ivrt,jvrt,nt), + cr(nstrc,mdc,ndc,nt),ci(nstrc,mdc,ndc,nt) dimension a(mab,nlat,nt),b(mab,nlat,nt),sqnn(nlat) dimension wsav(lwsav),wk(lwk) ncc=noffsc+1 c c set coefficient multiplyers c do 1 n=2,nlat fn = dfloat(n-1) sqnn(n) = dsqrt(fn*(fn+1.)) 1 continue c c compute divergence scalar coefficients for each vector field c do 2 k=1,nt do 3 n=1,nlat do 4 m=1,mab a(m,n,k) = 0.0 b(m,n,k) = 0.0 4 continue 3 continue c c compute m=0 coefficients c do 5 n=2,nlat a(1,n,k) = sqnn(n)*cr(ncc,1,n,k) b(1,n,k) = sqnn(n)*ci(ncc,1,n,k) 5 continue c c compute m>0 coefficients c mmax = min0(nlat,(nlon+1)/2) do 6 m=2,mmax do 7 n=m,nlat a(m,n,k) = sqnn(n)*cr(ncc,m,n,k) b(m,n,k) = sqnn(n)*ci(ncc,m,n,k) 7 continue 6 continue 2 continue c c synthesize a,b into vort c call shsgs(nstrv,1,noffsv,0,nlat,nlon,isym,nt,vort,ivrt,jvrt,a,b, + mab,nlat,mab,nlat,wsav,lwsav,wk,lwk,ierror) return end ================================================ FILE: external/SPHEREPACK/vtsgs.f ================================================ c c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c * * c * copyright (c) 1998 by UCAR * c * * c * University Corporation for Atmospheric Research * c * * c * all rights reserved * c * * c * SPHEREPACK version 3.2 * c * * c * A Package of Fortran77 Subroutines and Programs * c * * c * for Modeling Geophysical Processes * c * * c * by * c * * c * John Adams and Paul Swarztrauber * c * * c * of * c * * c * the National Center for Atmospheric Research * c * * c * Boulder, Colorado (80307) U.S.A. * c * * c * which is sponsored by * c * * c * the National Science Foundation * c * * c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * c c c c ... file vtsgs.f c c this file includes documentation and code for c subroutines vtsgs and vtsgsi c c ... files which must be loaded with vtsgs.f c c sphcom.f, hrfft.f, vhags.f, vhsgs.f,gaqd.f c c c subroutine vtsgs(nstrvw,nstrbc,noffsvw,noffsbc, c + nlat,nlon,ityp,nt,vt,wt,idvw,jdvw,br,bi,cr,ci, c + mdab,ndab,wvts,lwvts,work,lwork,ierror) c c given the vector harmonic analysis br,bi,cr, and ci (computed c by subroutine vhags) of some vector function (v,w), this c subroutine computes the vector function (vt,wt) which is c the derivative of (v,w) with respect to colatitude theta. vtsgs c is similar to vhsgs except the vector harmonics are replaced by c their derivative with respect to colatitude with the result that c (vt,wt) is computed instead of (v,w). vt(i,j) is the derivative c of the colatitudinal component v(i,j) at the gaussian colatitude c point theta(i) and longitude phi(j) = (j-1)*2*pi/nlon. the c spectral representation of (vt,wt) is given below at output c parameters vt,wt. c c input parameters c c nstrvw the stride in wt,vt c nstrbc the stride in bi,br,ci,cr c noffsvw the offset in wt,vt c noffsbc the offset in bi,br,ci,cr c -- must be between 0 and stride-1 c c nlat the number of gaussian colatitudinal grid points theta(i) c such that 0 < theta(1) <...< theta(nlat) < pi. they are c computed by subroutine gaqd which is called by this c subroutine. if nlat is odd the equator is c theta((nlat+1)/2). if nlat is even the equator lies c half way between theta(nlat/2) and theta(nlat/2+1). nlat c must be at least 3. note: if (v,w) is symmetric about c the equator (see parameter ityp below) the number of c colatitudinal grid points is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than zero. the axisymmetric case corresponds to nlon=1. c the efficiency of the computation is improved when nlon c is a product of small prime numbers. c c NOTE: this is a modified version of spherepack. Changes from c the original version to the current one have only been c tested for ityp=0,1,2. For this reason an error code will c be returned if ityp>2. c c ityp = 0 no symmetries exist about the equator. the synthesis c is performed on the entire sphere. i.e. the arrays c vt(i,j),wt(i,j) are computed for i=1,...,nlat and c j=1,...,nlon. c c = 1 no symmetries exist about the equator however the c the coefficients cr and ci are zero which implies c that the curl of (v,w) is zero. that is, c (d/dtheta (sin(theta) w) - dv/dphi)/sin(theta) = 0. c the calculations are performed on the entire sphere. c i.e. the arrays vt(i,j),wt(i,j) are computed for c i=1,...,nlat and j=1,...,nlon. c c = 2 no symmetries exist about the equator however the c the coefficients br and bi are zero which implies c that the divergence of (v,w) is zero. that is, c (d/dtheta (sin(theta) v) + dw/dphi)/sin(theta) = 0. c the calculations are performed on the entire sphere. c i.e. the arrays vt(i,j),wt(i,j) are computed for c i=1,...,nlat and j=1,...,nlon. c c = 3 vt is odd and wt is even about the equator. the c synthesis is performed on the northern hemisphere c only. i.e., if nlat is odd the arrays vt(i,j) c and wt(i,j) are computed for i=1,...,(nlat+1)/2 c and j=1,...,nlon. if nlat is even the arrays c are computed for i=1,...,nlat/2 and j=1,...,nlon. c c = 4 vt is odd and wt is even about the equator and the c coefficients cr and ci are zero. the synthesis is c performed on the northern hemisphere only. i.e. if c nlat is odd the arrays vt(i,j),wt(i,j) are computed c for i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the arrays vt(i,j),wt(i,j) are computed for c i=1,...,nlat/2 and j=1,...,nlon. c c = 5 vt is odd and wt is even about the equator and the c coefficients br and bi are zero. the synthesis is c performed on the northern hemisphere only. i.e. if c nlat is odd the arrays vt(i,j),wt(i,j) are computed c for i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the arrays vt(i,j),wt(i,j) are computed for c i=1,...,nlat/2 and j=1,...,nlon. c c = 6 vt is even and wt is odd about the equator. the c synthesis is performed on the northern hemisphere c only. i.e., if nlat is odd the arrays vt(i,j),wt(i,j) c are computed for i=1,...,(nlat+1)/2 and j=1,...,nlon. c if nlat is even the arrays vt(i,j),wt(i,j) are computed c for i=1,...,nlat/2 and j=1,...,nlon. c c = 7 vt is even and wt is odd about the equator and the c coefficients cr and ci are zero. the synthesis is c performed on the northern hemisphere only. i.e. if c nlat is odd the arrays vt(i,j),wt(i,j) are computed c for i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the arrays vt(i,j),wt(i,j) are computed for c i=1,...,nlat/2 and j=1,...,nlon. c c = 8 vt is even and wt is odd about the equator and the c coefficients br and bi are zero. the synthesis is c performed on the northern hemisphere only. i.e. if c nlat is odd the arrays vt(i,j),wt(i,j) are computed c for i=1,...,(nlat+1)/2 and j=1,...,nlon. if nlat is c even the arrays vt(i,j),wt(i,j) are computed for c i=1,...,nlat/2 and j=1,...,nlon. c c nt the number of syntheses. in the program that calls vtsgs, c the arrays vt,wt,br,bi,cr, and ci can be three dimensional c in which case multiple syntheses will be performed. c the third index is the synthesis index which assumes the c values k=1,...,nt. for a single synthesis set nt=1. the c discription of the remaining parameters is simplified c by assuming that nt=1 or that all the arrays are two c dimensional. c c idvw the first dimension of the arrays vt,wt as it appears in c the program that calls vtsgs. if ityp .le. 2 then idvw c must be at least nlat. if ityp .gt. 2 and nlat is c even then idvw must be at least nlat/2. if ityp .gt. 2 c and nlat is odd then idvw must be at least (nlat+1)/2. c c jdvw the second dimension of the arrays vt,wt as it appears in c the program that calls vtsgs. jdvw must be at least nlon. c c br,bi two or three dimensional arrays (see input parameter nt) c cr,ci that contain the vector spherical harmonic coefficients c of (v,w) as computed by subroutine vhags. c c mdab the first dimension of the arrays br,bi,cr, and ci as it c appears in the program that calls vtsgs. mdab must be at c least min0(nlat,nlon/2) if nlon is even or at least c min0(nlat,(nlon+1)/2) if nlon is odd. c c ndab the second dimension of the arrays br,bi,cr, and ci as it c appears in the program that calls vtsgs. ndab must be at c least nlat. c c wvts an array which must be initialized by subroutine vtsgsi. c once initialized, wvts can be used repeatedly by vtsgs c as long as nlon and nlat remain unchanged. wvts must c not be altered between calls of vtsgs. c c lwvts the dimension of the array wvts as it appears in the c program that calls vtsgs. define c c l1 = min0(nlat,nlon/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lwvts must be at least c c l1*l2*(nlat+nlat-l1+1)+nlon+15 c c c work a work array that does not have to be saved. c c lwork the dimension of the array work as it appears in the c program that calls vtsgs. define c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c if ityp .le. 2 then lwork must be at least c c (2*nt+1)*nlat*nlon c c if ityp .gt. 2 then lwork must be at least c c (2*nt+1)*l2*nlon c c ************************************************************** c c output parameters c c vt,wt two or three dimensional arrays (see input parameter nt) c in which the derivative of (v,w) with respect to c colatitude theta is stored. vt(i,j),wt(i,j) contain the c derivatives at gaussian colatitude points theta(i) for c i=1,...,nlat and longitude phi(j) = (j-1)*2*pi/nlon. c the index ranges are defined above at the input parameter c ityp. vt and wt are computed from the formulas for v and c w given in subroutine vhsgs but with vbar and wbar replaced c with their derivatives with respect to colatitude. these c derivatives are denoted by vtbar and wtbar. c c c ************************************************************* c c in terms of real variables this expansion takes the form c c for i=1,...,nlat and j=1,...,nlon c c vt(i,j) = the sum from n=1 to n=nlat-1 of c c .5*br(1,n+1)*vtbar(0,n,theta(i)) c c plus the sum from m=1 to m=mmax-1 of the sum from n=m to c n=nlat-1 of the real part of c c (br(m+1,n+1)*vtbar(m,n,theta(i)) c -ci(m+1,n+1)*wtbar(m,n,theta(i)))*cos(m*phi(j)) c -(bi(m+1,n+1)*vtbar(m,n,theta(i)) c +cr(m+1,n+1)*wtbar(m,n,theta(i)))*sin(m*phi(j)) c c and for i=1,...,nlat and j=1,...,nlon c c wt(i,j) = the sum from n=1 to n=nlat-1 of c c -.5*cr(1,n+1)*vtbar(0,n,theta(i)) c c plus the sum from m=1 to m=mmax-1 of the sum from n=m to c n=nlat-1 of the real part of c c -(cr(m+1,n+1)*vtbar(m,n,theta(i)) c +bi(m+1,n+1)*wtbar(m,n,theta(i)))*cos(m*phi(j)) c +(ci(m+1,n+1)*vtbar(m,n,theta(i)) c -br(m+1,n+1)*wtbar(m,n,theta(i)))*sin(m*phi(j)) c c c br(m+1,nlat),bi(m+1,nlat),cr(m+1,nlat), and ci(m+1,nlat) are c assumed zero for m even. c c c ierror = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of ityp c = 4 error in the specification of nt c = 5 error in the specification of idvw c = 6 error in the specification of jdvw c = 7 error in the specification of mdab c = 8 error in the specification of ndab c = 9 error in the specification of lwvts c = 10 error in the specification of lwork c c c ******************************************************************* c c subroutine vtsgsi(nlat,nlon,wvts,lwvts,work,lwork,dwork,ldwork, c + ierror) c c subroutine vtsgsi initializes the array wvts which can then be c used repeatedly by subroutine vtsgs until nlat or nlon is changed. c c input parameters c c nlat the number of gaussian colatitudinal grid points theta(i) c such that 0 < theta(1) <...< theta(nlat) < pi. they are c computed by subroutine gaqd which is called by this c subroutine. if nlat is odd the equator is c theta((nlat+1)/2). if nlat is even the equator lies c half way between theta(nlat/2) and theta(nlat/2+1). nlat c must be at least 3. note: if (v,w) is symmetric about c the equator (see parameter ityp below) the number of c colatitudinal grid points is nlat/2 if nlat is even or c (nlat+1)/2 if nlat is odd. c c nlon the number of distinct londitude points. nlon determines c the grid increment in longitude as 2*pi/nlon. for example c nlon = 72 for a five degree grid. nlon must be greater c than zero. the axisymmetric case corresponds to nlon=1. c the efficiency of the computation is improved when nlon c is a product of small prime numbers. c c lwvts the dimension of the array wvts as it appears in the c program that calls vtsgs. define c c l1 = min0(nlat,nlon/2) if nlon is even or c l1 = min0(nlat,(nlon+1)/2) if nlon is odd c c and c c l2 = nlat/2 if nlat is even or c l2 = (nlat+1)/2 if nlat is odd c c then lwvts must be at least c c l1*l2*(nlat+nlat-l1+1)+nlon+15 c c c work a work array that does not have to be saved. c c lwork the dimension of the array work as it appears in the c program that calls vtsgs. lwork must be at least c c 3*(max0(l1-2,0)*(nlat+nlat-l1-1))/2+(5*l2+2)*nlat c c dwork a double precision work array that does not have to be saved c c ldwork the length of dwork. ldwork must be at least c 3*nlat+2 c c ************************************************************** c c output parameters c c wvts an array which is initialized for use by subroutine vtsgs. c once initialized, wvts can be used repeatedly by vtsgs c as long as nlat or nlon remain unchanged. wvts must not c be altered between calls of vtsgs. c c c ierror = 0 no errors c = 1 error in the specification of nlat c = 2 error in the specification of nlon c = 3 error in the specification of lwvts c = 4 error in the specification of lwork c = 5 error in the specification of ldwork c subroutine vtsgs(nstrvw,nstrbc,noffsvw,noffsbc, 1 nlat,nlon,ityp,nt,vt,wt,idvw,jdvw,br,bi,cr,ci, 1 mdab,ndab,wvts,lwvts,work,lwork,ierror) implicit double precision (a-h,o-z) c dimension vt(nstrvw,idvw,jdvw,1),wt(nstrvw,idvw,jdvw,1), 1 br(nstrbc,mdab,ndab,1),bi(nstrbc,mdab,ndab,1), 1 cr(nstrbc,mdab,ndab,1),ci(nstrbc,mdab,ndab,1), 2 work(1),wvts(1) ierror = 1 if(nlat .lt. 3) return ierror = 2 if(nlon .lt. 1) return ierror = 3 if(ityp.lt.0 .or. ityp.gt.8) return ierror = 4 c see note above about symmetries if(ityp.gt.2) return if(nt .lt. 0) return ierror = 5 imid = (nlat+1)/2 c if((ityp.le.2 .and. idvw.lt.nlat) .or. c 1 (ityp.gt.2 .and. idvw.lt.imid)) return c see note above about symmetries if(ityp.ne.0) return ierror = 6 if(jdvw .lt. nlon) return ierror = 7 mmax = min0(nlat,(nlon+1)/2) if(mdab .lt. mmax) return ierror = 8 if(ndab .lt. nlat) return ierror = 9 idz = (mmax*(nlat+nlat-mmax+1))/2 lzimn = idz*imid if(lwvts .lt. lzimn+lzimn+nlon+15) return ierror = 10 idv = nlat if(ityp .gt. 2) idv = imid lnl = nt*idv*nlon if(lwork .lt. lnl+lnl+idv*nlon) return ierror = 11 if((noffsvw.lt.0).or.(noffsvw.ge.nstrvw)) return if((noffsbc.lt.0).or.(noffsbc.ge.nstrbc)) return ierror = 0 ist = 0 if(ityp .le. 2) ist = imid iw1 = ist+1 iw2 = lnl+1 iw3 = iw2+ist iw4 = iw2+lnl jw1 = lzimn+1 jw2 = jw1+lzimn call vtsgs1(nstrvw,nstrbc,noffsvw,noffsbc, 1 nlat,nlon,ityp,nt,imid,idvw,jdvw,vt,wt,mdab,ndab, 1 br,bi,cr,ci,idv,work,work(iw1),work(iw2),work(iw3), 2 work(iw4),idz,wvts,wvts(jw1),wvts(jw2)) return end subroutine vtsgs1(nstrvw,nstrbc,noffsvw,noffsbc, 1 nlat,nlon,ityp,nt,imid,idvw,jdvw,vt,wt,mdab, 1 ndab,br,bi,cr,ci,idv,vte,vto,wte,wto,work,idz,vb,wb,wrfft) implicit double precision (a-h,o-z) dimension vt(nstrvw,idvw,jdvw,1),wt(nstrvw,idvw,jdvw,1), 1 br(nstrbc,mdab,ndab,1),bi(nstrbc,mdab,ndab,1), 1 cr(nstrbc,mdab,ndab,1),ci(nstrbc,mdab,ndab,1), 2 vte(idv,nlon,1),vto(idv,nlon,1),wte(idv,nlon,1), 3 wto(idv,nlon,1),work(1),wrfft(1), 4 vb(imid,1),wb(imid,1) ncvw = noffsvw+1 ncbc = noffsbc+1 nlp1 = nlat+1 mlat = mod(nlat,2) mlon = mod(nlon,2) mmax = min0(nlat,(nlon+1)/2) imm1 = imid if(mlat .ne. 0) imm1 = imid-1 do 10 k=1,nt do 10 j=1,nlon do 10 i=1,idv vte(i,j,k) = 0.d0 wte(i,j,k) = 0.d0 10 continue ndo1 = nlat ndo2 = nlat if(mlat .ne. 0) ndo1 = nlat-1 if(mlat .eq. 0) ndo2 = nlat-1 18 itypp = ityp+1 go to (1,100,200,300,400,500,600,700,800),itypp c c case ityp=0 no symmetries c c case m = 0 c 1 do 15 k=1,nt do 15 np1=2,ndo2,2 do 15 i=1,imm1 vto(i,1,k)=vto(i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) wto(i,1,k)=wto(i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 15 continue do 16 k=1,nt do 16 np1=3,ndo1,2 do 16 i=1,imid vte(i,1,k)=vte(i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) wte(i,1,k)=wte(i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 16 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 30 mp1=2,mmax m = mp1-1 mb = m*(nlat-1)-(m*(m-1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 26 do 25 k=1,nt do 24 np1=mp1,ndo1,2 mn = mb+np1 do 23 i=1,imm1 vte(i,2*mp1-2,k) = vte(i,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(i,mn) vto(i,2*mp1-2,k) = vto(i,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(i,mn) vte(i,2*mp1-1,k) = vte(i,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(i,mn) vto(i,2*mp1-1,k) = vto(i,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(i,mn) wte(i,2*mp1-2,k) = wte(i,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(i,mn) wto(i,2*mp1-2,k) = wto(i,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(i,mn) wte(i,2*mp1-1,k) = wte(i,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(i,mn) wto(i,2*mp1-1,k) = wto(i,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(i,mn) 23 continue if(mlat .eq. 0) go to 24 vte(imid,2*mp1-2,k) = vte(imid,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(imid,mn) vte(imid,2*mp1-1,k) = vte(imid,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(imid,mn) wte(imid,2*mp1-2,k) = wte(imid,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(imid,mn) wte(imid,2*mp1-1,k) = wte(imid,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(imid,mn) 24 continue 25 continue 26 if(mp2 .gt. ndo2) go to 30 do 29 k=1,nt do 28 np1=mp2,ndo2,2 mn = mb+np1 do 27 i=1,imm1 vto(i,2*mp1-2,k) = vto(i,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(i,mn) vte(i,2*mp1-2,k) = vte(i,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(i,mn) vto(i,2*mp1-1,k) = vto(i,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(i,mn) vte(i,2*mp1-1,k) = vte(i,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(i,mn) wto(i,2*mp1-2,k) = wto(i,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(i,mn) wte(i,2*mp1-2,k) = wte(i,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(i,mn) wto(i,2*mp1-1,k) = wto(i,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(i,mn) wte(i,2*mp1-1,k) = wte(i,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(i,mn) 27 continue if(mlat .eq. 0) go to 28 vte(imid,2*mp1-2,k) = vte(imid,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(imid,mn) vte(imid,2*mp1-1,k) = vte(imid,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(imid,mn) wte(imid,2*mp1-2,k) = wte(imid,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(imid,mn) wte(imid,2*mp1-1,k) = wte(imid,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(imid,mn) 28 continue 29 continue 30 continue go to 950 c c case ityp=1 no symmetries, cr and ci equal zero c c case m = 0 c 100 do 115 k=1,nt do 115 np1=2,ndo2,2 do 115 i=1,imm1 vto(i,1,k)=vto(i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) 115 continue do 116 k=1,nt do 116 np1=3,ndo1,2 do 116 i=1,imid vte(i,1,k)=vte(i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) 116 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 130 mp1=2,mmax m = mp1-1 mb = m*(nlat-1)-(m*(m-1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 126 do 125 k=1,nt do 124 np1=mp1,ndo1,2 mn = mb+np1 do 123 i=1,imm1 vte(i,2*mp1-2,k) = vte(i,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(i,mn) vte(i,2*mp1-1,k) = vte(i,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(i,mn) wto(i,2*mp1-2,k) = wto(i,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(i,mn) wto(i,2*mp1-1,k) = wto(i,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(i,mn) 123 continue if(mlat .eq. 0) go to 124 vte(imid,2*mp1-2,k) = vte(imid,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(imid,mn) vte(imid,2*mp1-1,k) = vte(imid,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(imid,mn) 124 continue 125 continue 126 if(mp2 .gt. ndo2) go to 130 do 129 k=1,nt do 128 np1=mp2,ndo2,2 mn = mb+np1 do 127 i=1,imm1 vto(i,2*mp1-2,k) = vto(i,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(i,mn) vto(i,2*mp1-1,k) = vto(i,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(i,mn) wte(i,2*mp1-2,k) = wte(i,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(i,mn) wte(i,2*mp1-1,k) = wte(i,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(i,mn) 127 continue if(mlat .eq. 0) go to 128 wte(imid,2*mp1-2,k) = wte(imid,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(imid,mn) wte(imid,2*mp1-1,k) = wte(imid,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(imid,mn) 128 continue 129 continue 130 continue go to 950 c c case ityp=2 no symmetries, br and bi are equal to zero c c case m = 0 c 200 do 215 k=1,nt do 215 np1=2,ndo2,2 do 215 i=1,imm1 wto(i,1,k)=wto(i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 215 continue do 216 k=1,nt do 216 np1=3,ndo1,2 do 216 i=1,imid wte(i,1,k)=wte(i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 216 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 230 mp1=2,mmax m = mp1-1 mb = m*(nlat-1)-(m*(m-1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 226 do 225 k=1,nt do 224 np1=mp1,ndo1,2 mn = mb+np1 do 223 i=1,imm1 vto(i,2*mp1-2,k) = vto(i,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(i,mn) vto(i,2*mp1-1,k) = vto(i,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(i,mn) wte(i,2*mp1-2,k) = wte(i,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(i,mn) wte(i,2*mp1-1,k) = wte(i,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(i,mn) 223 continue if(mlat .eq. 0) go to 224 wte(imid,2*mp1-2,k) = wte(imid,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(imid,mn) wte(imid,2*mp1-1,k) = wte(imid,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(imid,mn) 224 continue 225 continue 226 if(mp2 .gt. ndo2) go to 230 do 229 k=1,nt do 228 np1=mp2,ndo2,2 mn = mb+np1 do 227 i=1,imm1 vte(i,2*mp1-2,k) = vte(i,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(i,mn) vte(i,2*mp1-1,k) = vte(i,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(i,mn) wto(i,2*mp1-2,k) = wto(i,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(i,mn) wto(i,2*mp1-1,k) = wto(i,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(i,mn) 227 continue if(mlat .eq. 0) go to 228 vte(imid,2*mp1-2,k) = vte(imid,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(imid,mn) vte(imid,2*mp1-1,k) = vte(imid,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(imid,mn) 228 continue 229 continue 230 continue go to 950 c c case ityp=3 v odd, w even c c case m = 0 c 300 do 315 k=1,nt do 315 np1=2,ndo2,2 do 315 i=1,imm1 vto(i,1,k)=vto(i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) 315 continue do 316 k=1,nt do 316 np1=3,ndo1,2 do 316 i=1,imid wte(i,1,k)=wte(i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 316 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 330 mp1=2,mmax m = mp1-1 mb = m*(nlat-1)-(m*(m-1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 326 do 325 k=1,nt do 324 np1=mp1,ndo1,2 mn = mb+np1 do 323 i=1,imm1 vto(i,2*mp1-2,k) = vto(i,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(i,mn) vto(i,2*mp1-1,k) = vto(i,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(i,mn) wte(i,2*mp1-2,k) = wte(i,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(i,mn) wte(i,2*mp1-1,k) = wte(i,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(i,mn) 323 continue if(mlat .eq. 0) go to 324 wte(imid,2*mp1-2,k) = wte(imid,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(imid,mn) wte(imid,2*mp1-1,k) = wte(imid,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(imid,mn) 324 continue 325 continue 326 if(mp2 .gt. ndo2) go to 330 do 329 k=1,nt do 328 np1=mp2,ndo2,2 mn = mb+np1 do 327 i=1,imm1 vto(i,2*mp1-2,k) = vto(i,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(i,mn) vto(i,2*mp1-1,k) = vto(i,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(i,mn) wte(i,2*mp1-2,k) = wte(i,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(i,mn) wte(i,2*mp1-1,k) = wte(i,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(i,mn) 327 continue if(mlat .eq. 0) go to 328 wte(imid,2*mp1-2,k) = wte(imid,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(imid,mn) wte(imid,2*mp1-1,k) = wte(imid,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(imid,mn) 328 continue 329 continue 330 continue go to 950 c c case ityp=4 v odd, w even, and both cr and ci equal zero c c case m = 0 c 400 do 415 k=1,nt do 415 np1=2,ndo2,2 do 415 i=1,imm1 vto(i,1,k)=vto(i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) 415 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 430 mp1=2,mmax m = mp1-1 mb = m*(nlat-1)-(m*(m-1))/2 mp2 = mp1+1 if(mp2 .gt. ndo2) go to 430 do 429 k=1,nt do 428 np1=mp2,ndo2,2 mn = mb+np1 do 427 i=1,imm1 vto(i,2*mp1-2,k) = vto(i,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(i,mn) vto(i,2*mp1-1,k) = vto(i,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(i,mn) wte(i,2*mp1-2,k) = wte(i,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(i,mn) wte(i,2*mp1-1,k) = wte(i,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(i,mn) 427 continue if(mlat .eq. 0) go to 428 wte(imid,2*mp1-2,k) = wte(imid,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(imid,mn) wte(imid,2*mp1-1,k) = wte(imid,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(imid,mn) 428 continue 429 continue 430 continue go to 950 c c case ityp=5 v odd, w even, br and bi equal zero c c case m = 0 c 500 do 516 k=1,nt do 516 np1=3,ndo1,2 do 516 i=1,imid wte(i,1,k)=wte(i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 516 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 530 mp1=2,mmax m = mp1-1 mb = m*(nlat-1)-(m*(m-1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 530 do 525 k=1,nt do 524 np1=mp1,ndo1,2 mn = mb+np1 do 523 i=1,imm1 vto(i,2*mp1-2,k) = vto(i,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(i,mn) vto(i,2*mp1-1,k) = vto(i,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(i,mn) wte(i,2*mp1-2,k) = wte(i,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(i,mn) wte(i,2*mp1-1,k) = wte(i,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(i,mn) 523 continue if(mlat .eq. 0) go to 524 wte(imid,2*mp1-2,k) = wte(imid,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(imid,mn) wte(imid,2*mp1-1,k) = wte(imid,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(imid,mn) 524 continue 525 continue 530 continue go to 950 c c case ityp=6 v even , w odd c c case m = 0 c 600 do 615 k=1,nt do 615 np1=2,ndo2,2 do 615 i=1,imm1 wto(i,1,k)=wto(i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 615 continue do 616 k=1,nt do 616 np1=3,ndo1,2 do 616 i=1,imid vte(i,1,k)=vte(i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) 616 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 630 mp1=2,mmax m = mp1-1 mb = m*(nlat-1)-(m*(m-1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 626 do 625 k=1,nt do 624 np1=mp1,ndo1,2 mn = mb+np1 do 623 i=1,imm1 vte(i,2*mp1-2,k) = vte(i,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(i,mn) vte(i,2*mp1-1,k) = vte(i,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(i,mn) wto(i,2*mp1-2,k) = wto(i,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(i,mn) wto(i,2*mp1-1,k) = wto(i,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(i,mn) 623 continue if(mlat .eq. 0) go to 624 vte(imid,2*mp1-2,k) = vte(imid,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(imid,mn) vte(imid,2*mp1-1,k) = vte(imid,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(imid,mn) 624 continue 625 continue 626 if(mp2 .gt. ndo2) go to 630 do 629 k=1,nt do 628 np1=mp2,ndo2,2 mn = mb+np1 do 627 i=1,imm1 vte(i,2*mp1-2,k) = vte(i,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(i,mn) vte(i,2*mp1-1,k) = vte(i,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(i,mn) wto(i,2*mp1-2,k) = wto(i,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(i,mn) wto(i,2*mp1-1,k) = wto(i,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(i,mn) 627 continue if(mlat .eq. 0) go to 628 vte(imid,2*mp1-2,k) = vte(imid,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(imid,mn) vte(imid,2*mp1-1,k) = vte(imid,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(imid,mn) 628 continue 629 continue 630 continue go to 950 c c case ityp=7 v even, w odd cr and ci equal zero c c case m = 0 c 700 do 716 k=1,nt do 716 np1=3,ndo1,2 do 716 i=1,imid vte(i,1,k)=vte(i,1,k)+br(ncbc,1,np1,k)*vb(i,np1) 716 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 730 mp1=2,mmax m = mp1-1 mb = m*(nlat-1)-(m*(m-1))/2 mp2 = mp1+1 if(mp1 .gt. ndo1) go to 730 do 725 k=1,nt do 724 np1=mp1,ndo1,2 mn = mb+np1 do 723 i=1,imm1 vte(i,2*mp1-2,k) = vte(i,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(i,mn) vte(i,2*mp1-1,k) = vte(i,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(i,mn) wto(i,2*mp1-2,k) = wto(i,2*mp1-2,k) 1 -bi(ncbc,mp1,np1,k)*wb(i,mn) wto(i,2*mp1-1,k) = wto(i,2*mp1-1,k) 1 +br(ncbc,mp1,np1,k)*wb(i,mn) 723 continue if(mlat .eq. 0) go to 724 vte(imid,2*mp1-2,k) = vte(imid,2*mp1-2,k) 1 +br(ncbc,mp1,np1,k)*vb(imid,mn) vte(imid,2*mp1-1,k) = vte(imid,2*mp1-1,k) 1 +bi(ncbc,mp1,np1,k)*vb(imid,mn) 724 continue 725 continue 730 continue go to 950 c c case ityp=8 v even, w odd, br and bi equal zero c c case m = 0 c 800 do 815 k=1,nt do 815 np1=2,ndo2,2 do 815 i=1,imm1 wto(i,1,k)=wto(i,1,k)-cr(ncbc,1,np1,k)*vb(i,np1) 815 continue c c case m = 1 through nlat-1 c if(mmax .lt. 2) go to 950 do 830 mp1=2,mmax m = mp1-1 mb = m*(nlat-1)-(m*(m-1))/2 mp2 = mp1+1 if(mp2 .gt. ndo2) go to 830 do 829 k=1,nt do 828 np1=mp2,ndo2,2 mn = mb+np1 do 827 i=1,imm1 vte(i,2*mp1-2,k) = vte(i,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(i,mn) vte(i,2*mp1-1,k) = vte(i,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(i,mn) wto(i,2*mp1-2,k) = wto(i,2*mp1-2,k) 1 -cr(ncbc,mp1,np1,k)*vb(i,mn) wto(i,2*mp1-1,k) = wto(i,2*mp1-1,k) 1 -ci(ncbc,mp1,np1,k)*vb(i,mn) 827 continue if(mlat .eq. 0) go to 828 vte(imid,2*mp1-2,k) = vte(imid,2*mp1-2,k) 1 -ci(ncbc,mp1,np1,k)*wb(imid,mn) vte(imid,2*mp1-1,k) = vte(imid,2*mp1-1,k) 1 +cr(ncbc,mp1,np1,k)*wb(imid,mn) 828 continue 829 continue 830 continue 950 do 14 k=1,nt call hrfftb(idv,nlon,vte(1,1,k),idv,wrfft,work) call hrfftb(idv,nlon,wte(1,1,k),idv,wrfft,work) 14 continue if(ityp .gt. 2) go to 12 do 60 k=1,nt do 60 j=1,nlon do 60 i=1,imm1 vt(ncvw,i,j,k) = .5d0*(vte(i,j,k)+vto(i,j,k)) wt(ncvw,i,j,k) = .5d0*(wte(i,j,k)+wto(i,j,k)) vt(ncvw,nlp1-i,j,k) = .5d0*(vte(i,j,k)-vto(i,j,k)) wt(ncvw,nlp1-i,j,k) = .5d0*(wte(i,j,k)-wto(i,j,k)) 60 continue go to 13 12 do 11 k=1,nt do 11 j=1,nlon do 11 i=1,imm1 vt(ncvw,i,j,k) = .5d0*vte(i,j,k) wt(ncvw,i,j,k) = .5d0*wte(i,j,k) 11 continue 13 if(mlat .eq. 0) return do 65 k=1,nt do 65 j=1,nlon vt(ncvw,imid,j,k) = .5d0*vte(imid,j,k) wt(ncvw,imid,j,k) = .5d0*wte(imid,j,k) 65 continue return end subroutine vtsgsi(nlat,nlon,wvts,lwvts,work,lwork,dwork,ldwork, + ierror) implicit double precision (a-h,o-z) c c define imid = (nlat+1)/2 and mmax = min0(nlat,(nlon+1)/2) c the length of wvts is imid*mmax*(nlat+nlat-mmax+1)+nlon+15 c and the length of work is labc+5*nlat*imid+2*nlat where c labc = 3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 c dimension wvts(lwvts),work(lwork) double precision dwork(ldwork) ierror = 1 if(nlat .lt. 3) return ierror = 2 if(nlon .lt. 1) return ierror = 3 c Fixed SpherePack error: was [ mmax = min0(nlat,nlon/2+1) ] mmax = min0(nlat,(nlon+1)/2) c imid = (nlat+1)/2 lzimn = (imid*mmax*(nlat+nlat-mmax+1))/2 if(lwvts .lt. lzimn+lzimn+nlon+15) return ierror = 4 labc = 3*(max0(mmax-2,0)*(nlat+nlat-mmax-1))/2 lvin = 3*nlat*imid lwvbin = 2*nlat*imid+labc ltheta = nlat+nlat if(lwork .lt. lvin+lwvbin+ltheta) return ierror = 5 if (ldwork .lt. 3*nlat+2) return ierror = 0 iw1 = lvin+1 iw2 = iw1+lwvbin jw1 = nlat+1 jw2 = jw1+nlat CALL VETG1(NLAT,NLON,IMID,WVTS,WVTS(LZIMN+1),WORK,work(IW1), 1 DWORK,DWORK(JW1),DWORK(JW2),IERROR) if(ierror .ne. 0) return call hrffti(nlon,wvts(2*lzimn+1)) return end subroutine vetg1(nlat,nlon,imid,vb,wb,vin,wvbin, 1 theta,wts,dwork,ierror) implicit double precision (a-h,o-z) dimension vb(imid,*),wb(imid,*),vin(imid,nlat,3),wvbin(*) double precision dwork(*),theta(*),wts(*) c Fixed SpherePack error: was [ mmax = min0(nlat,nlon/2+1) ] mmax = min0(nlat,(nlon+1)/2) c ldwork = 1 call gaqd(nlat,theta,wts,dwork,ldwork,ierr) if(ierr .eq. 0) go to 10 ierror = 10+ierr return 10 call vtgint (nlat,nlon,theta,wvbin,dwork) i1=1 i2=2 do 33 mp1=1,mmax m = mp1-1 call vbin (0,nlat,nlon,m,vin,i3,wvbin,i1,i2) do 33 np1=mp1,nlat mn = m*(nlat-1)-(m*(m-1))/2+np1 do 33 i=1,imid vb(i,mn) = vin(i,np1,i3) 33 continue call wtgint (nlat,nlon,theta,wvbin,dwork) i1=1 i2=2 do 34 mp1=1,mmax m = mp1-1 call wbin (0,nlat,nlon,m,vin,i3,wvbin,i1,i2) do 34 np1=mp1,nlat mn = m*(nlat-1)-(m*(m-1))/2+np1 do 34 i=1,imid wb(i,mn) = vin(i,np1,i3) 34 continue return end ================================================ FILE: external/brigand/CMakeLists.txt ================================================ # Distributed under the MIT License. # See LICENSE.txt for details. set(BRIGAND_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/external/brigand/include) message(STATUS "Brigand include: ${BRIGAND_INCLUDE_DIR}") add_library(Brigand INTERFACE IMPORTED GLOBAL) target_include_directories(Brigand SYSTEM INTERFACE ${BRIGAND_INCLUDE_DIR}) add_interface_lib_headers( TARGET Brigand HEADERS brigand/brigand.hpp ) set_property( GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS Brigand ) ================================================ FILE: external/brigand/LICENSE ================================================ Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: external/brigand/README.md ================================================ Brigand Meta-programming library ================================ ![A brigand](https://raw.githubusercontent.com/wiki/edouarda/brigand/brigand_small.jpg) [![Build Status](https://travis-ci.org/edouarda/brigand.svg?branch=master)](https://travis-ci.org/edouarda/brigand) [![Build Status](https://ci.appveyor.com/api/projects/status/github/edouarda/brigand)](https://ci.appveyor.com/project/edouarda/brigand) # Introduction Brigand is a light-weight, fully functional, instant-compile time C++ 11 meta-programming library. Everything you were doing with Boost.MPL can be done with Brigand. And if that's not the case, open an issue! # Learning Should you wish to learn more, feel free to [watch our Meeting C++ 2015 lightning talk](https://www.youtube.com/watch?v=B8XSDhWx7hY)! Want more? Our [CppCon 2016 presentation](https://www.youtube.com/watch?v=ky0JdPh_LgE) explains in details the library concepts and goes through two concrete usages. If you are looking to learn the concepts of metaprogramming, [have a look at our free e-book](http://www.oreilly.com/programming/free/practical-c-plus-plus-metaprogramming.csp). # Tutorials * [Introduction](https://github.com/edouarda/brigand/wiki/Introduction) * [Algorithms](https://github.com/edouarda/brigand/wiki/Algorithms) * [Runtime](https://github.com/edouarda/brigand/wiki/Runtime) # Documentation The documentation is available [here](https://github.com/edouarda/brigand/wiki). # Contributors We'd like to thank the following contributors, in alphabetical order * Odin Holmes * Marek Kurdej * Jonathan Poelen # Note: The copy in this directory is based on upstream hash 9a86130c87479a38659edd7c0dda776a27f7077d. ================================================ FILE: external/brigand/include/brigand/brigand.hpp ================================================ /*! @file @copyright Edouard Alligand and Joel Falcou 2015-2017 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) Edits by SXS: - count_if, filter, and remove_if have an explicit empty base-case for nvcc support. */ #ifndef BRIGAND_HPP_INCLUDED #define BRIGAND_HPP_INCLUDED namespace brigand { template struct integral_constant { static const T value = Value; using value_type = T; using type = integral_constant; operator value_type() const { return (value); } value_type operator()() const { return (value); } }; template const T integral_constant::value; using true_type = ::brigand::integral_constant; using false_type = ::brigand::integral_constant; } namespace brigand { template struct list { }; template using integral_list = brigand::list...>; using empty_sequence = brigand::list<>; } namespace brigand { namespace detail { template struct dup_append_list; template