diff --git a/.gitignore b/.gitignore index 9f608ea048ac93738e263dd975216e5c9de79998..54b93cb4250605efc11db4977bec6aa791a6db8b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ ThirdParty # Sublime project files *.sublime-project *.sublime-workspace +# CLion build directories +cmake-build-* diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a821f4b9cff6f07ba95aa26c0617856264071f4..5096bef3149769f386eb30621ee1d7f8487eca06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,19 @@ v5.3.0 - Added float and restore avx512 back-end for SimdLib (!1387) - Fix namespace pollution which causes boost 1.74+ errors (!1389) - Fix missing copy assignment operator warnings in clang 13+ (!1391) +- Add an integral filter for the time-evolution of integrals on composites, + supports dimension equal to or one lower than the mesh dimension (!1323) +- Overload PhysEvaluate to give first derivatives using barycentric + interpolation (!1323) +- Non-conformal interface support (!1323) + +**FieldConvert** +- Added conditional to select the eNearestNeighbour method for 3D interpolation (!1335) +- Fixed the output field names of WSS module of FieldConvert +- Added float to scalar and avx2 back-end, disable avx512, sse2, sve (!1255) +- Change MPI initialisation to allow MPI_Init call outside Nektar++ (!1376) +- Added float and restore avx512 back-end for SimdLib (!1387) +- Fix namespace pollution which causes boost 1.74+ errors (!1389) **Python** - Add wrappers for Interpreter and Equation classes (!1329) @@ -16,12 +29,12 @@ v5.3.0 - Added Laplacian (NonSmooth) AV to the explicit Navier Stokes solver (!1372) - Added Physical AV to the implicit Navier Stokes solver (!1372) - Fixed Segmentation Fault when using C0 Smoother with Shock Capturing (!1394) - -**CompressibleFlowSolver** - The Incomplete IP method was made the default method for the IP method (!1377). +- Add additional parameters for the Isentropic Vortex equation system (!1323) - Improve performance of the perconditioner and diffusion operator (!1393) **NekMesh** +- Multi domain input/output for Nekpp and HDF5 file formats (!1323) - Replace VTK pointers with VTK smart-pointers to avoid memory leaking, when exporting in .vtu format (!1386) - Preserve CAD face labels and save in to session file as a "NAME=" tag on the composites (!1396) diff --git a/cmake/ThirdPartyHDF5.cmake b/cmake/ThirdPartyHDF5.cmake index c062dd833495fc843370aaccf348aa3a4a7b4d05..6d53afadbd9d244d09d69426fd569001cf7b2d01 100644 --- a/cmake/ThirdPartyHDF5.cmake +++ b/cmake/ThirdPartyHDF5.cmake @@ -69,6 +69,12 @@ IF (NEKTAR_USE_HDF5) MESSAGE(STATUS "Found HDF5: ${HDF5_LIBRARIES}") SET(HDF5_CONFIG_INCLUDE_DIR ${HDF5_INCLUDE_DIRS}) ADD_CUSTOM_TARGET(hdf5-1.8.16 ALL) + + # Newer HDF5 versions have changed the API + # We compile deprecated symbols using the old API if newer than 1.10.0 + IF(HDF5_VERSION VERSION_GREATER_EQUAL 1.10.0) + ADD_DEFINITIONS(-DH5_USE_110_API) + ENDIF() ENDIF() MARK_AS_ADVANCED(HDF5_LIBRARIES) diff --git a/docs/user-guide/xml/xml-filters.tex b/docs/user-guide/xml/xml-filters.tex index 4faa16c0cc86d6caf2e688c1133961907d51b213..c93c3845842db46f41df567fee9028c7f4b05228 100644 --- a/docs/user-guide/xml/xml-filters.tex +++ b/docs/user-guide/xml/xml-filters.tex @@ -353,6 +353,8 @@ The following parameters are supported: Prefix of the output filename to which the errors are written.\\ \inltt{OutputFrequency} & \xmark & 1 & Number of timesteps after which output is written.\\ + \inltt{ConsoleOutput} & \xmark & 0 & + Also output error in the console when writing to file.\\ \bottomrule \end{tabularx} \end{center} @@ -363,6 +365,49 @@ An example syntax is given below: ErrorFile 10 + 1 + +\end{lstlisting} + +\subsection{Integral}\label{filters:Integral} + +This filter produces a file containing the time-evolution of the integral of +the solver variables on user defined composites. By default this file is called +\inltt{session.int} where \inltt{session} is the session name. + +The following parameters are supported: + +\begin{center} + \begin{tabularx}{0.99\textwidth}{lllX} + \toprule + \textbf{Option name} & \textbf{Required} & \textbf{Default} & + \textbf{Description} \\ + \midrule + \inltt{OutputFile} & \xmark & \inltt{session} & + Prefix of the output filename to which the integrals are written.\\ + \inltt{OutputFrequency} & \xmark & 1 & + Number of timesteps after which output is written.\\ + \inltt{OutputPrecision} & \xmark & 7 & + Decimal precision with which the output is written.\\ + \inltt{Composites} & \cmark & - & + Composites on which to calculate the integral.\\ + \bottomrule + \end{tabularx} +\end{center} + +Multiple composites can be defined together by using ranges with each composite +grouping producing a summed output for each variable in the \inltt{OutputFile}. +For example \inltt{C[1,3,5-7]} would produce a single integral output for each +variable whilst \inltt{C[1-3], C[4]} would produce two. + +An example syntax is given below: + +\begin{lstlisting}[style=XMLStyle,gobble=2] + + IntegralFile + 10 + 12 + C[1], C[2-4,6] \end{lstlisting} diff --git a/docs/user-guide/xml/xml-movement.tex b/docs/user-guide/xml/xml-movement.tex new file mode 100644 index 0000000000000000000000000000000000000000..6b11bb33fa28b3577ef76d460816395c41dd763e --- /dev/null +++ b/docs/user-guide/xml/xml-movement.tex @@ -0,0 +1,64 @@ +\section{Movement} +This section defines the movement of the mesh. Currently only static +non-conformal interfaces are supported. + +\subsection{Non-conformal meshes}\label{subsec:non-conformal-meshes} +Non-conformal meshes are defined using \inltt{ZONES} and \inltt{INTERFACES}. +Each zone is a domain as defined in the \inltt{GEOMETRY} section. For a mesh to +be non-conformal it must consist of at least two zones with different domain +tags. These two zones can then be split by an interface where every interface is +defined by two composite entities, we use \inltt{LEFT} and \inltt{RIGHT} +notation to distinguish between these. Each zone must contain either the left or +the right interface edge. Zones can contain multiple edges across different +interfaces but must not contain both edges for the same interface. These left +and right interface edges have to be geometrically identical but topologically +disconnected i.e.\ occupy the same space physically but consist of independent +geometry objects. + +Non-conformal interfaces are defined enclosed in the \inltt{NEKTAR} tag. An +example showing two non-conformal interfaces on a single mesh is below: + +\begin{lstlisting}[style=XMLStyle] + + + + + + + + + + + + + + + + + +\end{lstlisting} + +Zones must have a type specified, at the moment only `FIXED' interfaces are +supported however in the future there are plans to implement rotating, sliding, +and prescribed motion using the ALE method. It is important for the zone IDs to +correspond with the relevant interface IDs present on the zone, that is if there +is an interface with ID 0 there must also be a zone with ID 0 too. Zone IDs must +be unique but interfaces can have the same ID, e.g. in the example above zone ID +1 has two interfaces attached to it. The inclusion of an +\inltt{"INTERFACE NAME="..."} allows for specifying a name, which is used for +the debug output when the verbose flag `-v' is specified. This is for user +reference to ensure the non-conformal interfaces are set up correctly, and shows +zone/interface IDs, number of elements in each zone and interface, and +connections between each zone/interface. An example debug output for the above +XML is shown below: + +\begin{lstlisting} +Movement Info: + Num zones: 3 + - 0 Fixed: 8 Quadrilaterals + - 1 Fixed: 24 Quadrilaterals + - 2 Fixed: 4 Quadrilaterals + Num interfaces: 2 + - "First": 0 (4 Segments) <-> 1 (6 Segments) + - "Second": 1 (6 Segments) <-> 2 (2 Segments) +\end{lstlisting} \ No newline at end of file diff --git a/docs/user-guide/xml/xml.tex b/docs/user-guide/xml/xml.tex index 3f913bed3c89d7315aea521827ab62be2230839f..471fa45f4adb2fdc537a1cfb5b4fb2973ecb0458 100644 --- a/docs/user-guide/xml/xml.tex +++ b/docs/user-guide/xml/xml.tex @@ -77,3 +77,5 @@ files as illustrated below: \input{xml/xml-coupling.tex} \input{xml/xml-expressions.tex} + +\input{xml/xml-movement.tex} diff --git a/library/Demos/StdRegions/CMakeLists.txt b/library/Demos/StdRegions/CMakeLists.txt index 895c4a0400a5583f06ca4276ac9f8ecd00cec312..1c431ffbdd789918a0a749930fe65a033891322a 100644 --- a/library/Demos/StdRegions/CMakeLists.txt +++ b/library/Demos/StdRegions/CMakeLists.txt @@ -2,6 +2,8 @@ ADD_NEKTAR_EXECUTABLE(StdProject COMPONENT demos DEPENDS StdRegions SOURCES StdProject.cpp) ADD_NEKTAR_EXECUTABLE(StdInterp COMPONENT demos DEPENDS StdRegions SOURCES StdInterp.cpp) +ADD_NEKTAR_EXECUTABLE(StdInterpDeriv + COMPONENT demos DEPENDS StdRegions SOURCES StdInterpDeriv.cpp) ADD_NEKTAR_EXECUTABLE(StdInterpBasis COMPONENT demos DEPENDS StdRegions SOURCES StdInterpBasis.cpp) ADD_NEKTAR_EXECUTABLE(StdEquiToCoeff2D @@ -25,6 +27,26 @@ ADD_NEKTAR_TEST(StdInterpBasis_Tet_Mod_P4_Q5) ADD_NEKTAR_TEST(StdInterpBasis_Tri_Mod_P7_Q8) ADD_NEKTAR_TEST(StdInterpBasis_Hex_Mod_P7_Q8) ADD_NEKTAR_TEST(StdInterpBasis_Pyr_Mod_P7_Q8) +ADD_NEKTAR_TEST(StdInterpBasis_Tri_Orth_P7_Q8) + +# interpolation tests for derivatives. +ADD_NEKTAR_TEST(StdInterpDeriv_Seg_Lagrange_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Seg_Mod_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Seg_Orth_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Quad_Mod_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Quad_Orth_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Quad_Lagrange_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Tri_Mod_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Tri_Orth_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Pyr_Mod_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Pyr_Orth_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Prism_Mod_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Prism_Orth_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Hex_Mod_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Hex_Orth_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Hex_Lagrange_P7_Q8) +ADD_NEKTAR_TEST(StdInterpDeriv_Tet_Mod_P8_Q9) +ADD_NEKTAR_TEST(StdInterpDeriv_Tet_Orth_P8_Q9) # Projection tests. diff --git a/library/Demos/StdRegions/StdDemoSupport.hpp b/library/Demos/StdRegions/StdDemoSupport.hpp index 4f6aad7cacb885b684a8818af605fa59cd548b2a..882184d05a91b4ff979459525c06ec0a6c1474a4 100644 --- a/library/Demos/StdRegions/StdDemoSupport.hpp +++ b/library/Demos/StdRegions/StdDemoSupport.hpp @@ -435,6 +435,16 @@ public: return m_pointstype; } + std::vector &GetBasisType() + { + return m_basis; + } + + std::string &GetShape() + { + return m_shape; + } + Array> GetCoords(StdExpansion *E) { int dimension = E->GetShapeDimension(); diff --git a/library/Demos/StdRegions/StdInterpDeriv.cpp b/library/Demos/StdRegions/StdInterpDeriv.cpp new file mode 100644 index 0000000000000000000000000000000000000000..96da6440442465666dd64e94a29177d4ba76ebdd --- /dev/null +++ b/library/Demos/StdRegions/StdInterpDeriv.cpp @@ -0,0 +1,180 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// File: StdInterpDeriv.cpp +// +// For more information, please see: http://www.nektar.info +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// 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. +// +// Description: Demo for testing functionality of PhysEvaluateDeriv +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include "StdDemoSupport.hpp" + +// polynomial = 4x^4 + 3y^3 + 2z^2 + 1 +Array EvalPoly( + const Array> &pts) +{ + Array ret(pts[0].size()); + unsigned dim = pts.size(); + for (int i = 0; i < pts[0].size(); i++) + { + ret[i] = (4 * pts[0][i] * pts[0][i] * pts[0][i] * pts[0][i]) + + (dim >= 2 ? (3 * pts[1][i] * pts[1][i] * pts[1][i]) : 0.0) + + (dim >= 3 ? (2 * pts[2][i] * pts[2][i]) : 0.0) + 1; + } + + return ret; +} + +// derivative in x = 16x^3 +Array EvalPolyDerivx( + const Array> &pts) +{ + Array ret(pts[0].size()); + for (int i = 0; i < pts[0].size(); i++) + { + ret[i] = 16 * pts[0][i] * pts[0][i] * pts[0][i]; + } + + return ret; +} + +// derivative in y = 9y^2 +Array EvalPolyDerivy( + const Array> &pts) +{ + Array ret(pts[0].size()); + for (int i = 0; i < pts[0].size(); i++) + { + ret[i] = 9 * pts[1][i] * pts[1][i]; + } + + return ret; +} + +// derivative in z = 4z +Array EvalPolyDerivz( + const Array> &pts) +{ + Array ret(pts[0].size()); + for (int i = 0; i < pts[0].size(); i++) + { + ret[i] = 4 * pts[2][i]; + } + + return ret; +} + +int main(int argc, char *argv[]) +{ + DemoSupport demo; + demo.ParseArguments(argc, argv); + StdExpansion *E = demo.CreateStdExpansion(); + + const auto dimension = (unsigned)E->GetShapeDimension(); + + const auto totPoints = (unsigned)E->GetTotPoints(); + Array physIn(totPoints, 0.0), physOut(totPoints, 0.0), + sol(totPoints, 0.0), sol0(totPoints, 0.0), sol1(totPoints, 0.0), + sol2(totPoints, 0.0); + + Array> physOutDeriv(totPoints); + + Array> coordsE = demo.GetCoords(E); + physIn = EvalPoly(coordsE); + + // Create a new element but with GaussGaussChebyshev points so that we + // perform a PhysEvaluateDeriv at a different set of nodal points + // (i.e. non-collocated interpolation), all tests use default types + // initially + vector &ptypes = demo.GetPointsType(); + for (int i = 0; i < dimension; ++i) + { + ptypes[i] = "PolyEvenlySpaced"; + } + + StdExpansion *F = demo.CreateStdExpansion(); + const Array> coordsF = demo.GetCoords(F); + + for (int i = 0; i < totPoints; ++i) + { + // Fill coords array + Array coordIn(dimension, 0.0); + for (int j = 0; j < dimension; ++j) + { + coordIn[j] = coordsF[j][i]; + } + + // Operating on expansion E so using physIn from E, and coordIn from F + physOut[i] = E->PhysEvaluate(coordIn, physIn, physOutDeriv[i]); + } + + // Extract derivatives in to array for error calculation + Array physOut0(totPoints, 0.0), physOut1(totPoints, 0.0), + physOut2(totPoints, 0.0); + switch (dimension) + { + case 3: + for (int j = 0; j < totPoints; ++j) + { + physOut2[j] = physOutDeriv[j][2]; + } + sol2 = EvalPolyDerivz(coordsF); + /* fall through */ + case 2: + for (int j = 0; j < totPoints; ++j) + { + physOut1[j] = physOutDeriv[j][1]; + } + sol1 = EvalPolyDerivy(coordsF); + /* fall through */ + case 1: + for (int j = 0; j < totPoints; ++j) + { + physOut0[j] = physOutDeriv[j][0]; + } + sol0 = EvalPolyDerivx(coordsF); + /* fall through */ + default: + sol = EvalPoly(coordsF); + break; + } + + cout << "\nL infinity error: " << scientific + << E->Linf(physOut, sol) + E->Linf(physOut0, sol0) + + E->Linf(physOut1, sol1) + E->Linf(physOut2, sol2) + << endl; + cout << "L 2 error : " << scientific + << E->L2(physOut, sol) + E->L2(physOut0, sol0) + + E->L2(physOut1, sol1) + E->L2(physOut2, sol2) + << endl; + + return 0; +} diff --git a/library/Demos/StdRegions/Tests/StdInterpBasis_Pyr_Mod_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpBasis_Pyr_Mod_P7_Q8.tst index a7a9775bd491b98ccee1aee526a79c015e9b0d35..65450b5158d325a2ee0ca19a067f6d73ae5108a1 100644 --- a/library/Demos/StdRegions/Tests/StdInterpBasis_Pyr_Mod_P7_Q8.tst +++ b/library/Demos/StdRegions/Tests/StdInterpBasis_Pyr_Mod_P7_Q8.tst @@ -1,6 +1,6 @@ - StdInterpBasis Triangle Modified basis P=7 Q=8 + StdInterpBasis Pyramid Modified basis P=7 Q=8 StdInterpBasis -s pyramid -b Modified_A Modified_A ModifiedPyr_C -o 7 7 7 -p 8 8 8 diff --git a/library/Demos/StdRegions/Tests/StdInterpBasis_Tri_Orth_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpBasis_Tri_Orth_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..768c389df41c319e0d15b0bfe8ec7aeac7b2c048 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpBasis_Tri_Orth_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpBasis Triangle Ortho basis P=7 Q=8 + StdInterpBasis + -s triangle -b Ortho_A Ortho_B -o 7 7 -p 8 8 + + + 0 + + + 0 + + + diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Hex_Lagrange_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Hex_Lagrange_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..424c123d9d47bde4c4e5438fd23a3a0e65a12a22 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Hex_Lagrange_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Hex Lagrange basis P=7 Q=8 + StdInterpDeriv + -s hexahedron -b GLL_Lagrange GLL_Lagrange GLL_Lagrange -o 7 7 7 -p 8 8 8 -P GaussLobattoLegendre GaussLobattoLegendre GaussLobattoLegendre + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Hex_Mod_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Hex_Mod_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..c7818794ed4856128df3219fbb5fc973ccb441bf --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Hex_Mod_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Hex Mod basis P=7 Q=8 + StdInterpDeriv + -s hexahedron -b Modified_A Modified_A Modified_A -o 7 7 7 -p 8 8 8 -P GaussLobattoLegendre GaussLobattoLegendre GaussLobattoLegendre + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Hex_Orth_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Hex_Orth_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..2e48201a0115ff44e7ef7720c86ad7cc9cc7fb21 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Hex_Orth_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Hex Ortho basis P=7 Q=8 + StdInterpDeriv + -s hexahedron -b Ortho_A Ortho_A Ortho_A -o 7 7 7 -p 8 8 8 -P GaussLobattoLegendre GaussLobattoLegendre GaussLobattoLegendre + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Prism_Mod_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Prism_Mod_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..e9359ba26b2508b71bd8267dfcdefae4b3460c69 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Prism_Mod_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Prism Mod basis P=7 Q=8 + StdInterpDeriv + -s prism -b Modified_A Modified_A Modified_B -o 7 7 7 -p 8 8 8 -P GaussLobattoLegendre GaussLobattoLegendre GaussRadauMAlpha1Beta0 + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Prism_Orth_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Prism_Orth_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..af1142f10d52ab0067dfb92612d233c5becf73d8 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Prism_Orth_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Prism Ortho basis P=7 Q=8 + StdInterpDeriv + -s prism -b Ortho_A Ortho_A Ortho_B -o 7 7 7 -p 8 8 8 -P GaussLobattoLegendre GaussLobattoLegendre GaussRadauMAlpha1Beta0 + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Pyr_Mod_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Pyr_Mod_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..1fd9820aad10e282b65d6d5235729daed576ef70 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Pyr_Mod_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Pyr Mod basis P=7 Q=8 + StdInterpDeriv + -s pyramid -b Modified_A Modified_A ModifiedPyr_C -o 7 7 7 -p 8 8 8 -P GaussLobattoLegendre GaussLobattoLegendre GaussRadauMAlpha2Beta0 + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Pyr_Orth_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Pyr_Orth_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..1d2fad7f2bb82f7585300fac0792cc0bedec99b1 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Pyr_Orth_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Pyramid Ortho basis P=7 Q=8 + StdInterpDeriv + -s pyramid -b Ortho_A Ortho_A OrthoPyr_C -o 7 7 7 -p 8 8 8 -P GaussLobattoLegendre GaussLobattoLegendre GaussRadauMAlpha2Beta0 + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Quad_Lagrange_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Quad_Lagrange_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..b84886cba12e80ebe854c971b9736944fd9a0cb1 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Quad_Lagrange_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Quadrilateral Lagrange basis P=7 Q=8 + StdInterpDeriv + -s quadrilateral -b GLL_Lagrange GLL_Lagrange -o 7 7 -p 8 8 -P GaussLobattoLegendre GaussLobattoLegendre + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Quad_Mod_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Quad_Mod_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..f65efc0a9d584de9b369c9d1d72d38b6b06a3eb7 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Quad_Mod_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Quadrilateral Modified basis P=7 Q=8 + StdInterpDeriv + -s quadrilateral -b Modified_A Modified_A -o 7 7 -p 8 8 -P GaussLobattoLegendre GaussLobattoLegendre + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Quad_Orth_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Quad_Orth_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..bb6c7c165d49ddb093e76f64c6a7636d08a0f706 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Quad_Orth_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Quadrilateral Orth basis P=7 Q=8 + StdInterpDeriv + -s quadrilateral -b Ortho_A Ortho_A -o 7 7 -p 8 8 -P GaussLobattoLegendre GaussLobattoLegendre + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Seg_Lagrange_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Seg_Lagrange_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..4845a2c94da78c8b47389b38279bd2e411d8da43 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Seg_Lagrange_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Seg Lagrange basis P=7 Q=8 + StdInterpDeriv + -s segment -b GLL_Lagrange -o 7 -p 8 -P GaussLobattoLegendre + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Seg_Mod_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Seg_Mod_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..a30b5982b7ce0bdcf9a412db0a9d5c968f2716b6 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Seg_Mod_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Seg Mod basis P=7 Q=8 + StdInterpDeriv + -s segment -b Modified_A -o 7 -p 8 -P GaussLobattoLegendre + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Seg_Orth_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Seg_Orth_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..90e2aed0634cd4788c8093ecd4ca7ed3b2023d52 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Seg_Orth_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Seg Orth basis P=7 Q=8 + StdInterpDeriv + -s segment -b Ortho_A -o 7 -p 8 -P GaussLobattoLegendre + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Tet_Mod_P8_Q9.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Tet_Mod_P8_Q9.tst new file mode 100644 index 0000000000000000000000000000000000000000..7fe69f0ea1b832c165ee0573029b21ea8a4c6c6f --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Tet_Mod_P8_Q9.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Tet Mod basis P=8 Q=9 + StdInterpDeriv + -s tetrahedron -b Modified_A Modified_B Modified_C -o 8 8 8 -p 9 9 9 -P GaussLobattoLegendre GaussRadauMAlpha1Beta0 GaussRadauMAlpha2Beta0 + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Tet_Orth_P8_Q9.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Tet_Orth_P8_Q9.tst new file mode 100644 index 0000000000000000000000000000000000000000..43227919b8114bc81813597e01f4afa15cf1ec59 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Tet_Orth_P8_Q9.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Tet Orth basis P=8 Q=9 + StdInterpDeriv + -s tetrahedron -b Ortho_A Ortho_B Ortho_C -o 8 8 8 -p 9 9 9 -P GaussLobattoLegendre GaussRadauMAlpha1Beta0 GaussRadauMAlpha2Beta0 + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Tri_Mod_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Tri_Mod_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..bd187def1a1c6a644732c7ecadc00b41a65ab3c9 --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Tri_Mod_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Tri Modified basis P=7 Q=8 + StdInterpDeriv + -s triangle -b Modified_A Modified_B -o 7 7 -p 8 8 -P GaussLobattoLegendre GaussRadauMAlpha1Beta0 + + + 0 + + + 0 + + + diff --git a/library/Demos/StdRegions/Tests/StdInterpDeriv_Tri_Orth_P7_Q8.tst b/library/Demos/StdRegions/Tests/StdInterpDeriv_Tri_Orth_P7_Q8.tst new file mode 100644 index 0000000000000000000000000000000000000000..8701632b79276250a797738991b28bc7711c9c3d --- /dev/null +++ b/library/Demos/StdRegions/Tests/StdInterpDeriv_Tri_Orth_P7_Q8.tst @@ -0,0 +1,14 @@ + + + StdInterpDeriv Tri Ortho basis P=7 Q=8 + StdInterpDeriv + -s triangle -b Ortho_A Ortho_B -o 7 7 -p 8 8 -P GaussLobattoLegendre GaussRadauMAlpha1Beta0 + + + 0 + + + 0 + + + \ No newline at end of file diff --git a/library/FieldUtils/OutputModules/OutputVtk.cpp b/library/FieldUtils/OutputModules/OutputVtk.cpp index 57215bc6e02e863ed6af0ebde0757160bac46d6c..8e53c34614e0e11f2a7b9f8f3daa521e12df8f99 100644 --- a/library/FieldUtils/OutputModules/OutputVtk.cpp +++ b/library/FieldUtils/OutputModules/OutputVtk.cpp @@ -1605,6 +1605,22 @@ void OutputVtk::OutputFromPts(po::variables_map &vm) void OutputVtk::OutputFromExp(po::variables_map &vm) { + // Move geometry based on zones data in .xml and time in .fld metadatamap + // Perform movement of zones based on time in field files metadata map + if (m_f->m_graph->GetMovement()->GetMoveFlag()) + { + if (!m_f->m_fieldMetaDataMap["Time"].empty()) + { + m_f->m_graph->GetMovement()->PerformMovement( + boost::lexical_cast( + m_f->m_fieldMetaDataMap["Time"])); + for (auto &i : m_f->m_exp) + { + i->Reset(); + } + } + } + if (m_config["legacy"].m_beenSet) { ASSERTL0(!m_config["multiblock"].m_beenSet, @@ -1623,8 +1639,11 @@ void OutputVtk::OutputFromExp(po::variables_map &vm) // Save mesh state (if using filter this allows us to only ProcessEquispaced // if needed) - m_cachedMesh = m_vtkMesh; - + if (!m_f->m_graph->GetMovement()->GetMoveFlag()) + { + m_cachedMesh = m_vtkMesh; + } + if (m_config["highorder"].m_beenSet) { ASSERTL0(!m_config["multiblock"].m_beenSet, diff --git a/library/FieldUtils/OutputModules/OutputVtk.h b/library/FieldUtils/OutputModules/OutputVtk.h index b75c7c7706ac64ee33e1bfe7b422f265387b55ae..dc0a5577117fe17b7e7aa5055a8d360dae55e784 100644 --- a/library/FieldUtils/OutputModules/OutputVtk.h +++ b/library/FieldUtils/OutputModules/OutputVtk.h @@ -90,6 +90,8 @@ protected: /// Flag if mesh has been cached bool m_cachedMesh = false; + std::string PrepareOutput(po::variables_map &vm); + private: /// Prepare high order Lagrange VTK output vtkSmartPointer OutputFromExpHighOrder( diff --git a/library/LibUtilities/BasicConst/NektarUnivConsts.hpp b/library/LibUtilities/BasicConst/NektarUnivConsts.hpp index e606427cd9c2a73a14533cb80730d9e57943d1bb..23485a0784205219373f2cc78a82594028fdb030 100644 --- a/library/LibUtilities/BasicConst/NektarUnivConsts.hpp +++ b/library/LibUtilities/BasicConst/NektarUnivConsts.hpp @@ -62,6 +62,10 @@ static const NekDouble CoinTol = 1E-6; // Factor for tolerance for floating point comparison static const unsigned int kNekFloatCompFact = 4; + +// Constants for minimisation functions +static const NekDouble kFindDistanceMin = 5e-05; +static const unsigned int kNewtonIterations = 51; } // namespace NekConstants } // namespace Nektar diff --git a/library/LibUtilities/BasicUtils/FieldIO.h b/library/LibUtilities/BasicUtils/FieldIO.h index 43b7a86452aa52c015a0a263b48a25e09f37a6ec..b0aec9a601af9f5b8cc406c658dc10aa7ff92484 100644 --- a/library/LibUtilities/BasicUtils/FieldIO.h +++ b/library/LibUtilities/BasicUtils/FieldIO.h @@ -256,6 +256,10 @@ public: LIB_UTILITIES_EXPORT static void AddInfoTag( TagWriterSharedPtr root, const FieldMetaDataMap &fieldmetadatamap); + LIB_UTILITIES_EXPORT std::string SetUpOutput(const std::string outname, + bool perRank, + bool backup = false); + protected: /// Communicator to use when writing parallel format LibUtilities::CommSharedPtr m_comm; @@ -273,10 +277,6 @@ protected: return "fld"; } - LIB_UTILITIES_EXPORT std::string SetUpOutput(const std::string outname, - bool perRank, - bool backup = false); - /// @copydoc FieldIO::Write LIB_UTILITIES_EXPORT virtual void v_Write( const std::string &outFile, diff --git a/library/LibUtilities/BasicUtils/VmathArray.hpp b/library/LibUtilities/BasicUtils/VmathArray.hpp index d2d332a1b0efe2a7a81223d5d30bce671f47576d..ab55408255ab1753a423644ba8c025e4926ae3df 100644 --- a/library/LibUtilities/BasicUtils/VmathArray.hpp +++ b/library/LibUtilities/BasicUtils/VmathArray.hpp @@ -358,7 +358,7 @@ void Vvtvm(int n, const Array &w, const int incw, #endif } -/// \brief vvtvvtp (vector times vector plus vector times vector): z = v*w + y*z +/// \brief vvtvvtp (vector times vector plus vector times vector): z = v*w + x*y template void Vvtvvtp(int n, const Array &v, int incv, const Array &w, int incw, @@ -384,6 +384,24 @@ void Vvtvvtp(int n, const Array &v, int incv, #endif } +/// \brief vvtvvtm (vector times vector minus vector times vector): z = v*w - +/// x*y +template +void Vvtvvtm(int n, const Array &v, int incv, + const Array &w, int incw, + const Array &x, int incx, + const Array &y, int incy, Array &z, + int incz) +{ + ASSERTL1(n * incv <= v.size() + v.GetOffset(), "Array out of bounds"); + ASSERTL1(n * incw <= w.size() + w.GetOffset(), "Array out of bounds"); + ASSERTL1(n * incx <= x.size() + x.GetOffset(), "Array out of bounds"); + ASSERTL1(n * incy <= y.size() + y.GetOffset(), "Array out of bounds"); + ASSERTL1(n * incz <= z.size() + z.GetOffset(), "Array out of bounds"); + + Vvtvvtm(n, &v[0], incv, &w[0], incw, &x[0], incx, &y[0], incy, &z[0], incz); +} + /// \brief svtsvtp (scalar times vector plus scalar times vector): z = alpha*x + /// beta*y template diff --git a/library/LibUtilities/Communication/Comm.h b/library/LibUtilities/Communication/Comm.h index 7ec0b32911ba6787315a5a190e229835b0a7d303..86c64d5571dd058fedae3baeab5928b92ff2da52 100644 --- a/library/LibUtilities/Communication/Comm.h +++ b/library/LibUtilities/Communication/Comm.h @@ -145,6 +145,9 @@ public: void Irsend(int pProc, T &pData, int count, const CommRequestSharedPtr &request, int loc); template + void Isend(int pProc, T &pData, int count, + const CommRequestSharedPtr &request, int loc); + template void SendInit(int pProc, T &pData, int count, const CommRequestSharedPtr &request, int loc); template @@ -235,6 +238,8 @@ protected: virtual void v_Irsend(void *buf, int count, CommDataType dt, int dest, CommRequestSharedPtr request, int loc) = 0; + virtual void v_Isend(void *buf, int count, CommDataType dt, int dest, + CommRequestSharedPtr request, int loc) = 0; virtual void v_SendInit(void *buf, int count, CommDataType dt, int dest, CommRequestSharedPtr request, int loc) = 0; virtual void v_Irecv(void *buf, int count, CommDataType dt, int source, @@ -600,6 +605,23 @@ void Comm::Irsend(int pProc, T &pData, int count, CommDataTypeTraits::GetDataType(), pProc, request, loc); } +/** + * Starts a nonblocking send + * + * @param pProc Rank of destination + * @param pData Array/vector to send + * @param count Number of elements to send in pData + * @param request Communication request object + * @param loc Location in request to use + */ +template +void Comm::Isend(int pProc, T &pData, int count, + const CommRequestSharedPtr &request, int loc) +{ + v_Isend(CommDataTypeTraits::GetPointer(pData), count, + CommDataTypeTraits::GetDataType(), pProc, request, loc); +} + /** * Creates a persistent request for a send * diff --git a/library/LibUtilities/Communication/CommMpi.cpp b/library/LibUtilities/Communication/CommMpi.cpp index bc93c2bf2b9b93acc1ddc7f7a378d653147a0b27..8080e6dc8f5bdf449357483725fa82643b1c6123 100644 --- a/library/LibUtilities/Communication/CommMpi.cpp +++ b/library/LibUtilities/Communication/CommMpi.cpp @@ -416,6 +416,14 @@ void CommMpi::v_Irsend(void *buf, int count, CommDataType dt, int dest, MPI_Irsend(buf, count, dt, dest, 0, m_comm, req->GetRequest(loc)); } +void CommMpi::v_Isend(void *buf, int count, CommDataType dt, int dest, + CommRequestSharedPtr request, int loc) +{ + CommRequestMpiSharedPtr req = + std::static_pointer_cast(request); + MPI_Isend(buf, count, dt, dest, 0, m_comm, req->GetRequest(loc)); +} + void CommMpi::v_SendInit(void *buf, int count, CommDataType dt, int dest, CommRequestSharedPtr request, int loc) { @@ -444,14 +452,21 @@ void CommMpi::v_StartAll(CommRequestSharedPtr request) { CommRequestMpiSharedPtr req = std::static_pointer_cast(request); - MPI_Startall(req->GetNumRequest(), req->GetRequest(0)); + if (req->GetNumRequest() != 0) + { + MPI_Startall(req->GetNumRequest(), req->GetRequest(0)); + } } void CommMpi::v_WaitAll(CommRequestSharedPtr request) { CommRequestMpiSharedPtr req = std::static_pointer_cast(request); - MPI_Waitall(req->GetNumRequest(), req->GetRequest(0), MPI_STATUSES_IGNORE); + if (req->GetNumRequest() != 0) + { + MPI_Waitall(req->GetNumRequest(), req->GetRequest(0), + MPI_STATUSES_IGNORE); + } } CommRequestSharedPtr CommMpi::v_CreateRequest(int num) diff --git a/library/LibUtilities/Communication/CommMpi.h b/library/LibUtilities/Communication/CommMpi.h index 111da7a91fb133ad78d6973a0e28d44df1132540..f86e62241961d566f04d5fb4a14c938b4224b8bf 100644 --- a/library/LibUtilities/Communication/CommMpi.h +++ b/library/LibUtilities/Communication/CommMpi.h @@ -168,6 +168,8 @@ protected: CommDataType recvtype) final; virtual void v_Irsend(void *buf, int count, CommDataType dt, int dest, CommRequestSharedPtr request, int loc) final; + virtual void v_Isend(void *buf, int count, CommDataType dt, int dest, + CommRequestSharedPtr request, int loc) final; virtual void v_SendInit(void *buf, int count, CommDataType dt, int dest, CommRequestSharedPtr request, int loc) final; virtual void v_Irecv(void *buf, int count, CommDataType dt, int source, diff --git a/library/LibUtilities/Communication/CommSerial.cpp b/library/LibUtilities/Communication/CommSerial.cpp index e4e3f8a8e6a8754eca1b5a6b573acdb26deda4ed..550ec304a5f209c02ddad74aadd35f1b4e024274 100644 --- a/library/LibUtilities/Communication/CommSerial.cpp +++ b/library/LibUtilities/Communication/CommSerial.cpp @@ -255,6 +255,12 @@ void CommSerial::v_Irsend(void *buf, int count, CommDataType dt, int dest, boost::ignore_unused(buf, count, dt, dest, request, loc); } +void CommSerial::v_Isend(void *buf, int count, CommDataType dt, int dest, + CommRequestSharedPtr request, int loc) +{ + boost::ignore_unused(buf, count, dt, dest, request, loc); +} + void CommSerial::v_SendInit(void *buf, int count, CommDataType dt, int dest, CommRequestSharedPtr request, int loc) { diff --git a/library/LibUtilities/Communication/CommSerial.h b/library/LibUtilities/Communication/CommSerial.h index 6adec3774146ac832986100c5cf3d945766dee45..9823319cc7c03d224f16a6bd455ec378801ad14b 100644 --- a/library/LibUtilities/Communication/CommSerial.h +++ b/library/LibUtilities/Communication/CommSerial.h @@ -137,6 +137,11 @@ protected: CommRequestSharedPtr request, int loc) final; + LIB_UTILITIES_EXPORT virtual void v_Isend(void *buf, int count, + CommDataType dt, int dest, + CommRequestSharedPtr request, + int loc) final; + LIB_UTILITIES_EXPORT virtual void v_SendInit(void *buf, int count, CommDataType dt, int dest, CommRequestSharedPtr request, diff --git a/library/LocalRegions/HexExp.cpp b/library/LocalRegions/HexExp.cpp index de07729da56983cce29ec5ac7b0c75b8b95b71a1..f72bd3251a5f2f298fc67da6ec80a23ae56d2269 100644 --- a/library/LocalRegions/HexExp.cpp +++ b/library/LocalRegions/HexExp.cpp @@ -86,13 +86,6 @@ HexExp::HexExp(const HexExp &T) { } -/** - * \brief Destructor - */ -HexExp::~HexExp() -{ -} - //----------------------------- // Integration Methods //----------------------------- @@ -410,7 +403,7 @@ void HexExp::v_IProductWRTDerivBase(const int dir, const Array &inarray, Array &outarray) { - HexExp::IProductWRTDerivBase_SumFac(dir, inarray, outarray); + HexExp::v_IProductWRTDerivBase_SumFac(dir, inarray, outarray); } /** @@ -433,7 +426,7 @@ void HexExp::v_IProductWRTDerivBase(const int dir, * @param inarray The function \f$ u \f$. * @param outarray Value of the inner product. */ -void HexExp::IProductWRTDerivBase_SumFac( +void HexExp::v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, Array &outarray) { @@ -559,7 +552,7 @@ void HexExp::IProductWRTDerivBase_MatOp( * @param inarray The function \f$ u \f$. * @param outarray Value of the inner product. */ -void HexExp::IProductWRTDirectionalDerivBase_SumFac( +void HexExp::v_IProductWRTDirectionalDerivBase_SumFac( const Array &direction, const Array &inarray, Array &outarray) @@ -623,7 +616,7 @@ NekDouble HexExp::v_StdPhysEvaluate( const Array &physvals) { // Evaluate point in local coordinates. - return StdHexExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion3D::v_PhysEvaluate(Lcoord, physvals); } NekDouble HexExp::v_PhysEvaluate(const Array &coord, @@ -633,7 +626,17 @@ NekDouble HexExp::v_PhysEvaluate(const Array &coord, ASSERTL0(m_geom, "m_geom not defined"); m_geom->GetLocCoords(coord, Lcoord); - return StdHexExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion3D::v_PhysEvaluate(Lcoord, physvals); +} + +NekDouble HexExp::v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + Array Lcoord(3); + ASSERTL0(m_geom, "m_geom not defined"); + m_geom->GetLocCoords(coord, Lcoord); + return StdHexExp::v_PhysEvaluate(Lcoord, inarray, firstOrderDerivs); } StdRegions::StdExpansionSharedPtr HexExp::v_GetStdExp(void) const diff --git a/library/LocalRegions/HexExp.h b/library/LocalRegions/HexExp.h index e6265174ecbd99e69cda679fee384e2b4664ea31..320665ad61eaa7ea80d534ab8156fa8be2586b02 100644 --- a/library/LocalRegions/HexExp.h +++ b/library/LocalRegions/HexExp.h @@ -45,20 +45,10 @@ namespace Nektar { -namespace SpatialDomains -{ -class HexGeom; -typedef std::shared_ptr HexGeomSharedPtr; -} // namespace SpatialDomains - namespace LocalRegions { -class HexExp; - -typedef std::shared_ptr HexExpSharedPtr; -typedef std::vector HexExpVector; - -class HexExp : virtual public StdRegions::StdHexExp, virtual public Expansion3D +class HexExp final : virtual public StdRegions::StdHexExp, + virtual public Expansion3D { public: LOCAL_REGIONS_EXPORT HexExp(const LibUtilities::BasisKey &Ba, @@ -68,61 +58,61 @@ public: LOCAL_REGIONS_EXPORT HexExp(const HexExp &T); - LOCAL_REGIONS_EXPORT ~HexExp(); + LOCAL_REGIONS_EXPORT ~HexExp() final = default; protected: //------------------------------ // Integration Method //------------------------------ - LOCAL_REGIONS_EXPORT virtual NekDouble v_Integral( - const Array &inarray); + LOCAL_REGIONS_EXPORT NekDouble + v_Integral(const Array &inarray) final; //----------------------------- // Differentiation Methods //----------------------------- - LOCAL_REGIONS_EXPORT virtual void v_PhysDeriv( + LOCAL_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2); + Array &out_d2) final; - LOCAL_REGIONS_EXPORT virtual void v_PhysDeriv( - const int dir, const Array &inarray, - Array &outarray); + LOCAL_REGIONS_EXPORT void v_PhysDeriv( + int dir, const Array &inarray, + Array &outarray) final; LOCAL_REGIONS_EXPORT void v_PhysDirectionalDeriv( const Array &inarray, const Array &direction, - Array &out); + Array &out) final; //--------------------------------------- // Transforms //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual void v_FwdTrans( + LOCAL_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) final; //--------------------------------------- // Inner product functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase( + LOCAL_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); + Array &outarray) final; - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + LOCAL_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multiplybyweights = true); + Array &outarray, bool multiplybyweights = true) final; - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) final; - LOCAL_REGIONS_EXPORT void IProductWRTDerivBase_SumFac( + LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) final; - LOCAL_REGIONS_EXPORT virtual void v_AlignVectorToCollapsedDir( + LOCAL_REGIONS_EXPORT void v_AlignVectorToCollapsedDir( const int dir, const Array &inarray, - Array> &outarray); + Array> &outarray) final; LOCAL_REGIONS_EXPORT void IProductWRTDerivBase_MatOp( const int dir, const Array &inarray, @@ -136,113 +126,130 @@ protected: IProductWRTDirectionalDerivBase_SumFac(direction, inarray, outarray); } - LOCAL_REGIONS_EXPORT void IProductWRTDirectionalDerivBase_SumFac( + LOCAL_REGIONS_EXPORT void v_IProductWRTDirectionalDerivBase_SumFac( const Array &direction, const Array &inarray, - Array &outarray); + Array &outarray) final; //--------------------------------------- // Evaluation functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual NekDouble v_StdPhysEvaluate( - const Array &Lcoord, - const Array &physvals); + LOCAL_REGIONS_EXPORT NekDouble + v_StdPhysEvaluate(const Array &Lcoord, + const Array &physvals) final; + + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coords, + const Array &physvals) final; - LOCAL_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( - const Array &coords, - const Array &physvals); + STD_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) final; - LOCAL_REGIONS_EXPORT virtual void v_GetCoord( + LOCAL_REGIONS_EXPORT void v_GetCoord( const Array &Lcoords, - Array &coords); + Array &coords) final; - LOCAL_REGIONS_EXPORT virtual void v_GetCoords( + LOCAL_REGIONS_EXPORT void v_GetCoords( Array &coords_1, Array &coords_2, - Array &coords_3); + Array &coords_3) final; //--------------------------------------- // Helper functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual LibUtilities::ShapeType v_DetShapeType() const; + LOCAL_REGIONS_EXPORT + LibUtilities::ShapeType v_DetShapeType() const final; - LOCAL_REGIONS_EXPORT virtual StdRegions::StdExpansionSharedPtr v_GetStdExp( - void) const; + LOCAL_REGIONS_EXPORT + StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const final; - LOCAL_REGIONS_EXPORT virtual StdRegions::StdExpansionSharedPtr v_GetLinStdExp( - void) const; + LOCAL_REGIONS_EXPORT + StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const final; - LOCAL_REGIONS_EXPORT virtual void v_ExtractDataToCoeffs( + LOCAL_REGIONS_EXPORT void v_ExtractDataToCoeffs( const NekDouble *data, const std::vector &nummodes, const int mode_offset, NekDouble *coeffs, - std::vector &fromType); + std::vector &fromType) final; - LOCAL_REGIONS_EXPORT virtual bool v_GetFaceDGForwards(const int i) const; + LOCAL_REGIONS_EXPORT bool v_GetFaceDGForwards(const int i) const; - LOCAL_REGIONS_EXPORT virtual void v_GetTracePhysMap( - const int face, Array &outarray); + LOCAL_REGIONS_EXPORT void v_GetTracePhysMap( + const int face, Array &outarray) final; - LOCAL_REGIONS_EXPORT void v_ComputeTraceNormal(const int face); + LOCAL_REGIONS_EXPORT void v_ComputeTraceNormal(const int face) final; //--------------------------------------- // Operator creation functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual void v_MassMatrixOp( + LOCAL_REGIONS_EXPORT void v_MassMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + LOCAL_REGIONS_EXPORT void v_LaplacianMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + LOCAL_REGIONS_EXPORT void v_LaplacianMatrixOp( const int k1, const int k2, const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual void v_WeakDerivMatrixOp( + LOCAL_REGIONS_EXPORT void v_WeakDerivMatrixOp( const int i, const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual void v_WeakDirectionalDerivMatrixOp( + LOCAL_REGIONS_EXPORT void v_WeakDirectionalDerivMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual void v_MassLevelCurvatureMatrixOp( + LOCAL_REGIONS_EXPORT void v_MassLevelCurvatureMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp( + LOCAL_REGIONS_EXPORT void v_HelmholtzMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; LOCAL_REGIONS_EXPORT void v_GeneralMatrixOp_MatOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual void v_ReduceOrderCoeffs( + LOCAL_REGIONS_EXPORT void v_ReduceOrderCoeffs( int numMin, const Array &inarray, - Array &outarray); + Array &outarray) final; - LOCAL_REGIONS_EXPORT virtual void v_SVVLaplacianFilter( - Array &array, const StdRegions::StdMatrixKey &mkey); + LOCAL_REGIONS_EXPORT void v_SVVLaplacianFilter( + Array &array, + const StdRegions::StdMatrixKey &mkey) final; //--------------------------------------- // Matrix creation functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdRegions::StdMatrixKey &mkey); + LOCAL_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdRegions::StdMatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdRegions::StdMatrixKey &mkey); + LOCAL_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual DNekScalMatSharedPtr v_GetLocMatrix( - const MatrixKey &mkey); + LOCAL_REGIONS_EXPORT DNekScalMatSharedPtr + v_GetLocMatrix(const MatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix( - const MatrixKey &mkey); + LOCAL_REGIONS_EXPORT + DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix( + const MatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT void v_DropLocStaticCondMatrix(const MatrixKey &mkey); + LOCAL_REGIONS_EXPORT void v_DropLocStaticCondMatrix( + const MatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual void v_ComputeLaplacianMetric(); + LOCAL_REGIONS_EXPORT void v_ComputeLaplacianMetric() final; private: LibUtilities::NekManager @@ -250,18 +257,18 @@ private: LibUtilities::NekManager m_staticCondMatrixManager; - HexExp(); - - virtual void v_LaplacianMatrixOp_MatFree_Kernel( + void v_LaplacianMatrixOp_MatFree_Kernel( const Array &inarray, - Array &outarray, Array &wsp); + Array &outarray, Array &wsp) final; - virtual void v_NormalTraceDerivFactors( + void v_NormalTraceDerivFactors( Array> &factors, Array> &d0factors, - Array> &d1factors); + Array> &d1factors) final; }; +typedef std::shared_ptr HexExpSharedPtr; +typedef std::vector HexExpVector; } // namespace LocalRegions } // namespace Nektar diff --git a/library/LocalRegions/NodalTetExp.h b/library/LocalRegions/NodalTetExp.h index d31c044a36ddef5097ab3c9a03f0f822ad6df7bd..4bfecbac719b4f3c9ec1e00d69bdd523b4a4e540 100644 --- a/library/LocalRegions/NodalTetExp.h +++ b/library/LocalRegions/NodalTetExp.h @@ -44,7 +44,7 @@ namespace Nektar namespace LocalRegions { -class NodalTetExp : public TetExp +class NodalTetExp final : virtual public TetExp { // public: // NodalTetExp(const StdRegions::Basis &Ba, const StdRegions::Basis @@ -68,7 +68,7 @@ class NodalTetExp : public TetExp LOCAL_REGIONS_EXPORT NodalTetExp(const NodalTetExp &T); /// Destructor - LOCAL_REGIONS_EXPORT ~NodalTetExp(); + LOCAL_REGIONS_EXPORT ~NodalTetExp() final = default; protected: private: diff --git a/library/LocalRegions/NodalTriExp.cpp b/library/LocalRegions/NodalTriExp.cpp index 048d833dd5d448d4a9d208e691d714d46e566296..6020e1959dbf4588ad1769cbd5d529b46cde1bbf 100644 --- a/library/LocalRegions/NodalTriExp.cpp +++ b/library/LocalRegions/NodalTriExp.cpp @@ -62,16 +62,14 @@ NodalTriExp::NodalTriExp(const LibUtilities::BasisKey &Ba, } NodalTriExp::NodalTriExp(const NodalTriExp &T) - : StdExpansion(T), StdExpansion2D(T), StdRegions::StdNodalTriExp(T), + : StdExpansion(T), + StdExpansion2D(T), StdRegions::StdTriExp(T), StdRegions::StdNodalTriExp( + T), Expansion(T), Expansion2D(T), m_matrixManager(T.m_matrixManager), m_staticCondMatrixManager(T.m_staticCondMatrixManager) { } -NodalTriExp::~NodalTriExp() -{ -} - //---------------------------- // Integration Methods //---------------------------- @@ -459,7 +457,18 @@ NekDouble NodalTriExp::PhysEvaluate( ASSERTL0(m_geom, "m_geom not defined"); m_geom->GetLocCoords(coord, Lcoord); - return StdNodalTriExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion2D::v_PhysEvaluate(Lcoord, physvals); +} + +NekDouble NodalTriExp::v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + Array Lcoord(2); + ASSERTL0(m_geom, "m_geom not defined"); + m_geom->GetLocCoords(coord, Lcoord); + return StdExpansion2D::v_PhysEvaluate(Lcoord, inarray, firstOrderDerivs); } StdRegions::StdExpansionSharedPtr NodalTriExp::v_GetStdExp(void) const diff --git a/library/LocalRegions/NodalTriExp.h b/library/LocalRegions/NodalTriExp.h index ba76368ab5e2c9ffc6aa945a3edc3453a9ad0bd1..1b54489b8b7f8f3dd2c97a695917dcbd55519da0 100644 --- a/library/LocalRegions/NodalTriExp.h +++ b/library/LocalRegions/NodalTriExp.h @@ -49,8 +49,8 @@ namespace Nektar namespace LocalRegions { -class NodalTriExp : virtual public StdRegions::StdNodalTriExp, - virtual public Expansion2D +class NodalTriExp final : virtual public StdRegions::StdNodalTriExp, + virtual public Expansion2D { public: /** \brief Constructor using BasisKey class for quadrature @@ -64,7 +64,7 @@ public: LOCAL_REGIONS_EXPORT NodalTriExp(const NodalTriExp &T); /// Destructor - LOCAL_REGIONS_EXPORT ~NodalTriExp(); + LOCAL_REGIONS_EXPORT ~NodalTriExp() final = default; LOCAL_REGIONS_EXPORT void GetCoords( Array &coords_1, Array &coords_2, @@ -127,6 +127,11 @@ public: StdExpansion::MassMatrixOp_MatFree(inarray, outarray, mkey); } + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) final; + void LaplacianMatrixOp(const Array &inarray, Array &outarray, const StdRegions::StdMatrixKey &mkey) @@ -180,11 +185,11 @@ protected: Array &outarray, const StdRegions::StdMatrixKey &mkey); - virtual StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const; + StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const final; - virtual StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const; + StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const final; - virtual DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey); + DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey) final; private: LibUtilities::NekManager @@ -202,16 +207,16 @@ private: return StdNodalTriExp::GenNBasisTransMatrix(); } - virtual void v_GetCoords( + void v_GetCoords( Array &coords_0, Array &coords_1 = NullNekDouble1DArray, - Array &coords_2 = NullNekDouble1DArray) + Array &coords_2 = NullNekDouble1DArray) final { GetCoords(coords_0, coords_1, coords_2); } - virtual void v_GetCoord(const Array &lcoord, - Array &coord) + void v_GetCoord(const Array &lcoord, + Array &coord) final { GetCoord(lcoord, coord); } @@ -224,45 +229,44 @@ private: /** \brief Virtual call to integrate the physical point list \a inarray over region (see SegExp::Integral) */ - virtual NekDouble v_Integral(const Array &inarray) + NekDouble v_Integral(const Array &inarray) final { return Integral(inarray); } /** \brief Virtual call to TriExp::IProduct_WRT_B */ - virtual void v_IProductWRTBase(const Array &inarray, - Array &outarray) + void v_IProductWRTBase(const Array &inarray, + Array &outarray) final { IProductWRTBase(inarray, outarray); } - virtual void v_IProductWRTDerivBase( - const int dir, const Array &inarray, - Array &outarray) + void v_IProductWRTDerivBase(const int dir, + const Array &inarray, + Array &outarray) final { IProductWRTDerivBase(dir, inarray, outarray); } - virtual void v_StdPhysDeriv( + void v_StdPhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2 = NullNekDouble1DArray) + Array &out_d2 = NullNekDouble1DArray) final { StdTriExp::v_PhysDeriv(inarray, out_d0, out_d1, out_d2); } - virtual void v_PhysDeriv( + void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2 = NullNekDouble1DArray) + Array &out_d2 = NullNekDouble1DArray) final { boost::ignore_unused(out_d2); PhysDeriv(inarray, out_d0, out_d1); } - virtual void v_PhysDeriv(const int dir, - const Array &inarray, - Array &outarray) + void v_PhysDeriv(const int dir, const Array &inarray, + Array &outarray) final { Array tmp; switch (dir) @@ -286,28 +290,27 @@ private: } /// Virtual call to SegExp::FwdTrans - virtual void v_FwdTrans(const Array &inarray, - Array &outarray) + void v_FwdTrans(const Array &inarray, + Array &outarray) final { FwdTrans(inarray, outarray); } /// Virtual call to TriExp::Evaluate - virtual NekDouble v_PhysEvaluate( - const Array &coord, - const Array &physvals) + NekDouble v_PhysEvaluate(const Array &coord, + const Array &physvals) final { return PhysEvaluate(coord, physvals); } - virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdRegions::StdMatrixKey &mkey) + DNekMatSharedPtr v_CreateStdMatrix( + const StdRegions::StdMatrixKey &mkey) final { return CreateStdMatrix(mkey); } - virtual DNekScalMatSharedPtr v_GetLocMatrix(const MatrixKey &mkey) + DNekScalMatSharedPtr v_GetLocMatrix(const MatrixKey &mkey) final { return m_matrixManager[mkey]; } @@ -321,73 +324,75 @@ private: // m_matrixManager[mkey]; // } - virtual DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix( - const MatrixKey &mkey) + DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix( + const MatrixKey &mkey) final { return m_staticCondMatrixManager[mkey]; } - virtual void v_BwdTrans_SumFac(const Array &inarray, - Array &outarray) + void v_BwdTrans_SumFac(const Array &inarray, + Array &outarray) final { StdNodalTriExp::v_BwdTrans_SumFac(inarray, outarray); } - virtual void v_IProductWRTBase_SumFac( - const Array &inarray, - Array &outarray, bool multiplybyweights = true) + void v_IProductWRTBase_SumFac(const Array &inarray, + Array &outarray, + bool multiplybyweights = true) final { boost::ignore_unused(multiplybyweights); IProductWRTBase_SumFac(inarray, outarray); } - virtual void v_IProductWRTDerivBase_SumFac( + void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray) + Array &outarray) final { IProductWRTDerivBase_SumFac(dir, inarray, outarray); } - virtual void v_AlignVectorToCollapsedDir( + void v_AlignVectorToCollapsedDir( const int dir, const Array &inarray, - Array> &outarray); + Array> &outarray) final; - virtual void v_MassMatrixOp(const Array &inarray, - Array &outarray, - const StdRegions::StdMatrixKey &mkey) + void v_MassMatrixOp(const Array &inarray, + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final { MassMatrixOp(inarray, outarray, mkey); } - virtual void v_LaplacianMatrixOp( - const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey) + void v_LaplacianMatrixOp(const Array &inarray, + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final { LaplacianMatrixOp(inarray, outarray, mkey); } - virtual void v_LaplacianMatrixOp( - const int k1, const int k2, const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey) + void v_LaplacianMatrixOp(const int k1, const int k2, + const Array &inarray, + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final { LaplacianMatrixOp(k1, k2, inarray, outarray, mkey); } - virtual void v_WeakDerivMatrixOp( - const int i, const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey) + void v_WeakDerivMatrixOp(const int i, + const Array &inarray, + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final { WeakDerivMatrixOp(i, inarray, outarray, mkey); } - virtual void v_HelmholtzMatrixOp( - const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey) + void v_HelmholtzMatrixOp(const Array &inarray, + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final { HelmholtzMatrixOp(inarray, outarray, mkey); } - void v_ComputeTraceNormal(const int edge); + void v_ComputeTraceNormal(const int edge) final; }; typedef std::shared_ptr NodalTriExpSharedPtr; diff --git a/library/LocalRegions/PointExp.cpp b/library/LocalRegions/PointExp.cpp index a42168f29cb4b71b71ebe51b3cf7e124caed78f6..f2986dbc7558a68699d126053dbe591ff535bef0 100644 --- a/library/LocalRegions/PointExp.cpp +++ b/library/LocalRegions/PointExp.cpp @@ -46,10 +46,6 @@ PointExp::PointExp(const SpatialDomains::PointGeomSharedPtr &geom) m_ncoeffs = 1; } -PointExp::~PointExp(void) -{ -} - void PointExp::v_GetCoords(Array &coords_0, Array &coords_1, Array &coords_2) diff --git a/library/LocalRegions/PointExp.h b/library/LocalRegions/PointExp.h index 2139ea6b56108f1697712d0d766d08e8d049af91..6375f67e334fca2ee965a582fe813491bad3ef23 100644 --- a/library/LocalRegions/PointExp.h +++ b/library/LocalRegions/PointExp.h @@ -44,13 +44,14 @@ namespace Nektar { namespace LocalRegions { -class PointExp : virtual public StdRegions::StdPointExp, - virtual public Expansion0D +class PointExp final : virtual public StdRegions::StdPointExp, + virtual public Expansion0D { public: LOCAL_REGIONS_EXPORT PointExp( const SpatialDomains::PointGeomSharedPtr &m_geom); - LOCAL_REGIONS_EXPORT ~PointExp(void); + + LOCAL_REGIONS_EXPORT ~PointExp() final = default; inline const Array &GetCoeffs(void) const { @@ -123,19 +124,18 @@ protected: //!< same as the coefficient but is defined for consistency (It //!< is also used in Robin boundary conditions) - virtual void v_GetCoords(Array &coords_0, - Array &coords_1, - Array &coords_2); + void v_GetCoords(Array &coords_0, + Array &coords_1, + Array &coords_2) final; - virtual void v_NormVectorIProductWRTBase( - const Array &Fx, - Array &outarray); + void v_NormVectorIProductWRTBase(const Array &Fx, + Array &outarray) final; }; typedef std::shared_ptr PointExpSharedPtr; typedef std::vector PointExpVector; -const static Array NullPointExpSharedPtrArray; +const static Array NullPointExpSharedPtrArray{}; } // namespace LocalRegions } // namespace Nektar diff --git a/library/LocalRegions/PrismExp.cpp b/library/LocalRegions/PrismExp.cpp index db94737d4a575795944cc8a41d2566de10ae09a5..c51fdbe214e19c40f1f66d68d0ae1f8194fd4d3f 100644 --- a/library/LocalRegions/PrismExp.cpp +++ b/library/LocalRegions/PrismExp.cpp @@ -73,10 +73,6 @@ PrismExp::PrismExp(const PrismExp &T) { } -PrismExp::~PrismExp() -{ -} - //------------------------------- // Integration Methods //------------------------------- @@ -521,7 +517,7 @@ NekDouble PrismExp::v_StdPhysEvaluate( const Array &physvals) { // Evaluate point in local (eta) coordinates. - return StdPrismExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion3D::v_PhysEvaluate(Lcoord, physvals); } NekDouble PrismExp::v_PhysEvaluate(const Array &coord, @@ -533,7 +529,17 @@ NekDouble PrismExp::v_PhysEvaluate(const Array &coord, m_geom->GetLocCoords(coord, Lcoord); - return StdPrismExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion3D::v_PhysEvaluate(Lcoord, physvals); +} + +NekDouble PrismExp::v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + Array Lcoord(3); + ASSERTL0(m_geom, "m_geom not defined"); + m_geom->GetLocCoords(coord, Lcoord); + return StdPrismExp::v_PhysEvaluate(Lcoord, inarray, firstOrderDerivs); } //--------------------------------------- diff --git a/library/LocalRegions/PrismExp.h b/library/LocalRegions/PrismExp.h index fd9571dcb403b3ab96f8e99035c4053602e8f7a8..e27947b2c291e7109060ed2c3cb2ae99ff47805e 100644 --- a/library/LocalRegions/PrismExp.h +++ b/library/LocalRegions/PrismExp.h @@ -46,8 +46,8 @@ namespace Nektar { namespace LocalRegions { -class PrismExp : virtual public StdRegions::StdPrismExp, - virtual public Expansion3D +class PrismExp final : virtual public StdRegions::StdPrismExp, + virtual public Expansion3D { public: /// \brief Constructor using BasisKey class for quadrature @@ -59,132 +59,142 @@ public: LOCAL_REGIONS_EXPORT PrismExp(const PrismExp &T); - LOCAL_REGIONS_EXPORT ~PrismExp(); + LOCAL_REGIONS_EXPORT ~PrismExp() final = default; protected: //------------------------------- // Integration Methods //------------------------------- - LOCAL_REGIONS_EXPORT virtual NekDouble v_Integral( - const Array &inarray); + LOCAL_REGIONS_EXPORT NekDouble + v_Integral(const Array &inarray) final; //---------------------------- // Differentiation Methods //---------------------------- - LOCAL_REGIONS_EXPORT virtual void v_PhysDeriv( + LOCAL_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2); + Array &out_d2) final; //--------------------------------------- // Transforms //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual void v_FwdTrans( + LOCAL_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) final; //--------------------------------------- // Inner product functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase( + LOCAL_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + Array &outarray) final; + LOCAL_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multiplybyweights = true); + Array &outarray, bool multiplybyweights = true) final; LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) final; LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_AlignVectorToCollapsedDir( + Array &outarray) final; + LOCAL_REGIONS_EXPORT void v_AlignVectorToCollapsedDir( const int dir, const Array &inarray, - Array> &outarray); + Array> &outarray) final; //--------------------------------------- // Evaluation functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual void v_GetCoord( + LOCAL_REGIONS_EXPORT void v_GetCoord( const Array &Lcoords, - Array &coords); + Array &coords) final; - LOCAL_REGIONS_EXPORT virtual void v_GetCoords( + LOCAL_REGIONS_EXPORT void v_GetCoords( Array &coords_1, Array &coords_2, - Array &coords_3); + Array &coords_3) final; - LOCAL_REGIONS_EXPORT virtual NekDouble v_StdPhysEvaluate( - const Array &Lcoord, - const Array &physvals); + LOCAL_REGIONS_EXPORT NekDouble + v_StdPhysEvaluate(const Array &Lcoord, + const Array &physvals) final; - LOCAL_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( - const Array &coord, - const Array &physvals); + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &physvals) final; + + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) final; //--------------------------------------- // Helper functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual StdRegions::StdExpansionSharedPtr v_GetStdExp( - void) const; + LOCAL_REGIONS_EXPORT + StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const final; - LOCAL_REGIONS_EXPORT virtual StdRegions::StdExpansionSharedPtr v_GetLinStdExp( - void) const; + LOCAL_REGIONS_EXPORT + StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const final; - LOCAL_REGIONS_EXPORT virtual int v_GetCoordim(); - LOCAL_REGIONS_EXPORT virtual void v_ExtractDataToCoeffs( + LOCAL_REGIONS_EXPORT int v_GetCoordim() final; + LOCAL_REGIONS_EXPORT void v_ExtractDataToCoeffs( const NekDouble *data, const std::vector &nummodes, const int mode_offset, NekDouble *coeffs, - std::vector &fromType); + std::vector &fromType) final; - LOCAL_REGIONS_EXPORT virtual void v_GetTracePhysMap( - const int face, Array &outarray); + LOCAL_REGIONS_EXPORT void v_GetTracePhysMap( + const int face, Array &outarray) final; - LOCAL_REGIONS_EXPORT void v_ComputeTraceNormal(const int face); + LOCAL_REGIONS_EXPORT void v_ComputeTraceNormal(const int face) final; //--------------------------------------- // Operator creation functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual void v_MassMatrixOp( + LOCAL_REGIONS_EXPORT void v_MassMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT void v_LaplacianMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT void v_LaplacianMatrixOp( const int k1, const int k2, const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp( + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT void v_HelmholtzMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_GeneralMatrixOp_MatOp( + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT void v_GeneralMatrixOp_MatOp( const Array &inarray, Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_SVVLaplacianFilter( - Array &array, const StdRegions::StdMatrixKey &mkey); + LOCAL_REGIONS_EXPORT void v_SVVLaplacianFilter( + Array &array, + const StdRegions::StdMatrixKey &mkey) final; //--------------------------------------- // Matrix creation functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual DNekScalMatSharedPtr v_GetLocMatrix( - const MatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix( - const MatrixKey &mkey); + LOCAL_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdRegions::StdMatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT DNekScalMatSharedPtr + v_GetLocMatrix(const MatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT DNekScalBlkMatSharedPtr + v_GetLocStaticCondMatrix(const MatrixKey &mkey) final; LOCAL_REGIONS_EXPORT void v_DropLocStaticCondMatrix(const MatrixKey &mkey); LOCAL_REGIONS_EXPORT - virtual void v_GetSimplexEquiSpacedConnectivity(Array &conn, - bool standard = true); + void v_GetSimplexEquiSpacedConnectivity(Array &conn, + bool standard = true) final; LOCAL_REGIONS_EXPORT - virtual void v_NormalTraceDerivFactors( + void v_NormalTraceDerivFactors( Array> &d0factors, Array> &d1factors, - Array> &d2factors); + Array> &d2factors) final; private: LibUtilities::NekManager @@ -192,9 +202,9 @@ private: LibUtilities::NekManager m_staticCondMatrixManager; - virtual void v_LaplacianMatrixOp_MatFree_Kernel( + void v_LaplacianMatrixOp_MatFree_Kernel( const Array &inarray, - Array &outarray, Array &wsp); + Array &outarray, Array &wsp) final; }; typedef std::shared_ptr PrismExpSharedPtr; diff --git a/library/LocalRegions/PyrExp.cpp b/library/LocalRegions/PyrExp.cpp index ed723887898b397fc8e707e99920887ec7a48572..8abdfb7f097874efe8b32ff7f7d701ad466e086c 100644 --- a/library/LocalRegions/PyrExp.cpp +++ b/library/LocalRegions/PyrExp.cpp @@ -69,10 +69,6 @@ PyrExp::PyrExp(const PyrExp &T) { } -PyrExp::~PyrExp() -{ -} - //---------------------------- // Integration Methods //---------------------------- @@ -604,7 +600,7 @@ NekDouble PyrExp::v_StdPhysEvaluate( const Array &physvals) { // Evaluate point in local coordinates. - return StdPyrExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion3D::v_PhysEvaluate(Lcoord, physvals); } NekDouble PyrExp::v_PhysEvaluate(const Array &coord, @@ -617,7 +613,17 @@ NekDouble PyrExp::v_PhysEvaluate(const Array &coord, // TODO: check GetLocCoords() m_geom->GetLocCoords(coord, Lcoord); - return StdPyrExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion3D::v_PhysEvaluate(Lcoord, physvals); +} + +NekDouble PyrExp::v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + Array Lcoord(3); + ASSERTL0(m_geom, "m_geom not defined"); + m_geom->GetLocCoords(coord, Lcoord); + return StdPyrExp::v_PhysEvaluate(Lcoord, inarray, firstOrderDerivs); } //--------------------------------------- diff --git a/library/LocalRegions/PyrExp.h b/library/LocalRegions/PyrExp.h index 4130484f5febbf21f90ad7fc1b5f5f4201370bc8..5f8cc0af40deb07db1ef79bd92fc873f3ce2842a 100644 --- a/library/LocalRegions/PyrExp.h +++ b/library/LocalRegions/PyrExp.h @@ -47,7 +47,8 @@ namespace Nektar namespace LocalRegions { -class PyrExp : virtual public StdRegions::StdPyrExp, virtual public Expansion3D +class PyrExp final : virtual public StdRegions::StdPyrExp, + virtual public Expansion3D { public: /** \brief Constructor using BasisKey class for quadrature points and order @@ -59,110 +60,117 @@ public: LOCAL_REGIONS_EXPORT PyrExp(const PyrExp &T); - LOCAL_REGIONS_EXPORT ~PyrExp(); + LOCAL_REGIONS_EXPORT ~PyrExp() final = default; protected: //------------------------------- // Integration Methods //------------------------------- - LOCAL_REGIONS_EXPORT virtual NekDouble v_Integral( - const Array &inarray); + LOCAL_REGIONS_EXPORT NekDouble + v_Integral(const Array &inarray) final; //---------------------------- // Differentiation Methods //---------------------------- - LOCAL_REGIONS_EXPORT virtual void v_PhysDeriv( + LOCAL_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2); + Array &out_d2) final; //--------------------------------------- // Transforms //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual void v_FwdTrans( + LOCAL_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) final; //--------------------------------------- // Inner product functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase( + LOCAL_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + Array &outarray) final; + LOCAL_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multiplybyweights = true); + Array &outarray, bool multiplybyweights = true) final; LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) final; LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) final; - LOCAL_REGIONS_EXPORT virtual void v_AlignVectorToCollapsedDir( + LOCAL_REGIONS_EXPORT void v_AlignVectorToCollapsedDir( const int dir, const Array &inarray, - Array> &outarray); + Array> &outarray) final; //--------------------------------------- // Evaluation functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual StdRegions::StdExpansionSharedPtr v_GetStdExp( - void) const; + LOCAL_REGIONS_EXPORT + StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const final; - LOCAL_REGIONS_EXPORT virtual StdRegions::StdExpansionSharedPtr v_GetLinStdExp( - void) const; + LOCAL_REGIONS_EXPORT + StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const final; - LOCAL_REGIONS_EXPORT virtual void v_GetCoord( + LOCAL_REGIONS_EXPORT void v_GetCoord( const Array &Lcoords, - Array &coords); + Array &coords) final; - LOCAL_REGIONS_EXPORT virtual void v_GetCoords( + LOCAL_REGIONS_EXPORT void v_GetCoords( Array &coords_1, Array &coords_2, - Array &coords_3); + Array &coords_3) final; - LOCAL_REGIONS_EXPORT virtual void v_ExtractDataToCoeffs( + LOCAL_REGIONS_EXPORT void v_ExtractDataToCoeffs( const NekDouble *data, const std::vector &nummodes, const int mode_offset, NekDouble *coeffs, - std::vector &fromType); + std::vector &fromType) final; LOCAL_REGIONS_EXPORT NekDouble v_StdPhysEvaluate(const Array &Lcoord, const Array &physvals); - LOCAL_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( - const Array &coord, - const Array &physvals); + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &physvals) final; + + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) final; //--------------------------------------- // Helper functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual int v_GetCoordim(); + LOCAL_REGIONS_EXPORT int v_GetCoordim() final; - LOCAL_REGIONS_EXPORT virtual void v_GetTracePhysMap( - const int face, Array &outarray); + LOCAL_REGIONS_EXPORT void v_GetTracePhysMap( + const int face, Array &outarray) final; - LOCAL_REGIONS_EXPORT void v_ComputeTraceNormal(const int face); + LOCAL_REGIONS_EXPORT void v_ComputeTraceNormal(const int face) final; - LOCAL_REGIONS_EXPORT virtual void v_SVVLaplacianFilter( - Array &array, const StdRegions::StdMatrixKey &mkey); + LOCAL_REGIONS_EXPORT void v_SVVLaplacianFilter( + Array &array, + const StdRegions::StdMatrixKey &mkey) final; //--------------------------------------- // Matrix creation functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual DNekScalMatSharedPtr v_GetLocMatrix( - const MatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix( - const MatrixKey &mkey); - LOCAL_REGIONS_EXPORT void v_DropLocStaticCondMatrix(const MatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_ComputeLaplacianMetric(); - LOCAL_REGIONS_EXPORT virtual void v_NormalTraceDerivFactors( + LOCAL_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdRegions::StdMatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT DNekScalMatSharedPtr + v_GetLocMatrix(const MatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT DNekScalBlkMatSharedPtr + v_GetLocStaticCondMatrix(const MatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT void v_DropLocStaticCondMatrix( + const MatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT void v_ComputeLaplacianMetric() final; + LOCAL_REGIONS_EXPORT void v_NormalTraceDerivFactors( Array> &d0factors, Array> &d1factors, - Array> &d2factors); + Array> &d2factors) final; private: LibUtilities::NekManager @@ -170,9 +178,9 @@ private: LibUtilities::NekManager m_staticCondMatrixManager; - virtual void v_LaplacianMatrixOp_MatFree_Kernel( + void v_LaplacianMatrixOp_MatFree_Kernel( const Array &inarray, - Array &outarray, Array &wsp); + Array &outarray, Array &wsp) final; }; typedef std::shared_ptr PyrExpSharedPtr; diff --git a/library/LocalRegions/QuadExp.cpp b/library/LocalRegions/QuadExp.cpp index 4920c8a7438000e973cc39621f43e2af6281c4a2..ad7c25c041bdc235f75e8cb39b795f401e7b92af 100644 --- a/library/LocalRegions/QuadExp.cpp +++ b/library/LocalRegions/QuadExp.cpp @@ -70,10 +70,6 @@ QuadExp::QuadExp(const QuadExp &T) { } -QuadExp::~QuadExp() -{ -} - NekDouble QuadExp::v_Integral(const Array &inarray) { int nquad0 = m_base[0]->GetNumPoints(); @@ -628,7 +624,7 @@ NekDouble QuadExp::v_StdPhysEvaluate( const Array &physvals) { // Evaluate point in local (eta) coordinates. - return StdQuadExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion2D::v_PhysEvaluate(Lcoord, physvals); } NekDouble QuadExp::v_PhysEvaluate(const Array &coord, @@ -639,7 +635,17 @@ NekDouble QuadExp::v_PhysEvaluate(const Array &coord, ASSERTL0(m_geom, "m_geom not defined"); m_geom->GetLocCoords(coord, Lcoord); - return StdQuadExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion2D::v_PhysEvaluate(Lcoord, physvals); +} + +NekDouble QuadExp::v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + Array Lcoord(2); + ASSERTL0(m_geom, "m_geom not defined"); + m_geom->GetLocCoords(coord, Lcoord); + return StdQuadExp::v_PhysEvaluate(Lcoord, inarray, firstOrderDerivs); } // Get edge values from the 2D Phys space along an edge diff --git a/library/LocalRegions/QuadExp.h b/library/LocalRegions/QuadExp.h index 128292f488305189bd6ea1c219ed81f80735b403..7d2a841719baa01b884138ef5f22f35372b75824 100644 --- a/library/LocalRegions/QuadExp.h +++ b/library/LocalRegions/QuadExp.h @@ -47,8 +47,8 @@ namespace Nektar namespace LocalRegions { -class QuadExp : virtual public StdRegions::StdQuadExp, - virtual public Expansion2D +class QuadExp final : virtual public StdRegions::StdQuadExp, + virtual public Expansion2D { public: /** @@ -61,7 +61,7 @@ public: LOCAL_REGIONS_EXPORT QuadExp(const QuadExp &T); - LOCAL_REGIONS_EXPORT virtual ~QuadExp(); + LOCAL_REGIONS_EXPORT virtual ~QuadExp() final = default; protected: //------------------------------- @@ -152,6 +152,10 @@ protected: LOCAL_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( const Array &coord, const Array &physvals); + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) final; LOCAL_REGIONS_EXPORT virtual void v_GetEdgePhysVals( const int edge, const Array &inarray, Array &outarray); @@ -225,9 +229,10 @@ protected: LOCAL_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp( const Array &inarray, Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_GeneralMatrixOp_MatOp( + LOCAL_REGIONS_EXPORT void v_GeneralMatrixOp_MatOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; LOCAL_REGIONS_EXPORT virtual void v_LaplacianMatrixOp_MatFree_Kernel( const Array &inarray, Array &outarray, Array &wsp); @@ -249,8 +254,6 @@ private: m_matrixManager; LibUtilities::NekManager m_staticCondMatrixManager; - - QuadExp(); }; typedef std::shared_ptr QuadExpSharedPtr; diff --git a/library/LocalRegions/SegExp.cpp b/library/LocalRegions/SegExp.cpp index 20ade987739a8b6c07d38963435a2147b9389160..c46195b6c9d5d0dd4b20ba0d50de50505542caf2 100644 --- a/library/LocalRegions/SegExp.cpp +++ b/library/LocalRegions/SegExp.cpp @@ -81,13 +81,6 @@ SegExp::SegExp(const SegExp &S) { } -/** - * - */ -SegExp::~SegExp() -{ -} - //---------------------------- // Integration Methods //---------------------------- @@ -598,7 +591,7 @@ NekDouble SegExp::v_StdPhysEvaluate( const Array &physvals) { // Evaluate point in local (eta) coordinates. - return StdSegExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion1D::v_PhysEvaluate(Lcoord, physvals); } NekDouble SegExp::v_PhysEvaluate(const Array &coord, @@ -609,7 +602,29 @@ NekDouble SegExp::v_PhysEvaluate(const Array &coord, ASSERTL0(m_geom, "m_geom not defined"); m_geom->GetLocCoords(coord, Lcoord); - return StdSegExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion1D::v_PhysEvaluate(Lcoord, physvals); +} + +NekDouble SegExp::v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + Array Lcoord(1); + ASSERTL0(m_geom, "m_geom not defined"); + m_geom->GetLocCoords(coord, Lcoord); + return StdSegExp::v_PhysEvaluate(Lcoord, inarray, firstOrderDerivs); +} + +NekDouble SegExp::v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs, + std::array &secondOrderDerivs) +{ + Array Lcoord(1); + ASSERTL0(m_geom, "m_geom not defined"); + m_geom->GetLocCoords(coord, Lcoord); + return StdSegExp::v_PhysEvaluate(Lcoord, inarray, firstOrderDerivs, + secondOrderDerivs); } void SegExp::v_GetCoord(const Array &Lcoords, diff --git a/library/LocalRegions/SegExp.h b/library/LocalRegions/SegExp.h index 6e44cd3f693250513952d473ed5f20a5fe86fa06..2487d5565acb8823d32f32a58dfc67dadf473982 100644 --- a/library/LocalRegions/SegExp.h +++ b/library/LocalRegions/SegExp.h @@ -48,7 +48,8 @@ namespace Nektar namespace LocalRegions { -class SegExp : virtual public StdRegions::StdSegExp, virtual public Expansion1D +class SegExp final : virtual public StdRegions::StdSegExp, + virtual public Expansion1D { public: @@ -58,180 +59,189 @@ public: LOCAL_REGIONS_EXPORT SegExp(const SegExp &S); - LOCAL_REGIONS_EXPORT ~SegExp(); + LOCAL_REGIONS_EXPORT ~SegExp() final = default; protected: //---------------------------- // Integration Methods //---------------------------- - LOCAL_REGIONS_EXPORT virtual NekDouble v_Integral( - const Array &inarray) override; + LOCAL_REGIONS_EXPORT NekDouble + v_Integral(const Array &inarray) final; //----------------------------- // Differentiation Methods //----------------------------- - LOCAL_REGIONS_EXPORT virtual void v_PhysDeriv( + LOCAL_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1 = NullNekDouble1DArray, - Array &out_d2 = NullNekDouble1DArray) override; + Array &out_d2 = NullNekDouble1DArray) final; - LOCAL_REGIONS_EXPORT virtual void v_PhysDeriv( + LOCAL_REGIONS_EXPORT void v_PhysDeriv( const int dir, const Array &inarray, - Array &outarray) override; + Array &outarray) final; - LOCAL_REGIONS_EXPORT virtual void v_PhysDeriv_s( + LOCAL_REGIONS_EXPORT void v_PhysDeriv_s( const Array &inarray, - Array &out_ds) override; + Array &out_ds) final; - LOCAL_REGIONS_EXPORT virtual void v_PhysDeriv_n( + LOCAL_REGIONS_EXPORT void v_PhysDeriv_n( const Array &inarray, - Array &out_dn) override; + Array &out_dn) final; //----------------------------- // Transforms //----------------------------- - LOCAL_REGIONS_EXPORT virtual void v_FwdTrans( + LOCAL_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray) override; + Array &outarray) final; - LOCAL_REGIONS_EXPORT virtual void v_FwdTransBndConstrained( + LOCAL_REGIONS_EXPORT void v_FwdTransBndConstrained( const Array &inarray, - Array &outarray) override; + Array &outarray) final; //----------------------------- // Inner product functions //----------------------------- - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase( + LOCAL_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray) override; + Array &outarray) final; - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase( + LOCAL_REGIONS_EXPORT void v_IProductWRTBase( const Array &base, const Array &inarray, - Array &outarray, int coll_check) override; + Array &outarray, int coll_check) final; - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray) override; + Array &outarray) final; - LOCAL_REGIONS_EXPORT virtual void v_NormVectorIProductWRTBase( + LOCAL_REGIONS_EXPORT void v_NormVectorIProductWRTBase( const Array &Fx, const Array &Fy, - Array &outarray) override; + Array &outarray) final; - LOCAL_REGIONS_EXPORT virtual void v_NormVectorIProductWRTBase( + LOCAL_REGIONS_EXPORT void v_NormVectorIProductWRTBase( const Array> &Fvec, - Array &outarray) override; + Array &outarray) final; //----------------------------- // Evaluation functions //----------------------------- - LOCAL_REGIONS_EXPORT virtual NekDouble v_StdPhysEvaluate( - const Array &Lcoord, - const Array &physvals) override; - - LOCAL_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( - const Array &coord, - const Array &physvals) override; - - LOCAL_REGIONS_EXPORT virtual void v_GetCoord( + LOCAL_REGIONS_EXPORT NekDouble + v_StdPhysEvaluate(const Array &Lcoord, + const Array &physvals) final; + + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &physvals) final; + + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) final; + + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs, + std::array &secondOrderDerivs) final; + + LOCAL_REGIONS_EXPORT void v_GetCoord( const Array &Lcoords, - Array &coords) override; + Array &coords) final; - LOCAL_REGIONS_EXPORT virtual void v_GetCoords( + LOCAL_REGIONS_EXPORT void v_GetCoords( Array &coords_1, Array &coords_2, - Array &coords_3) override; + Array &coords_3) final; - LOCAL_REGIONS_EXPORT virtual void v_GetVertexPhysVals( + LOCAL_REGIONS_EXPORT void v_GetVertexPhysVals( const int vertex, const Array &inarray, - NekDouble &outarray) override; + NekDouble &outarray) final; - LOCAL_REGIONS_EXPORT virtual void v_AddVertexPhysVals( + LOCAL_REGIONS_EXPORT void v_AddVertexPhysVals( const int vertex, const NekDouble &inarray, Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_GetTracePhysVals( + LOCAL_REGIONS_EXPORT void v_GetTracePhysVals( const int edge, const StdRegions::StdExpansionSharedPtr &EdgeExp, const Array &inarray, - Array &outarray, - StdRegions::Orientation orient) override; + Array &outarray, StdRegions::Orientation orient) final; LOCAL_REGIONS_EXPORT virtual void v_GetTracePhysMap( - const int vertex, Array &map) override; + const int vertex, Array &map) final; //----------------------------- // Helper functions //----------------------------- - LOCAL_REGIONS_EXPORT virtual StdRegions::StdExpansionSharedPtr v_GetStdExp( - void) const override; + LOCAL_REGIONS_EXPORT + StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const final; - LOCAL_REGIONS_EXPORT virtual StdRegions::StdExpansionSharedPtr v_GetLinStdExp( - void) const override; + LOCAL_REGIONS_EXPORT + StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const final; - LOCAL_REGIONS_EXPORT virtual int v_GetCoordim() override; + LOCAL_REGIONS_EXPORT int v_GetCoordim() final; - LOCAL_REGIONS_EXPORT virtual void v_SetCoeffsToOrientation( + LOCAL_REGIONS_EXPORT void v_SetCoeffsToOrientation( StdRegions::Orientation dir, Array &inarray, - Array &outarray) override; + Array &outarray) final; LOCAL_REGIONS_EXPORT virtual int v_GetNumPoints(const int dir) const; LOCAL_REGIONS_EXPORT virtual int v_GetNcoeffs(void) const; - LOCAL_REGIONS_EXPORT virtual const LibUtilities::BasisSharedPtr &v_GetBasis( + LOCAL_REGIONS_EXPORT const LibUtilities::BasisSharedPtr &v_GetBasis( int dir) const; - LOCAL_REGIONS_EXPORT virtual int v_NumBndryCoeffs() const override; + LOCAL_REGIONS_EXPORT int v_NumBndryCoeffs() const final; - LOCAL_REGIONS_EXPORT virtual int v_NumDGBndryCoeffs() const override; + LOCAL_REGIONS_EXPORT int v_NumDGBndryCoeffs() const final; - LOCAL_REGIONS_EXPORT virtual void v_ComputeTraceNormal( - const int vertex) override; + LOCAL_REGIONS_EXPORT void v_ComputeTraceNormal(const int vertex) final; - LOCAL_REGIONS_EXPORT virtual SpatialDomains::GeomType v_MetricInfoType(); + LOCAL_REGIONS_EXPORT SpatialDomains::GeomType v_MetricInfoType(); - LOCAL_REGIONS_EXPORT virtual void v_ExtractDataToCoeffs( + LOCAL_REGIONS_EXPORT void v_ExtractDataToCoeffs( const NekDouble *data, const std::vector &nummodes, const int mode_offset, NekDouble *coeffs, - std::vector &fromType) override; + std::vector &fromType) final; - LOCAL_REGIONS_EXPORT virtual const Array - &v_GetPhysNormals(void) override; + LOCAL_REGIONS_EXPORT const Array &v_GetPhysNormals( + void) final; //----------------------------- // Operator creation functions //----------------------------- - LOCAL_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + LOCAL_REGIONS_EXPORT void v_LaplacianMatrixOp( const Array &inarray, Array &outarray, - const StdRegions::StdMatrixKey &mkey) override; + const StdRegions::StdMatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp( + LOCAL_REGIONS_EXPORT void v_HelmholtzMatrixOp( const Array &inarray, Array &outarray, - const StdRegions::StdMatrixKey &mkey) override; + const StdRegions::StdMatrixKey &mkey) final; //----------------------------- // Matrix creation functions //----------------------------- - LOCAL_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdRegions::StdMatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdRegions::StdMatrixKey &mkey) final; LOCAL_REGIONS_EXPORT DNekScalMatSharedPtr CreateMatrix(const MatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdRegions::StdMatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual DNekScalMatSharedPtr v_GetLocMatrix( - const MatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT DNekScalMatSharedPtr + v_GetLocMatrix(const MatrixKey &mkey) final; - LOCAL_REGIONS_EXPORT virtual DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix( - const MatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT DNekScalBlkMatSharedPtr + v_GetLocStaticCondMatrix(const MatrixKey &mkey) final; LOCAL_REGIONS_EXPORT void v_DropLocStaticCondMatrix( - const MatrixKey &mkey) override; + const MatrixKey &mkey) final; private: LibUtilities::NekManager @@ -239,8 +249,6 @@ private: LibUtilities::NekManager m_staticCondMatrixManager; - SegExp(); - LOCAL_REGIONS_EXPORT void ReverseCoeffsAndSign( const Array &inarray, Array &outarray); diff --git a/library/LocalRegions/TetExp.cpp b/library/LocalRegions/TetExp.cpp index a8444064d326a123bc23c3afa27108657716147b..574384ace7fb2ee6dc58e51bb3b26086ef6afef0 100644 --- a/library/LocalRegions/TetExp.cpp +++ b/library/LocalRegions/TetExp.cpp @@ -89,13 +89,6 @@ TetExp::TetExp(const TetExp &T) { } -/** - * \brief Destructor - */ -TetExp::~TetExp() -{ -} - //----------------------------- // Integration Methods //----------------------------- @@ -470,7 +463,7 @@ NekDouble TetExp::v_StdPhysEvaluate( const Array &physvals) { // Evaluate point in local (eta) coordinates. - return StdTetExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion3D::v_PhysEvaluate(Lcoord, physvals); } /** @@ -488,7 +481,17 @@ NekDouble TetExp::v_PhysEvaluate(const Array &coord, m_geom->GetLocCoords(coord, Lcoord); // Evaluate point in local (eta) coordinates. - return StdTetExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion3D::v_PhysEvaluate(Lcoord, physvals); +} + +NekDouble TetExp::v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + Array Lcoord(3); + ASSERTL0(m_geom, "m_geom not defined"); + m_geom->GetLocCoords(coord, Lcoord); + return StdTetExp::v_PhysEvaluate(Lcoord, inarray, firstOrderDerivs); } /** diff --git a/library/LocalRegions/TetExp.h b/library/LocalRegions/TetExp.h index 3e8bffe59cce7aa5bd663c7a3ed02a776c4e7a6e..6de5da6f0fe61664a92572837612d6c745fc8700 100644 --- a/library/LocalRegions/TetExp.h +++ b/library/LocalRegions/TetExp.h @@ -58,136 +58,141 @@ public: LOCAL_REGIONS_EXPORT TetExp(const TetExp &T); - LOCAL_REGIONS_EXPORT ~TetExp(); + LOCAL_REGIONS_EXPORT ~TetExp() override = default; protected: //----------------------------- // Integration Methods //----------------------------- - LOCAL_REGIONS_EXPORT virtual NekDouble v_Integral( - const Array &inarray); + LOCAL_REGIONS_EXPORT NekDouble + v_Integral(const Array &inarray) override; //----------------------------- // Differentiation Methods //----------------------------- - LOCAL_REGIONS_EXPORT virtual void v_PhysDeriv( + LOCAL_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2); + Array &out_d2) override; //----------------------------- // Transforms //----------------------------- - LOCAL_REGIONS_EXPORT virtual void v_FwdTrans( + LOCAL_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) override; //----------------------------- // Inner product functions //----------------------------- - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase( + LOCAL_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + Array &outarray) override; + LOCAL_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multiplybyweights = true); - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + Array &outarray, + bool multiplybyweights = true) override; + LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_AlignVectorToCollapsedDir( + Array &outarray) override; + LOCAL_REGIONS_EXPORT void v_AlignVectorToCollapsedDir( const int dir, const Array &inarray, - Array> &outarray); + Array> &outarray) override; //----------------------------- // Evaluation functions //----------------------------- - LOCAL_REGIONS_EXPORT virtual NekDouble v_StdPhysEvaluate( - const Array &Lcoord, - const Array &physvals); + LOCAL_REGIONS_EXPORT NekDouble + v_StdPhysEvaluate(const Array &Lcoord, + const Array &physvals) override; - LOCAL_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( - const Array &coords, - const Array &physvals); + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coords, + const Array &physvals) override; - LOCAL_REGIONS_EXPORT virtual void v_GetCoord( + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) final; + + LOCAL_REGIONS_EXPORT void v_GetCoord( const Array &Lcoords, - Array &coords); + Array &coords) override; - LOCAL_REGIONS_EXPORT virtual void v_GetCoords( + LOCAL_REGIONS_EXPORT void v_GetCoords( Array &coords_1, Array &coords_2, - Array &coords_3); + Array &coords_3) override; //----------------------------- // Helper functions //----------------------------- - LOCAL_REGIONS_EXPORT virtual LibUtilities::ShapeType v_DetShapeType() const; + LOCAL_REGIONS_EXPORT + LibUtilities::ShapeType v_DetShapeType() const override; - LOCAL_REGIONS_EXPORT virtual StdRegions::StdExpansionSharedPtr v_GetStdExp( - void) const; + LOCAL_REGIONS_EXPORT + StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const override; - LOCAL_REGIONS_EXPORT virtual StdRegions::StdExpansionSharedPtr v_GetLinStdExp( - void) const; + LOCAL_REGIONS_EXPORT + StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const override; - LOCAL_REGIONS_EXPORT virtual int v_GetCoordim(); + LOCAL_REGIONS_EXPORT int v_GetCoordim() override; - LOCAL_REGIONS_EXPORT virtual void v_ExtractDataToCoeffs( + LOCAL_REGIONS_EXPORT void v_ExtractDataToCoeffs( const NekDouble *data, const std::vector &nummodes, const int mode_offset, NekDouble *coeffs, - std::vector &fromType); + std::vector &fromType) override; - LOCAL_REGIONS_EXPORT virtual void v_GetTracePhysMap( - const int face, Array &outarray); + LOCAL_REGIONS_EXPORT void v_GetTracePhysMap( + const int face, Array &outarray) override; - LOCAL_REGIONS_EXPORT void v_ComputeTraceNormal(const int face); + LOCAL_REGIONS_EXPORT void v_ComputeTraceNormal(const int face) override; //----------------------------- // Operator creation functions //----------------------------- - LOCAL_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp( + LOCAL_REGIONS_EXPORT void v_HelmholtzMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; - LOCAL_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + LOCAL_REGIONS_EXPORT void v_LaplacianMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; - LOCAL_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + LOCAL_REGIONS_EXPORT void v_LaplacianMatrixOp( const int k1, const int k2, const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; - LOCAL_REGIONS_EXPORT virtual void v_SVVLaplacianFilter( - Array &array, const StdRegions::StdMatrixKey &mkey); + LOCAL_REGIONS_EXPORT void v_SVVLaplacianFilter( + Array &array, + const StdRegions::StdMatrixKey &mkey) override; //----------------------------- // Matrix creation functions //----------------------------- - LOCAL_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdRegions::StdMatrixKey &mkey); + LOCAL_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdRegions::StdMatrixKey &mkey) override; - LOCAL_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdRegions::StdMatrixKey &mkey); + LOCAL_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey) override; - LOCAL_REGIONS_EXPORT virtual DNekScalMatSharedPtr v_GetLocMatrix( - const MatrixKey &mkey); + LOCAL_REGIONS_EXPORT DNekScalMatSharedPtr + v_GetLocMatrix(const MatrixKey &mkey) override; - LOCAL_REGIONS_EXPORT virtual DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix( - const MatrixKey &mkey); + LOCAL_REGIONS_EXPORT + DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix( + const MatrixKey &mkey) override; - LOCAL_REGIONS_EXPORT void v_DropLocStaticCondMatrix(const MatrixKey &mkey); + LOCAL_REGIONS_EXPORT void v_DropLocStaticCondMatrix( + const MatrixKey &mkey) override; - LOCAL_REGIONS_EXPORT void SetUpInverseTransformationMatrix( - const DNekMatSharedPtr &m_transformationmatrix, - DNekMatSharedPtr m_inversetransformationmatrix, - DNekMatSharedPtr m_inversetransposedtransformationmatrix); + LOCAL_REGIONS_EXPORT void v_ComputeLaplacianMetric() override; - LOCAL_REGIONS_EXPORT void v_ComputeConditionNumberOfMatrix( - const DNekScalMatSharedPtr &mat); - - LOCAL_REGIONS_EXPORT virtual void v_ComputeLaplacianMetric(); - - LOCAL_REGIONS_EXPORT virtual void v_NormalTraceDerivFactors( + LOCAL_REGIONS_EXPORT void v_NormalTraceDerivFactors( Array> &d0factors, Array> &d1factors, - Array> &d2factors); + Array> &d2factors) override; private: LibUtilities::NekManager @@ -195,14 +200,12 @@ private: LibUtilities::NekManager m_staticCondMatrixManager; - TetExp(); - LOCAL_REGIONS_EXPORT void GeneralMatrixOp_MatOp( const Array &inarray, Array &outarray, const StdRegions::StdMatrixKey &mkey); - virtual void v_LaplacianMatrixOp_MatFree_Kernel( + void v_LaplacianMatrixOp_MatFree_Kernel( const Array &inarray, - Array &outarray, Array &wsp); + Array &outarray, Array &wsp) override; }; typedef std::shared_ptr TetExpSharedPtr; diff --git a/library/LocalRegions/TriExp.cpp b/library/LocalRegions/TriExp.cpp index 5a563183e09e2d9d19f4668b2da66fc3a95fa7a2..0ce25fd70d9a77044e857f6188a9b4f377638a97 100644 --- a/library/LocalRegions/TriExp.cpp +++ b/library/LocalRegions/TriExp.cpp @@ -72,10 +72,6 @@ TriExp::TriExp(const TriExp &T) { } -TriExp::~TriExp() -{ -} - NekDouble TriExp::v_Integral(const Array &inarray) { int nquad0 = m_base[0]->GetNumPoints(); @@ -750,7 +746,7 @@ NekDouble TriExp::v_StdPhysEvaluate( const Array &physvals) { // Evaluate point in local (eta) coordinates. - return StdTriExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion2D::v_PhysEvaluate(Lcoord, physvals); } NekDouble TriExp::v_PhysEvaluate(const Array &coord, @@ -761,7 +757,17 @@ NekDouble TriExp::v_PhysEvaluate(const Array &coord, ASSERTL0(m_geom, "m_geom not defined"); m_geom->GetLocCoords(coord, Lcoord); - return StdTriExp::v_PhysEvaluate(Lcoord, physvals); + return StdExpansion2D::v_PhysEvaluate(Lcoord, physvals); +} + +NekDouble TriExp::v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + Array Lcoord(2); + ASSERTL0(m_geom, "m_geom not defined"); + m_geom->GetLocCoords(coord, Lcoord); + return StdTriExp::v_PhysEvaluate(Lcoord, inarray, firstOrderDerivs); } void TriExp::v_GetTracePhysVals( diff --git a/library/LocalRegions/TriExp.h b/library/LocalRegions/TriExp.h index 064e4e7ccc9ac725eb3036cf8d171c508e222112..ca4c127fac69e380ada855605b39f9eac5662b2a 100644 --- a/library/LocalRegions/TriExp.h +++ b/library/LocalRegions/TriExp.h @@ -61,196 +61,212 @@ public: LOCAL_REGIONS_EXPORT TriExp(const TriExp &T); - LOCAL_REGIONS_EXPORT ~TriExp(); + LOCAL_REGIONS_EXPORT ~TriExp() override = default; protected: //------------------------------- // Integration Methods //------------------------------- - LOCAL_REGIONS_EXPORT virtual NekDouble v_Integral( - const Array &inarray); + LOCAL_REGIONS_EXPORT NekDouble + v_Integral(const Array &inarray) override; //---------------------------- // Differentiation Methods //---------------------------- - LOCAL_REGIONS_EXPORT virtual void v_PhysDeriv( + LOCAL_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2 = NullNekDouble1DArray); - LOCAL_REGIONS_EXPORT virtual void v_PhysDeriv( + Array &out_d2 = NullNekDouble1DArray) override; + LOCAL_REGIONS_EXPORT void v_PhysDeriv( const int dir, const Array &inarray, - Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_PhysDirectionalDeriv( + Array &outarray) override; + LOCAL_REGIONS_EXPORT void v_PhysDirectionalDeriv( const Array &inarray, const Array &direction, - Array &out); + Array &out) override; //--------------------------------------- // Transforms //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual void v_FwdTrans( + LOCAL_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_FwdTransBndConstrained( + Array &outarray) override; + LOCAL_REGIONS_EXPORT void v_FwdTransBndConstrained( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Inner product functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase( + LOCAL_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + Array &outarray) override; + LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + Array &outarray) override; + LOCAL_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multiplybyweights = true); - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTBase_MatOp( + Array &outarray, + bool multiplybyweights = true) override; + LOCAL_REGIONS_EXPORT void v_IProductWRTBase_MatOp( const Array &inarray, - Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_SumFac( + Array &outarray) override; + LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_AlignVectorToCollapsedDir( + Array &outarray) override; + LOCAL_REGIONS_EXPORT void v_AlignVectorToCollapsedDir( const int dir, const Array &inarray, - Array> &outarray); + Array> &outarray) override; - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_MatOp( + LOCAL_REGIONS_EXPORT void v_IProductWRTDerivBase_MatOp( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTDirectionalDerivBase( + LOCAL_REGIONS_EXPORT void v_IProductWRTDirectionalDerivBase( const Array &direction, const Array &inarray, - Array &outarray); + Array &outarray) override; - LOCAL_REGIONS_EXPORT virtual void v_IProductWRTDirectionalDerivBase_SumFac( + LOCAL_REGIONS_EXPORT void v_IProductWRTDirectionalDerivBase_SumFac( const Array &direction, const Array &inarray, - Array &outarray); + Array &outarray) override; - LOCAL_REGIONS_EXPORT virtual void v_NormVectorIProductWRTBase( + LOCAL_REGIONS_EXPORT void v_NormVectorIProductWRTBase( const Array &Fx, const Array &Fy, const Array &Fz, - Array &outarray); + Array &outarray) override; - LOCAL_REGIONS_EXPORT virtual void v_NormVectorIProductWRTBase( + LOCAL_REGIONS_EXPORT void v_NormVectorIProductWRTBase( const Array> &Fvec, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Evaluation functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual StdRegions::StdExpansionSharedPtr v_GetStdExp( - void) const; + LOCAL_REGIONS_EXPORT + StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const override; - LOCAL_REGIONS_EXPORT virtual StdRegions::StdExpansionSharedPtr v_GetLinStdExp( - void) const; + LOCAL_REGIONS_EXPORT + StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const override; - LOCAL_REGIONS_EXPORT virtual void v_GetCoord( + LOCAL_REGIONS_EXPORT void v_GetCoord( const Array &Lcoords, - Array &coords); - LOCAL_REGIONS_EXPORT virtual void v_GetCoords( + Array &coords) override; + LOCAL_REGIONS_EXPORT void v_GetCoords( Array &coords_1, Array &coords_2, - Array &coords_3); - LOCAL_REGIONS_EXPORT virtual NekDouble v_StdPhysEvaluate( - const Array &Lcoord, - const Array &physvals); - LOCAL_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( - const Array &coord, - const Array &physvals); - LOCAL_REGIONS_EXPORT virtual void v_GetTracePhysVals( + Array &coords_3) override; + LOCAL_REGIONS_EXPORT NekDouble + v_StdPhysEvaluate(const Array &Lcoord, + const Array &physvals) override; + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &physvals) override; + LOCAL_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) final; + LOCAL_REGIONS_EXPORT void v_GetTracePhysVals( const int edge, const StdRegions::StdExpansionSharedPtr &EdgeExp, const Array &inarray, - Array &outarray, StdRegions::Orientation orient); - LOCAL_REGIONS_EXPORT virtual void v_GetEdgeInterpVals( + Array &outarray, + StdRegions::Orientation orient) override; + LOCAL_REGIONS_EXPORT void v_GetEdgeInterpVals( const int edge, const Array &inarray, Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_GetTraceQFactors( - const int edge, Array &outarray); - LOCAL_REGIONS_EXPORT virtual void v_ComputeTraceNormal(const int edge); + LOCAL_REGIONS_EXPORT void v_GetTraceQFactors( + const int edge, Array &outarray) override; + LOCAL_REGIONS_EXPORT void v_ComputeTraceNormal(const int edge) override; //--------------------------------------- // Helper functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual int v_GetCoordim(); - LOCAL_REGIONS_EXPORT virtual void v_ExtractDataToCoeffs( + LOCAL_REGIONS_EXPORT int v_GetCoordim() override; + LOCAL_REGIONS_EXPORT void v_ExtractDataToCoeffs( const NekDouble *data, const std::vector &nummodes, const int mode_offset, NekDouble *coeffs, - std::vector &fromType); - LOCAL_REGIONS_EXPORT virtual StdRegions::Orientation v_GetTraceOrient( - int edge); + std::vector &fromType) override; + LOCAL_REGIONS_EXPORT + StdRegions::Orientation v_GetTraceOrient(int edge) override; LOCAL_REGIONS_EXPORT virtual const LibUtilities::BasisSharedPtr &v_GetBasis( int dir) const; LOCAL_REGIONS_EXPORT virtual int v_GetNumPoints(const int dir) const; - LOCAL_REGIONS_EXPORT virtual void v_GetTracePhysMap( - const int edge, Array &outarray); + LOCAL_REGIONS_EXPORT void v_GetTracePhysMap( + const int edge, Array &outarray) override; //--------------------------------------- // Matrix creation functions //--------------------------------------- - LOCAL_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual DNekScalMatSharedPtr v_GetLocMatrix( - const MatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix( - const MatrixKey &mkey); + LOCAL_REGIONS_EXPORT + DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT + DNekMatSharedPtr v_CreateStdMatrix( + const StdRegions::StdMatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT + DNekScalMatSharedPtr v_GetLocMatrix(const MatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT + DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix( + const MatrixKey &mkey) override; - LOCAL_REGIONS_EXPORT void v_DropLocStaticCondMatrix(const MatrixKey &mkey); + LOCAL_REGIONS_EXPORT void v_DropLocStaticCondMatrix( + const MatrixKey &mkey) override; - LOCAL_REGIONS_EXPORT virtual void v_MassMatrixOp( + LOCAL_REGIONS_EXPORT void v_MassMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT void v_LaplacianMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT void v_LaplacianMatrixOp( const int k1, const int k2, const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_WeakDerivMatrixOp( + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT void v_WeakDerivMatrixOp( const int i, const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_WeakDirectionalDerivMatrixOp( + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT void v_WeakDirectionalDerivMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_MassLevelCurvatureMatrixOp( + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT void v_MassLevelCurvatureMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp( + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT void v_HelmholtzMatrixOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_GeneralMatrixOp_MatOp( + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; + LOCAL_REGIONS_EXPORT void v_GeneralMatrixOp_MatOp( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); - LOCAL_REGIONS_EXPORT virtual void v_LaplacianMatrixOp_MatFree_Kernel( + Array &outarray, + const StdRegions::StdMatrixKey &mkey) final; + LOCAL_REGIONS_EXPORT void v_LaplacianMatrixOp_MatFree_Kernel( const Array &inarray, - Array &outarray, Array &wsp); - LOCAL_REGIONS_EXPORT virtual void v_ReduceOrderCoeffs( + Array &outarray, Array &wsp) override; + LOCAL_REGIONS_EXPORT void v_ReduceOrderCoeffs( int numMin, const Array &inarray, - Array &outarray); + Array &outarray) override; - LOCAL_REGIONS_EXPORT virtual void v_ComputeLaplacianMetric(); + LOCAL_REGIONS_EXPORT void v_ComputeLaplacianMetric() override; - LOCAL_REGIONS_EXPORT virtual void v_SVVLaplacianFilter( - Array &array, const StdRegions::StdMatrixKey &mkey); + LOCAL_REGIONS_EXPORT void v_SVVLaplacianFilter( + Array &array, + const StdRegions::StdMatrixKey &mkey) override; - LOCAL_REGIONS_EXPORT virtual void v_NormalTraceDerivFactors( + LOCAL_REGIONS_EXPORT void v_NormalTraceDerivFactors( Array> &factors, Array> &d0factors, - Array> &d1factors); + Array> &d1factors) override; private: LibUtilities::NekManager m_matrixManager; LibUtilities::NekManager m_staticCondMatrixManager; - - TriExp(); }; typedef std::shared_ptr TriExpSharedPtr; diff --git a/library/MultiRegions/AssemblyMap/AssemblyCommDG.cpp b/library/MultiRegions/AssemblyMap/AssemblyCommDG.cpp index ff962bdbef9752a180a19f381eeeac0466d6be2a..d4deae6eeadd220dff809227432335a0ff44f3c4 100644 --- a/library/MultiRegions/AssemblyMap/AssemblyCommDG.cpp +++ b/library/MultiRegions/AssemblyMap/AssemblyCommDG.cpp @@ -400,21 +400,33 @@ AssemblyCommDG::AssemblyCommDG( std::vector avg(MPIFuncs.size(), -1); bool verbose = locExp.GetSession()->DefinesCmdLineArgument("verbose"); - if (verbose && comm->GetRank() == 0) + if (verbose && comm->TreatAsRankZero()) { std::cout << "MPI setup for trace exchange: " << std::endl; } + // Padding for output + int maxStrLen = 0; + for (size_t i = 0; i < MPIFuncs.size(); ++i) + { + maxStrLen = MPIFuncsNames[i].size() > maxStrLen + ? MPIFuncsNames[i].size() + : maxStrLen; + } + for (size_t i = 0; i < MPIFuncs.size(); ++i) { Timing(comm, warmup, numPoints, MPIFuncs[i]); std::tie(avg[i], min, max) = Timing(comm, iter, numPoints, MPIFuncs[i]); - if (verbose && comm->GetRank() == 0) + if (verbose && comm->TreatAsRankZero()) { std::cout << " " << MPIFuncsNames[i] - << " times (avg, min, max): " << avg[i] << " " << min - << " " << max << std::endl; + << " times (avg, min, max)" + << std::string(maxStrLen - MPIFuncsNames[i].size(), + ' ') + << ": " << avg[i] << " " << min << " " << max + << std::endl; } } @@ -422,7 +434,7 @@ AssemblyCommDG::AssemblyCommDG( int fastestMPI = std::distance( avg.begin(), std::min_element(avg.begin(), avg.end())); - if (verbose && comm->GetRank() == 0) + if (verbose && comm->TreatAsRankZero()) { std::cout << " Chosen fastest method: " << MPIFuncsNames[fastestMPI] << std::endl; @@ -567,7 +579,7 @@ void AssemblyCommDG::InitialiseStructure( } // This creates a list of all geometry of problem dimension - 1 - // and populates the maxQuad member variable + // and populates the maxQuad member variable for AllToAll std::vector localEdgeIds; for (eid = 0; eid < locExpVector.size(); ++eid) { @@ -586,7 +598,7 @@ void AssemblyCommDG::InitialiseStructure( } } - // Find max quadrature points across all processes + // Find max quadrature points across all processes for AllToAll method comm->AllReduce(m_maxQuad, LibUtilities::ReduceMax); // Create list of boundary edge IDs @@ -675,7 +687,6 @@ void AssemblyCommDG::InitialiseStructure( // Find what edge Ids match with other ranks size_t myRank = comm->GetRank(); - Array perTraceSend(m_nRanks, 0); for (size_t i = 0; i < m_nRanks; ++i) { if (i == myRank) diff --git a/library/MultiRegions/AssemblyMap/AssemblyCommDG.h b/library/MultiRegions/AssemblyMap/AssemblyCommDG.h index c6117b53a7bb0ad40d056dda58fd65bc7e4e98ed..a54b085d6e003c9ae7f4d8fce26c6573580099df 100644 --- a/library/MultiRegions/AssemblyMap/AssemblyCommDG.h +++ b/library/MultiRegions/AssemblyMap/AssemblyCommDG.h @@ -262,7 +262,7 @@ public: * and backwards spaces. * * @param testFwd Local forwards space of the trace (which will be sent) - * @param testBwd Local bacwards space of the trace (which will receive + * @param testBwd Local backwards space of the trace (which will receive * contributions) */ MULTI_REGIONS_EXPORT inline void PerformExchange( diff --git a/library/MultiRegions/AssemblyMap/InterfaceMapDG.cpp b/library/MultiRegions/AssemblyMap/InterfaceMapDG.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7d9a0d8c6e35f188fb3cf080be6d973faa474a5f --- /dev/null +++ b/library/MultiRegions/AssemblyMap/InterfaceMapDG.cpp @@ -0,0 +1,680 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// File InterfaceMapDG.cpp +// +// For more information, please see: http://www.nektar.info +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// 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. +// +// Description: MPI communication for interfaces +// +/////////////////////////////////////////////////////////////////////////////// + +#include "InterfaceMapDG.h" +#include + +namespace Nektar +{ +namespace MultiRegions +{ + +InterfaceTrace::InterfaceTrace( + const ExpListSharedPtr &trace, + const SpatialDomains::InterfaceShPtr &interfaceShPtr) + : m_trace(trace), m_interface(interfaceShPtr) +{ +} + +// Creates the objects that communicates trace values across the interface in +// serial and parallel. Does this by checking all interfaces to see if they +// are contained locally (on the current rank), and checks all other ranks for +// the same interface ID and if contains the opposite interface side i.e. +// 'left' or 'right' +InterfaceMapDG::InterfaceMapDG( + const SpatialDomains::MeshGraphSharedPtr &meshGraph, + const ExpListSharedPtr &trace) + : m_graph(meshGraph), m_movement(meshGraph->GetMovement()), m_trace(trace) +{ + auto comm = m_trace->GetComm(); + auto interfaceCollection = m_movement->GetInterfaces(); + + // myIndxLR contains the info about what interface edges are present on + // current rank with each interface no, i, consisting of: + // [i] = indx + // [i + 1] = 0 (non), = 1 (left only), = 2 (right only), = 3 (both) + std::map myIndxLRMap; + + // localInterfaces contains a map of interface ID to a pair of interface + // traces, this pair is 'left' and 'right' interface and is used to + // construct and store the traces for interfaces present on the current rank + std::map> + localInterfaces; + + // Map of m_localInterfaces vector to interface ID + Array indxToInterfaceID(interfaceCollection.size()); + + // Loops over all interfaces and check if either side, 'left' or 'right' + // are empty on the current rank, if not empty then populate the local + // interface data structures and keep track using myIndxLRMap + size_t cnt = 0; + for (const auto &interface : interfaceCollection) + { + indxToInterfaceID[cnt] = interface.first.first; + myIndxLRMap[interface.first.first] = 0; + + if (!interface.second->GetLeftInterface()->IsEmpty()) + { + myIndxLRMap[interface.first.first] += 1; + + localInterfaces[interface.first.first].first = + MemoryManager::AllocateSharedPtr( + trace, interface.second->GetLeftInterface()); + m_localInterfaces.emplace_back( + localInterfaces[interface.first.first].first); + } + + if (!interface.second->GetRightInterface()->IsEmpty()) + { + myIndxLRMap[interface.first.first] += 2; + + localInterfaces[interface.first.first].second = + MemoryManager::AllocateSharedPtr( + trace, interface.second->GetRightInterface()); + m_localInterfaces.emplace_back( + localInterfaces[interface.first.first].second); + } + + cnt++; + } + + // Send num of interfaces size so all partitions can prepare buffers + int nRanks = comm->GetSize(); + + // Send all interface edges present to all partitions + Array interfaceEdges(myIndxLRMap.size()); + cnt = 0; + for (auto pres : myIndxLRMap) + { + interfaceEdges[cnt++] = pres.second; + } + Array rankLocalInterfaceIds(myIndxLRMap.size() * nRanks, 0); + comm->AllGather(interfaceEdges, rankLocalInterfaceIds); + + // Map of rank to vector of interface traces + std::map> oppRankSharedInterface; + + // Find what interface Ids match with other ranks, then check if opposite + // edge + size_t myRank = comm->GetRank(); + size_t numInterfaces = interfaceCollection.size(); + for (int i = 0; i < nRanks; ++i) + { + for (size_t j = 0; j < numInterfaces; ++j) + { + int otherId = indxToInterfaceID[j]; + + // otherCode represents for a specific interface ID what sides are + // present on rank i, 0=non, 1=left, 2=right, 3=both + int otherCode = rankLocalInterfaceIds[i * numInterfaces + j]; + + // myCode represents for a specific interface ID what sides are + // present on this rank/process 0=non, 1=left, 2=right, 3=both + int myCode = myIndxLRMap[otherId]; + + // Special case if checking current rank (this process) + if (i == myRank) + { + // If contains both edges locally then set check local to true + if (myCode == 3) + { + localInterfaces[otherId].first->SetCheckLocal(true); + localInterfaces[otherId].second->SetCheckLocal(true); + } + + continue; + } + + // Checks if this ranks 'left' matches any 'right' on other rank + if ((myCode == 1 && otherCode == 2) || + (myCode == 1 && otherCode == 3) || + (myCode == 3 && otherCode == 2)) + { + oppRankSharedInterface[i].emplace_back( + localInterfaces[otherId].first); + } + // Checks if this ranks 'right' matches any 'left' on other rank + else if ((myCode == 2 && otherCode == 1) || + (myCode == 2 && otherCode == 3) || + (myCode == 3 && otherCode == 1)) + { + oppRankSharedInterface[i].emplace_back( + localInterfaces[otherId].second); + } + // Checks if this ranks 'both' matches any 'both' on other rank + else if (myCode == 3 && otherCode == 3) + { + oppRankSharedInterface[i].emplace_back( + localInterfaces[otherId].first); + oppRankSharedInterface[i].emplace_back( + localInterfaces[otherId].second); + } + } + } + + // Create individual interface exchange objects (each object is rank -> + // rank) and contains a vector of interfaceTrace objects + for (auto &rank : oppRankSharedInterface) + { + m_exchange.emplace_back( + MemoryManager::AllocateSharedPtr( + m_movement, m_trace, comm, rank)); + } + + // Find missing coordinates on interface from other side + ExchangeCoords(); +} + +void InterfaceMapDG::ExchangeCoords() +{ + LibUtilities::Timer timer; + timer.Start(); + + auto comm = m_trace->GetComm(); + auto zones = m_movement->GetZones(); + + LibUtilities::Timer timer2; + timer2.Start(); + for (auto &interfaceTrace : m_localInterfaces) + { + interfaceTrace->CalcLocalMissing(); + } + timer2.Stop(); + timer2.AccumulateRegion("InterfaceMapDG::ExchangeCoords local", 1); + + // If parallel communication is needed + if (!m_exchange.empty()) + { + LibUtilities::Timer timer3; + timer3.Start(); + + auto requestSend = comm->CreateRequest(m_exchange.size()); + auto requestRecv = comm->CreateRequest(m_exchange.size()); + + for (int i = 0; i < m_exchange.size(); ++i) + { + m_exchange[i]->RankFillSizes(requestSend, requestRecv, i); + } + comm->WaitAll(requestSend); + comm->WaitAll(requestRecv); + + for (int i = 0; i < m_exchange.size(); ++i) + { + m_exchange[i]->SendMissing(requestSend, requestRecv, i); + } + comm->WaitAll(requestSend); + comm->WaitAll(requestRecv); + + for (auto &i : m_exchange) + { + i->CalcRankDistances(); + } + + timer3.Stop(); + timer3.AccumulateRegion("InterfaceMapDG::ExchangeCoords parallel", 1); + } + + m_movement->GetCoordExchangeFlag() = false; + + timer.Stop(); + timer.AccumulateRegion("InterfaceMapDG::ExchangeCoords"); +} + +/** + * Calculates what coordinates on the interface are missing; i.e. aren't located + * in an edge from the other side of the interface on this partition. These are + * stored in the vector #m_missingCoords, and another vector of the same index + * layout contains the location of that coordinate in the trace i.e. the + * 'offset + i' value. It checks first if the interface is flagged local, which + * denotes whether the opposite side is also present on this rank, if not then + * all coordinates are missing. If local then the same structure as + * CalcRankDistances is used to minimise computational cost. + */ +void InterfaceTrace::CalcLocalMissing() +{ + // Nuke old missing/found + m_missingCoords.clear(); + m_mapMissingCoordToTrace.clear(); + + // Store copy of found coords to optimise search before clearing + auto foundLocalCoordsCopy = m_foundLocalCoords; + m_foundLocalCoords.clear(); + + auto childEdge = m_interface->GetEdge(); + // If not flagged 'check local' then all points are missing + if (!m_checkLocal) + { + int cnt = 0; + for (auto &childId : childEdge) + { + auto childElmt = m_trace->GetExpFromGeomId(childId.first); + size_t nq = childElmt->GetTotPoints(); + Array xc(nq, 0.0), yc(nq, 0.0), zc(nq, 0.0); + childElmt->GetCoords(xc, yc, zc); + int offset = + m_trace->GetPhys_Offset(m_trace->GetElmtToExpId(childId.first)); + + for (int i = 0; i < nq; ++i, ++cnt) + { + Array xs(3); + xs[0] = xc[i]; + xs[1] = yc[i]; + xs[2] = zc[i]; + + m_missingCoords.emplace_back(xs); + m_mapMissingCoordToTrace.emplace_back(offset + i); + } + } + } + // Otherwise we need to check to see what points the other side of the + // interface on this rank contains. This is done by looping over each + // quadrature point in all the edges on this side of the interface, then + // check if this quadrature point is also in any edges on the other side + // of the interface. First use MinMaxCheck as a cheap method to eliminate + // far away edges. If it passes MinMaxCheck perform the FindDistance search + // which numerically searches for the closest local coordinate on the other + // interface side edge and returns the cartesian distance from the search + // coordinate to the found local coordinate. If determined to be close + // enough then add to found local coordinates. + else + { + for (auto &childId : childEdge) + { + auto childElmt = m_trace->GetExpFromGeomId(childId.first); + size_t nq = childElmt->GetTotPoints(); + Array xc(nq, 0.0), yc(nq, 0.0), zc(nq, 0.0); + childElmt->GetCoords(xc, yc, zc); + int offset = + m_trace->GetPhys_Offset(m_trace->GetElmtToExpId(childId.first)); + + for (int i = 0; i < nq; ++i) + { + bool found = false; + Array foundLocCoord; + Array xs(3); + xs[0] = xc[i]; + xs[1] = yc[i]; + xs[2] = zc[i]; + + // First search the edge the point was found in last timestep + if (foundLocalCoordsCopy.find(offset + i) != + foundLocalCoordsCopy.end()) + { + auto edge = m_interface->GetOppInterface()->GetEdge( + foundLocalCoordsCopy[offset + i].first); + NekDouble dist = edge->FindDistance(xs, foundLocCoord); + + if (dist < 5e-5) + { + m_foundLocalCoords[offset + i] = + std::make_pair(edge->GetGlobalID(), foundLocCoord); + continue; + } + } + + // If not in last timestep edge then loop over all interface + // edges + auto parentEdge = m_interface->GetOppInterface()->GetEdge(); + for (auto &edge : parentEdge) + { + // First check if inside the edge bounding box + if (!edge.second->MinMaxCheck(xs)) + { + continue; + } + + NekDouble dist = + edge.second->FindDistance(xs, foundLocCoord); + if (dist < NekConstants::kFindDistanceMin) + { + found = true; + m_foundLocalCoords[offset + i] = std::make_pair( + edge.second->GetGlobalID(), foundLocCoord); + break; + } + } + + if (!found) + { + m_missingCoords.emplace_back(xs); + m_mapMissingCoordToTrace.emplace_back(offset + i); + } + } + } + } + + // If running in serial there shouldn't be any missing coordinates. + // Unless we flag to ignore this check for this specific interface. + if (m_trace->GetComm()->IsSerial() && !m_interface->GetSkipCoordCheck()) + { + ASSERTL0(m_missingCoords.empty(), + "Missing " + std::to_string(m_missingCoords.size()) + + " coordinates on interface ID " + + std::to_string(m_interface->GetId()) + + " linked to interface ID " + + std::to_string(m_interface->GetOppInterface()->GetId()) + + ". Check both sides of the interface line up."); + } +} + +// This fills m_sendSize and m_recvSize with the correct sizes for the +// communication lengths for each rank when communicating the traces. I.e. +// however many quadrature points on the opposite side of the interface to +// send, and however many on this side to receive. +void InterfaceExchange::RankFillSizes( + LibUtilities::CommRequestSharedPtr &requestSend, + LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum) +{ + + // Recalc size is the number of interfaces missing points that need to be + // communicated. + int recalcSize = 0; + for (auto &localInterface : m_interfaceTraces) + { + recalcSize += + m_zones[localInterface->GetInterface()->GetId()]->GetMoved(); + } + + m_sendSize[m_rank] = Array(recalcSize); + m_recvSize[m_rank] = Array(recalcSize); + + int cnt = 0; + for (auto &interface : m_interfaceTraces) + { + if (m_zones[interface->GetInterface()->GetId()]->GetMoved()) + { + // Calculates the number of missing coordinates to be communicated + // This size is 3 times the number of missing coordinates to allow + // for 3D points + m_sendSize[m_rank][cnt++] = + interface->GetMissingCoords().size() * 3; + } + } + + // Uses non-blocking send/recvs to send communication sizes to other ranks + m_comm->Isend(m_rank, m_sendSize[m_rank], m_interfaceTraces.size(), + requestSend, requestNum); + m_comm->Irecv(m_rank, m_recvSize[m_rank], m_interfaceTraces.size(), + requestRecv, requestNum); +} + +// Uses the calculated send/recv sizes to send all missing coordinates to +// other ranks. +void InterfaceExchange::SendMissing( + LibUtilities::CommRequestSharedPtr &requestSend, + LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum) +{ + m_totSendSize[m_rank] = std::accumulate(m_sendSize[m_rank].begin(), + m_sendSize[m_rank].end(), 0); + m_totRecvSize[m_rank] = std::accumulate(m_recvSize[m_rank].begin(), + m_recvSize[m_rank].end(), 0); + + m_send = Array(m_totSendSize[m_rank]); + m_recv = Array(m_totRecvSize[m_rank]); + + int cnt = 0; + for (auto &interface : m_interfaceTraces) + { + if (m_zones[interface->GetInterface()->GetId()]->GetMoved()) + { + auto missing = interface->GetMissingCoords(); + for (auto coord : missing) + { + // Points are organised in blocks of three + // x coord, then y coord, then z coord. + for (int k = 0; k < 3; ++k, ++cnt) + { + m_send[cnt] = coord[k]; + } + } + } + } + + // Uses non-blocking send/recvs to send missing points to other ranks + m_comm->Isend(m_rank, m_send, m_totSendSize[m_rank], requestSend, + requestNum); + m_comm->Irecv(m_rank, m_recv, m_totRecvSize[m_rank], requestRecv, + requestNum); +} + +/** + * Performs the trace exchange across interfaces + * 1) Calculate and send the Fwd trace to other ranks with pairwise comms + * 2) While waiting for the send/recv to complete we fill the local interfaces + * Bwd trace + * 3) Fill the remaining Bwd trace with the received trace data from other ranks + */ +void InterfaceMapDG::ExchangeTrace(Array &Fwd, + Array &Bwd) +{ + if (m_movement->GetCoordExchangeFlag()) + { + ExchangeCoords(); + } + auto comm = m_trace->GetComm(); + // If no parallel exchange needed we only fill the local traces + if (m_exchange.empty()) + { + + // Fill local interface traces + for (auto &m_localInterface : m_localInterfaces) + { + m_localInterface->FillLocalBwdTrace(Fwd, Bwd); + } + } + else + { + auto requestSend = comm->CreateRequest(m_exchange.size()); + auto requestRecv = comm->CreateRequest(m_exchange.size()); + for (int i = 0; i < m_exchange.size(); ++i) + { + m_exchange[i]->SendFwdTrace(requestSend, requestRecv, i, Fwd); + } + + // Fill local interface traces + for (auto &m_localInterface : m_localInterfaces) + { + m_localInterface->FillLocalBwdTrace(Fwd, Bwd); + } + + comm->WaitAll(requestSend); + comm->WaitAll(requestRecv); + + // Fill communicated interface traces + for (auto &i : m_exchange) + { + i->FillRankBwdTraceExchange(Bwd); + } + } +} + +void InterfaceTrace::FillLocalBwdTrace(Array &Fwd, + Array &Bwd) +{ + // If flagged then fill trace from local coords + if (m_checkLocal) + { + for (auto &foundLocCoord : m_foundLocalCoords) + { + int traceId = m_trace->GetElmtToExpId(foundLocCoord.second.first); + Array locCoord = foundLocCoord.second.second; + + Array edgePhys = + Fwd + m_trace->GetPhys_Offset(traceId); + + Bwd[foundLocCoord.first] = + m_trace->GetExp(traceId)->StdPhysEvaluate(locCoord, edgePhys); + } + } +} + +void InterfaceExchange::FillRankBwdTraceExchange(Array &Bwd) +{ + int cnt = 0; + for (int i = 0; i < m_interfaceTraces.size(); ++i) + { + Array traceTmp(m_sendSize[m_rank][i] / 3, 0.0); + for (int j = 0; j < m_sendSize[m_rank][i] / 3; ++j, ++cnt) + { + traceTmp[j] = m_recvTrace[cnt]; + } + + m_interfaceTraces[i]->FillRankBwdTrace(traceTmp, Bwd); + } +} + +void InterfaceTrace::FillRankBwdTrace(Array &trace, + Array &Bwd) +{ + for (int i = 0; i < m_mapMissingCoordToTrace.size(); ++i) + { + if (!std::isnan(trace[i])) + { + Bwd[m_mapMissingCoordToTrace[i]] = trace[i]; + } + } +} + +void InterfaceExchange::SendFwdTrace( + LibUtilities::CommRequestSharedPtr &requestSend, + LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum, + Array &Fwd) +{ + m_recvTrace = + Array(m_totSendSize[m_rank] / 3, std::nan("")); + m_sendTrace = + Array(m_totRecvSize[m_rank] / 3, std::nan("")); + + for (auto &i : m_foundRankCoords[m_rank]) + { + int traceId = m_trace->GetElmtToExpId(i.second.first); + Array locCoord = i.second.second; + + Array edgePhys = + Fwd + m_trace->GetPhys_Offset(traceId); + + m_sendTrace[i.first] = + m_trace->GetExp(traceId)->StdPhysEvaluate(locCoord, edgePhys); + } + + m_comm->Isend(m_rank, m_sendTrace, m_sendTrace.size(), requestSend, + requestNum); + m_comm->Irecv(m_rank, m_recvTrace, m_recvTrace.size(), requestRecv, + requestNum); +} + +/** + * Check coords in m_recv from other rank to see if present on this rank, and + * then populates m_foundRankCoords if found. + * - Loops over all interface traces present in the exchange, i.e. every + * interface needed on this rank-to-rank communication object + * - Then loops over all the quadrature points missing from the other side in + * that interface using global coordinates + * - Loop over each local edge and use MinMaxCheck on the point as a fast + * comparison on whether the point lies on the edge + * - If true then use the more expensive FindDistance function to find the + * closest local coordinate of the global 'missing' point on the local edge + * and the distance from the edge that corresponds to + * - If distance is less than 5e-5 save found coordinate in m_foundRankCoords + */ + +void InterfaceExchange::CalcRankDistances() +{ + // Clear old found coordinates + auto foundRankCoordsCopy = m_foundRankCoords; + m_foundRankCoords[m_rank] + .clear(); // @TODO: This may cause problems with 2 interfaces and one is + // fixed? With the skip below. + + Array disp(m_recvSize[m_rank].size() + 1, 0.0); + std::partial_sum(m_recvSize[m_rank].begin(), m_recvSize[m_rank].end(), + &disp[1]); + + for (int i = 0; i < m_interfaceTraces.size(); ++i) + { + if (!m_zones[m_interfaceTraces[i]->GetInterface()->GetId()]->GetMoved()) + { + // If zone is not moved then skip + continue; + } + + auto localEdge = m_interfaceTraces[i]->GetInterface()->GetEdge(); + + for (int j = disp[i]; j < disp[i + 1]; j += 3) + { + Array foundLocCoord; + Array xs(3); + xs[0] = m_recv[j]; + xs[1] = m_recv[j + 1]; + xs[2] = m_recv[j + 2]; + + // First search the edge the point was found in last timestep + if (foundRankCoordsCopy[m_rank].find(j / 3) != + foundRankCoordsCopy[m_rank].end()) + { + auto edge = m_interfaceTraces[i]->GetInterface()->GetEdge( + foundRankCoordsCopy[m_rank][j / 3].first); + NekDouble dist = edge->FindDistance(xs, foundLocCoord); + + if (dist < 5e-5) + { + m_foundRankCoords[m_rank][j / 3] = + std::make_pair(edge->GetGlobalID(), foundLocCoord); + continue; + } + } + + for (auto &edge : localEdge) + { + // First check if inside the edge bounding box + if (!edge.second->MinMaxCheck(xs)) + { + continue; + } + + NekDouble dist = edge.second->FindDistance(xs, foundLocCoord); + + if (dist < NekConstants::kFindDistanceMin) + { + m_foundRankCoords[m_rank][j / 3] = std::make_pair( + edge.second->GetGlobalID(), foundLocCoord); + break; + } + } + } + } +} + +} // namespace MultiRegions +} // namespace Nektar \ No newline at end of file diff --git a/library/MultiRegions/AssemblyMap/InterfaceMapDG.h b/library/MultiRegions/AssemblyMap/InterfaceMapDG.h new file mode 100644 index 0000000000000000000000000000000000000000..d59a89f69933f0b0ade816f1347fd8ead701345c --- /dev/null +++ b/library/MultiRegions/AssemblyMap/InterfaceMapDG.h @@ -0,0 +1,274 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// File InterfaceMapDG.h +// +// For more information, please see: http://www.nektar.info +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// 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. +// +// Description: MPI communication for interfaces, header file +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef NEKTAR_INTERFACEMAPDG_H +#define NEKTAR_INTERFACEMAPDG_H + +#include +#include + +namespace Nektar +{ +namespace MultiRegions +{ + +/** + * Object for each interface present between two ranks, which are held in the + * InterfaceExchange object. + */ + +class InterfaceTrace +{ +public: + /// Constructor + MULTI_REGIONS_EXPORT InterfaceTrace( + const ExpListSharedPtr &trace, + const SpatialDomains::InterfaceShPtr &interfaceShPtr); + + /// Default destructor + MULTI_REGIONS_EXPORT virtual ~InterfaceTrace() = default; + + inline void SetCheckLocal(bool flag) + { + m_checkLocal = flag; + } + + /// Returns the missing coordinates vector + inline std::vector> GetMissingCoords() + { + return m_missingCoords; + } + + /// Returns the interface object + SpatialDomains::InterfaceShPtr GetInterface() + { + return m_interface; + } + + /// Calculates what coordinates on the interface are missing locally + void CalcLocalMissing(); + /// Fills the Bwd trace by interpolating from the Fwd for local interfaces + void FillLocalBwdTrace(Array &Fwd, + Array &Bwd); + /// Fills the Bwd trace from partitioned trace + void FillRankBwdTrace(Array &trace, + Array &Bwd); + +private: + /// Trace expansion list + ExpListSharedPtr m_trace; + /// Local interface object + SpatialDomains::InterfaceShPtr m_interface; + /// Flag whether the opposite side of the interface is present locally + bool m_checkLocal = false; + /// Vector of coordinates on interface missing from the other side locally + std::vector> m_missingCoords; + /// Map of found coordinates present locally + std::map>> m_foundLocalCoords; + /// Vector of indices corresponding to m_missingCoord locations in trace + std::vector m_mapMissingCoordToTrace; +}; + +typedef std::shared_ptr InterfaceTraceSharedPtr; + +/** + * Object for one rank-to-rank communication for all interfaces shared + * between those ranks. e.g. if on rank 1 and there are interfaces shared with + * rank 2 and 3, there will be two InterfaceExchange objects in m_exchange in + * InterfaceMapDG. This holds the InterfaceTrace objects in m_interfaceTraces. + */ +class InterfaceExchange +{ +public: + /// Default destructor + MULTI_REGIONS_EXPORT virtual ~InterfaceExchange() = default; + + /// Constructor + MULTI_REGIONS_EXPORT InterfaceExchange( + SpatialDomains::MovementSharedPtr movement, + const ExpListSharedPtr &trace, const LibUtilities::CommSharedPtr &comm, + std::pair> rankPair) + : m_movement(movement), m_zones(movement->GetZones()), m_trace(trace), + m_comm(comm), m_rank(rankPair.first), + m_interfaceTraces(rankPair.second) + { + } + + /** + * Communicates with other ranks how many missing coordinates for each + * interface to expect + * + * @param requestSend List of send requests + * @param requestRecv List of receive requests + * @param requestNum Index of request in list to use + */ + MULTI_REGIONS_EXPORT void RankFillSizes( + LibUtilities::CommRequestSharedPtr &requestSend, + LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum); + + /** + * Sends/receives the missing coordinates to/from other ranks + * + * @param requestSend List of send requests + * @param requestRecv List of receive requests + * @param requestNum Index of request in list to use + */ + MULTI_REGIONS_EXPORT void SendMissing( + LibUtilities::CommRequestSharedPtr &requestSend, + LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum); + + /// Populates m_foundRankCoords using the FindDistance function + MULTI_REGIONS_EXPORT void CalcRankDistances(); + + /** + * Calculates and sends the trace to other rank from the m_foundRankCoords + * structure using non-blocking pairwise communication i.e. Isend & Irecv + * + * @param requestSend List of send requests + * @param requestRecv List of receive requests + * @param requestNum Index of request in list to use + * @param Fwd The values to send across the interface + */ + MULTI_REGIONS_EXPORT void SendFwdTrace( + LibUtilities::CommRequestSharedPtr &requestSend, + LibUtilities::CommRequestSharedPtr &requestRecv, int requestNum, + Array &Fwd); + + /** + * Loops over interfaces and partitions out the received trace from the + * other ranks for insertion into Bwd using FillRankBwdTrace + * + * @param Bwd The Bwd trace to be filled from across the interface + */ + MULTI_REGIONS_EXPORT void FillRankBwdTraceExchange( + Array &Bwd); + +private: + /// Movement object associated with the non-conformal interfaces + SpatialDomains::MovementSharedPtr m_movement; + /// Map of zone IDs to zone bases + std::map m_zones; + /// Trace expansion list + const ExpListSharedPtr m_trace; + /// Communicator + const LibUtilities::CommSharedPtr m_comm; + /// Process rank + int m_rank; + /// Vector of interface traces i.e. every interface side present on m_rank + const std::vector m_interfaceTraces; + /// Send buffer for coord exchange + Array m_send; + /// Receive buffer for coord exchange + Array m_recv; + /// Receive buffer for trace exchange + Array m_recvTrace; + /// Send buffer for trace exchange + Array m_sendTrace; + /// Map of rank to total size of send buffer for all interfaces + std::map m_totSendSize; + /// Map of rank to total size of receive buffer for all interfaces + std::map m_totRecvSize; + /// Map of rank to array of size of send buffer for each interface + std::map> m_sendSize; + /// Map of rank to array of size of receive buffer for each interface + std::map> m_recvSize; + + /** + * Caches the found coordinates to reuse when exchanging the trace in a + * map of integer rank to a map of integer missing coordinate location to a + * pair of local edge ID and found local coordinate + */ + std::map>>> + m_foundRankCoords; +}; + +typedef std::shared_ptr InterfaceExchangeSharedPtr; + +/** + * Implements the communication patterns to allow for exchange of information + * across non-conformal interfaces and across different partitions. Holds all + * the InterfaceExchange objects in m_exchange. + */ +class InterfaceMapDG +{ +public: + /// Default destructor + MULTI_REGIONS_EXPORT ~InterfaceMapDG() = default; + + /** + * Sets up the InterfaceExchange objects stored in m_exchange, each object + * is rank -> rank and contains a vector of InterfaceTrace objects + * corresponding to shared interfaces between those ranks. + */ + MULTI_REGIONS_EXPORT InterfaceMapDG( + const SpatialDomains::MeshGraphSharedPtr &graph, + const ExpListSharedPtr &trace); + + /** + * @brief Perform the trace exchange between processors, given the forwards + * and backwards spaces. + * + * @param Fwd Local forwards space of the trace (which will be sent) + * @param Bwd Local backwards space of the trace (which will receive + * contributions) + */ + MULTI_REGIONS_EXPORT void ExchangeTrace(Array &Fwd, + Array &Bwd); + /** + * @brief Perform the coordinate exchange between processors. This is where + * the missing coordinates on the interface are found and sent to all other + * processors on the other side of that interface so the matching ranks can + * be found. + */ + MULTI_REGIONS_EXPORT void ExchangeCoords(); + +private: + /// Mesh associated with this expansion list. + SpatialDomains::MeshGraphSharedPtr m_graph; + /// Movement object associated with the non-conformal interfaces + SpatialDomains::MovementSharedPtr m_movement; + /// Interface sides present on current process + std::vector m_localInterfaces; + /// Trace expansion list + const ExpListSharedPtr m_trace; + /// Vector of interface exchanges, i.e. every rank-to-rank comm needed + std::vector m_exchange; +}; + +typedef std::shared_ptr InterfaceMapDGSharedPtr; + +} // namespace MultiRegions +} // namespace Nektar + +#endif \ No newline at end of file diff --git a/library/MultiRegions/CMakeLists.txt b/library/MultiRegions/CMakeLists.txt index 67daccb0e6e6b8e1954cb4b4b522f2719b20beb7..790e0cbfafc39eda6689e9f8233dfac522ca7e07 100644 --- a/library/MultiRegions/CMakeLists.txt +++ b/library/MultiRegions/CMakeLists.txt @@ -3,6 +3,7 @@ SET(MULTI_REGIONS_SOURCES ./AssemblyMap/AssemblyMap.cpp ./AssemblyMap/AssemblyMapCG.cpp ./AssemblyMap/AssemblyMapDG.cpp +./AssemblyMap/InterfaceMapDG.cpp ./AssemblyMap/LocTraceToTraceMap.cpp ContField.cpp ContField3DHomogeneous1D.cpp @@ -76,6 +77,7 @@ SET(ASSEMBLY_MAP_HEADERS ./AssemblyMap/AssemblyMap.h ./AssemblyMap/AssemblyMapCG.h ./AssemblyMap/AssemblyMapDG.h +./AssemblyMap/InterfaceMapDG.h ./AssemblyMap/LocTraceToTraceMap.h ) diff --git a/library/MultiRegions/DisContField.cpp b/library/MultiRegions/DisContField.cpp index e08894f27855f78a85e3b2d00335d76de93ea6d0..3b57a136e41355739c665b1d7794316b614e7226 100644 --- a/library/MultiRegions/DisContField.cpp +++ b/library/MultiRegions/DisContField.cpp @@ -213,6 +213,10 @@ void DisContField::SetUpDG(const std::string variable, // Set up physical normals SetUpPhysNormals(); + // Create interface exchange object + m_interfaceMap = + MemoryManager::AllocateSharedPtr(m_graph, m_trace); + int cnt, n; // Identify boundary trace @@ -736,6 +740,7 @@ DisContField::DisContField(const DisContField &In, m_globalBndMat = In.m_globalBndMat; m_trace = In.m_trace; m_traceMap = In.m_traceMap; + m_interfaceMap = In.m_interfaceMap; m_locTraceToTraceMap = In.m_locTraceToTraceMap; m_periodicVerts = In.m_periodicVerts; m_periodicEdges = In.m_periodicEdges; @@ -745,7 +750,7 @@ DisContField::DisContField(const DisContField &In, m_boundaryTraces = In.m_boundaryTraces; m_leftAdjacentTraces = In.m_leftAdjacentTraces; - if (SetUpJustDG == false) + if (!SetUpJustDG) { // set elmt edges to point to robin bc edges if required int i, cnt = 0; @@ -2893,6 +2898,11 @@ void DisContField::v_GetFwdBwdTracePhys( { // Do parallel exchange for forwards/backwards spaces. m_traceMap->GetAssemblyCommDG()->PerformExchange(Fwd, Bwd); + + // Do exchange of interface traces (local and parallel) + // We may have to split this out into separate local and + // parallel for IP method??? + m_interfaceMap->ExchangeTrace(Fwd, Bwd); } } @@ -3063,6 +3073,7 @@ void DisContField::v_ExtractTracePhys( m_locTraceToTraceMap->GetNFwdLocTracePts()); m_locTraceToTraceMap->FwdLocTracesFromField(inarray, tracevals); m_locTraceToTraceMap->InterpLocTracesToTrace(0, tracevals, outarray); + m_traceMap->GetAssemblyCommDG()->PerformExchange(outarray, outarray); } else diff --git a/library/MultiRegions/DisContField.h b/library/MultiRegions/DisContField.h index e345541f05dcc8bfc9fb21187fcab20c231e7078..6f64ff50525910f738fa39f7e27afbe6fa558deb 100644 --- a/library/MultiRegions/DisContField.h +++ b/library/MultiRegions/DisContField.h @@ -37,6 +37,7 @@ #define NEKTAR_LIBS_MULTIREGIONS_DISCONTFIELD1D_H #include +#include #include #include #include @@ -148,6 +149,9 @@ protected: /// condition on the different boundary regions. Array m_bndConditions; + /// Interfaces mapping for trace space. + InterfaceMapDGSharedPtr m_interfaceMap; + /// Global boundary matrix. GlobalLinSysMapShPtr m_globalBndMat; diff --git a/library/MultiRegions/ExpList.cpp b/library/MultiRegions/ExpList.cpp index ea3d8838fdbbb16d9e29967bc5ca4c125d5e9a8a..5bf104168d3be20444b8677a5bb04cc62fd086ce 100644 --- a/library/MultiRegions/ExpList.cpp +++ b/library/MultiRegions/ExpList.cpp @@ -126,7 +126,8 @@ ExpList::ExpList(const ExpList &in, const bool DeclareCoeffPhysArrays) m_coll_coeff_offset(in.m_coll_coeff_offset), m_coll_phys_offset(in.m_coll_phys_offset), m_coeff_offset(in.m_coeff_offset), m_phys_offset(in.m_phys_offset), - m_blockMat(in.m_blockMat), m_WaveSpace(false) + m_blockMat(in.m_blockMat), m_WaveSpace(false), + m_elmtToExpId(in.m_elmtToExpId) { // Set up m_coeffs, m_phys and offset arrays. @@ -194,7 +195,7 @@ ExpList::ExpList(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::ExpansionInfoMap &expansions = graph->GetExpansionInfo(var); - // Initialise Expansionn Vector + // Initialise Expansion Vector InitialiseExpVector(expansions); // Setup phys coeff space @@ -754,6 +755,15 @@ ExpList::ExpList( { CreateCollections(ImpType); } + + // Setup element to expansion ID maps for the trace elements + // Loop in reverse order so that in case where using a + // Homogeneous expansion it sets geometry ids to first part of + // m_exp list. Otherwise will set to second (complex) expansion + for (int i = (*m_exp).size() - 1; i >= 0; --i) + { + m_elmtToExpId[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i; + } } /** @@ -1289,7 +1299,8 @@ void ExpList::InitialiseExpVector( "Dimension of basis key is greater than 3"); } - // Assign next id + // Assign next id and fill the global id -> exp id map + m_elmtToExpId[exp->GetGeom()->GetGlobalID()] = id; exp->SetElmtId(id++); // Add the expansion @@ -2675,6 +2686,9 @@ void ExpList::v_Reset() LibUtilities::NekManager::ClearManager(); + // Reset block matrix map + m_blockMat->clear(); + // Loop over all elements and reset geometry information. for (int i = 0; i < m_exp->size(); ++i) { @@ -2687,6 +2701,21 @@ void ExpList::v_Reset() { (*m_exp)[i]->Reset(); } + + CreateCollections(Collections::eNoImpType); // @TODO: Might need to pass in + // correct type here +} + +void ExpList::ResetMatrices() +{ + // Reset matrix managers. + LibUtilities::NekManager::ClearManager(); + LibUtilities::NekManager::ClearManager(); + + // Reset block matrix map + m_blockMat->clear(); } /** diff --git a/library/MultiRegions/ExpList.h b/library/MultiRegions/ExpList.h index 2dec5110da6f9816a681c3bf3f472623b8e3913c..20d5f611947fcfc3ed11359244b9140d07e4f2c2 100644 --- a/library/MultiRegions/ExpList.h +++ b/library/MultiRegions/ExpList.h @@ -51,6 +51,7 @@ #include #include #include +#include #include namespace Nektar @@ -409,6 +410,9 @@ public: v_Reset(); } + /// Reset matrices + MULTI_REGIONS_EXPORT void ResetMatrices(); + void WriteTecplotHeader(std::ostream &outfile, std::string var = "") { v_WriteTecplotHeader(outfile, var); @@ -703,6 +707,11 @@ public: /// expansion of the \f$n^{\mathrm{th}}\f$ element. inline LocalRegions::ExpansionSharedPtr &GetExp(int n) const; + /// This function returns (a shared pointer to) the local elemental + /// expansion of the \f$n^{\mathrm{th}}\f$ element given a global + /// geometry ID. + inline LocalRegions::ExpansionSharedPtr &GetExpFromGeomId(int n); + /// This function returns (a shared pointer to) the local elemental /// expansion containing the arbitrary point given by \a gloCoord. MULTI_REGIONS_EXPORT LocalRegions::ExpansionSharedPtr &GetExp( @@ -1114,8 +1123,26 @@ public: // points otwards from MULTI_REGIONS_EXPORT std::vector &GetLeftAdjacentTraces(void); + /// This function returns the map of index inside m_exp to geom id + MULTI_REGIONS_EXPORT inline const std::unordered_map + &GetElmtToExpId(void) + { + return m_elmtToExpId; + } + + /// This function returns the index inside m_exp for a given geom id + MULTI_REGIONS_EXPORT inline int GetElmtToExpId(int elmtId) + { + auto it = m_elmtToExpId.find(elmtId); + ASSERTL0(it != m_elmtToExpId.end(), "Global geometry ID " + + std::to_string(elmtId) + + " not found in element ID to " + "expansion ID map.") + return it->second; + } + protected: - /// Exapnsion type + /// Expansion type ExpansionType m_expType; std::shared_ptr GenGlobalMatrixFull( @@ -2217,6 +2244,22 @@ inline LocalRegions::ExpansionSharedPtr &ExpList::GetExp(int n) const return (*m_exp)[n]; } +/** + * @param n The global id of the element concerned. + * + * @return (A shared pointer to) the local expansion of the + * \f$n^{\mathrm{th}}\f$ element. + */ +inline LocalRegions::ExpansionSharedPtr &ExpList::GetExpFromGeomId(int n) +{ + auto it = m_elmtToExpId.find(n); + ASSERTL0(it != m_elmtToExpId.end(), "Global geometry ID " + + std::to_string(n) + + " not found in element ID to " + "expansion ID map.") + return (*m_exp)[it->second]; +} + /** * @return (A const shared pointer to) the local expansion vector #m_exp */ diff --git a/library/NekMesh/CMakeLists.txt b/library/NekMesh/CMakeLists.txt index d41b0e6a36b629e60c45af58d424cca6ed673f64..adb3d762b7deb64001c37958d115dec2011cee1e 100644 --- a/library/NekMesh/CMakeLists.txt +++ b/library/NekMesh/CMakeLists.txt @@ -13,6 +13,7 @@ SET(NEKMESH_SOURCES Module/OutputModules/OutputSTL.cpp Module/OutputModules/OutputStdOut.cpp Module/ProcessModules/ProcessBL.cpp + Module/ProcessModules/ProcessCombine.cpp Module/ProcessModules/ProcessCurve.cpp Module/ProcessModules/ProcessCurvedEdges.cpp Module/ProcessModules/ProcessCyl.cpp @@ -71,6 +72,7 @@ SET(NEKMESH_HEADERS Module/OutputModules/OutputSTL.h Module/OutputModules/OutputStdOut.h Module/ProcessModules/ProcessBL.h + Module/ProcessModules/ProcessCombine.h Module/ProcessModules/ProcessCurve.h Module/ProcessModules/ProcessCurvedEdges.h Module/ProcessModules/ProcessCyl.h diff --git a/library/NekMesh/MeshElements/Node.h b/library/NekMesh/MeshElements/Node.h index f9dcfa70f7e78c435b6cdca0b38b643c3f8c895c..dca34b6dbe922d5268cec57493c94f1bab51a6be 100644 --- a/library/NekMesh/MeshElements/Node.h +++ b/library/NekMesh/MeshElements/Node.h @@ -452,12 +452,18 @@ NEKMESH_EXPORT bool IsNodeClose( */ struct NodeHash : std::unary_function { + + // @TODO: Way of fixing this so it doesn't delete coincident nodes for + // non-conformal grids std::size_t operator()(NodeSharedPtr const &p) const { return hash_combine(p->m_x, p->m_y, p->m_z); } }; -typedef std::unordered_set NodeSet; + +// @TODO: Fixed by just hashing based on memory address, I feel like we +// shouldn't just delete vertices anyway... +typedef std::unordered_set NodeSet; } // namespace NekMesh } // namespace Nektar diff --git a/library/NekMesh/Module/InputModules/InputNekpp.cpp b/library/NekMesh/Module/InputModules/InputNekpp.cpp index b0a4f3211e50e94125dd8ec626fab327663e6b3d..6e378bcf8b9c4a9d6521b359ceb96b0fcfe7ade3 100644 --- a/library/NekMesh/Module/InputModules/InputNekpp.cpp +++ b/library/NekMesh/Module/InputModules/InputNekpp.cpp @@ -74,9 +74,13 @@ void InputNekpp::Process() m_log(VERBOSE) << "Reading Nektar++ XML file '" << filename[0] << "'" << endl; + LibUtilities::CommSharedPtr pComm = + m_mesh->m_comm ? m_mesh->m_comm : LibUtilities::CommSharedPtr(); + char *prgname = const_cast("NekMesh"); LibUtilities::SessionReaderSharedPtr pSession = - LibUtilities::SessionReader::CreateInstance(1, &prgname, filename); + LibUtilities::SessionReader::CreateInstance(1, &prgname, filename, + pComm); SpatialDomains::MeshGraphSharedPtr graph = SpatialDomains::MeshGraph::Read(pSession); diff --git a/library/NekMesh/Module/OutputModules/OutputNekpp.cpp b/library/NekMesh/Module/OutputModules/OutputNekpp.cpp index 799e7addf6ad9ea11d52703bf2b4956f95f96276..f930ffb4ff9eda6eceb7e9fc297f781b1fb0a44f 100644 --- a/library/NekMesh/Module/OutputModules/OutputNekpp.cpp +++ b/library/NekMesh/Module/OutputModules/OutputNekpp.cpp @@ -782,14 +782,19 @@ void OutputNekpp::TransferComposites(MeshGraphSharedPtr graph) } } +// @TODO: We currently lose domain information from input file here. This +// assumes +// every composite that is of expansion dimension is a separate domain +// and sequentially numbered. So junks multi-composite domains & IDs. void OutputNekpp::TransferDomain(MeshGraphSharedPtr graph) { - map &domain = graph->GetDomain(); - - string list; + std::map &domain = graph->GetDomain(); + int cnt = 0; for (auto &it : m_mesh->m_composite) { + + string list; if (it.second->m_items[0]->GetDim() == m_mesh->m_expDim) { if (list.length() > 0) @@ -797,12 +802,12 @@ void OutputNekpp::TransferDomain(MeshGraphSharedPtr graph) list += ","; } list += boost::lexical_cast(it.second->m_id); + + SpatialDomains::CompositeMap fullDomain; + graph->GetCompositeList(list, fullDomain); + domain[cnt++] = fullDomain; } } - - SpatialDomains::CompositeMap fullDomain; - graph->GetCompositeList(list, fullDomain); - domain[0] = fullDomain; } } // namespace NekMesh diff --git a/library/NekMesh/Module/ProcessModules/ProcessCombine.cpp b/library/NekMesh/Module/ProcessModules/ProcessCombine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d97ffb953271b927cb4d1914cb02ed5e5a7a21cc --- /dev/null +++ b/library/NekMesh/Module/ProcessModules/ProcessCombine.cpp @@ -0,0 +1,329 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: ProcessCombine.cpp +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// 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. +// +// Description: Combine two mesh files into one output file. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "ProcessCombine.h" +#include +#include +#include +#include + +using namespace std; +using namespace Nektar::NekMesh; + +namespace Nektar +{ +namespace NekMesh +{ + +ModuleKey ProcessCombine::className = + GetModuleFactory().RegisterCreatorFunction( + ModuleKey(eProcessModule, "combine"), ProcessCombine::create, + "Combine two mesh files into one output file."); + +ProcessCombine::ProcessCombine(MeshSharedPtr m) : ProcessModule(m) +{ + m_config["file"] = ConfigOption( + false, "", "Second mesh file to be combined with the input mesh file."); +} + +ProcessCombine::~ProcessCombine() +{ +} + +void ProcessCombine::Process() +{ + ASSERTL0(m_config["file"].beenSet, + "The 'file' module parameter must be set.") + + std::string fname = m_config["file"].as(); + + // Check to see if filename exists. + if (!boost::filesystem::exists(fname)) + { + m_log(FATAL) << "Unable to read file: '" << fname << "'" << std::endl; + } + + // Process the second mesh input + ModuleKey module; + module.first = eInputModule; + + vector tmp1; + boost::split(tmp1, fname, boost::is_any_of(":")); + if (tmp1.size() == 1) + { + int dot = tmp1[0].find_last_of('.') + 1; + string ext = tmp1[0].substr(dot, tmp1[0].length() - dot); + + if (ext == "gz") + { + string tmp = tmp1[0].substr(0, tmp1[0].length() - 3); + dot = tmp.find_last_of('.') + 1; + ext = tmp.substr(dot, tmp.length() - dot); + } + + module.second = ext; + tmp1.push_back("infile=" + tmp1[0]); + } + else + { + module.second = tmp1[1]; + tmp1.push_back("infile=" + tmp1[0]); + } + + // Copy communicator + MeshSharedPtr mesh = std::make_shared(); + mesh->m_comm = m_mesh->m_comm; + + ModuleSharedPtr mod = GetModuleFactory().CreateInstance(module, mesh); + mod->SetLogger(m_log); + mod->GetLogger().SetPrefix("ProcessCombine"); + + // Set options for this module. + for (int j = 1; j < tmp1.size(); ++j) + { + vector tmp2; + boost::split(tmp2, tmp1[j], boost::is_any_of("=")); + + if (tmp2.size() == 1) + { + mod->RegisterConfig(tmp2[0]); + } + else if (tmp2.size() == 2) + { + mod->RegisterConfig(tmp2[0], tmp2[1]); + } + else + { + NEKERROR(ErrorUtil::efatal, "ERROR: Invalid module configuration: " + "format is either :arg or :arg=val"); + } + } + + // Ensure configuration options have been set. + mod->SetDefaults(); + + // Run second input module + mod->Process(); + MeshSharedPtr mesh2 = mod->GetMesh(); + + // Check dimensions of both meshes are the same + ASSERTL0(m_mesh->m_expDim == mesh2->m_expDim, + "The expansion dimensions of the meshes being combined must be " + "the same.") + + // Renumber vertices and copy in to m_vertexSet + int vid = m_mesh->m_vertexSet.size(); + for (auto &elmt : mesh2->m_element[m_mesh->m_expDim]) + { + for (int j = 0; j < elmt->GetVertexCount(); ++j) + { + pair testIns = + m_mesh->m_vertexSet.insert(elmt->GetVertex(j)); + + if (testIns.second) + { + (*testIns.first)->m_id = vid++; + } + + elmt->SetVertex(j, *testIns.first); + } + } + + // Renumber edges and copy in to m_edgeSet + int eid = m_mesh->m_edgeSet.size(); + for (auto &elmt : mesh2->m_element[m_mesh->m_expDim]) + { + for (int j = 0; j < elmt->GetEdgeCount(); ++j) + { + EdgeSharedPtr ed = elmt->GetEdge(j); + pair testIns = + m_mesh->m_edgeSet.insert(ed); + + if (testIns.second) + { + EdgeSharedPtr ed2 = *testIns.first; + ed2->m_id = eid++; + // ed2->m_elLink.push_back( + // pair(elmt, j)); + } + else + { + EdgeSharedPtr e2 = *(testIns.first); + elmt->SetEdge(j, e2); + if (e2->m_edgeNodes.size() == 0 && ed->m_edgeNodes.size() > 0) + { + e2->m_curveType = ed->m_curveType; + e2->m_edgeNodes = ed->m_edgeNodes; + + // Reverse nodes if appropriate. + if (e2->m_n1->m_id != ed->m_n1->m_id) + { + reverse(e2->m_edgeNodes.begin(), e2->m_edgeNodes.end()); + } + } + + // if (ed->m_parentCAD) + //{ + // e2->m_parentCAD = ed->m_parentCAD; + //} + + // Update edge to element map. + // e2->m_elLink.push_back( + // pair(elmt, j)); + } + + elmt->SetEdge(j, *testIns.first); + } + } + + // @TODO: Create links for 1D elements? + + // Renumber faces and copy in to m_faceSet + int fid = m_mesh->m_faceSet.size(); + for (auto &elmt : mesh2->m_element[m_mesh->m_expDim]) + { + for (int j = 0; j < elmt->GetFaceCount(); ++j) + { + pair testIns = + m_mesh->m_faceSet.insert(elmt->GetFace(j)); + + if (testIns.second) + { + (*(testIns.first))->m_id = fid++; + // Update face to element map. + //(*(testIns.first))->m_elLink.push_back( + // pair(elmt,j)); + } + else + { + // Update face to element map. + //(*(testIns.first))->m_elLink.push_back( + // pair(elmt,j)); + } + + elmt->SetFace(j, *testIns.first); + } + } + + // @TODO: Create links for 2D elements? + + // Renumber elements and copy in to m_element + auto &elmts = mesh2->m_element; + for (int d = 0; d < 4; ++d) + { + int numEl = m_mesh->m_element[d].size(); + auto elVec = elmts[d]; + for (auto &el : elVec) + { + el->SetId(numEl++); + m_mesh->m_element[d].emplace_back(el); + } + } + + // Renumber composites and copy in to m_composite + std::map compRenumber; + for (int d = 0; d <= m_mesh->m_expDim; ++d) + { + vector &elmt = m_mesh->m_element[d]; + for (int i = elmt.size() - mesh2->m_element[d].size(); i < elmt.size(); + ++i) // for number of elements added by mesh 2 + { + CompositeMap::iterator it; + unsigned int tagid = elmt[i]->GetTagList()[0]; + + auto findKey = compRenumber.find(elmt[i]->GetTagList()[0]); + if (findKey != compRenumber.end()) + { + tagid = findKey->second; + } + else + { + // Checks if composite tag is already defined in mesh 1 + while (m_mesh->m_composite.find(tagid) != + m_mesh->m_composite.end()) + { + tagid++; + // Checks if trying to replace the tag with a tag already + // defined in mesh 2 + if (mesh2->m_composite.find(tagid) != + mesh2->m_composite.end()) + { + tagid++; + } + } + + compRenumber[elmt[i]->GetTagList()[0]] = tagid; + } + + it = m_mesh->m_composite.find(tagid); + if (it == m_mesh->m_composite.end()) + { + CompositeSharedPtr tmp = + std::shared_ptr(new Composite()); + pair testIns; + tmp->m_id = tagid; + tmp->m_tag = elmt[i]->GetTag(); + if (mesh2->m_faceLabels.count(tmp->m_id) != 0) + { + tmp->m_label = mesh2->m_faceLabels[tmp->m_id]; + } + + testIns = m_mesh->m_composite.insert( + pair(tagid, tmp)); + it = testIns.first; + } + + elmt[i]->GetTagList()[0] = tagid; + it->second->m_items.push_back(elmt[i]); + } + } + + if (!compRenumber.empty()) + { + m_log << "Duplicate composite IDs from mesh 1 detected in mesh 2." + << endl; + m_log << "These will be remapped in the output file to:" << endl; + + for (auto &cIt : compRenumber) + { + if (cIt.first != cIt.second) + { + m_log << "- C[" << cIt.first << "] => " + << "C[" << cIt.second << "]" << endl; + } + } + } +} +} // namespace NekMesh +} // namespace Nektar diff --git a/library/NekMesh/Module/ProcessModules/ProcessCombine.h b/library/NekMesh/Module/ProcessModules/ProcessCombine.h new file mode 100644 index 0000000000000000000000000000000000000000..2535f617bfab9c01ef26250f4f00ce370e3e958a --- /dev/null +++ b/library/NekMesh/Module/ProcessModules/ProcessCombine.h @@ -0,0 +1,75 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: ProcessCombine.h +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// 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. +// +// Description: Combine two mesh files into one output file. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTILITIES_NEKMESH_PROCESSCombine +#define UTILITIES_NEKMESH_PROCESSCombine + +#include + +namespace Nektar +{ +namespace NekMesh +{ + +/** + * @brief This processing module calculates the Jacobian of elements + * using %SpatialDomains::GeomFactors and the %Element::GetGeom + * method. For now it simply prints a list of elements which have + * negative Jacobian. + */ +class ProcessCombine : public NekMesh::ProcessModule +{ +public: + /// Creates an instance of this class + static std::shared_ptr create(NekMesh::MeshSharedPtr m) + { + return MemoryManager::AllocateSharedPtr(m); + } + static NekMesh::ModuleKey className; + + ProcessCombine(NekMesh::MeshSharedPtr m); + virtual ~ProcessCombine(); + + /// Write mesh to output file. + void Process() override; + + std::string GetModuleName() override + { + return "ProcessCombine"; + } +}; +} // namespace NekMesh +} // namespace Nektar + +#endif diff --git a/library/SolverUtils/ALEHelper.cpp b/library/SolverUtils/ALEHelper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6491c6ae056f8fc42203d50825daa95e3822520e --- /dev/null +++ b/library/SolverUtils/ALEHelper.cpp @@ -0,0 +1,429 @@ +#include "ALEHelper.h" +#include +#include + +namespace Nektar +{ + +namespace SolverUtils +{ + +void ALEHelper::InitObject(int spaceDim, + Array &fields) +{ + m_spaceDim = spaceDim; + m_fieldsALE = fields; + + // Initialise grid velocities as 0s + m_gridVelocity = Array>(m_spaceDim); + m_gridVelocityTrace = Array>(m_spaceDim); + for (int i = 0; i < spaceDim; ++i) + { + m_gridVelocity[i] = + Array(fields[0]->GetTotPoints(), 0.0); + m_gridVelocityTrace[i] = + Array(fields[0]->GetTrace()->GetTotPoints(), 0.0); + } + + // Create ALE objects for each interface zone + if (fields[0]->GetGraph() != + nullptr) // homogeneous graphs are missing the graph data + { + for (auto &zone : fields[0]->GetGraph()->GetMovement()->GetZones()) + { + switch (zone.second->GetMovementType()) + { + case SpatialDomains::MovementType::eFixed: + m_ALEs.emplace_back(ALEFixedShPtr( + MemoryManager::AllocateSharedPtr( + zone.second))); + break; + case SpatialDomains::MovementType::eTranslate: + m_ALEs.emplace_back(ALETranslateShPtr( + MemoryManager::AllocateSharedPtr( + zone.second))); + m_ALESolver = true; + break; + case SpatialDomains::MovementType::eRotate: + m_ALEs.emplace_back(ALERotateShPtr( + MemoryManager::AllocateSharedPtr( + zone.second))); + m_ALESolver = true; + break; + case SpatialDomains::MovementType::ePrescribe: + m_ALEs.emplace_back(ALEPrescribeShPtr( + MemoryManager::AllocateSharedPtr( + zone.second))); + m_ALESolver = true; + break; + case SpatialDomains::MovementType::eNone: + WARNINGL0(false, + "Zone cannot have movement type of 'None'.") + } + } + } + + // Update grid velocity + UpdateGridVelocity(0); +} + +void ALEHelper::UpdateGridVelocity(const NekDouble &time) +{ + // Reset grid velocity to 0 + for (int i = 0; i < m_spaceDim; ++i) + { + std::fill(m_gridVelocity[i].begin(), m_gridVelocity[i].end(), 0.0); + } + + // Now update for each movement zone, adding the grid velocities + for (auto &ALE : m_ALEs) + { + ALE->UpdateGridVel(time, m_fieldsALE, m_gridVelocity); + } +} + +void ALEHelper::ALEPreMultiplyMass(Array> &fields) +{ + const int nm = m_fieldsALE[0]->GetNcoeffs(); + MultiRegions::GlobalMatrixKey mkey(StdRegions::eMass); + + // Premultiply each field by the mass matrix + for (int i = 0; i < m_fieldsALE.size(); ++i) + { + fields[i] = Array(nm); + m_fieldsALE[i]->GeneralMatrixOp(mkey, m_fieldsALE[i]->GetCoeffs(), + fields[i]); + } +} + +void ALEHelper::ALEDoElmtInvMass( + Array> &traceNormals, + Array> &fields, NekDouble time) +{ + boost::ignore_unused(time, traceNormals); + // Update m_fields with u^n by multiplying by inverse mass + // matrix. That's then used in e.g. checkpoint output and L^2 error + // calculation. + + // @TODO: Look at geometric factor and junk only what is needed + // @TODO: Look at collections and see if they offer a speed up + for (int i = 0; i < m_fieldsALE.size(); ++i) + { + m_fieldsALE[i]->MultiplyByElmtInvMass( + fields[i], + m_fieldsALE[i]->UpdateCoeffs()); // @TODO: Potentially matrix free? + m_fieldsALE[i]->BwdTrans(m_fieldsALE[i]->GetCoeffs(), + m_fieldsALE[i]->UpdatePhys()); + } +} + +void ALEHelper::ALEDoElmtInvMassBwdTrans( + const Array> &inarray, + Array> &outarray) +{ + const int nc = m_fieldsALE[0]->GetNcoeffs(); + int nVariables = inarray.size(); + + // General idea is that we are time-integrating the quantity (Mu), so we + // need to multiply input by inverse mass matrix to get coefficients u, + // and then backwards transform to physical space so we can apply the DG + // operator. + Array tmp(nc); + for (int i = 0; i < nVariables; ++i) + { + outarray[i] = Array(m_fieldsALE[0]->GetNpoints()); + m_fieldsALE[i]->MultiplyByElmtInvMass(inarray[i], tmp); + m_fieldsALE[i]->BwdTrans(tmp, outarray[i]); + } +} + +void ALEHelper::MoveMesh(const NekDouble &time, + Array> &traceNormals) +{ + // Only move if timestepped + if (time == m_prevStageTime) + { + return; + } + + auto curvedEdges = m_fieldsALE[0]->GetGraph()->GetCurvedEdges(); + auto curvedFaces = m_fieldsALE[0]->GetGraph()->GetCurvedFaces(); + + LibUtilities::Timer timer; + timer.Start(); + m_fieldsALE[0]->GetGraph()->GetMovement()->PerformMovement( + time); // @TODO: Moved out of loop! + timer.Stop(); + timer.AccumulateRegion("Movement::PerformMovement"); + + // The order of the resets below is v important to avoid errors + for (auto &field : m_fieldsALE) + { + field->ResetMatrices(); + } + + // Loop over all elements and faces and edges and reset geometry + // information. Only need to do this on the first field as the geometry + // information is shared. + for (auto &zone : m_fieldsALE[0]->GetGraph()->GetMovement()->GetZones()) + { + if (zone.second->GetMoved()) + { + auto conEl = zone.second->GetConstituentElements(); + for (const auto &i : conEl) + { + for (const auto &j : i) + { + j->ResetNonRecursive(curvedEdges, curvedFaces); + } + } + + // We need to rebuild geometric factors on the trace elements + for (const auto &i : conEl[m_fieldsALE[0]->GetShapeDimension() - + 1]) // This only takes the trace elements + { + m_fieldsALE[0]->GetTrace()->GetExpFromGeomId(i->GetGlobalID()) + ->Reset(); + } + } + } + + for (auto &field : m_fieldsALE) + { + for (auto &zone : field->GetGraph()->GetMovement()->GetZones()) + { + if (zone.second->GetMoved()) + { + auto conEl = zone.second->GetConstituentElements(); + // Loop over zone elements expansions and rebuild geometric + // factors + for (const auto &i : + conEl[0]) // This only takes highest dimensioned elements + { + field->GetExpFromGeomId(i->GetGlobalID())->Reset(); + } + } + } + } + + for (auto &zone : m_fieldsALE[0]->GetGraph()->GetMovement()->GetZones()) + { + if (zone.second->GetMoved()) + { + auto conEl = zone.second->GetConstituentElements(); + // Loop over zone elements expansions and rebuild geometric factors + // and recalc trace normals + for (const auto &i : + conEl[0]) // This only takes highest dimensioned elements + { + for (int j = 0; j < m_fieldsALE[0] + ->GetExpFromGeomId(i->GetGlobalID()) + ->GetNtraces(); + ++j) + { + m_fieldsALE[0] + ->GetExpFromGeomId(i->GetGlobalID()) + ->ComputeTraceNormal(j); + } + } + } + } + + for (auto &field : m_fieldsALE) + { + // Reset collections (despite the default being eNoCollection it does + // remember the last auto-tuned values), eNoImpType gives lots of output + field->CreateCollections(Collections::eNoCollection); + } + + // Reload new trace normals in to the solver cache + m_fieldsALE[0]->GetTrace()->GetNormals(traceNormals); + + // Recompute grid velocity. + UpdateGridVelocity(time); + + // Updates trace grid velocity + for (int i = 0; i < m_gridVelocityTrace.size(); ++i) + { + m_fieldsALE[0]->ExtractTracePhys(m_gridVelocity[i], + m_gridVelocityTrace[i]); + } + + // Set the flag to exchange coords in InterfaceMapDG to true + m_fieldsALE[0]->GetGraph()->GetMovement()->GetCoordExchangeFlag() = true; + + m_prevStageTime = time; +} + +const Array> + &ALEHelper::GetGridVelocityTrace() +{ + return m_gridVelocityTrace; +} + +ALEFixed::ALEFixed(SpatialDomains::ZoneBaseShPtr zone) + : m_zone(std::static_pointer_cast(zone)) +{ +} + +void ALEFixed::v_UpdateGridVel( + NekDouble time, Array &fields, + Array> &gridVelocity) +{ + boost::ignore_unused(time, fields, gridVelocity); +} + +ALETranslate::ALETranslate(SpatialDomains::ZoneBaseShPtr zone) + : m_zone(std::static_pointer_cast(zone)) +{ +} + +void ALETranslate::v_UpdateGridVel( + NekDouble time, Array &fields, + Array> &gridVelocity) +{ + boost::ignore_unused(time); + + auto vel = m_zone->GetVel(time); + auto exp = fields[0]->GetExp(); + + auto elements = m_zone->GetElements(); + for (auto &el : elements) + { + int indx = fields[0]->GetElmtToExpId(el->GetGlobalID()); + int offset = fields[0]->GetPhys_Offset(indx); + auto expansion = (*exp)[indx]; + + int nq = expansion->GetTotPoints(); + for (int i = 0; i < nq; ++i) + { + for (int j = 0; j < gridVelocity.size(); ++j) + { + gridVelocity[j][offset + i] += vel[j]; + } + } + } +} + +ALERotate::ALERotate(SpatialDomains::ZoneBaseShPtr zone) + : m_zone(std::static_pointer_cast(zone)) +{ +} + +void ALERotate::v_UpdateGridVel( + NekDouble time, Array &fields, + Array> &gridVelocity) +{ + boost::ignore_unused(time, fields, gridVelocity); + + auto angVel = m_zone->GetAngularVel(time); + auto axis = m_zone->GetAxis(); + auto origin = m_zone->GetOrigin(); + + auto exp = fields[0]->GetExp(); + + auto elements = m_zone->GetElements(); + for (auto &el : elements) + { + int indx = fields[0]->GetElmtToExpId(el->GetGlobalID()); + int offset = fields[0]->GetPhys_Offset(indx); + auto expansion = (*exp)[indx]; + + int nq = expansion->GetTotPoints(); + + Array xc(nq, 0.0), yc(nq, 0.0), zc(nq, 0.0); + expansion->GetCoords(xc, yc, zc); + for (int i = 0; i < nq; ++i) + { + // Vector from origin to point + DNekVec pointMinOrigin = {xc[i] - origin(0), yc[i] - origin(1), + zc[i] - origin(2)}; + + // Vector orthogonal to plane formed by axis and point + DNekVec norm = pointMinOrigin.Cross(axis); + // We negate here as by convention a positive angular velocity is + // counter-clockwise + norm = norm * -angVel; + + for (int j = 0; j < gridVelocity.size(); ++j) + { + gridVelocity[j][offset + i] = norm[j]; + } + } + } +} + +ALEPrescribe::ALEPrescribe(SpatialDomains::ZoneBaseShPtr zone) + : m_zone(std::static_pointer_cast(zone)) +{ + auto elements = zone->GetElements(); + for (auto &el : zone->GetElements()) + { + for (int j = 0; j < 4; ++j) + { + Array coords(3); + el->GetVertex(j)->GetCoords(coords); + m_coords[el->GetGlobalID()][j] = coords; + } + } +} + +void ALEPrescribe::v_UpdateGridVel( + NekDouble time, Array &fields, + Array> &gridVelocity) +{ + boost::ignore_unused(time, fields, gridVelocity); + + auto exp = fields[0]->GetExp(); + auto elements = m_zone->GetElements(); + for (auto &el : elements) + { + int indx = fields[0]->GetElmtToExpId(el->GetGlobalID()); + int offset = fields[0]->GetPhys_Offset(indx); + auto expansion = (*exp)[indx]; + + LibUtilities::BasisKey bkeyx(expansion->GetBasis(0)->GetBasisType(), 2, + expansion->GetBasis(0)->GetPointsKey()); + LibUtilities::BasisKey bkeyy(expansion->GetBasis(1)->GetBasisType(), 2, + expansion->GetBasis(1)->GetPointsKey()); + StdRegions::StdQuadExp stdexp(bkeyx, bkeyy); + + // Grid velocity of each quadrilateral vertex. + Array tmpx(4), tmpy(4); + for (int j = 0; j < 4; ++j) + { + auto vert = expansion->GetGeom()->GetVertex(j); + Array coords = m_coords[el->GetGlobalID()][j]; + // x/y velocity for each vertex + /*tmpx[j] = 0.5 * 2 * M_PI / 7.07106781187 * + cos(2 * M_PI * time / 7.07106781187) * + sin(2 * M_PI * coords[0] / 20) * + sin(2 * M_PI * coords[1] / 20); + tmpy[j] = 0.5 * 2 * M_PI / 7.07106781187 * + cos(2 * M_PI * time / 7.07106781187) * + sin(2 * M_PI * coords[0] / 20) * + sin(2 * M_PI * coords[1] / 20);*/ + + tmpx[j] = 0.5 * 2 * M_PI / sqrt(50) * cos(2 * M_PI * time / sqrt(50)) * + sin(2 * M_PI * vert->x() / 20) * + sin(2 * M_PI * vert->y() / 20); + tmpy[j] = 0.5 * 2 * M_PI / sqrt(50) * cos(2 * M_PI * time / sqrt(50)) * + sin(2 * M_PI * vert->x() / 20) * + sin(2 * M_PI * vert->y() / 20); + } + + // swap to match tensor product order of coefficients + // vs. anti-clockwise order of vertices. + std::swap(tmpx[2], tmpx[3]); + std::swap(tmpy[2], tmpy[3]); + + // Evaluate at all points in the deformed (time t) high-order + // element. + Array tmp; + stdexp.BwdTrans(tmpx, tmp = gridVelocity[0] + offset); + stdexp.BwdTrans(tmpy, tmp = gridVelocity[1] + offset); + } +} + +} // namespace SolverUtils +} // namespace Nektar \ No newline at end of file diff --git a/library/SolverUtils/ALEHelper.h b/library/SolverUtils/ALEHelper.h new file mode 100644 index 0000000000000000000000000000000000000000..895555a295b5f2fa0876dbbfe410603a0889a7da --- /dev/null +++ b/library/SolverUtils/ALEHelper.h @@ -0,0 +1,133 @@ +#ifndef NEKTAR_ALEHELPER_H +#define NEKTAR_ALEHELPER_H + +#include + +namespace Nektar +{ + +namespace SolverUtils +{ + +struct ALEBase; +typedef std::shared_ptr ALEBaseShPtr; + +class ALEHelper +{ +public: + void InitObject(int spaceDim, + Array &fields); + + void UpdateGridVelocity(const NekDouble &time); + + void ALEPreMultiplyMass(Array> &fields); + + void ALEDoElmtInvMass(Array> &traceNormals, + Array> &fields, + NekDouble time); + + void ALEDoElmtInvMassBwdTrans( + const Array> &inarray, + Array> &outarray); + + void MoveMesh(const NekDouble &time, + Array> &traceNormals); + + inline const Array> &GetGridVelocity() + { + return m_gridVelocity; + } + + const Array> &GetGridVelocityTrace(); + +protected: + Array m_fieldsALE; + Array> m_gridVelocity; + Array> m_gridVelocityTrace; + std::vector m_ALEs; + bool m_ALESolver = false; + NekDouble m_prevStageTime = 0.0; + int m_spaceDim; +}; + +struct ALEBase +{ + virtual ~ALEBase() = default; + + inline void UpdateGridVel( + const NekDouble time, + Array &fields, + Array> &gridVelocity) + { + v_UpdateGridVel(time, fields, gridVelocity); + } + +private: + virtual void v_UpdateGridVel( + const NekDouble time, + Array &fields, + Array> &gridVelocity) = 0; +}; + +struct ALEFixed final : public ALEBase +{ + ALEFixed(SpatialDomains::ZoneBaseShPtr zone); + + virtual void v_UpdateGridVel( + const NekDouble time, + Array &fields, + Array> &gridVelocity) final; + +private: + SpatialDomains::ZoneFixedShPtr m_zone; +}; + +struct ALETranslate final : public ALEBase +{ + ALETranslate(SpatialDomains::ZoneBaseShPtr zone); + + virtual void v_UpdateGridVel( + const NekDouble time, + Array &fields, + Array> &gridVelocity) final; + +private: + SpatialDomains::ZoneTranslateShPtr m_zone; +}; + +struct ALERotate final : public ALEBase +{ + ALERotate(SpatialDomains::ZoneBaseShPtr zone); + + virtual void v_UpdateGridVel( + const NekDouble time, + Array &fields, + Array> &gridVelocity) final; + +private: + SpatialDomains::ZoneRotateShPtr m_zone; +}; + +struct ALEPrescribe final : public ALEBase +{ + ALEPrescribe(SpatialDomains::ZoneBaseShPtr zone); + + virtual void v_UpdateGridVel( + const NekDouble time, + Array &fields, + Array> &gridVelocity) final; + +private: + SpatialDomains::ZonePrescribeShPtr m_zone; + std::map>> m_coords; +}; + +typedef std::shared_ptr ALEFixedShPtr; +typedef std::shared_ptr ALETranslateShPtr; +typedef std::shared_ptr ALERotateShPtr; +typedef std::shared_ptr ALEPrescribeShPtr; + +} // namespace SolverUtils + +} // namespace Nektar +#endif // NEKTAR_ALEHELPER_H diff --git a/library/SolverUtils/Advection/AdvectionWeakDG.cpp b/library/SolverUtils/Advection/AdvectionWeakDG.cpp index e12200ebe7af00652861cd6fa4ebf7bc7760baa1..a5856b2ca23633cd68e61de51175f223c0ea0672 100644 --- a/library/SolverUtils/Advection/AdvectionWeakDG.cpp +++ b/library/SolverUtils/Advection/AdvectionWeakDG.cpp @@ -104,16 +104,26 @@ void AdvectionWeakDG::v_Advect( timer.Stop(); timer.AccumulateRegion("AdvWeakDG:v_AdvectCoeffs", 2); + // Multiply by inverse mass matrix + LibUtilities::Timer timer2; + for (int i = 0; i < nConvectiveFields; ++i) + { + timer2.Start(); + fields[i]->MultiplyByElmtInvMass(tmp[i], tmp[i]); + timer2.Stop(); + timer2.AccumulateRegion("AdvWeakDG:_MultiplyByElmtInvMass", 1); + } + // why was this broken in many loops over convective fields? // this is terrible for locality - - timer.Start(); + LibUtilities::Timer timer3; + timer3.Start(); for (int i = 0; i < nConvectiveFields; ++i) { fields[i]->BwdTrans(tmp[i], outarray[i]); } - timer.Stop(); - timer.AccumulateRegion("AdvWeakDG:_BwdTrans", 10); + timer3.Stop(); + timer3.AccumulateRegion("AdvWeakDG:_BwdTrans", 1); timer1.Stop(); timer1.AccumulateRegion("AdvWeakDG:All", 10); } @@ -127,6 +137,9 @@ void AdvectionWeakDG::v_AdvectCoeffs( const Array> &pFwd, const Array> &pBwd) { + LibUtilities::Timer timer1; + timer1.Start(); + size_t nPointsTot = fields[0]->GetTotPoints(); size_t nCoeffs = fields[0]->GetNcoeffs(); size_t nTracePointsTot = fields[0]->GetTrace()->GetTotPoints(); @@ -178,13 +191,11 @@ void AdvectionWeakDG::v_AdvectCoeffs( timer.Start(); fields[i]->AddTraceIntegral(numflux[i], outarray[i]); timer.Stop(); - timer.AccumulateRegion("AdvWeakDG:_AddTraceIntegral", 10); - - timer.Start(); - fields[i]->MultiplyByElmtInvMass(outarray[i], outarray[i]); - timer.Stop(); - timer.AccumulateRegion("AdvWeakDG:_MultiplyByElmtInvMass", 10); + timer.AccumulateRegion("AdvWeakDG:_AddTraceIntegral", 1); } + + timer1.Stop(); + timer1.AccumulateRegion("AdvWeakDG: Coeff All"); } void AdvectionWeakDG::v_AdvectTraceFlux( diff --git a/library/SolverUtils/CMakeLists.txt b/library/SolverUtils/CMakeLists.txt index 63d1b03b222c79a3246bb54026ba5a5bd612112b..543904366fabc451112b15ee1529151578a258e9 100644 --- a/library/SolverUtils/CMakeLists.txt +++ b/library/SolverUtils/CMakeLists.txt @@ -4,6 +4,7 @@ SET(SOLVER_UTILS_SOURCES Core/Misc.cpp Core/SessionFunction.cpp AdvectionSystem.cpp + ALEHelper.cpp Advection/Advection.cpp Advection/Advection3DHomogeneous1D.cpp Advection/AdvectionFR.cpp @@ -31,6 +32,7 @@ SET(SOLVER_UTILS_SOURCES Filters/FilterEnergy.cpp Filters/FilterError.cpp Filters/FilterHistoryPoints.cpp + Filters/FilterIntegral.cpp Filters/FilterMean.cpp Filters/FilterModalEnergy.cpp Filters/FilterMovingAverage.cpp @@ -56,6 +58,7 @@ SET(SOLVER_UTILS_HEADERS Core/Misc.h Core/SessionFunction.h AdvectionSystem.h + ALEHelper.h Advection/Advection.h Advection/AdvectionFR.h Advection/Advection3DHomogeneous1D.h @@ -84,6 +87,7 @@ SET(SOLVER_UTILS_HEADERS Filters/FilterError.h Filters/FilterHistoryPoints.h Filters/FilterInterfaces.hpp + Filters/FilterIntegral.h Filters/FilterMean.h Filters/FilterModalEnergy.h Filters/FilterMovingAverage.h diff --git a/library/SolverUtils/Diffusion/Diffusion.h b/library/SolverUtils/Diffusion/Diffusion.h index 10267c4c1199c41249b5ab3fb4ecc6351ff9a0b5..605c1cb00d7a164b0577535f92646a4dae9c5f40 100644 --- a/library/SolverUtils/Diffusion/Diffusion.h +++ b/library/SolverUtils/Diffusion/Diffusion.h @@ -372,6 +372,12 @@ public: std::placeholders::_5, std::placeholders::_6); } + inline void SetGridVelocityTrace( + Array> &gridVelocityTrace) + { + m_gridVelocityTrace = gridVelocityTrace; + } + inline void SetHomoDerivs(Array> &deriv) { v_SetHomoDerivs(deriv); @@ -408,7 +414,7 @@ protected: DiffusionFluxCons m_FunctorDiffusionfluxConsTrace; SpecialBndTreat m_SpecialBndTreat; DiffusionSymmFluxCons m_FunctorSymmetricfluxCons; - + Array> m_gridVelocityTrace; NekDouble m_time = 0.0; SOLVER_UTILS_EXPORT virtual void v_InitObject( diff --git a/library/SolverUtils/Diffusion/DiffusionLDG.cpp b/library/SolverUtils/Diffusion/DiffusionLDG.cpp index b09b96cd3e6fe82418032587c1b13665cfe54f72..371d87e5c11a4127ad7925652208f98e6fa117d6 100644 --- a/library/SolverUtils/Diffusion/DiffusionLDG.cpp +++ b/library/SolverUtils/Diffusion/DiffusionLDG.cpp @@ -92,6 +92,17 @@ void DiffusionLDG::v_Diffuse( DiffusionLDG::v_DiffuseCoeffs(nConvectiveFields, fields, inarray, tmp, pFwd, pBwd); + // Multiply by inverse mass matrix // @TODO: We don't want + // MultiplyByElmtInvMassfor ALE so we moved out of the diffusecoeffs method + LibUtilities::Timer timer; + for (int i = 0; i < nConvectiveFields; ++i) + { + timer.Start(); + fields[i]->MultiplyByElmtInvMass(tmp[i], tmp[i]); + timer.Stop(); + timer.AccumulateRegion("MultiplyByElmtInvMass"); + } + for (std::size_t i = 0; i < nConvectiveFields; ++i) { fields[i]->BwdTrans(tmp[i], outarray[i]); @@ -106,13 +117,17 @@ void DiffusionLDG::v_DiffuseCoeffs( const Array> &pFwd, const Array> &pBwd) { + if (fields[0]->GetGraph()->GetMovement()->GetMoveFlag()) // i.e. if + // m_ALESolver + { + fields[0]->GetTrace()->GetNormals(m_traceNormals); + } + std::size_t nDim = fields[0]->GetCoordim(0); std::size_t nPts = fields[0]->GetTotPoints(); std::size_t nCoeffs = fields[0]->GetNcoeffs(); std::size_t nTracePts = fields[0]->GetTrace()->GetTotPoints(); - Array tmp{nCoeffs}; - TensorOfArray3D qfield{nDim}; for (std::size_t j = 0; j < nDim; ++j) { @@ -146,19 +161,17 @@ void DiffusionLDG::v_DiffuseCoeffs( pBwd); Array> qdbase{nDim}; - for (std::size_t i = 0; i < nConvectiveFields; ++i) { for (std::size_t j = 0; j < nDim; ++j) { qdbase[j] = viscTensor[j][i]; } - fields[i]->IProductWRTDerivBase(qdbase, tmp); + fields[i]->IProductWRTDerivBase(qdbase, outarray[i]); - Vmath::Neg(nCoeffs, tmp, 1); - fields[i]->AddTraceIntegral(traceflux[i], tmp); + Vmath::Neg(nCoeffs, outarray[i], 1); + fields[i]->AddTraceIntegral(traceflux[i], outarray[i]); fields[i]->SetPhysState(false); - fields[i]->MultiplyByElmtInvMass(tmp, outarray[i]); } } @@ -321,7 +334,10 @@ void DiffusionLDG::ApplyScalarBCs( "WallViscous") || boost::iequals( fields[var]->GetBndConditions()[i]->GetUserDefined(), - "WallAdiabatic")) + "WallAdiabatic") || + boost::iequals( + fields[var]->GetBndConditions()[i]->GetUserDefined(), + "WallRotational")) { Vmath::Vcopy(nBndEdgePts, &Fwd[id2], 1, &penaltyflux[id2], 1); } @@ -461,7 +477,10 @@ void DiffusionLDG::ApplyVectorBCs( "WallViscous") || boost::iequals( fields[var]->GetBndConditions()[i]->GetUserDefined(), - "WallAdiabatic")) + "WallAdiabatic") || + boost::iequals( + fields[var]->GetBndConditions()[i]->GetUserDefined(), + "WallRotational")) { Vmath::Zero(nBndEdgePts, &penaltyflux[id2], 1); } diff --git a/library/SolverUtils/DriverStandard.cpp b/library/SolverUtils/DriverStandard.cpp index 618789767c29dc4f6debf6388ff8cc0121e7879e..bdee3ca3c5661a0c74fcb6fc28b1e90865adbebd 100644 --- a/library/SolverUtils/DriverStandard.cpp +++ b/library/SolverUtils/DriverStandard.cpp @@ -75,23 +75,23 @@ void DriverStandard::v_InitObject(ostream &out) void DriverStandard::v_Execute(ostream &out) { - time_t starttime, endtime; + clock_t starttime, endtime; NekDouble CPUtime; m_equ[0]->PrintSummary(out); - time(&starttime); + starttime = clock(); m_equ[0]->DoInitialise(); m_equ[0]->DoSolve(); - time(&endtime); + endtime = clock(); m_equ[0]->Output(); if (m_comm->GetRank() == 0) { - CPUtime = difftime(endtime, starttime); + CPUtime = (endtime - starttime) / NekDouble(CLOCKS_PER_SEC); cout << "-------------------------------------------" << endl; cout << "Total Computation Time = " << CPUtime << "s" << endl; cout << "-------------------------------------------" << endl; diff --git a/library/SolverUtils/EquationSystem.cpp b/library/SolverUtils/EquationSystem.cpp index 307423a65c74adf8da68109d00c15b6a0370c56b..9635c163298708061d9880b6e18ecfe2f18f7b96 100644 --- a/library/SolverUtils/EquationSystem.cpp +++ b/library/SolverUtils/EquationSystem.cpp @@ -594,13 +594,32 @@ void EquationSystem::v_InitObject(bool DeclareFields) } else { - for (i = 0; i < m_fields.size(); i++) + i = 0; + MultiRegions::DisContFieldSharedPtr firstfield; + firstfield = MemoryManager:: + AllocateSharedPtr(m_session, m_graph, + m_session->GetVariable(i)); + m_fields[0] = firstfield; + for (i = 1; i < m_fields.size(); i++) { - m_fields[i] = - MemoryManager:: - AllocateSharedPtr( - m_session, m_graph, - m_session->GetVariable(i)); + if (m_graph->SameExpansionInfo( + m_session->GetVariable(0), + m_session->GetVariable(i))) + { + m_fields[i] = + MemoryManager:: + AllocateSharedPtr( + *firstfield, m_graph, + m_session->GetVariable(i)); + } + else + { + m_fields[i] = + MemoryManager:: + AllocateSharedPtr( + m_session, m_graph, + m_session->GetVariable(i)); + } } } @@ -616,13 +635,32 @@ void EquationSystem::v_InitObject(bool DeclareFields) } else { - for (i = 0; i < m_fields.size(); i++) + i = 0; + MultiRegions::DisContFieldSharedPtr firstfield = + MemoryManager:: + AllocateSharedPtr(m_session, m_graph, + m_session->GetVariable(i)); + m_fields[0] = firstfield; + for (i = 1; i < m_fields.size(); i++) { - m_fields[i] = - MemoryManager:: - AllocateSharedPtr( - m_session, m_graph, - m_session->GetVariable(i)); + if (m_graph->SameExpansionInfo( + m_session->GetVariable(0), + m_session->GetVariable(i))) + { + m_fields[i] = + MemoryManager:: + AllocateSharedPtr( + *firstfield, m_graph, + m_session->GetVariable(i)); + } + else + { + m_fields[i] = + MemoryManager:: + AllocateSharedPtr( + m_session, m_graph, + m_session->GetVariable(i)); + } } } break; @@ -1454,6 +1492,24 @@ void EquationSystem::SessionSummary(SummaryList &s) "Mixed Continuous Galerkin and Discontinuous"); } + if (m_session->DefinesSolverInfo("DiffusionType")) + { + std::string DiffusionType; + DiffusionType = m_session->GetSolverInfo("DiffusionType"); + AddSummaryItem( + s, "Diffusion Type", + GetDiffusionFactory().GetClassDescription(DiffusionType)); + } + else if (m_projectionType == MultiRegions::eDiscontinuous) + { + AddSummaryItem(s, "Projection Type", "Discontinuous Galerkin"); + } + else if (m_projectionType == MultiRegions::eMixed_CG_Discontinuous) + { + AddSummaryItem(s, "Projection Type", + "Mixed Continuous Galerkin and Discontinuous"); + } + if (m_session->DefinesSolverInfo("DiffusionType")) { std::string DiffusionType; diff --git a/library/SolverUtils/Filters/FilterError.cpp b/library/SolverUtils/Filters/FilterError.cpp index bd5ffca8478690f76579fa5b2a1199806ce13fb3..2c084d0e274ca502dbd3ddee657d165d4a06e32c 100644 --- a/library/SolverUtils/Filters/FilterError.cpp +++ b/library/SolverUtils/Filters/FilterError.cpp @@ -99,6 +99,20 @@ FilterError::FilterError(const LibUtilities::SessionReaderSharedPtr &pSession, LibUtilities::Equation equ(m_session->GetInterpreter(), it->second); m_outputFrequency = round(equ.Evaluate()); } + + // ConsoleOutput + it = pParams.find("ConsoleOutput"); + if (it == pParams.end()) + { + m_consoleOutput = false; + } + else + { + ASSERTL0(it->second.length() > 0, "Empty parameter 'ConsoleOutput'."); + ASSERTL0(it->second == "0" || it->second == "1", + "Parameter 'ConsoleOutput' can only be '0' or '1'."); + m_consoleOutput = boost::lexical_cast(it->second); + } } void FilterError::v_Initialise( @@ -142,6 +156,16 @@ void FilterError::v_Update( if (m_comm->GetRank() == 0) { m_outFile << " " << vL2Error << " " << vLinfError; + + if (m_consoleOutput) + { + std::cout << "L 2 error (variable " + << equationSys->GetVariable(i) << ") : " << vL2Error + << std::endl; + std::cout << "L inf error (variable " + << equationSys->GetVariable(i) << ") : " << vLinfError + << std::endl; + } } } diff --git a/library/SolverUtils/Filters/FilterError.h b/library/SolverUtils/Filters/FilterError.h index 496716d5a1c488f4c18ee9514471750438b122bd..53933bf4615b7052aa391fc410b6efa2f098642d 100644 --- a/library/SolverUtils/Filters/FilterError.h +++ b/library/SolverUtils/Filters/FilterError.h @@ -81,6 +81,7 @@ protected: private: size_t m_index = 0; size_t m_outputFrequency; + bool m_consoleOutput; size_t m_numVariables; std::ofstream m_outFile; LibUtilities::CommSharedPtr m_comm; diff --git a/library/SolverUtils/Filters/FilterIntegral.cpp b/library/SolverUtils/Filters/FilterIntegral.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0cf87adb642542691a1937d402cd358628dc2874 --- /dev/null +++ b/library/SolverUtils/Filters/FilterIntegral.cpp @@ -0,0 +1,396 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// File FilterIntegral.cpp +// +// For more information, please see: http://www.nektar.info +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// 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. +// +// Description: Outputs integrals of fields during time-stepping. +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include + +#include +#include + +namespace Nektar +{ +namespace SolverUtils +{ +std::string FilterIntegral::className = + GetFilterFactory().RegisterCreatorFunction("Integral", + FilterIntegral::create); + +FilterIntegral::FilterIntegral( + const LibUtilities::SessionReaderSharedPtr &pSession, + const std::weak_ptr &pEquation, const ParamMap &pParams) + : Filter(pSession, pEquation) +{ + std::string outName; + + // OutputFile + auto it = pParams.find("OutputFile"); + if (it == pParams.end()) + { + outName = m_session->GetSessionName(); + } + else + { + ASSERTL0(it->second.length() > 0, "Empty parameter 'OutputFile'."); + outName = it->second; + } + outName += ".int"; + + // Composites (to calculate integrals on) + it = pParams.find("Composites"); + ASSERTL0(it != pParams.end(), "Missing parameter 'Composites'."); + ASSERTL0(it->second.length() > 0, "Empty parameter 'Composites'."); + + std::vector splitComposite; + boost::split(m_splitCompString, it->second, boost::is_any_of(","), + boost::token_compress_on); + + for (auto &comp : m_splitCompString) + { + boost::trim(comp); + size_t first = comp.find_first_of('[') + 1; + size_t last = comp.find_last_of(']') - 1; + auto tmpString = comp.substr(first, last - first + 1); + + std::vector tmpVec; + bool parseGood = ParseUtils::GenerateSeqVector(tmpString, tmpVec); + + ASSERTL0(parseGood && !tmpVec.empty(), + "Unable to read composite regions index range for " + "FilterIntegral: " + + comp); + + m_compVector.emplace_back(tmpVec); + } + + // OutputPrecision + size_t precision; + it = pParams.find("OutputPrecision"); + if (it == pParams.end()) + { + precision = 7; + } + else + { + ASSERTL0(it->second.length() > 0, "Empty parameter 'OutputPrecision'."); + precision = std::stoi(it->second); + } + + // Lock equation system pointer + auto equationSys = m_equ.lock(); + ASSERTL0(equationSys, "Weak pointer expired"); + + m_numVariables = equationSys->GetNvariables(); + + m_comm = pSession->GetComm(); + if (m_comm->GetRank() == 0) + { + m_outFile.open(outName); + ASSERTL0(m_outFile.good(), "Unable to open: '" + outName + "'"); + m_outFile.setf(std::ios::scientific, std::ios::floatfield); + m_outFile.precision(precision); + m_outFile << "#Time"; + + for (auto &compName : m_splitCompString) + { + for (size_t j = 0; j < m_numVariables; ++j) + { + std::string varName = equationSys->GetVariable(j); + m_outFile << " " + compName + "_" + varName + "_integral"; + } + } + m_outFile << std::endl; + } + + // OutputFrequency + it = pParams.find("OutputFrequency"); + if (it == pParams.end()) + { + m_outputFrequency = 1; + } + else + { + ASSERTL0(it->second.length() > 0, "Empty parameter 'OutputFrequency'."); + LibUtilities::Equation equ(m_session->GetInterpreter(), it->second); + m_outputFrequency = round(equ.Evaluate()); + } +} + +void FilterIntegral::v_Initialise( + const Array &pFields, + const NekDouble &time) +{ + + // Create map from element ID -> expansion list ID + auto expList = pFields[0]->GetExp(); + auto meshGraph = pFields[0]->GetGraph(); + + for (size_t i = 0; i < expList->size(); ++i) + { + auto exp = (*expList)[i]; + m_geomElmtIdToExpId[exp->GetGeom()->GetGlobalID()] = i; + } + + // Create a map from geom ID -> trace expansion list ID + std::map geomIdToTraceId; + auto trace = pFields[0]->GetTrace()->GetExp(); + for (size_t i = 0; i < trace->size(); ++i) + { + auto exp = (*trace)[i]; + geomIdToTraceId[exp->GetGeom()->GetGlobalID()] = i; + } + + // Get comp list dimension from first composite & element + auto composites = pFields[0]->GetGraph()->GetComposites(); + size_t meshDim = pFields[0]->GetGraph()->GetMeshDimension(); + + for (int i = 0; i < m_compVector.size(); ++i) + { + // Check composite is present in the rank + if (composites.find(m_compVector[i][0]) == composites.end()) + { + continue; + } + + std::vector> geomVec = + composites[m_compVector[i][0]]->m_geomVec; + size_t dim = + composites[m_compVector[i][0]]->m_geomVec[0]->GetShapeDim(); + + // Vector of all geometry IDs contained within the composite list + std::vector compGeomIds; + for (auto compNum : m_compVector[i]) + { + ASSERTL0(composites.find(compNum) != composites.end(), + "In FilterIntegral defined composite C[" + + std::to_string(compNum) + + "] does not exist in the mesh.") + + auto compGeom = composites[compNum]->m_geomVec; + + for (auto &geom : compGeom) + { + compGeomIds.emplace_back(geom->GetGlobalID()); + } + + // Only check first element in each comp for dimension + ASSERTL0( + dim == compGeom[0]->GetShapeDim(), + "Differing geometry dimensions specified in FilterIntegral '" + + m_splitCompString[i] + "'."); + } + + std::vector> + tmpCompExp(compGeomIds.size()); + + // If dimension of composite == dimension of mesh then we only need the + // expansion of the element + if (dim == pFields[0]->GetShapeDimension()) + { + for (size_t j = 0; j < compGeomIds.size(); ++j) + { + tmpCompExp[j] = std::make_pair( + (*expList)[m_geomElmtIdToExpId[compGeomIds[j]]], -1); + } + } + // however if the dimension is less we need the expansion of the element + // containing the global composite geometry and the face/edge local ID + // within that. 3D mesh -> 2D, 2D -> 1D. + // @TODO: Restructure with the new dimension independent functions + // and check all is correct with this filter. + else if (meshDim == 3 && dim == 2) + { + for (size_t j = 0; j < compGeomIds.size(); ++j) + { + LocalRegions::ExpansionSharedPtr exp = + (*trace)[geomIdToTraceId[compGeomIds[j]]]; + LocalRegions::Expansion2DSharedPtr exp2D = + std::dynamic_pointer_cast(exp); + + LocalRegions::ExpansionSharedPtr leftAdjElmtExp = + std::dynamic_pointer_cast( + exp2D->GetLeftAdjacentElementExp()); + int leftAdjElmtFace = exp2D->GetLeftAdjacentElementTrace(); + + tmpCompExp[j] = std::make_pair(leftAdjElmtExp, leftAdjElmtFace); + } + } + else if (meshDim == 2 && dim == 1) + { + for (size_t j = 0; j < compGeomIds.size(); ++j) + { + LocalRegions::ExpansionSharedPtr exp = + (*trace)[geomIdToTraceId[compGeomIds[j]]]; + LocalRegions::Expansion1DSharedPtr exp1D = + std::dynamic_pointer_cast(exp); + + LocalRegions::ExpansionSharedPtr leftAdjElmtExp = + std::dynamic_pointer_cast( + exp1D->GetLeftAdjacentElementExp()); + int leftAdjElmtEdge = exp1D->GetLeftAdjacentElementTrace(); + + tmpCompExp[j] = std::make_pair(leftAdjElmtExp, leftAdjElmtEdge); + } + } + else + { + ASSERTL0(false, + "FilterIntegral: Only composite dimensions equal to or " + "one lower than the mesh dimension are supported.") + } + + m_compExpMap[i] = tmpCompExp; + } + + v_Update(pFields, time); +} + +void FilterIntegral::v_Update( + const Array &pFields, + const NekDouble &time) +{ + if (m_index++ % m_outputFrequency > 0) + { + return; + } + + if (m_comm->GetRank() == 0) + { + m_outFile << time; + } + + for (size_t j = 0; j < m_compVector.size(); ++j) + { + for (size_t i = 0; i < m_numVariables; ++i) + { + Array phys; + phys = pFields[i]->GetPhys(); + + NekDouble sum = 0.0; + NekDouble c = 0.0; + + // Check if composite is on the rank + if (m_compExpMap.find(j) != m_compExpMap.end()) + { + auto compExp = m_compExpMap[j]; + size_t dim = compExp[0].first->GetGeom()->GetShapeDim(); + size_t meshDim = pFields[i]->GetGraph()->GetMeshDimension(); + + // Evaluate integral using improved Kahan–Babuška summation + // algorithm to reduce numerical error from adding floating + // points + for (auto &expPair : compExp) + { + NekDouble input = 0; + auto exp = expPair.first; + + if (meshDim == dim) + { + size_t offset = pFields[i]->GetPhys_Offset( + m_geomElmtIdToExpId[exp->GetGeom()->GetGlobalID()]); + input = exp->Integral(phys + offset); + } + else if (meshDim == 3 && dim == 2) + { + Array facePhys; + exp->GetTracePhysVals(expPair.second, exp, phys, + facePhys); + input = + pFields[i] + ->GetTrace() + ->GetExp(exp->GetGeom()->GetTid(expPair.second)) + ->Integral(facePhys); + } + else if (meshDim == 2 && dim == 1) + { + Array edgePhys; + exp->GetTracePhysVals(expPair.second, exp, phys, + edgePhys); + input = + pFields[i] + ->GetTrace() + ->GetExp(exp->GetGeom()->GetTid(expPair.second)) + ->Integral(edgePhys); + } + else + { + ASSERTL0(false, + "FilterIntegral: Only composite dimensions " + "equal to or one lower than the mesh " + "dimension are supported.") + } + + NekDouble t = sum + input; + c += fabs(sum) >= fabs(input) ? (sum - t) + input + : (input - t) + sum; + sum = t; + } + } + + // Sum integral values from all ranks + Array sumArray(1, sum + c); + m_comm->AllReduce(sumArray, LibUtilities::ReduceSum); + if (m_comm->GetRank() == 0) + { + m_outFile << " " << sumArray[0]; + } + } + } + + if (m_comm->GetRank() == 0) + { + m_outFile << std::endl; + } +} + +void FilterIntegral::v_Finalise( + const Array &pFields, + const NekDouble &time) +{ + boost::ignore_unused(pFields, time); + + if (m_comm->GetRank() == 0) + { + m_outFile.close(); + } +} + +bool FilterIntegral::v_IsTimeDependent() +{ + return true; +} +} // namespace SolverUtils +} // namespace Nektar diff --git a/library/SolverUtils/Filters/FilterIntegral.h b/library/SolverUtils/Filters/FilterIntegral.h new file mode 100644 index 0000000000000000000000000000000000000000..3f56aa148b27aef13bfd1bd96b1ffd7203781aa9 --- /dev/null +++ b/library/SolverUtils/Filters/FilterIntegral.h @@ -0,0 +1,131 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// File FilterIntegral.h +// +// For more information, please see: http://www.nektar.info +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// 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. +// +// Description: Outputs integrals of fields during time-stepping. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef NEKTAR_SOLVERUTILS_FILTERS_FILTERINTEGRAL_H +#define NEKTAR_SOLVERUTILS_FILTERS_FILTERINTEGRAL_H + +#include + +namespace Nektar +{ +namespace SolverUtils +{ +class FilterIntegral : public Filter +{ +public: + friend class MemoryManager; + + /// Creates an instance of this class + static FilterSharedPtr create( + const LibUtilities::SessionReaderSharedPtr &pSession, + const std::weak_ptr &pEquation, + const std::map &pParams) + { + FilterSharedPtr p = MemoryManager::AllocateSharedPtr( + pSession, pEquation, pParams); + return p; + } + + /// Name of the class + static std::string className; + + /// Constructs the integral filter and parses filter options, opens file + SOLVER_UTILS_EXPORT FilterIntegral( + const LibUtilities::SessionReaderSharedPtr &pSession, + const std::weak_ptr &pEquation, + const ParamMap &pParams); + + /// Default destructor + SOLVER_UTILS_EXPORT virtual ~FilterIntegral() = default; + +protected: + /** + * Initialises the integral filter and stores the composite expansions in + * #m_compExpMap for all composites specified in the XML file + * + * @param pFields Field data + * @param time Current time + */ + virtual void v_Initialise( + const Array &pFields, + const NekDouble &time) final; + + /** + * Performs the integration on the stored composite expansions and outputs + * in to the output data file + * + * @param pFields Field data + * @param time Current time + */ + virtual void v_Update( + const Array &pFields, + const NekDouble &time) final; + + /** + * Closes the output data file + * + * @param pFields Field data + * @param time Current time + */ + virtual void v_Finalise( + const Array &pFields, + const NekDouble &time) final; + + /// Returns true as filter depends on time + virtual bool v_IsTimeDependent() final; + +private: + size_t m_index = 0; + /// Frequency to write to output data file in timesteps + size_t m_outputFrequency; + /// Number of fields to perform integral on + size_t m_numVariables; + /// Out file + std::ofstream m_outFile; + /// Global communicator + LibUtilities::CommSharedPtr m_comm; + /// Vector of composite IDs as a single string + std::vector m_splitCompString; + /// Vector of vector of composites IDs as integers + std::vector> m_compVector; + /// Mapping from geometry ID to expansion ID + std::map m_geomElmtIdToExpId; + /// Map of composite ID to vector of expansions an face/edge local ID + std::map>> + m_compExpMap; +}; +} // namespace SolverUtils +} // namespace Nektar + +#endif /* NEKTAR_SOLVERUTILS_FILTERS_FILTERIntegral_H */ diff --git a/library/SolverUtils/RiemannSolvers/RiemannSolver.cpp b/library/SolverUtils/RiemannSolvers/RiemannSolver.cpp index f2c32a28ab7d971425a49c02215072f326e9b4b5..cedd4d5f8109dd3574f207f30100d2e91e67190f 100644 --- a/library/SolverUtils/RiemannSolvers/RiemannSolver.cpp +++ b/library/SolverUtils/RiemannSolvers/RiemannSolver.cpp @@ -134,10 +134,48 @@ void RiemannSolver::Solve(const int nDim, } } + // auto vgt = m_vectors["vgt"](); + // Array> rot1(nFields); + // Array> veclocs(1); + // veclocs[0] = Array(2); + // veclocs[0][0] = 0.0; + // veclocs[0][1] = 1.0; + // for (int i =0; i < nFields; ++i) + //{ + // rot1[i] = Array(nPts); + //} + // rotateToNormal(vgt, normals, veclocs, rot1); + rotateToNormal(Fwd, normals, vecLocs, m_rotStorage[0]); rotateToNormal(Bwd, normals, vecLocs, m_rotStorage[1]); + + // for (int i = 0; i < 2; ++i) + //{ + // std::cout << "nfields = " << nFields << std::endl; + // for (int j = 0; j < m_rotStorage[0][0].size(); ++j) + // { + // m_rotStorage[0][i+1][j] -= rot1[i][j] * m_rotStorage[0][0][j]; + // m_rotStorage[1][i+1][j] -= rot1[i][j] * m_rotStorage[0][0][j]; + // } + //} + v_Solve(nDim, m_rotStorage[0], m_rotStorage[1], m_rotStorage[2]); rotateFromNormal(m_rotStorage[2], normals, vecLocs, flux); + + // Attempt to subtract (\vec{U}\vec{vg})\dot n for ALE + if (m_ALESolver) + { + auto vgt = m_vectors["vgt"](); + auto N = m_vectors["N"](); + for (int i = 0; i < flux.size(); ++i) + { + for (int j = 0; j < flux[i].size(); ++j) + { + flux[i][j] -= 0.5 * (Fwd[i][j] + Bwd[i][j]) * + (N[0][j] * vgt[0][j] + N[1][j] * vgt[1][j]); + } + } + } } else { diff --git a/library/SolverUtils/RiemannSolvers/RiemannSolver.h b/library/SolverUtils/RiemannSolvers/RiemannSolver.h index 6b19825baf40ac6fd13180b49c08baffbb520c1b..0a3860956e2e305b81d6d6a59118ff6486fa8c39 100644 --- a/library/SolverUtils/RiemannSolvers/RiemannSolver.h +++ b/library/SolverUtils/RiemannSolvers/RiemannSolver.h @@ -90,6 +90,11 @@ public: m_params[name] = std::bind(func, obj); } + void SetALEFlag(bool &ALE) + { + m_ALESolver = ALE; + } + void SetParam(std::string name, RSParamFuncType fp) { m_params[name] = fp; @@ -152,6 +157,8 @@ protected: Array> m_rotMat; /// Rotation storage Array>> m_rotStorage; + /// Flag if using the ALE formulation + bool m_ALESolver = false; SOLVER_UTILS_EXPORT RiemannSolver(); SOLVER_UTILS_EXPORT RiemannSolver( diff --git a/library/SolverUtils/UnsteadySystem.cpp b/library/SolverUtils/UnsteadySystem.cpp index 184035a9dee15b17691d9f8707acd460b5a86d35..ef055eddea788a4fd5fe8ecfcb9cd52681b76b89 100644 --- a/library/SolverUtils/UnsteadySystem.cpp +++ b/library/SolverUtils/UnsteadySystem.cpp @@ -68,7 +68,8 @@ namespace SolverUtils UnsteadySystem::UnsteadySystem( const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph) - : EquationSystem(pSession, pGraph), m_infosteps(10) + : EquationSystem(pSession, pGraph), SolverUtils::ALEHelper(), + m_infosteps(10) { } @@ -79,6 +80,7 @@ UnsteadySystem::UnsteadySystem( void UnsteadySystem::v_InitObject(bool DeclareField) { EquationSystem::v_InitObject(DeclareField); + ALEHelper::InitObject(m_spacedim, m_fields); m_initialStep = 0; @@ -226,12 +228,23 @@ void UnsteadySystem::v_DoSolve() Array> fields(nvariables); // Order storage to list time-integrated fields first. + // @TODO: Refactor to take coeffs (FwdTrans) if boolean flag (in constructor + // function) says to. for (i = 0; i < nvariables; ++i) { fields[i] = m_fields[m_intVariables[i]]->GetPhys(); m_fields[m_intVariables[i]]->SetPhysState(false); } + // @TODO: Virtual function that allows to transform the field space, embed + // the MultiplyMassMatrix in here. + // @TODO: Specify what the fields variables are physical or coefficient, + // boolean in UnsteadySystem class... + if (m_ALESolver) + { + ALEHelper::ALEPreMultiplyMass(fields); + } + // Initialise time integration scheme m_intScheme->InitializeScheme(m_timestep, fields, m_time, m_ode); @@ -321,7 +334,9 @@ void UnsteadySystem::v_DoSolve() // Perform any solver-specific pre-integration steps timer.Start(); - if (v_PreIntegrate(step)) + if (v_PreIntegrate( + step)) // Could be possible to put a preintegrate step in the + // ALEHelper class, put in the Unsteady Advection class { break; } @@ -365,19 +380,30 @@ void UnsteadySystem::v_DoSolve() } } - // Transform data into coefficient space - for (i = 0; i < nvariables; ++i) + // @TODO: Another virtual function with this in it based on if ALE or + // not. + if (m_ALESolver) // Change to advect coeffs, change flag to physical vs + // coefficent space + { + SetBoundaryConditions(m_time); + ALEHelper::ALEDoElmtInvMass(m_traceNormals, fields, m_time); + } + else { - // copy fields into ExpList::m_phys and assign the new - // array to fields - m_fields[m_intVariables[i]]->SetPhys(fields[i]); - fields[i] = m_fields[m_intVariables[i]]->UpdatePhys(); - if (v_RequireFwdTrans()) + // Transform data into coefficient space + for (i = 0; i < nvariables; ++i) { - m_fields[m_intVariables[i]]->FwdTransLocalElmt( - fields[i], m_fields[m_intVariables[i]]->UpdateCoeffs()); + // copy fields into ExpList::m_phys and assign the new + // array to fields + m_fields[m_intVariables[i]]->SetPhys(fields[i]); + fields[i] = m_fields[m_intVariables[i]]->UpdatePhys(); + if (v_RequireFwdTrans()) + { + m_fields[m_intVariables[i]]->FwdTransLocalElmt( + fields[i], m_fields[m_intVariables[i]]->UpdateCoeffs()); + } + m_fields[m_intVariables[i]]->SetPhysState(false); } - m_fields[m_intVariables[i]]->SetPhysState(false); } // Perform any solver-specific post-integration steps @@ -470,7 +496,7 @@ void UnsteadySystem::v_DoSolve() // Write out checkpoint files if ((m_checksteps && !((step + 1) % m_checksteps)) || doCheckTime) { - if (m_HomogeneousType != eNotHomogeneous) + if (m_HomogeneousType != eNotHomogeneous && !m_ALESolver) { vector transformed(nfields, false); for (i = 0; i < nfields; i++) @@ -535,28 +561,30 @@ void UnsteadySystem::v_DoSolve() } // If homogeneous, transform back into physical space if necessary. - if (m_HomogeneousType != eNotHomogeneous) + if (!m_ALESolver) { - for (i = 0; i < nfields; i++) + if (m_HomogeneousType != eNotHomogeneous) { - if (m_fields[i]->GetWaveSpace()) + for (i = 0; i < nfields; i++) { - m_fields[i]->SetWaveSpace(false); - m_fields[i]->BwdTrans(m_fields[i]->GetCoeffs(), - m_fields[i]->UpdatePhys()); - m_fields[i]->SetPhysState(true); + if (m_fields[i]->GetWaveSpace()) + { + m_fields[i]->SetWaveSpace(false); + m_fields[i]->BwdTrans(m_fields[i]->GetCoeffs(), + m_fields[i]->UpdatePhys()); + m_fields[i]->SetPhysState(true); + } } } - } - else - { - for (i = 0; i < nvariables; ++i) + else { - m_fields[m_intVariables[i]]->SetPhys(fields[i]); - m_fields[m_intVariables[i]]->SetPhysState(true); + for (i = 0; i < nvariables; ++i) + { + m_fields[m_intVariables[i]]->SetPhys(fields[i]); + m_fields[m_intVariables[i]]->SetPhysState(true); + } } } - // Finalise filters for (auto &x : m_filters) { @@ -578,6 +606,12 @@ void UnsteadySystem::v_DoInitialise() CheckForRestartTime(m_time, m_nchk); SetBoundaryConditions(m_time); SetInitialConditions(m_time); + + if (m_ALESolver) + { + UpdateGridVelocity(m_time); + } + InitializeSteadyState(); } diff --git a/library/SolverUtils/UnsteadySystem.h b/library/SolverUtils/UnsteadySystem.h index b72d27973b9a02b672b6b16d35ee35936c9f8dde..dc8ec834ea0cc73a1fd7d210506e8e48cc89b8cf 100644 --- a/library/SolverUtils/UnsteadySystem.h +++ b/library/SolverUtils/UnsteadySystem.h @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -45,7 +46,7 @@ namespace Nektar namespace SolverUtils { /// Base class for unsteady solvers. -class UnsteadySystem : public EquationSystem +class UnsteadySystem : public EquationSystem, public SolverUtils::ALEHelper { public: /// Destructor diff --git a/library/SpatialDomains/CMakeLists.txt b/library/SpatialDomains/CMakeLists.txt index d544d76a815b222a8e209d2b2978baf0f3f914aa..ab27d6000257fad4578a00d557ef75a1eda91279 100644 --- a/library/SpatialDomains/CMakeLists.txt +++ b/library/SpatialDomains/CMakeLists.txt @@ -18,6 +18,8 @@ SegGeom.cpp PointGeom.cpp TetGeom.cpp TriGeom.cpp +Movement/Zones.cpp +Movement/Movement.cpp ) SET(SPATIAL_DOMAINS_HEADERS @@ -44,6 +46,9 @@ SpatialDomainsDeclspec.h TetGeom.h TriGeom.h SpatialDomains.hpp +Movement/Zones.h + Movement/InterfaceInterpolation.h +Movement/Movement.h ) IF(NEKTAR_USE_HDF5) diff --git a/library/SpatialDomains/Geometry.cpp b/library/SpatialDomains/Geometry.cpp index 85550990b23345e9d21fe1fa913d8ae90231615f..a1ca0be50f447b456f492ad4f28639e56ec9a064 100644 --- a/library/SpatialDomains/Geometry.cpp +++ b/library/SpatialDomains/Geometry.cpp @@ -273,6 +273,15 @@ bool Geometry::v_ContainsPoint(const Array &gloCoord, } } +NekDouble Geometry::v_FindDistance(const Array &xs, + Array &xi) +{ + boost::ignore_unused(xs, xi); + NEKERROR(ErrorUtil::efatal, + "This function has not been defined for this geometry"); + return false; +} + /** * @copydoc Geometry::GetVertexEdgeMap() */ @@ -447,8 +456,8 @@ std::array Geometry::GetBoundingBox() for (int j = 0; j < 3; ++j) { const NekDouble len = max[j] - min[j]; - min[j] -= (0.1 + NekConstants::kGeomFactorsTol) * len; - max[j] += (0.1 + NekConstants::kGeomFactorsTol) * len; + min[j] -= (0.1 * len + NekConstants::kGeomFactorsTol); + max[j] += (0.1 * len + NekConstants::kGeomFactorsTol); } // save bounding box @@ -462,6 +471,11 @@ std::array Geometry::GetBoundingBox() return {{min[0], min[1], min[2], max[0], max[1], max[2]}}; } +void Geometry::ClearBoundingBox() +{ + m_boundingBox = {}; +} + /** * @brief Check if given global coord is within the BoundingBox * of the element. diff --git a/library/SpatialDomains/Geometry.h b/library/SpatialDomains/Geometry.h index 2fbeba412cf76758741271c640d59ae087cde5fb..01777296d6889707a1998e166fb26693f3505be8 100644 --- a/library/SpatialDomains/Geometry.h +++ b/library/SpatialDomains/Geometry.h @@ -137,6 +137,7 @@ public: // Point lookups //--------------------------------------- SPATIAL_DOMAINS_EXPORT std::array GetBoundingBox(); + SPATIAL_DOMAINS_EXPORT void ClearBoundingBox(); SPATIAL_DOMAINS_EXPORT inline bool ContainsPoint( const Array &gloCoord, NekDouble tol = 0.0); @@ -153,8 +154,11 @@ public: const int i, const Array &Lcoord); SPATIAL_DOMAINS_EXPORT bool MinMaxCheck( const Array &gloCoord); - SPATIAL_DOMAINS_EXPORT bool ClampLocCoords(Array &locCoord, - NekDouble tol); + SPATIAL_DOMAINS_EXPORT bool ClampLocCoords( + Array &locCoord, + NekDouble tol = std::numeric_limits::epsilon()); + SPATIAL_DOMAINS_EXPORT inline NekDouble FindDistance( + const Array &xs, Array &xi); //--------------------------------------- // Misc. helper functions @@ -169,8 +173,14 @@ public: SPATIAL_DOMAINS_EXPORT inline void Reset(CurveMap &curvedEdges, CurveMap &curvedFaces); + SPATIAL_DOMAINS_EXPORT inline void ResetNonRecursive(CurveMap &curvedEdges, + CurveMap &curvedFaces); + SPATIAL_DOMAINS_EXPORT inline void Setup(); + /// Handles generation of geometry factors. + void GenGeomFactors(); + protected: SPATIAL_DOMAINS_EXPORT static GeomFactorsSharedPtr ValidateRegGeomFactor( GeomFactorsSharedPtr geomFactor); @@ -199,9 +209,6 @@ protected: /// Array containing bounding box Array m_boundingBox; - /// Handles generation of geometry factors. - void GenGeomFactors(); - //--------------------------------------- // Helper functions //--------------------------------------- @@ -226,6 +233,8 @@ protected: const Array &Lcoord); virtual NekDouble v_GetLocCoords(const Array &coords, Array &Lcoords); + virtual NekDouble v_FindDistance(const Array &xs, + Array &xi); virtual int v_GetVertexEdgeMap(int i, int j) const; virtual int v_GetVertexFaceMap(int i, int j) const; @@ -545,6 +554,12 @@ inline NekDouble Geometry::GetCoord(const int i, return v_GetCoord(i, Lcoord); } +inline NekDouble Geometry::FindDistance(const Array &xs, + Array &xi) +{ + return v_FindDistance(xs, xi); +} + /** * @brief Returns the standard element edge IDs that are connected to a given * vertex. @@ -649,6 +664,17 @@ inline void Geometry::Reset(CurveMap &curvedEdges, CurveMap &curvedFaces) { v_Reset(curvedEdges, curvedFaces); } + +/** + * @brief Reset this geometry object non-recursively: unset the current state, + * zero Geometry::m_coeffs and remove allocated GeomFactors. + */ +inline void Geometry::ResetNonRecursive(CurveMap &curvedEdges, + CurveMap &curvedFaces) +{ + Geometry::v_Reset(curvedEdges, curvedFaces); +} + inline void Geometry::Setup() { v_Setup(); diff --git a/library/SpatialDomains/Geometry2D.cpp b/library/SpatialDomains/Geometry2D.cpp index 0ac1bec46a8fbc63fc562e7963b8648da29acfdd..07c8a721a84db5703954c8afdaa3d0f755663f03 100644 --- a/library/SpatialDomains/Geometry2D.cpp +++ b/library/SpatialDomains/Geometry2D.cpp @@ -69,7 +69,7 @@ void Geometry2D::NewtonIterationForLocCoord( NekDouble &dist) { // Maximum iterations for convergence - const int MaxIterations = 51; + const int MaxIterations = NekConstants::kNewtonIterations; // |x-xp|^2 < EPSILON error tolerance const NekDouble Tol = 1.e-8; // |r,s| > LcoordDIV stop the search @@ -351,5 +351,231 @@ int Geometry2D::v_GetShapeDim() const return 2; } +NekDouble Geometry2D::v_FindDistance(const Array &xs, + Array &xiOut) +{ + if (m_geomFactors->GetGtype() == eRegular) + { + xiOut = Array(2, 0.0); + + GetLocCoords(xs, xiOut); + ClampLocCoords(xiOut); + + Array gloCoord(3); + gloCoord[0] = GetCoord(0, xiOut); + gloCoord[1] = GetCoord(1, xiOut); + gloCoord[2] = GetCoord(2, xiOut); + + return sqrt((xs[0] - gloCoord[0]) * (xs[0] - gloCoord[0]) + + (xs[1] - gloCoord[1]) * (xs[1] - gloCoord[1]) + + (xs[2] - gloCoord[2]) * (xs[2] - gloCoord[2])); + } + // If deformed edge then the inverse mapping is non-linear so need to + // numerically solve for the local coordinate + else if (m_geomFactors->GetGtype() == eDeformed) + { + // Choose starting based on closest quad + Array xi(2, 0.0), eta(2, 0.0); + m_xmap->LocCollapsedToLocCoord(eta, xi); + + // Armijo constants: + // https://en.wikipedia.org/wiki/Backtracking_line_search + const NekDouble c1 = 1e-4, c2 = 0.9; + + int nq = m_xmap->GetTotPoints(); + + Array x(nq), y(nq), z(nq); + m_xmap->BwdTrans(m_coeffs[0], x); + m_xmap->BwdTrans(m_coeffs[1], y); + m_xmap->BwdTrans(m_coeffs[2], z); + + Array xderxi1(nq, 0.0), yderxi1(nq, 0.0), + zderxi1(nq, 0.0), xderxi2(nq, 0.0), yderxi2(nq, 0.0), + zderxi2(nq, 0.0), xderxi1xi1(nq, 0.0), yderxi1xi1(nq, 0.0), + zderxi1xi1(nq, 0.0), xderxi1xi2(nq, 0.0), yderxi1xi2(nq, 0.0), + zderxi1xi2(nq, 0.0), xderxi2xi1(nq, 0.0), yderxi2xi1(nq, 0.0), + zderxi2xi1(nq, 0.0), xderxi2xi2(nq, 0.0), yderxi2xi2(nq, 0.0), + zderxi2xi2(nq, 0.0); + + // Get first & second derivatives & partial derivatives of x,y,z values + std::array xc_derxi, yc_derxi, zc_derxi; + + m_xmap->PhysDeriv(x, xderxi1, xderxi2); + m_xmap->PhysDeriv(y, yderxi1, yderxi2); + m_xmap->PhysDeriv(z, zderxi1, zderxi2); + + m_xmap->PhysDeriv(xderxi1, xderxi1xi1, xderxi1xi2); + m_xmap->PhysDeriv(yderxi1, yderxi1xi1, yderxi1xi2); + m_xmap->PhysDeriv(zderxi1, zderxi1xi1, zderxi1xi2); + + m_xmap->PhysDeriv(yderxi2, yderxi2xi1, yderxi2xi2); + m_xmap->PhysDeriv(xderxi2, xderxi2xi1, xderxi2xi2); + m_xmap->PhysDeriv(zderxi2, zderxi2xi1, zderxi2xi2); + + // Minimisation loop (Quasi-newton method) + NekDouble fx_prev = std::numeric_limits::max(); + for (int i = 0; i < NekConstants::kNewtonIterations; ++i) + { + // Compute the objective function, f(x_k) and its derivatives + NekDouble xc = m_xmap->PhysEvaluate(xi, x, xc_derxi); + NekDouble yc = m_xmap->PhysEvaluate(xi, y, yc_derxi); + NekDouble zc = m_xmap->PhysEvaluate(xi, z, zc_derxi); + + NekDouble xc_derxi1xi1 = m_xmap->PhysEvaluate(xi, xderxi1xi1); + NekDouble yc_derxi1xi1 = m_xmap->PhysEvaluate(xi, yderxi1xi1); + NekDouble zc_derxi1xi1 = m_xmap->PhysEvaluate(xi, zderxi1xi1); + + NekDouble xc_derxi1xi2 = m_xmap->PhysEvaluate(xi, xderxi1xi2); + NekDouble yc_derxi1xi2 = m_xmap->PhysEvaluate(xi, yderxi1xi2); + NekDouble zc_derxi1xi2 = m_xmap->PhysEvaluate(xi, zderxi1xi2); + + NekDouble xc_derxi2xi2 = m_xmap->PhysEvaluate(xi, xderxi2xi2); + NekDouble yc_derxi2xi2 = m_xmap->PhysEvaluate(xi, yderxi2xi2); + NekDouble zc_derxi2xi2 = m_xmap->PhysEvaluate(xi, zderxi2xi2); + + // Objective function is the distance to the search point + NekDouble xdiff = xc - xs[0]; + NekDouble ydiff = yc - xs[1]; + NekDouble zdiff = zc - xs[2]; + + NekDouble fx = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff; + + NekDouble fx_derxi1 = 2.0 * xdiff * xc_derxi[0] + + 2.0 * ydiff * yc_derxi[0] + + 2.0 * zdiff * zc_derxi[0]; + + NekDouble fx_derxi2 = 2.0 * xdiff * xc_derxi[1] + + 2.0 * ydiff * yc_derxi[1] + + 2.0 * zdiff * zc_derxi[1]; + + NekDouble fx_derxi1xi1 = + 2.0 * xdiff * xc_derxi1xi1 + 2.0 * xc_derxi[0] * xc_derxi[0] + + 2.0 * ydiff * yc_derxi1xi1 + 2.0 * yc_derxi[0] * yc_derxi[0] + + 2.0 * zdiff * zc_derxi1xi1 + 2.0 * zc_derxi[0] * zc_derxi[0]; + + NekDouble fx_derxi1xi2 = + 2.0 * xdiff * xc_derxi1xi2 + 2.0 * xc_derxi[1] * xc_derxi[0] + + 2.0 * ydiff * yc_derxi1xi2 + 2.0 * yc_derxi[1] * yc_derxi[0] + + 2.0 * zdiff * zc_derxi1xi2 + 2.0 * zc_derxi[1] * zc_derxi[0]; + + NekDouble fx_derxi2xi2 = + 2.0 * xdiff * xc_derxi2xi2 + 2.0 * xc_derxi[1] * xc_derxi[1] + + 2.0 * ydiff * yc_derxi2xi2 + 2.0 * yc_derxi[1] * yc_derxi[1] + + 2.0 * zdiff * zc_derxi2xi2 + 2.0 * zc_derxi[1] * zc_derxi[1]; + + // Jacobian + NekDouble jac[2]; + jac[0] = fx_derxi1; + jac[1] = fx_derxi2; + + // Inverse of 2x2 hessian + NekDouble hessInv[2][2]; + + NekDouble det = + 1 / (fx_derxi1xi1 * fx_derxi2xi2 - fx_derxi1xi2 * fx_derxi1xi2); + hessInv[0][0] = det * fx_derxi2xi2; + hessInv[0][1] = det * -fx_derxi1xi2; + hessInv[1][0] = det * -fx_derxi1xi2; + hessInv[1][1] = det * fx_derxi1xi1; + + // Check for convergence + if (abs(fx - fx_prev) < 1e-12) + { + fx_prev = fx; + break; + } + else + { + fx_prev = fx; + } + + NekDouble gamma = 1.0; + bool conv = false; + + // Search direction: Newton's method + NekDouble pk[2]; + pk[0] = -(hessInv[0][0] * jac[0] + hessInv[1][0] * jac[1]); + pk[1] = -(hessInv[0][1] * jac[0] + hessInv[1][1] * jac[1]); + + // Backtracking line search + while (gamma > 1e-10) + { + Array xi_pk(2); + xi_pk[0] = xi[0] + pk[0] * gamma; + xi_pk[1] = xi[1] + pk[1] * gamma; + + Array eta_pk(2, 0.0); + m_xmap->LocCoordToLocCollapsed(xi_pk, eta_pk); + + if (eta_pk[0] < + (-1 - std::numeric_limits::epsilon()) || + eta_pk[0] > + (1 + std::numeric_limits::epsilon()) || + eta_pk[1] < + (-1 - std::numeric_limits::epsilon()) || + eta_pk[1] > (1 + std::numeric_limits::epsilon())) + { + gamma /= 2.0; + continue; + } + + std::array xc_pk_derxi, yc_pk_derxi, zc_pk_derxi; + + NekDouble xc_pk = m_xmap->PhysEvaluate(xi_pk, x, xc_pk_derxi); + NekDouble yc_pk = m_xmap->PhysEvaluate(xi_pk, y, yc_pk_derxi); + NekDouble zc_pk = m_xmap->PhysEvaluate(xi_pk, z, zc_pk_derxi); + + NekDouble xc_pk_diff = xc_pk - xs[0]; + NekDouble yc_pk_diff = yc_pk - xs[1]; + NekDouble zc_pk_diff = zc_pk - xs[2]; + + NekDouble fx_pk = xc_pk_diff * xc_pk_diff + + yc_pk_diff * yc_pk_diff + + zc_pk_diff * zc_pk_diff; + + NekDouble fx_pk_derxi1 = 2.0 * xc_pk_diff * xc_pk_derxi[0] + + 2.0 * yc_pk_diff * yc_pk_derxi[0] + + 2.0 * zc_pk_diff * zc_pk_derxi[0]; + + NekDouble fx_pk_derxi2 = 2.0 * xc_pk_diff * xc_pk_derxi[1] + + 2.0 * yc_pk_diff * yc_pk_derxi[1] + + 2.0 * zc_pk_diff * zc_pk_derxi[1]; + + // Check Wolfe conditions using Armijo constants + // https://en.wikipedia.org/wiki/Wolfe_conditions + NekDouble tmp = pk[0] * fx_derxi1 + pk[1] * fx_derxi2; + NekDouble tmp2 = pk[0] * fx_pk_derxi1 + pk[1] * fx_pk_derxi2; + if ((fx_pk - (fx + c1 * gamma * tmp)) < + std::numeric_limits::epsilon() && + (-tmp2 - (-c2 * tmp)) < + std::numeric_limits::epsilon()) + { + conv = true; + break; + } + + gamma /= 2.0; + } + + if (!conv) + { + break; + } + + xi[0] += gamma * pk[0]; + xi[1] += gamma * pk[1]; + } + + xiOut = xi; + return sqrt(fx_prev); + } + else + { + ASSERTL0(false, "Geometry type unknown") + } + + return -1.0; +} + } // namespace SpatialDomains } // namespace Nektar diff --git a/library/SpatialDomains/Geometry2D.h b/library/SpatialDomains/Geometry2D.h index b8600324735cd815db78bffba18f02e296143149..59ed58c674f929a7a371bde45d8364cf069edb00 100644 --- a/library/SpatialDomains/Geometry2D.h +++ b/library/SpatialDomains/Geometry2D.h @@ -73,6 +73,10 @@ public: SPATIAL_DOMAINS_EXPORT virtual ~Geometry2D(); SPATIAL_DOMAINS_EXPORT static const int kDim = 2; + SPATIAL_DOMAINS_EXPORT CurveSharedPtr GetCurve() + { + return m_curve; + } protected: PointGeomVector m_verts; @@ -100,6 +104,9 @@ private: virtual int v_GetNumVerts() const; virtual int v_GetNumEdges() const; virtual StdRegions::Orientation v_GetEorient(const int i) const; + + virtual NekDouble v_FindDistance(const Array &xs, + Array &xi) final; }; } // namespace SpatialDomains diff --git a/library/SpatialDomains/Geometry3D.cpp b/library/SpatialDomains/Geometry3D.cpp index 06d484d26eafb1c484c78110a948edef566c0b4f..578a34be5101ba8c2c599656c466dd97935df0e9 100644 --- a/library/SpatialDomains/Geometry3D.cpp +++ b/library/SpatialDomains/Geometry3D.cpp @@ -77,7 +77,7 @@ void Geometry3D::NewtonIterationForLocCoord( NekDouble &dist) { // maximum iterations for convergence - const int MaxIterations = 51; + const int MaxIterations = NekConstants::kNewtonIterations; // |x-xp|^2 < EPSILON error tolerance const NekDouble Tol = 1.e-8; // |r,s| > LcoordDIV stop the search diff --git a/library/SpatialDomains/MeshGraph.cpp b/library/SpatialDomains/MeshGraph.cpp index c33dd70c5d510a71e17899039209af8090c68188..4c3e3a786f75cbda2dffd741b593a49dc3c06053 100644 --- a/library/SpatialDomains/MeshGraph.cpp +++ b/library/SpatialDomains/MeshGraph.cpp @@ -47,6 +47,7 @@ #include #include +#include // These are required for the Write(...) and Import(...) functions. #include @@ -199,13 +200,17 @@ void MeshGraph::FillGraph() break; case 1: { - for (auto x : m_segGeoms) + for (auto &x : m_segGeoms) { x.second->Setup(); } } break; } + + // Populate the movement object + m_movement = MemoryManager::AllocateSharedPtr( + m_session, this); } void MeshGraph::FillBoundingBoxTree() @@ -588,7 +593,7 @@ void MeshGraph::GetCompositeList(const std::string &compositeStr, addedVector.push_back(*iter); ASSERTL0(m_meshComposites.find(*iter) != m_meshComposites.end(), - "Composite not found."); + "Composite C[" + std::to_string(*iter) + "] not found."); CompositeSharedPtr composite = m_meshComposites.find(*iter)->second; if (composite) @@ -598,7 +603,7 @@ void MeshGraph::GetCompositeList(const std::string &compositeStr, else { char str[64]; - ::sprintf(str, "%d", *iter); + ::snprintf(str, 64, "%d", *iter); NEKERROR(ErrorUtil::ewarning, (std::string("Undefined composite: ") + str).c_str()); } @@ -2544,36 +2549,31 @@ ExpansionInfoMapShPtr MeshGraph::SetUpExpansionInfoMap(void) for (auto &d : m_domain) { - for (auto compIter = d.second.begin(); compIter != d.second.end(); - ++compIter) + for (auto &compIter : d.second) { // regular elements first - for (auto x = compIter->second->m_geomVec.begin(); - x != compIter->second->m_geomVec.end(); ++x) + for (auto &x : compIter.second->m_geomVec) { - if ((*x)->GetGeomFactors()->GetGtype() != + if (x->GetGeomFactors()->GetGtype() != SpatialDomains::eDeformed) { LibUtilities::BasisKeyVector def; ExpansionInfoShPtr expansionElementShPtr = - MemoryManager::AllocateSharedPtr(*x, - def); - int id = (*x)->GetGlobalID(); + MemoryManager::AllocateSharedPtr(x, def); + int id = x->GetGlobalID(); (*returnval)[id] = expansionElementShPtr; } } // deformed elements - for (auto x = compIter->second->m_geomVec.begin(); - x != compIter->second->m_geomVec.end(); ++x) + for (auto &x : compIter.second->m_geomVec) { - if ((*x)->GetGeomFactors()->GetGtype() == + if (x->GetGeomFactors()->GetGtype() == SpatialDomains::eDeformed) { LibUtilities::BasisKeyVector def; ExpansionInfoShPtr expansionElementShPtr = - MemoryManager::AllocateSharedPtr(*x, - def); - int id = (*x)->GetGlobalID(); + MemoryManager::AllocateSharedPtr(x, def); + int id = x->GetGlobalID(); (*returnval)[id] = expansionElementShPtr; } } @@ -2977,8 +2977,11 @@ void MeshGraph::ReadExpansionInfo() { auto x = expansionMap->find((*geomVecIter)->GetGlobalID()); - ASSERTL0(x != expansionMap->end(), - "Expansion not found!!"); + ASSERTL0( + x != expansionMap->end(), + "Expansion " + + std::to_string((*geomVecIter)->GetGlobalID()) + + " not found!!"); if (useExpansionType) { (x->second)->m_basisKeyVector = @@ -3536,10 +3539,9 @@ GeometryLinkSharedPtr MeshGraph::GetElementsFromEdge(Geometry1DSharedPtr edge) for (auto &d : m_domain) { - for (auto compIter = d.second.begin(); compIter != d.second.end(); - ++compIter) + for (auto &compIter : d.second) { - for (auto &geomIter : compIter->second->m_geomVec) + for (auto &geomIter : compIter.second->m_geomVec) { triGeomShPtr = std::dynamic_pointer_cast(geomIter); quadGeomShPtr = std::dynamic_pointer_cast(geomIter); diff --git a/library/SpatialDomains/MeshGraph.h b/library/SpatialDomains/MeshGraph.h index 8c64dd8eb31c670b39169a932a61842abdd2f7cf..84992f322a8b14013b459e68604b0bfd612800e2 100644 --- a/library/SpatialDomains/MeshGraph.h +++ b/library/SpatialDomains/MeshGraph.h @@ -172,6 +172,9 @@ typedef std::map MeshMetaDataMap; class MeshGraph; typedef std::shared_ptr MeshGraphSharedPtr; +class Movement; +typedef std::shared_ptr MovementSharedPtr; + /// Base class for a spectral/hp element mesh. class MeshGraph { @@ -436,6 +439,11 @@ public: SPATIAL_DOMAINS_EXPORT std::map CreateMeshEntities(); SPATIAL_DOMAINS_EXPORT CompositeDescriptor CreateCompositeDescriptor(); + SPATIAL_DOMAINS_EXPORT inline MovementSharedPtr &GetMovement() + { + return m_movement; + } + protected: void PopulateFaceToElMap(Geometry3DSharedPtr element, int kNfaces); ExpansionInfoMapShPtr SetUpExpansionInfoMap(); @@ -479,6 +487,7 @@ protected: struct GeomRTree; std::unique_ptr m_boundingBoxTree; + MovementSharedPtr m_movement = nullptr; }; typedef std::shared_ptr MeshGraphSharedPtr; typedef LibUtilities::NekFactory MeshGraphFactory; diff --git a/library/SpatialDomains/MeshGraphHDF5.cpp b/library/SpatialDomains/MeshGraphHDF5.cpp index 278a76d1ad1861cc45ed1f59159db67c13438fd2..bc137e385a0324b632ed4dfbb378e49ad2caa69d 100644 --- a/library/SpatialDomains/MeshGraphHDF5.cpp +++ b/library/SpatialDomains/MeshGraphHDF5.cpp @@ -46,7 +46,7 @@ #define TIME_RESULT(verb, msg, timer) \ if (verb) \ { \ - std::cout << " - " << msg << ": " << timer.TimePerTest(1) \ + std::cout << " - " << msg << ": " << timer.TimePerTest(1) << "\n" \ << std::endl; \ } @@ -60,7 +60,7 @@ namespace SpatialDomains /// Version of the Nektar++ HDF5 geometry format, which is embedded into the /// main NEKTAR/GEOMETRY group as an attribute. -const unsigned int MeshGraphHDF5::FORMAT_VERSION = 1; +const unsigned int MeshGraphHDF5::FORMAT_VERSION = 2; std::string MeshGraphHDF5::className = GetMeshGraphFactory().RegisterCreatorFunction("HDF5", MeshGraphHDF5::create, @@ -251,7 +251,6 @@ void MeshGraphHDF5::PartitionMesh(LibUtilities::SessionReaderSharedPtr session) ASSERTL0(root2, "Cannot find NEKTAR/GEOMETRY group in HDF5 file."); // Check format version - unsigned int formatVersion; H5::Group::AttrIterator attrIt = root2->attr_begin(); H5::Group::AttrIterator attrEnd = root2->attr_end(); for (; attrIt != attrEnd; ++attrIt) @@ -263,9 +262,9 @@ void MeshGraphHDF5::PartitionMesh(LibUtilities::SessionReaderSharedPtr session) } ASSERTL0(attrIt != attrEnd, "Unable to determine Nektar++ geometry HDF5 file version."); - root2->GetAttribute("FORMAT_VERSION", formatVersion); + root2->GetAttribute("FORMAT_VERSION", m_inFormatVersion); - ASSERTL0(formatVersion <= FORMAT_VERSION, + ASSERTL0(m_inFormatVersion <= FORMAT_VERSION, "File format in " + m_hdf5Name + " is higher than supported in " "this version of Nektar++"); @@ -1063,14 +1062,42 @@ void MeshGraphHDF5::ReadCurveMap(CurveMap &curveMap, std::string dsName, void MeshGraphHDF5::ReadDomain() { - map fullDomain; + if (m_inFormatVersion == 1) + { + map fullDomain; + H5::DataSetSharedPtr dst = m_mesh->OpenDataSet("DOMAIN"); + H5::DataSpaceSharedPtr space = dst->GetSpace(); + + vector data; + dst->ReadVectorString(data, space, m_readPL); + GetCompositeList(data[0], fullDomain); + m_domain[0] = fullDomain; + + return; + } + + std::vector fullDomain; H5::DataSetSharedPtr dst = m_mesh->OpenDataSet("DOMAIN"); H5::DataSpaceSharedPtr space = dst->GetSpace(); vector data; dst->ReadVectorString(data, space, m_readPL); - GetCompositeList(data[0], fullDomain); - m_domain[0] = fullDomain; + for (auto &dIt : data) + { + fullDomain.push_back(CompositeMap()); + GetCompositeList(dIt, fullDomain.back()); + } + + H5::DataSetSharedPtr mdata = m_maps->OpenDataSet("DOMAIN"); + H5::DataSpaceSharedPtr mspace = mdata->GetSpace(); + + vector ids; + mdata->Read(ids, mspace); + + for (int i = 0; i < ids.size(); ++i) + { + m_domain[ids[i]] = fullDomain[i]; + } } void MeshGraphHDF5::ReadComposites() @@ -1476,21 +1503,43 @@ void MeshGraphHDF5::WriteComposites(CompositeMap &composites) dst->Write(c_map, ds); } -void MeshGraphHDF5::WriteDomain(map &domain) +void MeshGraphHDF5::WriteDomain(std::map &domain) { - vector idxList; - for (auto cIt = domain[0].begin(); cIt != domain[0].end(); ++cIt) + // dont need location map only a id map + // will filter the composites per parition on read, its easier + // composites do not need to be written in paralell. + vector d_map; + std::vector> idxList; + + int cnt = 0; + for (auto &dIt : domain) { - idxList.push_back(cIt->first); + idxList.push_back(std::vector()); + for (auto cIt = dIt.second.begin(); cIt != dIt.second.end(); ++cIt) + { + idxList[cnt].push_back(cIt->first); + } + + ++cnt; + d_map.push_back(dIt.first); } + stringstream domString; vector doms; - doms.push_back(ParseUtils::GenerateSeqString(idxList)); + for (auto &cIt : idxList) + { + doms.push_back(ParseUtils::GenerateSeqString(cIt)); + } H5::DataTypeSharedPtr tp = H5::DataType::String(); H5::DataSpaceSharedPtr ds = H5::DataSpace::OneD(doms.size()); H5::DataSetSharedPtr dst = m_mesh->CreateDataSet("DOMAIN", tp, ds); dst->WriteVectorString(doms, ds, tp); + + tp = H5::DataType::OfObject(d_map[0]); + ds = H5::DataSpace::OneD(d_map.size()); + dst = m_maps->CreateDataSet("DOMAIN", tp, ds); + dst->Write(d_map, ds); } void MeshGraphHDF5::WriteGeometry( diff --git a/library/SpatialDomains/MeshGraphHDF5.h b/library/SpatialDomains/MeshGraphHDF5.h index 0eaaf1d0c09fa4bced28b99b8be5e86c54b2e4ed..18e222791248cf7517e2162572fd4321f4bc33b6 100644 --- a/library/SpatialDomains/MeshGraphHDF5.h +++ b/library/SpatialDomains/MeshGraphHDF5.h @@ -113,6 +113,7 @@ private: LibUtilities::H5::PListSharedPtr m_readPL; LibUtilities::H5::GroupSharedPtr m_mesh; LibUtilities::H5::GroupSharedPtr m_maps; + unsigned int m_inFormatVersion; static const unsigned int FORMAT_VERSION; }; diff --git a/library/SpatialDomains/MeshGraphXml.cpp b/library/SpatialDomains/MeshGraphXml.cpp index 1bfc699a3cbea73ee90c4dd7f72badcd8fabfccf..9012f3b098bb8c90abe615fca8f100705be8bad5 100644 --- a/library/SpatialDomains/MeshGraphXml.cpp +++ b/library/SpatialDomains/MeshGraphXml.cpp @@ -2024,7 +2024,7 @@ void MeshGraphXml::ResolveGeomRef1D(const std::string &prevToken, if (m_vertSet.find(*iter) == m_vertSet.end()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *iter); + ::snprintf(errStr, 16, "%d", *iter); NEKERROR( ErrorUtil::ewarning, (std::string("Unknown vertex index: ") + errStr) @@ -2044,7 +2044,7 @@ void MeshGraphXml::ResolveGeomRef1D(const std::string &prevToken, if (m_segGeoms.find(*iter) == m_segGeoms.end()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *iter); + ::snprintf(errStr, 16, "%d", *iter); NEKERROR( ErrorUtil::ewarning, (std::string("Unknown segment index: ") + errStr) @@ -2128,7 +2128,7 @@ void MeshGraphXml::ResolveGeomRef2D(const std::string &prevToken, if (m_segGeoms.find(*seqIter) == m_segGeoms.end()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR(ErrorUtil::ewarning, (std::string("Unknown edge index: ") + errStr) .c_str()); @@ -2148,7 +2148,7 @@ void MeshGraphXml::ResolveGeomRef2D(const std::string &prevToken, if (m_triGeoms.count(*seqIter) == 0) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR( ErrorUtil::ewarning, (std::string("Unknown triangle index: ") + errStr) @@ -2174,7 +2174,7 @@ void MeshGraphXml::ResolveGeomRef2D(const std::string &prevToken, if (m_quadGeoms.count(*seqIter) == 0) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR(ErrorUtil::ewarning, (std::string("Unknown quad index: ") + errStr + std::string(" in Composite section")) @@ -2199,7 +2199,7 @@ void MeshGraphXml::ResolveGeomRef2D(const std::string &prevToken, if (*seqIter >= m_vertSet.size()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR( ErrorUtil::ewarning, (std::string("Unknown vertex index: ") + errStr) @@ -2292,7 +2292,7 @@ void MeshGraphXml::ResolveGeomRef3D(const std::string &prevToken, if (m_vertSet.find(*seqIter) == m_vertSet.end()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR( ErrorUtil::ewarning, (std::string("Unknown vertex index: ") + errStr) @@ -2312,7 +2312,7 @@ void MeshGraphXml::ResolveGeomRef3D(const std::string &prevToken, if (m_segGeoms.find(*seqIter) == m_segGeoms.end()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR(ErrorUtil::ewarning, (std::string("Unknown edge index: ") + errStr) .c_str()); @@ -2332,7 +2332,7 @@ void MeshGraphXml::ResolveGeomRef3D(const std::string &prevToken, if (face == Geometry2DSharedPtr()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR(ErrorUtil::ewarning, (std::string("Unknown face index: ") + errStr) .c_str()); @@ -2354,7 +2354,7 @@ void MeshGraphXml::ResolveGeomRef3D(const std::string &prevToken, if (m_triGeoms.find(*seqIter) == m_triGeoms.end()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR( ErrorUtil::ewarning, (std::string("Unknown triangle index: ") + errStr) @@ -2378,7 +2378,7 @@ void MeshGraphXml::ResolveGeomRef3D(const std::string &prevToken, if (m_quadGeoms.find(*seqIter) == m_quadGeoms.end()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR(ErrorUtil::ewarning, (std::string("Unknown quad index: ") + errStr) .c_str()); @@ -2402,7 +2402,7 @@ void MeshGraphXml::ResolveGeomRef3D(const std::string &prevToken, if (m_tetGeoms.find(*seqIter) == m_tetGeoms.end()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR(ErrorUtil::ewarning, (std::string("Unknown tet index: ") + errStr) .c_str()); @@ -2426,7 +2426,7 @@ void MeshGraphXml::ResolveGeomRef3D(const std::string &prevToken, if (m_pyrGeoms.find(*seqIter) == m_pyrGeoms.end()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR( ErrorUtil::ewarning, (std::string("Unknown pyramid index: ") + errStr) @@ -2451,7 +2451,7 @@ void MeshGraphXml::ResolveGeomRef3D(const std::string &prevToken, if (m_prismGeoms.find(*seqIter) == m_prismGeoms.end()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR(ErrorUtil::ewarning, (std::string("Unknown prism index: ") + errStr) .c_str()); @@ -2475,7 +2475,7 @@ void MeshGraphXml::ResolveGeomRef3D(const std::string &prevToken, if (m_hexGeoms.find(*seqIter) == m_hexGeoms.end()) { char errStr[16] = ""; - ::sprintf(errStr, "%d", *seqIter); + ::snprintf(errStr, 16, "%d", *seqIter); NEKERROR(ErrorUtil::ewarning, (std::string("Unknown hex index: ") + errStr) .c_str()); @@ -2728,29 +2728,29 @@ void MeshGraphXml::WriteComposites(TiXmlElement *geomTag, CompositeMap &comps, } void MeshGraphXml::WriteDomain(TiXmlElement *geomTag, - map &domain) + std::map &domainMap) { TiXmlElement *domTag = new TiXmlElement("DOMAIN"); - for (auto &d : domain) + vector idxList; + for (auto &domain : domainMap) { - stringstream domString; - if (d.second.size()) - { - domString.clear(); - TiXmlElement *dtag = new TiXmlElement("D"); - dtag->SetAttribute("ID", d.first); + TiXmlElement *c = new TiXmlElement("D"); + idxList.clear(); + stringstream s; + s << " " + << "C" + << "["; - vector idxList; - for (auto cIt = d.second.begin(); cIt != d.second.end(); ++cIt) - { - idxList.push_back(cIt->first); - } - domString << " C[" << ParseUtils::GenerateSeqString(idxList) - << "] "; - dtag->LinkEndChild(new TiXmlText(domString.str())); - domTag->LinkEndChild(dtag); + for (const auto &elem : domain.second) + { + idxList.push_back(elem.first); } + + s << ParseUtils::GenerateSeqString(idxList) << "] "; + c->SetAttribute("ID", domain.first); + c->LinkEndChild(new TiXmlText(s.str())); + domTag->LinkEndChild(c); } geomTag->LinkEndChild(domTag); @@ -2804,6 +2804,11 @@ void MeshGraphXml::WriteGeometry(std::string &outfilename, bool defaultExp, geomTag->SetAttribute("DIM", m_meshDimension); geomTag->SetAttribute("SPACE", m_spaceDimension); + if (m_session != nullptr && !m_session->GetComm()->IsSerial()) + { + geomTag->SetAttribute("PARTITION", m_session->GetComm()->GetRank()); + } + // Clear existing elements. geomTag->Clear(); @@ -3140,17 +3145,19 @@ void MeshGraphXml::WriteXMLGeometry(std::string outname, WriteComposites(geomTag, localComp, localCompLabels); map domain; - for (auto &d : m_domain) + for (auto &j : localComp) { - CompositeMap domMap; - for (auto &j : localComp) + for (auto &dom : m_domain) { - if (d.second.count(j.first)) + for (auto &dIt : dom.second) { - domMap[j.first] = j.second; + if (j.first == dIt.first) + { + domain[dom.first][j.first] = j.second; + break; + } } } - domain[d.first] = domMap; } WriteDomain(geomTag, domain); diff --git a/library/SpatialDomains/Movement/InterfaceInterpolation.h b/library/SpatialDomains/Movement/InterfaceInterpolation.h new file mode 100644 index 0000000000000000000000000000000000000000..4f23d2ef4d2429182282964c0aa1a386cacb0ea8 --- /dev/null +++ b/library/SpatialDomains/Movement/InterfaceInterpolation.h @@ -0,0 +1,163 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: InterfaceInterpolation.hpp +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// 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 s: +// +// 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. +// +// Description: Interface handling for zones using the interpolation method +// +// +//////////////////////////////////////////////////////////////////////////////// +#ifndef NEKTAR_SPATIALDOMAINS_INTERFACEINTERPOLATION_H +#define NEKTAR_SPATIALDOMAINS_INTERFACEINTERPOLATION_H + +#include + +namespace Nektar +{ + +namespace SpatialDomains +{ + +// Fwd def to allow for inclusion in meshgraph +struct Composite; +typedef std::shared_ptr CompositeSharedPtr; +typedef std::map CompositeMap; + +/// A interface which is a single edge on a zone for handling non-conformality +struct Interface +{ + /// Constructor + Interface(int indx, const CompositeMap &edge, bool skipCoordCheck) + : m_id(indx), m_skipCoordCheck(skipCoordCheck) + { + // Fill element Ids + for (auto &comp : edge) + { + for (auto &geom : comp.second->m_geomVec) + { + m_edge[geom->GetGlobalID()] = geom; + } + } + } + + /// Default destructor + virtual ~Interface() = default; + + /// Returns map of global ID to geometry of the interface edge + inline std::map const &GetEdge() const + { + return m_edge; + } + + /// Returns geometry of the interface edge with global ID @param id + inline GeometrySharedPtr const &GetEdge(int id) + { + return m_edge[id]; + } + + /// Checks if the interface edge is empty (used for parallelisation) + inline bool IsEmpty() const + { + return m_edge.empty(); + } + + /// Returns the matching opposite interface from the interface pair + inline std::shared_ptr &GetOppInterface() + { + return m_oppInterface; + } + + /// Returns the interface ID + inline int &GetId() + { + return m_id; + } + + /// Return the skip check flag for coordinate exchange in InterfaceMapDG + inline bool GetSkipCoordCheck() const + { + return m_skipCoordCheck; + } + +protected: + /// Matching opposite interface of the interface pair + std::shared_ptr m_oppInterface; + /// Interface ID + int m_id; + /// Map of global ID to geometry of the interface edge + std::map m_edge; + /// Skip the coord found check in InterfaceMapDG + bool m_skipCoordCheck; +}; + +typedef std::shared_ptr InterfaceShPtr; + +/** + * Interface pair consisting of a 'left' and 'right' interface. The allocation + * of 'left' and 'right' is arbitrary for any interface as long as it stays + * consistent. Every full interface will consist of exactly one 'left' and one + * 'right' interface, the nomenclature helps keep code understandable. + */ +struct InterfacePair +{ + /// Constructor + InterfacePair(const InterfaceShPtr &leftInterface, + const InterfaceShPtr &rightInterface) + : m_leftInterface(leftInterface), m_rightInterface(rightInterface) + { + // Sets the opposite interfaces + leftInterface->GetOppInterface() = rightInterface; + rightInterface->GetOppInterface() = leftInterface; + } + + /// 'Left' interface of the interface pair + InterfaceShPtr m_leftInterface; + /// 'Right' interface of the interface pair + InterfaceShPtr m_rightInterface; + +public: + /// Return the 'left' interface from the interface pair + inline const InterfaceShPtr &GetLeftInterface() const + { + return m_leftInterface; + } + + /// Return the 'right' interface from the interface pair + inline const InterfaceShPtr &GetRightInterface() const + { + return m_rightInterface; + } +}; + +typedef std::shared_ptr InterfacePairShPtr; + +} // namespace SpatialDomains +} // namespace Nektar + +#endif // NEKTAR_SPATIALDOMAINS_INTERFACEINTERPOLATION_H diff --git a/library/SpatialDomains/Movement/Movement.cpp b/library/SpatialDomains/Movement/Movement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac8045d6c0ca87ce035cc0ddeb0f9be8df3a8470 --- /dev/null +++ b/library/SpatialDomains/Movement/Movement.cpp @@ -0,0 +1,471 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: Movement.cpp +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// 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. +// +// Description: This file contains the base class for implementing +// non-conformal geometry using the Movement object +// +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +namespace Nektar +{ +namespace SpatialDomains +{ + +std::string static inline ReadTag(std::string &tagStr) +{ + std::string::size_type indxBeg = tagStr.find_first_of('[') + 1; + std::string::size_type indxEnd = tagStr.find_last_of(']') - 1; + + ASSERTL0( + indxBeg <= indxEnd, + (std::string("Error reading interface region definition:") + tagStr) + .c_str()); + + std::string indxStr = tagStr.substr(indxBeg, indxEnd - indxBeg + 1); + + return indxStr; +} + +Movement::Movement(const LibUtilities::SessionReaderSharedPtr &pSession, + MeshGraph *meshGraph) +{ + TiXmlNode *nektar = pSession->GetElement("NEKTAR"); + if (nektar == nullptr) + { + return; + } + + TiXmlNode *movement = nektar->FirstChild("MOVEMENT"); + if (movement != nullptr) + { + bool zones = movement->FirstChild("ZONES") != nullptr; + if (zones) + { + ReadZones(pSession->GetElement("NEKTAR/MOVEMENT/ZONES"), meshGraph, + pSession); + } + + bool interfaces = movement->FirstChild("INTERFACES") != nullptr; + if (interfaces) + { + ReadInterfaces(pSession->GetElement("NEKTAR/MOVEMENT/INTERFACES"), + meshGraph); + } + + ASSERTL0(zones == interfaces, + "Only one of ZONES or INTERFACES present in the MOVEMENT " + "block.") + + // Don't support interior penalty yet + if (pSession->DefinesSolverInfo("DiffusionType")) + { + ASSERTL0(pSession->GetSolverInfo("DiffusionType") == "LDGNS", + "Only LDGNS is supported as the DiffusionType in " + "SOLVERINFO when a MOVEMENT block is defined.") + } + } + + // DEBUG COMMENTS + if (movement != nullptr && pSession->DefinesCmdLineArgument("verbose")) + { + auto comm = pSession->GetComm(); + if (comm->TreatAsRankZero()) + { + std::cout << "Movement Info:\n"; + std::cout << "\tNum zones: " << m_zones.size() << "\n"; + } + + for (auto &zone : m_zones) + { + auto numEl = zone.second->GetElements().size(); + comm->AllReduce(numEl, LibUtilities::ReduceSum); + + // Find shape type if not on this proc + int shapeType = + !zone.second->GetElements().empty() + ? zone.second->GetElements().front()->GetShapeType() + : -1; + comm->AllReduce(shapeType, LibUtilities::ReduceMax); + + if (comm->TreatAsRankZero()) + { + std::cout << "\t- " << zone.first << " " + << MovementTypeStr[static_cast( + zone.second->GetMovementType())] + << ": " << numEl << " " + << LibUtilities::ShapeTypeMap[shapeType] << "s\n"; + } + } + + if (comm->TreatAsRankZero()) + { + std::cout << "\tNum interfaces: " << m_interfaces.size() << "\n"; + } + + for (auto &interface : m_interfaces) + { + auto numLeft = + interface.second->GetLeftInterface()->GetEdge().size(); + auto numRight = + interface.second->GetRightInterface()->GetEdge().size(); + comm->AllReduce(numLeft, LibUtilities::ReduceSum); + comm->AllReduce(numRight, LibUtilities::ReduceSum); + + // Find shape type if not on this proc + int shapeTypeLeft = + !interface.second->GetLeftInterface()->GetEdge().empty() + ? interface.second->GetLeftInterface() + ->GetEdge() + .begin() + ->second->GetShapeType() + : -1; + comm->AllReduce(shapeTypeLeft, LibUtilities::ReduceMax); + int shapeTypeRight = + !interface.second->GetRightInterface()->GetEdge().empty() + ? interface.second->GetRightInterface() + ->GetEdge() + .begin() + ->second->GetShapeType() + : -1; + comm->AllReduce(shapeTypeRight, LibUtilities::ReduceMax); + + if (comm->TreatAsRankZero()) + { + std::cout << "\t- \"" << interface.first.second << "\": " + << interface.second->GetLeftInterface()->GetId() + << " (" << numLeft << " " + << LibUtilities::ShapeTypeMap[shapeTypeLeft] + << "s) <-> " + << interface.second->GetRightInterface()->GetId() + << " (" << numRight << " " + << LibUtilities::ShapeTypeMap[shapeTypeRight] + << "s)\n"; + } + } + + comm->Block(); + if (comm->TreatAsRankZero()) + { + std::cout << std::endl; + } + } +} + +void Movement::ReadZones(TiXmlElement *zonesTag, MeshGraph *meshGraph, + const LibUtilities::SessionReaderSharedPtr &pSession) +{ + int coordDim = meshGraph->GetSpaceDimension(); + + ASSERTL0(zonesTag, "Unable to find ZONES tag in file."); + TiXmlElement *zonesElement = zonesTag->FirstChildElement(); + while (zonesElement) + { + std::string zoneType = zonesElement->Value(); + + int err; + int indx; + + err = zonesElement->QueryIntAttribute("ID", &indx); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read zone ID."); + + std::string interfaceDomainStr; + err = zonesElement->QueryStringAttribute("DOMAIN", &interfaceDomainStr); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read zone domain."); + + auto &domains = meshGraph->GetDomain(); + auto domFind = stoi(ReadTag(interfaceDomainStr)); + std::map domain; + if (domains.find(domFind) != domains.end()) + { + domain = domains.at(domFind); + } + + ZoneBaseShPtr zone; + if (zoneType == "F" || zoneType == "FIXED") + { + zone = ZoneFixedShPtr(MemoryManager::AllocateSharedPtr( + indx, domain, coordDim)); + } + else if (zoneType == "R" || zoneType == "ROTATE" || + zoneType == "ROTATING") + { + std::string originStr; + err = zonesElement->QueryStringAttribute("ORIGIN", &originStr); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read origin."); + std::vector originVec; + ParseUtils::GenerateVector(originStr, originVec); + NekPoint origin = + NekPoint(originVec[0], originVec[1], originVec[2]); + + std::string axisStr; + err = zonesElement->QueryStringAttribute("AXIS", &axisStr); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read axis."); + DNekVec axis(axisStr); + axis.Normalize(); + + std::string angularVelStr; + err = zonesElement->QueryStringAttribute("ANGVEL", &angularVelStr); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read angular velocity."); + + pSession->SubstituteExpressions(angularVelStr); + LibUtilities::EquationSharedPtr angularVelEqn = + MemoryManager::AllocateSharedPtr( + pSession->GetInterpreter(), angularVelStr); + + zone = ZoneRotateShPtr(MemoryManager::AllocateSharedPtr( + indx, domain, coordDim, origin, axis, angularVelEqn)); + + m_moveFlag = true; + } + else if (zoneType == "T" || zoneType == "TRANSLATE" || + zoneType == "TRANSLATING") + { + // Read velocity information + std::string velocityStr; + err = zonesElement->QueryStringAttribute("VELOCITY", &velocityStr); + ASSERTL0(err == TIXML_SUCCESS, + "Unable to read VELOCITY for translating zone " + + std::to_string(indx)); + + std::vector velocityStrSplit; + ParseUtils::GenerateVector(velocityStr, velocityStrSplit); + + ASSERTL0(velocityStrSplit.size() >= coordDim, + "VELOCITY dimensions must be greater than or equal to the " + "coordinate dimension for translating zone " + + std::to_string(indx)); + + Array velocityEqns(coordDim); + for (int i = 0; i < coordDim; ++i) + { + pSession->SubstituteExpressions(velocityStrSplit[i]); + + velocityEqns[i] = + MemoryManager::AllocateSharedPtr( + pSession->GetInterpreter(), velocityStrSplit[i]); + } + + // Read displacement information + std::string displacementStr; + err = zonesElement->QueryStringAttribute("DISPLACEMENT", + &displacementStr); + ASSERTL0(err == TIXML_SUCCESS, + "Unable to read DISPLACEMENT for translating zone " + + std::to_string(indx)); + + std::vector displacementStrSplit; + ParseUtils::GenerateVector(displacementStr, displacementStrSplit); + + ASSERTL0( + displacementStrSplit.size() >= coordDim, + "DISPLACEMENT dimensions must be greater than or equal to the " + "coordinate dimension for translating zone " + + std::to_string(indx)); + + Array displacementEqns( + coordDim); + for (int i = 0; i < coordDim; ++i) + { + pSession->SubstituteExpressions(displacementStrSplit[i]); + + displacementEqns[i] = + MemoryManager::AllocateSharedPtr( + pSession->GetInterpreter(), displacementStrSplit[i]); + } + + zone = ZoneTranslateShPtr( + MemoryManager::AllocateSharedPtr( + indx, domain, coordDim, velocityEqns, displacementEqns)); + + m_moveFlag = true; + } + else if (zoneType == "P" || zoneType == "PRESCRIBED") + { + std::string xDeformStr; + err = zonesElement->QueryStringAttribute("XDEFORM", &xDeformStr); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read x deform equation."); + LibUtilities::EquationSharedPtr xDeformEqn = + std::make_shared( + pSession->GetInterpreter(), xDeformStr); + + std::string yDeformStr; + err = zonesElement->QueryStringAttribute("YDEFORM", &yDeformStr); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read y deform equation."); + LibUtilities::EquationSharedPtr yDeformEqn = + std::make_shared( + pSession->GetInterpreter(), yDeformStr); + + std::string zDeformStr; + err = zonesElement->QueryStringAttribute("ZDEFORM", &zDeformStr); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read z deform equation."); + LibUtilities::EquationSharedPtr zDeformEqn = + std::make_shared( + pSession->GetInterpreter(), zDeformStr); + + zone = ZonePrescribeShPtr( + MemoryManager::AllocateSharedPtr( + indx, domain, coordDim, xDeformEqn, yDeformEqn, + zDeformEqn)); + + m_moveFlag = true; + } + else + { + WARNINGL0(false, "Zone type '" + zoneType + + "' is unsupported. Valid types are: 'Fixed', " + "'Rotate', 'Translate', or 'Prescribe'.") + } + + m_zones[indx] = zone; + zonesElement = zonesElement->NextSiblingElement(); + } +} + +void Movement::ReadInterfaces(TiXmlElement *interfacesTag, MeshGraph *meshGraph) +{ + ASSERTL0(interfacesTag, "Unable to find INTERFACES tag in file."); + TiXmlElement *interfaceElement = interfacesTag->FirstChildElement(); + + while (interfaceElement) + { + ASSERTL0( + "INTERFACE" == (std::string)interfaceElement->Value(), + "Only INTERFACE tags may be present inside the INTERFACES block.") + + int err; + + std::string name; + err = interfaceElement->QueryStringAttribute("NAME", &name); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read interface name."); + TiXmlElement *sideElement = interfaceElement->FirstChildElement(); + + Array interfaces(2); + std::vector cnt; + while (sideElement) + { + ASSERTL0( + cnt.size() < 2, + "In INTERFACE NAME " + name + + ", only two sides may be present in each INTERFACE block.") + + // Read ID + int indx; + err = sideElement->QueryIntAttribute("ID", &indx); + ASSERTL0(err == TIXML_SUCCESS, "Unable to read interface ID."); + + // Read boundary + std::string boundaryStr; + err = sideElement->QueryStringAttribute("BOUNDARY", &boundaryStr); + ASSERTL0(err == TIXML_SUCCESS, + "Unable to read BOUNDARY in interface " + + std::to_string(indx)); + + CompositeMap boundaryEdge; + std::string indxStr = ReadTag(boundaryStr); + meshGraph->GetCompositeList(indxStr, boundaryEdge); + + // Read SKIPCHECK flag + bool skipCheck = false; + err = sideElement->QueryBoolAttribute("SKIPCHECK", &skipCheck); + + // Sets location in interface pair to 0 for left, and 1 for right + auto sideElVal = sideElement->ValueStr(); + if (sideElVal == "LEFT" || sideElVal == "L") + { + cnt.emplace_back(0); + } + else if (sideElVal == "RIGHT" || sideElVal == "R") + { + cnt.emplace_back(1); + } + else + { + NEKERROR(ErrorUtil::efatal, + sideElement->ValueStr() + + " is not a valid interface side for interface " + "NAME " + + name + ". Please only use LEFT or RIGHT.") + } + + interfaces[cnt[cnt.size() - 1]] = + InterfaceShPtr(MemoryManager::AllocateSharedPtr( + indx, boundaryEdge, skipCheck)); + + sideElement = sideElement->NextSiblingElement(); + } + + ASSERTL0(std::accumulate(cnt.begin(), cnt.end(), 0) == 1, + "You must have only one LEFT and one RIGHT side" + " present in interface NAME " + + name) + + m_interfaces[std::make_pair(m_interfaces.size(), name)] = + InterfacePairShPtr(MemoryManager::AllocateSharedPtr( + interfaces[0], interfaces[1])); + interfaceElement = interfaceElement->NextSiblingElement(); + } +} + +// Acts as a placeholder for when ALE function and moving geometry capability +// is added. Currently unused. +void Movement::PerformMovement(NekDouble timeStep) +{ + std::set movedZoneIds; + for (auto &zone : m_zones) + { + if (zone.second->Move(timeStep)) + { + movedZoneIds.insert(zone.first); + } + } + + // If zone has moved, set all interfaces on that zone to moved. + for (auto &interPair : m_interfaces) + { + int leftId = interPair.second->GetLeftInterface()->GetId(); + int rightId = interPair.second->GetRightInterface()->GetId(); + + if (movedZoneIds.find(leftId) != movedZoneIds.end() || + movedZoneIds.find(rightId) != movedZoneIds.end()) + { + m_zones[leftId]->GetMoved() = true; + m_zones[rightId]->GetMoved() = true; + } + } +} + +} // namespace SpatialDomains +} // namespace Nektar diff --git a/library/SpatialDomains/Movement/Movement.h b/library/SpatialDomains/Movement/Movement.h new file mode 100644 index 0000000000000000000000000000000000000000..8b6af59fc549fded3f11eea887611af561da9d3d --- /dev/null +++ b/library/SpatialDomains/Movement/Movement.h @@ -0,0 +1,104 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: Movement.h +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// 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 s: +// +// 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. +// +// Description: This file contains the base class for implementing +// non-conformal geometry using the Movement object +// +//////////////////////////////////////////////////////////////////////////////// +#ifndef NEKTAR_SPATIALDOMAINS_MOVEMENT_H +#define NEKTAR_SPATIALDOMAINS_MOVEMENT_H + +#include +#include + +namespace Nektar +{ + +namespace SpatialDomains +{ + +typedef std::map, InterfacePairShPtr> + InterfaceCollection; + +class Movement +{ +public: + /// Constructor + SPATIAL_DOMAINS_EXPORT Movement( + const LibUtilities::SessionReaderSharedPtr &pSession, + MeshGraph *meshGraph); + + /// Default destructor + SPATIAL_DOMAINS_EXPORT ~Movement() = default; + + inline const InterfaceCollection &GetInterfaces() const + { + return m_interfaces; + } + + inline const std::map &GetZones() const + { + return m_zones; + } + + void PerformMovement(NekDouble timeStep); + + inline const bool &GetMoveFlag() const + { + return m_moveFlag; + } + + inline bool &GetCoordExchangeFlag() + { + return m_coordExchangeFlag; + } + +protected: + InterfaceCollection m_interfaces; + std::map m_zones; + bool m_moveFlag = false; // Flags presence of moving zones + bool m_coordExchangeFlag = + true; // Flags if missing coordinates need to be calculated + +private: + /// Read zones given TiXmlDocument + void ReadZones(TiXmlElement *zonesTag, MeshGraph *meshGraph, + const LibUtilities::SessionReaderSharedPtr &pSession); + /// Read interfaces given TiXmlDocument + void ReadInterfaces(TiXmlElement *interfacesTag, MeshGraph *meshGraph); +}; + +typedef std::shared_ptr MovementSharedPtr; + +} // namespace SpatialDomains +} // namespace Nektar + +#endif // NEKTAR_SPATIALDOMAINS_MOVEMENT_H \ No newline at end of file diff --git a/library/SpatialDomains/Movement/Zones.cpp b/library/SpatialDomains/Movement/Zones.cpp new file mode 100644 index 0000000000000000000000000000000000000000..af78e51bbf07716b62cc8aee9b1b63e5a90ecb13 --- /dev/null +++ b/library/SpatialDomains/Movement/Zones.cpp @@ -0,0 +1,377 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: Zones.cpp +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// 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. +// +// Description: Zones used in the non-conformal interfaces +// and ALE implementations +// +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +namespace Nektar +{ +namespace SpatialDomains +{ + +ZoneBase::ZoneBase(MovementType type, int indx, CompositeMap domain, + int coordDim) + : m_type(type), m_id(indx), m_domain(domain), m_coordDim(coordDim) +{ + for (auto &comp : domain) + { + for (auto &geom : comp.second->m_geomVec) + { + m_elements.emplace_back(geom); + + // Fill constituent elements (i.e. faces and edges) + switch (geom->GetShapeDim()) + { + case 3: + for (int i = 0; i < geom->GetNumFaces(); ++i) + { + m_constituentElements[2].insert(geom->GetFace(i)); + } + /* fall through */ + case 2: + for (int i = 0; i < geom->GetNumEdges(); ++i) + { + m_constituentElements[1].insert(geom->GetEdge(i)); + } + /* fall through */ + case 1: + m_constituentElements[0].insert(geom); + /* fall through */ + default: + break; + } + } + } + + // The seenVerts/Edges/Faces keeps track of geometry so duplicates aren't + // emplaced in to the storage vector + std::unordered_set seenVerts, seenEdges, seenFaces; + + // Fill verts/edges/faces vector storage that are to be moved each timestep + for (auto &comp : m_domain) + { + for (auto &geom : comp.second->m_geomVec) + { + for (int i = 0; i < geom->GetNumVerts(); ++i) + { + PointGeomSharedPtr vert = geom->GetVertex(i); + + if (seenVerts.find(vert->GetGlobalID()) != seenVerts.end()) + { + continue; + } + + seenVerts.insert(vert->GetGlobalID()); + m_verts.emplace_back(vert); + } + + for (int i = 0; i < geom->GetNumEdges(); ++i) + { + SegGeomSharedPtr edge = + std::static_pointer_cast(geom->GetEdge(i)); + + if (seenEdges.find(edge->GetGlobalID()) != seenEdges.end()) + { + continue; + } + + seenEdges.insert(edge->GetGlobalID()); + + CurveSharedPtr curve = edge->GetCurve(); + if (!curve) + { + continue; + } + + m_curves.emplace_back(curve); + } + + for (int i = 0; i < geom->GetNumFaces(); ++i) + { + Geometry2DSharedPtr face = + std::static_pointer_cast(geom->GetFace(i)); + + if (seenFaces.find(face->GetGlobalID()) != seenFaces.end()) + { + continue; + } + + seenFaces.insert(face->GetGlobalID()); + + CurveSharedPtr curve = face->GetCurve(); + if (!curve) + { + continue; + } + + m_curves.emplace_back(curve); + } + } + } + + // Copy points so we know original positions. + for (auto &pt : m_verts) + { + m_origVerts.emplace_back(*pt); + } + + for (auto &curve : m_curves) + { + for (auto &pt : curve->m_points) + { + m_origVerts.emplace_back(*pt); + } + } +} + +ZoneRotate::ZoneRotate(int id, const CompositeMap &domain, const int coordDim, + const NekPoint &origin, const DNekVec &axis, + const LibUtilities::EquationSharedPtr &angularVelEqn) + : ZoneBase(MovementType::eRotate, id, domain, coordDim), m_origin(origin), + m_axis(axis), m_angularVelEqn(angularVelEqn) +{ + // Construct rotation matrix + m_W(0, 1) = -m_axis[2]; + m_W(0, 2) = m_axis[1]; + m_W(1, 0) = m_axis[2]; + m_W(1, 2) = -m_axis[0]; + m_W(2, 0) = -m_axis[1]; + m_W(2, 1) = m_axis[0]; + + m_W2 = m_W * m_W; +} + +void ZoneBase::ClearBoundingBoxes() +{ + // Clear bboxes (these will be regenerated next time GetBoundingBox is + // called) + for (auto &el : m_elements) + { + el->ClearBoundingBox(); + + int nfaces = el->GetNumFaces(); + for (int i = 0; i < nfaces; ++i) + { + el->GetFace(i)->ClearBoundingBox(); + } + + int nedges = el->GetNumEdges(); + for (int i = 0; i < nedges; ++i) + { + el->GetEdge(i)->ClearBoundingBox(); + } + } +} + +NekDouble ZoneRotate::GetAngularVel(NekDouble &time) const +{ + NekDouble rampTime = 1; + if (time < rampTime) + { + return m_angularVelEqn->Evaluate(0, 0, 0, time) * time/rampTime; + } + else + { + return m_angularVelEqn->Evaluate(0, 0, 0, time); + } +} + +// Calculate new location of points using Rodrigues formula +bool ZoneRotate::v_Move(NekDouble time) +{ + // This works for a linear ramp + NekDouble rampTime = 1; + NekDouble angle; + if (time < rampTime) + { + angle = GetAngularVel(time) * (time/rampTime) / 2; + } + else + { + angle = GetAngularVel(rampTime) * rampTime / 2 + GetAngularVel(time) * (time - rampTime); + } + + // TODO: I want to integrate m_angularVelEqn up to current time + + // Identity matrix + DNekMat rot(3, 3, 0.0); + rot(0, 0) = 1.0; + rot(1, 1) = 1.0; + rot(2, 2) = 1.0; + + // Rodrigues' rotation formula in matrix form + rot = rot + sin(angle) * m_W + (1 - cos(angle)) * m_W2; + + int cnt = 0; + for (auto &vert : m_verts) + { + NekPoint pnt = m_origVerts[cnt] - m_origin; + DNekVec pntVec = {pnt[0], pnt[1], pnt[2]}; + + DNekVec newLoc = rot * pntVec; + + vert->UpdatePosition(newLoc(0) + m_origin[0], newLoc(1) + m_origin[1], + newLoc(2) + m_origin[2]); + cnt++; + } + + for (auto &curve : m_curves) + { + for (auto &vert : curve->m_points) + { + NekPoint pnt = m_origVerts[cnt] - m_origin; + DNekVec pntVec = {pnt[0], pnt[1], pnt[2]}; + + DNekVec newLoc = rot * pntVec; + + vert->UpdatePosition(newLoc(0) + m_origin[0], + newLoc(1) + m_origin[1], + newLoc(2) + m_origin[2]); + cnt++; + } + } + + ClearBoundingBoxes(); + + return true; +} + +std::vector ZoneTranslate::GetVel(NekDouble &time) const +{ + std::vector vel(m_coordDim); + for (int i = 0; i < m_coordDim; ++i) + { + vel[i] = m_velocityEqns[i]->Evaluate(0, 0, 0, time); + } + + return vel; +} + +std::vector ZoneTranslate::GetDisp(NekDouble &time) const +{ + std::vector disp(m_coordDim); + for (int i = 0; i < m_coordDim; ++i) + { + disp[i] = m_displacementEqns[i]->Evaluate(0, 0, 0, time); + } + + return disp; +} + +bool ZoneTranslate::v_Move(NekDouble time) +{ + auto disp = GetDisp(time); + + int cnt = 0; + for (auto &vert : m_verts) + { + Array newLoc(3, 0.0); + auto pnt = m_origVerts[cnt]; + + for (int i = 0; i < m_coordDim; ++i) + { + newLoc[i] = pnt(i) + disp[i]; + } + + vert->UpdatePosition(newLoc[0], newLoc[1], newLoc[2]); + cnt++; + } + + for (auto &curve : m_curves) + { + for (auto &vert : curve->m_points) + { + Array newLoc(3, 0.0); + auto pnt = m_origVerts[cnt]; + + for (int i = 0; i < m_coordDim; ++i) + { + newLoc[i] = pnt(i) + disp[i]; + } + + vert->UpdatePosition(newLoc[0], newLoc[1], newLoc[2]); + cnt++; + } + } + + ClearBoundingBoxes(); + + return true; +} + +bool ZoneFixed::v_Move(NekDouble time) +{ + boost::ignore_unused(time); + return false; +} + +bool ZonePrescribe::v_Move(NekDouble time) +{ + int cnt = 0; + for (auto &vert : m_verts) + { + auto pnt = m_origVerts[cnt++]; + + Array coords(3, 0.0); + vert->GetCoords(coords); + + Array newLoc(3, 0.0); + /*newLoc[0] = + m_xDeform->Evaluate(coords[0], coords[1], coords[2], time) + pnt(0); + newLoc[1] = + m_yDeform->Evaluate(coords[0], coords[1], coords[2], time) + pnt(1); + newLoc[2] = + m_zDeform->Evaluate(coords[0], coords[1], coords[2], time) + pnt(2);*/ + + newLoc[0] = pnt(0) + 0.5 * sin(2 * M_PI * time / sqrt(50)) * + sin(2 * M_PI * coords[0] / 20) * + sin(2 * M_PI * coords[1] / 20); + newLoc[1] = pnt(1) + 0.5 * sin(2 * M_PI * time / sqrt(50)) * + sin(2 * M_PI * coords[0] / 20) * + sin(2 * M_PI * coords[1] / 20); + newLoc[2] = 0.0; + vert->UpdatePosition(newLoc[0], newLoc[1], newLoc[2]); + } + + ClearBoundingBoxes(); + + return true; +} + +} // namespace SpatialDomains +} // namespace Nektar diff --git a/library/SpatialDomains/Movement/Zones.h b/library/SpatialDomains/Movement/Zones.h new file mode 100644 index 0000000000000000000000000000000000000000..453422e2e4a2b6d12099a2478178abd87bf4366c --- /dev/null +++ b/library/SpatialDomains/Movement/Zones.h @@ -0,0 +1,339 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// File: Zones.h +// +// For more information, please see: http://www.nektar.info/ +// +// The MIT License +// +// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA), +// Department of Aeronautics, Imperial College London (UK), and Scientific +// Computing and Imaging Institute, University of Utah (USA). +// +// License for the specific language governing rights and limitations under +// 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 s: +// +// 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. +// +// Description: Zones used in the non-conformal interfaces +// and ALE implementations +// +//////////////////////////////////////////////////////////////////////////////// +#ifndef NEKTAR_SPATIALDOMAINS_ZONES_H +#define NEKTAR_SPATIALDOMAINS_ZONES_H + +#include + +namespace Nektar +{ + +namespace SpatialDomains +{ + +/// Enum of zone movement type +enum class MovementType +{ + eNone, + eFixed, + eRotate, + eTranslate, + ePrescribe +}; + +/// Map of zone movement type to movement type string +const std::string MovementTypeStr[] = {"None", "Fixed", "Rotated", "Translated", + "Prescribed"}; + +/// Zone base: Contains the shared functions and variables +struct ZoneBase +{ + /// Constructor + ZoneBase(MovementType type, int indx, CompositeMap domain, int coordDim); + + /// Default destructor + virtual ~ZoneBase() = default; + + /// Returns the type of movement + inline MovementType GetMovementType() const + { + return m_type; + } + + /// Returns the domain the zone is on + inline CompositeMap GetDomain() const + { + return m_domain; + } + + /// Returns the zone ID + inline int &GetId() + { + return m_id; + } + + /// Virtual function for movement of the zone at @param time + inline virtual bool v_Move(NekDouble time) + { + boost::ignore_unused(time); + return false; + } + + /// Performs the movement of the zone at @param time + inline bool Move(NekDouble time) + { + return v_Move(time); + } + + /// Returns all highest dimension elements in the zone + inline std::vector const &GetElements() const + { + return m_elements; + } + + /// Returns the flag which states if the zone has moved in this timestep + inline bool &GetMoved() + { + return m_moved; + } + + /// Clears all bounding boxes associated with the zones elements + void ClearBoundingBoxes(); + + /// Returns constituent elements, i.e. faces + edges + inline std::array, 3> &GetConstituentElements() + { + return m_constituentElements; + } + +protected: + /// Type of zone movement + MovementType m_type = MovementType::eNone; + /// Zone ID + int m_id; + /// Zone domain + CompositeMap m_domain; + /// Vector of highest dimension zone elements + std::vector m_elements; + /// Array of all dimension elements i.e. faces = [2], edges = [1], geom = + /// [0] + std::array, 3> m_constituentElements; + /// Moved flag + bool m_moved = true; + /// Coordinate dimension + int m_coordDim; + /// Vector of all points in the zone + std::vector m_verts; + /// Vector of all curves in the zone + std::vector m_curves; + /// Vector of all points in the zone at initialisation + std::vector m_origVerts; +}; + +typedef std::shared_ptr ZoneBaseShPtr; + +/// Rotating zone: Motion of every point around a given axis on an origin +struct ZoneRotate final : public ZoneBase +{ + /** + * Constructor for rotating zones + * + * @param id Zone ID + * @param domain Domain that the zone consists of + * @param coordDim Coordinate dimension + * @param origin Origin that the zone rotates about + * @param axis Axis that the zone rotates about + * @param angularVelEqn Equation for the angular velocity of rotation + */ + ZoneRotate(int id, const CompositeMap &domain, const int coordDim, + const NekPoint &origin, const DNekVec &axis, + const LibUtilities::EquationSharedPtr &angularVelEqn); + + /// Default destructor + virtual ~ZoneRotate() = default; + + /// Return the angular velocity of the zone at @param time + NekDouble GetAngularVel(NekDouble &time) const; + + /// Virtual function for movement of the zone at @param time + virtual bool v_Move(NekDouble time) final; + + inline NekPoint GetOrigin() const + { + return m_origin; + } + + inline DNekVec GetAxis() const + { + return m_axis; + } + +protected: + /// Origin point rotation is performed around + NekPoint m_origin; + /// Axis rotation is performed around + DNekVec m_axis; + /// Equation defining angular velocity as a function of time + LibUtilities::EquationSharedPtr m_angularVelEqn; + /// W matrix Rodrigues' rotation formula, cross product of axis + DNekMat m_W = DNekMat(3, 3, 0.0); + /// W^2 matrix Rodrigues' rotation formula, cross product of axis squared + DNekMat m_W2 = DNekMat(3, 3, 0.0); +}; + +/// Translating zone: addition of a constant vector to every point +struct ZoneTranslate final : public ZoneBase +{ + /** + * Constructor for translating zone + * + * @param id Zone ID + * @param domain Domain that the zone consists of + * @param coordDim Coordinate dimension + * @param velocity Vector of translation velocity in x,y,z direction + */ + ZoneTranslate(int id, const CompositeMap &domain, const int coordDim, + const Array &velocityEqns, + const Array &displacementEqns) + : ZoneBase(MovementType::eTranslate, id, domain, coordDim), + m_velocityEqns(velocityEqns), m_displacementEqns(displacementEqns) + { + } + + /// Default destructor + virtual ~ZoneTranslate() = default; + + /// Returns the velocity of the zone + std::vector GetVel(NekDouble &time) const; + + /// Returns the displacement of the zone + std::vector GetDisp(NekDouble &time) const; + + /// Virtual function for movement of the zone at @param time + virtual bool v_Move(NekDouble time) final; + +protected: + Array m_velocityEqns; + Array m_displacementEqns; +}; + +/// Prescribed zone: applies equation to every point +struct ZonePrescribe final : public ZoneBase +{ + /** + * Constructor for prescribed zone + * + * @param id Zone ID + * @param domain Domain that the zone consists of + * @param coordDim Coordinate dimension + * @param xDeform Equation for prescribed motion of x-coordinate + * @param yDeform Equation for prescribed motion of y-coordinate + * @param zDeform Equation for prescribed motion of z-coordinate + */ + ZonePrescribe(int id, const CompositeMap &domain, const int coordDim, + LibUtilities::EquationSharedPtr xDeform, + LibUtilities::EquationSharedPtr yDeform, + LibUtilities::EquationSharedPtr zDeform) + : ZoneBase(MovementType::ePrescribe, id, domain, coordDim), + m_xDeform(xDeform), m_yDeform(yDeform), m_zDeform(zDeform) + { + } + + /// Default destructor + virtual ~ZonePrescribe() = default; + + /** + * Returns point @param x @param y @param z deformation in the x direction + * at time @param t + * @param x x-coordinate + * @param y y-coordinate + * @param z z-coordinate + * @param t time + * @return deformation in x direction + */ + inline NekDouble GetXDeform(NekDouble x, NekDouble y, NekDouble z, + NekDouble t) const + { + return m_xDeform->Evaluate(x, y, z, t); + } + + /** + * Returns point @param x @param y @param z deformation in the y direction + * at time @param t + * @param x x-coordinate + * @param y y-coordinate + * @param z z-coordinate + * @param t time + * @return deformation in y direction + */ + inline NekDouble GetYDeform(NekDouble x, NekDouble y, NekDouble z, + NekDouble t) const + { + return m_yDeform->Evaluate(x, y, z, t); + } + + /** + * Returns point @param x @param y @param z deformation in the z direction + * at time @param t + * @param x x-coordinate + * @param y y-coordinate + * @param z z-coordinate + * @param t time + * @return deformation in z direction + */ + inline NekDouble GetZDeform(NekDouble x, NekDouble y, NekDouble z, + NekDouble t) const + { + return m_zDeform->Evaluate(x, y, z, t); + } + + /// Virtual function for movement of the zone at @param time + virtual bool v_Move(NekDouble time) final; + +protected: + /// Equation specifying prescribed motion in x-direction + LibUtilities::EquationSharedPtr m_xDeform; + /// Equation specifying prescribed motion in y-direction + LibUtilities::EquationSharedPtr m_yDeform; + /// Equation specifying prescribed motion in z-direction + LibUtilities::EquationSharedPtr m_zDeform; +}; + +/// Fixed zone: does not move +struct ZoneFixed final : public ZoneBase +{ + /// Constructor + ZoneFixed(int id, const CompositeMap &domain, const int coordDim) + : ZoneBase(MovementType::eFixed, id, domain, coordDim) + { + } + + /// Default destructor + virtual ~ZoneFixed() = default; + + /// Virtual function for movement of the zone at @param time + virtual bool v_Move(NekDouble time) final; +}; + +typedef std::shared_ptr ZoneRotateShPtr; +typedef std::shared_ptr ZoneTranslateShPtr; +typedef std::shared_ptr ZonePrescribeShPtr; +typedef std::shared_ptr ZoneFixedShPtr; + +} // namespace SpatialDomains +} // namespace Nektar + +#endif // NEKTAR_SPATIALDOMAINS_ZONES_H diff --git a/library/SpatialDomains/QuadGeom.cpp b/library/SpatialDomains/QuadGeom.cpp index 7905dd0a4544ddc40c09125d1908c0012becc288..0bed61dc5d1b73cd6474d4174a47995f6d19dc0c 100644 --- a/library/SpatialDomains/QuadGeom.cpp +++ b/library/SpatialDomains/QuadGeom.cpp @@ -317,7 +317,7 @@ void QuadGeom::v_GenGeomFactors() { if (fabs((*m_verts[0])(i) - (*m_verts[1])(i) + (*m_verts[2])(i) - (*m_verts[3])(i)) > - NekConstants::kNekZeroTol) + NekConstants::kGeomFactorsTol) { Gtype = eDeformed; break; diff --git a/library/SpatialDomains/SegGeom.cpp b/library/SpatialDomains/SegGeom.cpp index 521ef8f08f339cda59c2d287b5271b2bd6fd9369..9761bc359aae6ac7cc90d43064fbb1ae8f8c9f0d 100644 --- a/library/SpatialDomains/SegGeom.cpp +++ b/library/SpatialDomains/SegGeom.cpp @@ -349,5 +349,149 @@ int SegGeom::v_GetNumVerts() const return kNverts; } +NekDouble SegGeom::v_FindDistance(const Array &xs, + Array &xiOut) +{ + if (m_geomFactors->GetGtype() == eRegular) + { + xiOut = Array(1, 0.0); + + GetLocCoords(xs, xiOut); + ClampLocCoords(xiOut); + + Array gloCoord(m_coordim); + NekDouble tmp = 0; + for (int i = 0; i < m_coordim; ++i) + { + gloCoord[i] = GetCoord(i, xiOut); + tmp += (xs[i] - gloCoord[i]) * (xs[i] - gloCoord[i]); + } + + return sqrt(tmp); + } + // If deformed edge then the inverse mapping is non-linear so need to + // numerically solve for the local coordinate + else if (m_geomFactors->GetGtype() == eDeformed) + { + Array xi(1, 0.0); + + // Armijo constants: + // https://en.wikipedia.org/wiki/Backtracking_line_search + const NekDouble c1 = 1e-4, c2 = 0.9; + + int dim = GetCoordim(); + int nq = m_xmap->GetTotPoints(); + + Array> x(dim), xder(dim), xder2(dim); + // Get x,y,z phys values from coefficients + for (int i = 0; i < dim; ++i) + { + x[i] = Array(nq); + xder[i] = Array(nq); + xder2[i] = Array(nq); + + m_xmap->BwdTrans(m_coeffs[i], x[i]); + } + + NekDouble fx_prev = std::numeric_limits::max(); + + // Minimisation loop (Quasi-newton method) + for (int i = 0; i < NekConstants::kNewtonIterations; ++i) + { + // Compute the objective function, f(x_k) and its derivatives + Array xc(dim); + Array> xc_der(dim); + Array> xc_der2(dim); + NekDouble fx = 0, fxp = 0, fxp2 = 0, xcDiff = 0; + for (int j = 0; j < dim; ++j) + { + xc[j] = m_xmap->PhysEvaluate(xi, x[j], xc_der[j], xc_der2[j]); + + xcDiff = xc[j] - xs[j]; + // Objective function is the distance to the search point + fx += xcDiff * xcDiff; + fxp += xc_der[j][0] * xcDiff; + fxp2 += xc_der2[j][0] * xcDiff + xc_der[j][0] * xc_der[j][0]; + } + + fxp *= 2; + fxp2 *= 2; + + // Check for convergence + if (std::abs(fx - fx_prev) < 1e-12) + { + fx_prev = fx; + break; + } + else + { + fx_prev = fx; + } + + NekDouble gamma = 1.0; + bool conv = false; + + // Search direction: Newton's method + NekDouble pk = -fxp / fxp2; + + // Perform backtracking line search + while (gamma > 1e-10) + { + Array xi_pk(1); + xi_pk[0] = xi[0] + pk * gamma; + + if (xi_pk[0] < -1.0 || xi_pk[0] > 1.0) + { + gamma /= 2.0; + continue; + } + + Array xc_pk(dim); + Array> xc_der_pk(dim); + NekDouble fx_pk = 0, fxp_pk = 0, xc_pkDiff = 0; + for (int j = 0; j < dim; ++j) + { + xc_pk[j] = m_xmap->PhysEvaluate(xi_pk, x[j], xc_der_pk[j]); + + xc_pkDiff = xc_pk[j] - xs[j]; + fx_pk += xc_pkDiff * xc_pkDiff; + fxp_pk += xc_der_pk[j][0] * xc_pkDiff; + } + + fxp_pk *= 2; + + // Check Wolfe conditions using Armijo constants + // https://en.wikipedia.org/wiki/Wolfe_conditions + if ((fx_pk - (fx + c1 * gamma * pk * fxp)) < + std::numeric_limits::epsilon() && + (-pk * fxp_pk + c2 * pk * fxp) < + std::numeric_limits::epsilon()) + { + conv = true; + break; + } + + gamma /= 2.0; + } + + if (!conv) + { + break; + } + + xi[0] += gamma * pk; + } + + xiOut = xi; + return sqrt(fx_prev); + } + else + { + ASSERTL0(false, "Geometry type unknown") + } + + return -1.0; +} + } // namespace SpatialDomains } // namespace Nektar diff --git a/library/SpatialDomains/SegGeom.h b/library/SpatialDomains/SegGeom.h index 29348642d7324cce352b40dcd8f64ad7352b289e..5b93fd3e95f7e8419a273accd077bff62ba6c8ba 100644 --- a/library/SpatialDomains/SegGeom.h +++ b/library/SpatialDomains/SegGeom.h @@ -89,6 +89,8 @@ protected: virtual NekDouble v_GetCoord(const int i, const Array &Lcoord); virtual int v_GetNumVerts() const; + virtual NekDouble v_FindDistance(const Array &xs, + Array &xi); private: /// Boolean indicating whether object owns the data diff --git a/library/StdRegions/StdExpansion.cpp b/library/StdRegions/StdExpansion.cpp index 1032082d5a80089ac282391e06e42b4d43e668ce..a856b4794b963a9427e3b8f244ef4df8b3c7eb70 100644 --- a/library/StdRegions/StdExpansion.cpp +++ b/library/StdRegions/StdExpansion.cpp @@ -42,10 +42,6 @@ namespace Nektar { namespace StdRegions { -StdExpansion::StdExpansion(void) : m_elmt_id(0), m_ncoeffs(0) -{ -} - StdExpansion::StdExpansion(const int numcoeffs, const int numbases, const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, @@ -91,10 +87,6 @@ StdExpansion::StdExpansion(const StdExpansion &T) { } -StdExpansion::~StdExpansion() -{ -} - NekDouble StdExpansion::Linf(const Array &phys, const Array &sol) { @@ -1303,6 +1295,35 @@ NekDouble StdExpansion::v_PhysEvaluateBasis( return 0; } +NekDouble StdExpansion::v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + boost::ignore_unused(coord, inarray, firstOrderDerivs); + NEKERROR(ErrorUtil::efatal, + "PhysEvaluate first order derivative method does not exist" + " for this shape type: " + + static_cast( + LibUtilities::ShapeTypeMap[DetShapeType()])); + return 0; +} + +NekDouble StdExpansion::v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs, + std::array &secondOrderDerivs) +{ + boost::ignore_unused(coord, inarray, firstOrderDerivs, secondOrderDerivs); + NEKERROR(ErrorUtil::efatal, + "PhysEvaluate second order derivative method does not exist" + " for this shape type: " + + static_cast( + LibUtilities::ShapeTypeMap[DetShapeType()])); + return 0; +} + void StdExpansion::v_FillMode(const int mode, Array &outarray) { boost::ignore_unused(mode, outarray); diff --git a/library/StdRegions/StdExpansion.h b/library/StdRegions/StdExpansion.h index 635bd406e46b3f3aa7d68e71cb4dd4e9252f2b51..ce7319938253b5cf1caf0d8bba7ebbedb6593b74 100644 --- a/library/StdRegions/StdExpansion.h +++ b/library/StdRegions/StdExpansion.h @@ -71,7 +71,7 @@ class StdExpansion : public std::enable_shared_from_this { public: /** \brief Default Constructor */ - STD_REGIONS_EXPORT StdExpansion(); + STD_REGIONS_EXPORT StdExpansion() = default; /** \brief Constructor */ STD_REGIONS_EXPORT StdExpansion( @@ -84,7 +84,7 @@ public: STD_REGIONS_EXPORT StdExpansion(const StdExpansion &T); /** \brief Destructor */ - STD_REGIONS_EXPORT virtual ~StdExpansion(); + STD_REGIONS_EXPORT virtual ~StdExpansion() = default; // Standard Expansion Routines Applicable Regardless of Region @@ -923,6 +923,35 @@ public: return v_PhysEvaluate(coords, physvals); } + /** \brief This function evaluates the first derivative of the expansion + * at a single (arbitrary) point of the domain + * + * This function is a wrapper around the virtual function + * \a v_PhysEvaluate() + + * Based on the value of the expansion at the quadrature + * points provided in \a physvals, this function + * calculates the value of the expansion at a set of points + * given in \a coords + */ + inline NekDouble PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) + + { + return v_PhysEvaluate(coord, inarray, firstOrderDerivs); + } + + inline NekDouble PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs, + std::array &secondOrderDerivs) + + { + return v_PhysEvaluate(coord, inarray, firstOrderDerivs, + secondOrderDerivs); + } + /** \brief This function evaluates the expansion at a single * (arbitrary) point of the domain * @@ -1290,6 +1319,9 @@ protected: * @brief This function performs the barycentric interpolation of * the polynomial stored in @p coord at a point @p physvals using * barycentric interpolation weights in direction @tparam DIR. + * It can also perform the barycentric interpolation of the + * derivative of the polynomial if @tparam DERIV is set to true, + * which outputs in to @param deriv. * * This method is intended to be used a helper function for * StdExpansion::PhysEvaluate and its elemental instances, so that @@ -1299,15 +1331,20 @@ protected: * * @param coord The coordinate of the single point. * @param physvals The polynomial stored at each quadrature point. + * @param deriv The value of the derivative. + * @param deriv The value of the 2nd derivative. * @tparam DIR The direction of evaluation. + * @tparam DERIV Bool to find derivative. * * @return The value of @p physvals at @p coord in direction @p dir. */ - template + template inline NekDouble BaryEvaluate(const NekDouble &coord, - const NekDouble *physvals) + const NekDouble *physvals, NekDouble &deriv, + NekDouble &deriv2) { - NekDouble numer = 0.0, denom = 0.0; + NekDouble numer1 = 0.0, numer2 = 0.0, numer3 = 0.0, numer4 = 0.0, + numer5 = 0.0, denom = 0.0; ASSERTL2(DIR < m_base.size(), "Direction should be less than shape dimension."); @@ -1316,7 +1353,6 @@ protected: const Array &bw = m_base[DIR]->GetBaryWeights(); const auto nquad = z.size(); - for (int i = 0; i < nquad; ++i) { NekDouble xdiff = z[i] - coord; @@ -1329,17 +1365,74 @@ protected: * the paper here: *https://people.maths.ox.ac.uk/trefethen/barycentric.pdf */ - if (xdiff == 0.0) + if ((!DERIV && xdiff == 0.0) || + ((DERIV || DERIV2) && std::abs(xdiff) < 1e-15)) { + + if (DERIV2) + { + DNekMatSharedPtr D0 = m_base[DIR]->GetD(); + + // take ith row of z and multiply with physvals + Array tmp(nquad); + for (int kk = 0; kk < nquad; kk++) + { + tmp[kk] = Vmath::Dot(nquad, &(D0->GetPtr())[kk], nquad, + &physvals[0], 1); + } + + deriv2 = Vmath::Dot(nquad, &(D0->GetPtr())[i], nquad, + &tmp[0], 1); + deriv = tmp[i]; + } + else if (DERIV) + { + DNekMatSharedPtr D0 = m_base[DIR]->GetD(); + + // take ith row of z and multiply with physvals + deriv = Vmath::Dot(z.size(), &(D0->GetPtr())[i], z.size(), + &physvals[0], 1); + } + return pval; } NekDouble tmp = bw[i] / xdiff; - numer += tmp * pval; + numer1 += tmp * pval; denom += tmp; + + if (DERIV || DERIV2) + { + NekDouble tmp2 = tmp / xdiff; + numer2 += tmp2 * pval; + numer3 += tmp2; + + if (DERIV2) + { + NekDouble tmp3 = tmp2 / xdiff; + numer4 += tmp3 * pval; + numer5 += tmp3; + } + } } - return numer / denom; + if (DERIV || DERIV2) + { + NekDouble denomdenom = denom * denom; + NekDouble numer1numer3 = numer1 * numer3; + + deriv = (numer2 * denom - numer1numer3) / (denomdenom); + + if (DERIV2) + { + deriv2 = (2.0 * numer4 / denom) - + (2.0 * numer5 * numer1) / (denomdenom) - + (2.0 * numer2 * numer3) / (denomdenom) + + (2.0 * numer3 * numer1numer3) / (denomdenom * denom); + } + } + + return numer1 / denom; } /** @@ -1361,6 +1454,35 @@ protected: &(m_base[DIR]->GetBdata())[0] + nquad * mode); } + /** + * @brief Helper function to pass an unused value by reference into + * BaryEvaluate. + * + * @param coord The coordinate of the single point. + * @param physvals The polynomial stored at each quadrature point. + * @tparam DIR The direction of evaluation. + * @tparam DERIV Bool to find derivative. + * + * @return The value of @p physvals at @p coord in direction @p dir. + */ + template + inline NekDouble BaryEvaluate(const NekDouble &coord, + const NekDouble *physvals) + { + NekDouble unusedValue = 0.0; + return BaryEvaluate(coord, physvals, unusedValue, + unusedValue); + } + + template + inline NekDouble BaryEvaluate(const NekDouble &coord, + const NekDouble *physvals, NekDouble &deriv) + { + NekDouble unusedValue = 0.0; + return BaryEvaluate(coord, physvals, deriv, + unusedValue); + } + private: // Virtual functions STD_REGIONS_EXPORT virtual int v_GetNverts() const = 0; @@ -1483,6 +1605,17 @@ private: const Array &I, const Array &physvals); + STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs); + + STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs, + std::array &secondOrderDerivs); + STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluateBasis( const Array &coords, int mode); diff --git a/library/StdRegions/StdExpansion0D.cpp b/library/StdRegions/StdExpansion0D.cpp index 6d5af1c971d8cff5a5c063ee95747800494cc8a5..36ffc8e3d3fd0ba2e56bd8281b0f910bd8b90d76 100644 --- a/library/StdRegions/StdExpansion0D.cpp +++ b/library/StdRegions/StdExpansion0D.cpp @@ -40,11 +40,6 @@ namespace Nektar { namespace StdRegions { - -StdExpansion0D::StdExpansion0D() -{ -} - StdExpansion0D::StdExpansion0D(int numcoeffs, const LibUtilities::BasisKey &Ba) : StdExpansion(numcoeffs, 1, Ba) { @@ -54,10 +49,6 @@ StdExpansion0D::StdExpansion0D(const StdExpansion0D &T) : StdExpansion(T) { } -StdExpansion0D::~StdExpansion0D() -{ -} - //---------------------------- // Differentiation Methods //----------------------------- @@ -87,14 +78,20 @@ NekDouble StdExpansion0D::v_PhysEvaluate( const Array &Lcoord, const Array &physvals) { - int nquad = GetTotPoints(); - NekDouble val; - DNekMatSharedPtr I = m_base[0]->GetI(Lcoord); + ASSERTL2(Lcoord[0] >= -1 - NekConstants::kNekZeroTol, "Lcoord[0] < -1"); + ASSERTL2(Lcoord[0] <= 1 + NekConstants::kNekZeroTol, "Lcoord[0] > 1"); + + return StdExpansion::BaryEvaluate<0>(Lcoord[0], &physvals[0]); +} - ASSERTL2(Lcoord[0] >= -1, "Lcoord[0] < -1"); - ASSERTL2(Lcoord[0] <= 1, "Lcoord[0] > 1"); +NekDouble StdExpansion0D::v_PhysEvaluate( + const Array &I, + const Array &physvals) +{ + NekDouble val; + int nquad = GetTotPoints(); - val = Blas::Ddot(nquad, I->GetPtr(), 1, physvals, 1); + val = Blas::Ddot(nquad, I[0]->GetPtr(), 1, physvals, 1); return val; } diff --git a/library/StdRegions/StdExpansion0D.h b/library/StdRegions/StdExpansion0D.h index 514e909007b1f668d8c06c3f7635e0cdea0014b4..7ce01ed506a72e081aa3b0ee1a09dd3dc40355b6 100644 --- a/library/StdRegions/StdExpansion0D.h +++ b/library/StdRegions/StdExpansion0D.h @@ -49,35 +49,41 @@ class StdExpansion0D : virtual public StdExpansion { public: - STD_REGIONS_EXPORT StdExpansion0D(); + STD_REGIONS_EXPORT StdExpansion0D() : StdExpansion() + { + } + STD_REGIONS_EXPORT StdExpansion0D(int numcoeffs, const LibUtilities::BasisKey &Ba); STD_REGIONS_EXPORT StdExpansion0D(const StdExpansion0D &T); - STD_REGIONS_EXPORT virtual ~StdExpansion0D(); + STD_REGIONS_EXPORT ~StdExpansion0D() override = default; STD_REGIONS_EXPORT void PhysTensorDeriv( const Array &inarray, Array &outarray); + // Virtual Functions ---------------------------------------- protected: STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( const Array &coords, - const Array &physvals); + const Array &physvals) final; -private: - // Virtual Functions ---------------------------------------- + STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( + const Array &I, + const Array &physvals) override; - virtual int v_GetCoordim(void) +private: + virtual int v_GetCoordim(void) final { return 1; } - virtual int v_GetShapeDimension() const + virtual int v_GetShapeDimension() const final { return 1; } - virtual int v_GetNtraces() const + virtual int v_GetNtraces() const override { return 0; } diff --git a/library/StdRegions/StdExpansion1D.cpp b/library/StdRegions/StdExpansion1D.cpp index 3cf213473081ff0912f58c76467576faaf4071e6..708d96b7135fd0cd0173dda170be31adedcd8a31 100644 --- a/library/StdRegions/StdExpansion1D.cpp +++ b/library/StdRegions/StdExpansion1D.cpp @@ -40,11 +40,6 @@ namespace Nektar { namespace StdRegions { - -StdExpansion1D::StdExpansion1D() -{ -} - StdExpansion1D::StdExpansion1D(int numcoeffs, const LibUtilities::BasisKey &Ba) : StdExpansion(numcoeffs, 1, Ba) { @@ -54,10 +49,6 @@ StdExpansion1D::StdExpansion1D(const StdExpansion1D &T) : StdExpansion(T) { } -StdExpansion1D::~StdExpansion1D() -{ -} - //---------------------------- // Differentiation Methods //----------------------------- @@ -93,5 +84,24 @@ NekDouble StdExpansion1D::v_PhysEvaluate( return StdExpansion::BaryEvaluate<0>(Lcoord[0], &physvals[0]); } +NekDouble StdExpansion1D::v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + boost::ignore_unused(coord, inarray, firstOrderDerivs); + return 0; +} + +NekDouble StdExpansion1D::v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs, + std::array &secondOrderDerivs) +{ + boost::ignore_unused(coord, inarray, firstOrderDerivs, secondOrderDerivs); + return 0; +} + } // namespace StdRegions } // namespace Nektar diff --git a/library/StdRegions/StdExpansion1D.h b/library/StdRegions/StdExpansion1D.h index 959ed6141bde8115b1e87b42447b96b09658f2ec..e0cd9366d593319c40934a79e28c3eda26ad7114 100644 --- a/library/StdRegions/StdExpansion1D.h +++ b/library/StdRegions/StdExpansion1D.h @@ -49,11 +49,11 @@ class StdExpansion1D : virtual public StdExpansion { public: - STD_REGIONS_EXPORT StdExpansion1D(); + STD_REGIONS_EXPORT StdExpansion1D() = default; STD_REGIONS_EXPORT StdExpansion1D(int numcoeffs, const LibUtilities::BasisKey &Ba); STD_REGIONS_EXPORT StdExpansion1D(const StdExpansion1D &T); - STD_REGIONS_EXPORT virtual ~StdExpansion1D(); + STD_REGIONS_EXPORT ~StdExpansion1D() override = default; /** \brief Evaluate the derivative \f$ d/d{\xi_1} \f$ at the * physical quadrature points given by \a inarray and return in @@ -69,20 +69,52 @@ public: const Array &inarray, Array &outarray); + // find derivative of u (inarray) at all coords points + STD_REGIONS_EXPORT inline NekDouble BaryTensorDeriv( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) + { + return StdExpansion::BaryEvaluate<0, true>(coord[0], &inarray[0], + firstOrderDerivs[0]); + } + + // find derivative/2nd Derivative of u (inarray) at all coords points + STD_REGIONS_EXPORT inline NekDouble BaryTensorDeriv( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs, + std::array &secondOrderDerivs) + { + return StdExpansion::BaryEvaluate<0, true, true>( + coord[0], &inarray[0], firstOrderDerivs[0], secondOrderDerivs[0]); + } + protected: STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( const Array &coords, const Array &physvals) override; + STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) override; + + STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs, + std::array &secondOrderDerivs) override; + private: // Virtual Functions ---------------------------------------- - virtual int v_GetCoordim(void) override + int v_GetCoordim(void) override { return 1; } - virtual int v_GetShapeDimension() const final + int v_GetShapeDimension() const final { return 1; } diff --git a/library/StdRegions/StdExpansion2D.cpp b/library/StdRegions/StdExpansion2D.cpp index 71f18bf13e1d4793596b80d7a7e90b6593e19d8e..7924ab54c74fcb88094d572eecd731b815e6c81e 100644 --- a/library/StdRegions/StdExpansion2D.cpp +++ b/library/StdRegions/StdExpansion2D.cpp @@ -44,11 +44,6 @@ namespace Nektar { namespace StdRegions { - -StdExpansion2D::StdExpansion2D() -{ -} - StdExpansion2D::StdExpansion2D(int numcoeffs, const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb) : StdExpansion(numcoeffs, 2, Ba, Bb) @@ -59,10 +54,6 @@ StdExpansion2D::StdExpansion2D(const StdExpansion2D &T) : StdExpansion(T) { } -StdExpansion2D::~StdExpansion2D() -{ -} - //---------------------------- // Differentiation Methods //---------------------------- @@ -159,6 +150,15 @@ NekDouble StdExpansion2D::v_PhysEvaluate( return val; } +NekDouble StdExpansion2D::v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + boost::ignore_unused(coord, inarray, firstOrderDerivs); + return 0; +} + ////////////////////////////// // Integration Methods ////////////////////////////// diff --git a/library/StdRegions/StdExpansion2D.h b/library/StdRegions/StdExpansion2D.h index a510059bf0b008f1bbd77febe40930008906e1be..8d451f2271afd33d323e588cfbfd0f3f6c5ca983 100644 --- a/library/StdRegions/StdExpansion2D.h +++ b/library/StdRegions/StdExpansion2D.h @@ -48,12 +48,12 @@ namespace StdRegions class StdExpansion2D : virtual public StdExpansion { public: - STD_REGIONS_EXPORT StdExpansion2D(); + STD_REGIONS_EXPORT StdExpansion2D() = default; STD_REGIONS_EXPORT StdExpansion2D(int numcoeffs, const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb); STD_REGIONS_EXPORT StdExpansion2D(const StdExpansion2D &T); - STD_REGIONS_EXPORT virtual ~StdExpansion2D(); + STD_REGIONS_EXPORT virtual ~StdExpansion2D() override = default; // Generic operations in different element @@ -99,6 +99,31 @@ public: const Array &w0, const Array &w1); + // find derivative of u (inarray) at all coords points + STD_REGIONS_EXPORT inline NekDouble BaryTensorDeriv( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) + { + const int nq0 = m_base[0]->GetNumPoints(); + const int nq1 = m_base[1]->GetNumPoints(); + + const NekDouble *ptr = &inarray[0]; + Array deriv0(nq1, 0.0); + Array phys0(nq1, 0.0); + + for (int j = 0; j < nq1; ++j, ptr += nq0) + { + phys0[j] = + StdExpansion::BaryEvaluate<0, true>(coord[0], ptr, deriv0[j]); + } + firstOrderDerivs[0] = + StdExpansion::BaryEvaluate<1, false>(coord[1], &deriv0[0]); + + return StdExpansion::BaryEvaluate<1, true>(coord[1], &phys0[0], + firstOrderDerivs[1]); + } + STD_REGIONS_EXPORT void BwdTrans_SumFacKernel( const Array &base0, const Array &base1, @@ -138,11 +163,16 @@ protected: */ STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( const Array &coords, - const Array &physvals); + const Array &physvals) override; STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( const Array &I, - const Array &physvals); + const Array &physvals) override; + + STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) override; STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFacKernel( const Array &base0, @@ -160,34 +190,38 @@ protected: STD_REGIONS_EXPORT virtual void v_LaplacianMatrixOp_MatFree( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; STD_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp_MatFree( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; STD_REGIONS_EXPORT virtual void v_GetTraceCoeffMap( - const unsigned int traceid, Array &maparray); + const unsigned int traceid, + Array &maparray) override; STD_REGIONS_EXPORT virtual void v_GetElmtTraceToTraceMap( const unsigned int eid, Array &maparray, - Array &signarray, Orientation edgeOrient, int P, int Q); + Array &signarray, Orientation edgeOrient, int P, + int Q) override; STD_REGIONS_EXPORT virtual void v_GetTraceToElementMap( const int eid, Array &maparray, Array &signarray, Orientation edgeOrient = eForwards, - int P = -1, int Q = -1); + int P = -1, int Q = -1) override; - STD_REGIONS_EXPORT virtual void v_GenStdMatBwdDeriv(const int dir, - DNekMatSharedPtr &mat); + STD_REGIONS_EXPORT virtual void v_GenStdMatBwdDeriv( + const int dir, DNekMatSharedPtr &mat) override; private: // Virtual Functions ---------------------------------------- - virtual int v_GetShapeDimension() const + virtual int v_GetShapeDimension() const final { return 2; } - virtual int v_GetCoordim(void) + virtual int v_GetCoordim(void) override { return 2; } diff --git a/library/StdRegions/StdExpansion3D.cpp b/library/StdRegions/StdExpansion3D.cpp index ca8b7b766e6639f939f904c55819f394b0fa5b3c..42fbf7697c0ee515e7f4f7a338fa7b64967c0fba 100644 --- a/library/StdRegions/StdExpansion3D.cpp +++ b/library/StdRegions/StdExpansion3D.cpp @@ -46,10 +46,6 @@ namespace Nektar { namespace StdRegions { -StdExpansion3D::StdExpansion3D() -{ -} - StdExpansion3D::StdExpansion3D(int numcoeffs, const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc) @@ -61,9 +57,6 @@ StdExpansion3D::StdExpansion3D(const StdExpansion3D &T) : StdExpansion(T) { } -StdExpansion3D::~StdExpansion3D() -{ -} void StdExpansion3D::PhysTensorDeriv( const Array &inarray, Array &out_dx, Array &out_dy, Array &out_dz) @@ -278,6 +271,15 @@ NekDouble StdExpansion3D::v_PhysEvaluate( return value; } +NekDouble StdExpansion3D::v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + boost::ignore_unused(coord, inarray, firstOrderDerivs); + return 0; +} + /** * @param inarray Input coefficients. * @param output Output coefficients. diff --git a/library/StdRegions/StdExpansion3D.h b/library/StdRegions/StdExpansion3D.h index 0c7ca062271adc2d9c72796d56d748792453c84c..0df665512b1af2214118414ec46e9820dd63d6a7 100644 --- a/library/StdRegions/StdExpansion3D.h +++ b/library/StdRegions/StdExpansion3D.h @@ -52,13 +52,13 @@ class StdExpansion3D : virtual public StdExpansion { public: - STD_REGIONS_EXPORT StdExpansion3D(); + STD_REGIONS_EXPORT StdExpansion3D() = default; STD_REGIONS_EXPORT StdExpansion3D(int numcoeffs, const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc); STD_REGIONS_EXPORT StdExpansion3D(const StdExpansion3D &T); - STD_REGIONS_EXPORT virtual ~StdExpansion3D(); + STD_REGIONS_EXPORT virtual ~StdExpansion3D() override = default; // Differentiation @@ -173,11 +173,16 @@ protected: */ STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( const Array &coords, - const Array &physvals); + const Array &physvals) override; STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( const Array &I, - const Array &physvals); + const Array &physvals) override; + + STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) override; STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFacKernel( const Array &base0, @@ -197,36 +202,94 @@ protected: STD_REGIONS_EXPORT virtual void v_LaplacianMatrixOp_MatFree( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; STD_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp_MatFree( const Array &inarray, - Array &outarray, const StdRegions::StdMatrixKey &mkey); + Array &outarray, + const StdRegions::StdMatrixKey &mkey) override; STD_REGIONS_EXPORT virtual NekDouble v_Integral( - const Array &inarray); + const Array &inarray) override; STD_REGIONS_EXPORT virtual int v_GetNedges(void) const; STD_REGIONS_EXPORT virtual int v_GetEdgeNcoeffs(const int i) const; + /** + * Performs tensor product evaluation in 3D to evaluate the physical + * and derivative values in each direction at input coordinate + * @param coord using input physical values at quadrature points + * @param inarray. Returns via reference the derivatives. + + * @param coord Global coordinate + * @param inarray Phys values + * @param out_d0 Return by reference parameter for 0th derivative + * @param out_d1 Return by reference parameter for 1st derivative + * @param out_d2 Return by reference parameter for 2nd derivative + * @return Physical value at @param coord + */ + STD_REGIONS_EXPORT inline NekDouble BaryTensorDeriv( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) + { + const int nq0 = m_base[0]->GetNumPoints(); + const int nq1 = m_base[1]->GetNumPoints(); + const int nq2 = m_base[2]->GetNumPoints(); + + const NekDouble *ptr = &inarray[0]; + Array deriv0(nq1 * nq2, 0.0); + Array phys0(nq1 * nq2, 0.0); + Array deriv0phys1(nq1, 0.0); + Array phys0deriv1(nq1, 0.0); + Array phys0phys1(nq1, 0.0); + + for (int j = 0; j < nq1 * nq2; ++j, ptr += nq0) + { + phys0[j] = + StdExpansion::BaryEvaluate<0, true>(coord[0], ptr, deriv0[j]); + } + + for (int j = 0; j < nq2; ++j) + { + deriv0phys1[j] = StdExpansion::BaryEvaluate<1, false>( + coord[1], &deriv0[j * nq1]); + } + firstOrderDerivs[0] = + StdExpansion::BaryEvaluate<2, false>(coord[2], &deriv0phys1[0]); + + for (int j = 0; j < nq2; ++j) + { + phys0phys1[j] = StdExpansion::BaryEvaluate<1, true>( + coord[1], &phys0[j * nq1], phys0deriv1[j]); + } + firstOrderDerivs[1] = + StdExpansion::BaryEvaluate<2, false>(coord[2], &phys0deriv1[0]); + + return StdExpansion::BaryEvaluate<2, true>(coord[2], &phys0phys1[0], + firstOrderDerivs[2]); + } + STD_REGIONS_EXPORT virtual void v_GetEdgeInteriorToElementMap( const int tid, Array &maparray, Array &signarray, Orientation traceOrient = eForwards); STD_REGIONS_EXPORT virtual void v_GetTraceToElementMap( const int tid, Array &maparray, - Array &signarray, Orientation traceOrient, int P, int Q); + Array &signarray, Orientation traceOrient, int P, + int Q) override; - STD_REGIONS_EXPORT virtual void v_GenStdMatBwdDeriv(const int dir, - DNekMatSharedPtr &mat); + STD_REGIONS_EXPORT virtual void v_GenStdMatBwdDeriv( + const int dir, DNekMatSharedPtr &mat) override; private: - virtual int v_GetShapeDimension() const + virtual int v_GetShapeDimension() const final { return 3; } - virtual int v_GetCoordim(void) + virtual int v_GetCoordim(void) override { return 3; } diff --git a/library/StdRegions/StdHexExp.cpp b/library/StdRegions/StdHexExp.cpp index a41e59b09e49a0dcb6873c8237256cd500e5ffa5..a692a38787d5700a8ed578fbd8a759d3cacf79cf 100644 --- a/library/StdRegions/StdHexExp.cpp +++ b/library/StdRegions/StdHexExp.cpp @@ -44,11 +44,6 @@ namespace Nektar { namespace StdRegions { - -StdHexExp::StdHexExp() -{ -} - StdHexExp::StdHexExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc) @@ -63,10 +58,6 @@ StdHexExp::StdHexExp(const StdHexExp &T) : StdExpansion(T), StdExpansion3D(T) { } -StdHexExp::~StdHexExp() -{ -} - bool StdHexExp::v_IsBoundaryInteriorExpansion() { return (m_base[0]->GetBasisType() == LibUtilities::eModified_A && @@ -1177,6 +1168,13 @@ void StdHexExp::v_GetBoundaryMap(Array &outarray) sort(outarray.get(), outarray.get() + nBndCoeffs); } +NekDouble StdHexExp::v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + return BaryTensorDeriv(coord, inarray, firstOrderDerivs); +} + /** * Only for basis type Modified_A or GLL_LAGRANGE in all directions. */ diff --git a/library/StdRegions/StdHexExp.h b/library/StdRegions/StdHexExp.h index e505939ca2704c55f9afaef63f4dd5bd316e307d..e378c773b8d1129e6117b47be563bc76d829adb3 100644 --- a/library/StdRegions/StdHexExp.h +++ b/library/StdRegions/StdHexExp.h @@ -48,207 +48,216 @@ class StdHexExp : virtual public StdExpansion3D { public: - STD_REGIONS_EXPORT StdHexExp(); + STD_REGIONS_EXPORT StdHexExp() = default; STD_REGIONS_EXPORT StdHexExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc); STD_REGIONS_EXPORT StdHexExp(const StdHexExp &T); - STD_REGIONS_EXPORT ~StdHexExp(); + STD_REGIONS_EXPORT ~StdHexExp() override = default; protected: //---------------------------- // Differentiation Methods //---------------------------- - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + STD_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2); - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + Array &out_d2) override; + STD_REGIONS_EXPORT void v_PhysDeriv( const int dir, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + Array &outarray) override; + STD_REGIONS_EXPORT void v_StdPhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2); - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + Array &out_d2) override; + STD_REGIONS_EXPORT void v_StdPhysDeriv( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Transforms //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_BwdTrans( + STD_REGIONS_EXPORT void v_BwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFac( + STD_REGIONS_EXPORT void v_BwdTrans_SumFac( const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFacKernel( + STD_REGIONS_EXPORT void v_BwdTrans_SumFacKernel( const Array &base0, const Array &base1, const Array &base2, const Array &inarray, Array &outarray, Array &wsp, - bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2); + bool doCheckCollDir0, bool doCheckCollDir1, + bool doCheckCollDir2) override; - STD_REGIONS_EXPORT virtual void v_FwdTrans( + STD_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Inner product functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_IProductWRTBase( + STD_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); + Array &outarray) override; STD_REGIONS_EXPORT virtual void v_IProductWRTBase_MatOp( const Array &inarray, Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multbyweights = true); + Array &outarray, bool multbyweights = true) override; - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFacKernel( + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFacKernel( const Array &base0, const Array &base1, const Array &base2, const Array &inarray, Array &outarray, Array &wsp, - bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2); + bool doCheckCollDir0, bool doCheckCollDir1, + bool doCheckCollDir2) override; - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + STD_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_MatOp( const int dir, const Array &inarray, Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_SumFac( + STD_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_LocCoordToLocCollapsed( - const Array &xi, Array &eta); - STD_REGIONS_EXPORT virtual void v_LocCollapsedToLocCoord( - const Array &eta, Array &xi); - STD_REGIONS_EXPORT virtual void v_FillMode( - const int mode, Array &outarray); + STD_REGIONS_EXPORT void v_LocCoordToLocCollapsed( + const Array &xi, + Array &eta) override; + STD_REGIONS_EXPORT void v_LocCollapsedToLocCoord( + const Array &eta, + Array &xi) override; + STD_REGIONS_EXPORT void v_FillMode( + const int mode, Array &outarray) override; STD_REGIONS_EXPORT NekDouble v_PhysEvaluateBasis( const Array &coords, int mode) final; + STD_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) override; //--------------------------- // Helper functions //--------------------------- - STD_REGIONS_EXPORT virtual int v_GetNverts() const; - STD_REGIONS_EXPORT virtual int v_GetNedges() const; - STD_REGIONS_EXPORT virtual int v_GetNtraces() const; - STD_REGIONS_EXPORT virtual LibUtilities::ShapeType v_DetShapeType() const; - STD_REGIONS_EXPORT virtual int v_NumBndryCoeffs() const; - STD_REGIONS_EXPORT virtual int v_NumDGBndryCoeffs() const; - STD_REGIONS_EXPORT virtual int v_GetTraceNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual int v_GetTotalTraceIntNcoeffs() const; - STD_REGIONS_EXPORT virtual int v_GetTraceIntNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual int v_GetTraceNumPoints(const int i) const; - - STD_REGIONS_EXPORT virtual LibUtilities::PointsKey v_GetTracePointsKey( - const int i, const int j) const; - STD_REGIONS_EXPORT virtual int v_CalcNumberOfCoefficients( - const std::vector &nummodes, int &modes_offset); - STD_REGIONS_EXPORT virtual const LibUtilities::BasisKey v_GetTraceBasisKey( - const int i, const int k) const; - STD_REGIONS_EXPORT virtual bool v_IsBoundaryInteriorExpansion(); - STD_REGIONS_EXPORT virtual void v_GetCoords( + STD_REGIONS_EXPORT int v_GetNverts() const override; + STD_REGIONS_EXPORT int v_GetNedges() const override; + STD_REGIONS_EXPORT int v_GetNtraces() const override; + STD_REGIONS_EXPORT LibUtilities::ShapeType v_DetShapeType() const override; + STD_REGIONS_EXPORT int v_NumBndryCoeffs() const override; + STD_REGIONS_EXPORT int v_NumDGBndryCoeffs() const override; + STD_REGIONS_EXPORT int v_GetTraceNcoeffs(const int i) const override; + STD_REGIONS_EXPORT int v_GetTotalTraceIntNcoeffs() const override; + STD_REGIONS_EXPORT int v_GetTraceIntNcoeffs(const int i) const override; + STD_REGIONS_EXPORT int v_GetTraceNumPoints(const int i) const override; + + STD_REGIONS_EXPORT LibUtilities::PointsKey v_GetTracePointsKey( + const int i, const int j) const override; + STD_REGIONS_EXPORT int v_CalcNumberOfCoefficients( + const std::vector &nummodes, int &modes_offset) override; + STD_REGIONS_EXPORT const LibUtilities::BasisKey v_GetTraceBasisKey( + const int i, const int k) const override; + STD_REGIONS_EXPORT bool v_IsBoundaryInteriorExpansion() override; + STD_REGIONS_EXPORT void v_GetCoords( Array &coords_x, Array &coords_y, - Array &coords_z); - STD_REGIONS_EXPORT virtual void v_GetTraceNumModes( + Array &coords_z) override; + STD_REGIONS_EXPORT void v_GetTraceNumModes( const int fid, int &numModes0, int &numModes1, - Orientation faceOrient = eDir1FwdDir1_Dir2FwdDir2); + Orientation faceOrient = eDir1FwdDir1_Dir2FwdDir2) override; - STD_REGIONS_EXPORT virtual int v_GetEdgeNcoeffs(const int i) const; + STD_REGIONS_EXPORT int v_GetEdgeNcoeffs(const int i) const override; //-------------------------- // Mappings //-------------------------- - STD_REGIONS_EXPORT virtual int v_GetVertexMap(int localVertexId, - bool useCoeffPacking = false); - STD_REGIONS_EXPORT virtual void v_GetInteriorMap( - Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetBoundaryMap( - Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetTraceCoeffMap( - const unsigned int fid, Array &maparray); - STD_REGIONS_EXPORT virtual void v_GetElmtTraceToTraceMap( + STD_REGIONS_EXPORT int v_GetVertexMap( + int localVertexId, bool useCoeffPacking = false) override; + STD_REGIONS_EXPORT void v_GetInteriorMap( + Array &outarray) override; + STD_REGIONS_EXPORT void v_GetBoundaryMap( + Array &outarray) override; + STD_REGIONS_EXPORT void v_GetTraceCoeffMap( + const unsigned int fid, Array &maparray) override; + STD_REGIONS_EXPORT void v_GetElmtTraceToTraceMap( const unsigned int fid, Array &maparray, - Array &signarray, Orientation faceOrient, int P, int Q); - STD_REGIONS_EXPORT virtual void v_GetEdgeInteriorToElementMap( + Array &signarray, Orientation faceOrient, int P, + int Q) override; + STD_REGIONS_EXPORT void v_GetEdgeInteriorToElementMap( const int tid, Array &maparray, Array &signarray, - const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2); + const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2) override; - STD_REGIONS_EXPORT virtual void v_GetTraceInteriorToElementMap( + STD_REGIONS_EXPORT void v_GetTraceInteriorToElementMap( const int tid, Array &maparray, Array &signarray, - const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2); + const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2) override; //--------------------------------------- // Wrapper functions //--------------------------------------- - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdMatrixKey &mkey); + STD_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdMatrixKey &mkey) override; //--------------------------------------- // Output interpolation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_GetSimplexEquiSpacedConnectivity( - Array &conn, bool standard = true); + STD_REGIONS_EXPORT void v_GetSimplexEquiSpacedConnectivity( + Array &conn, bool standard = true) override; //--------------------------------------- // Operator evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_MassMatrixOp( + STD_REGIONS_EXPORT void v_MassMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); + Array &outarray, const StdMatrixKey &mkey) override; - STD_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + STD_REGIONS_EXPORT void v_LaplacianMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); + Array &outarray, const StdMatrixKey &mkey) override; - STD_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + STD_REGIONS_EXPORT void v_LaplacianMatrixOp( const int k1, const int k2, const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); + Array &outarray, const StdMatrixKey &mkey) override; - STD_REGIONS_EXPORT virtual void v_WeakDerivMatrixOp( + STD_REGIONS_EXPORT void v_WeakDerivMatrixOp( const int i, const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); + Array &outarray, const StdMatrixKey &mkey) override; - STD_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp( + STD_REGIONS_EXPORT void v_HelmholtzMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); + Array &outarray, const StdMatrixKey &mkey) override; STD_REGIONS_EXPORT virtual void v_GeneralMatrixOp_MatOp( const Array &inarray, Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_MultiplyByStdQuadratureMetric( + STD_REGIONS_EXPORT void v_MultiplyByStdQuadratureMetric( const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_SVVLaplacianFilter( - Array &array, const StdMatrixKey &mkey); + STD_REGIONS_EXPORT void v_SVVLaplacianFilter( + Array &array, const StdMatrixKey &mkey) override; - STD_REGIONS_EXPORT virtual void v_ExponentialFilter( + STD_REGIONS_EXPORT void v_ExponentialFilter( Array &array, const NekDouble alpha, - const NekDouble exponent, const NekDouble cutoff); + const NekDouble exponent, const NekDouble cutoff) override; }; typedef std::shared_ptr StdHexExpSharedPtr; diff --git a/library/StdRegions/StdNodalPrismExp.cpp b/library/StdRegions/StdNodalPrismExp.cpp index 1cd31186a17b3409a8dadda7ef2610c262428dfa..c4c8323d2489fdf16696e0d186f84e0f2b2523de 100644 --- a/library/StdRegions/StdNodalPrismExp.cpp +++ b/library/StdRegions/StdNodalPrismExp.cpp @@ -64,10 +64,6 @@ StdNodalPrismExp::StdNodalPrismExp(const StdNodalPrismExp &T) { } -StdNodalPrismExp::~StdNodalPrismExp() -{ -} - bool StdNodalPrismExp::v_IsNodalNonTensorialExp() { return true; @@ -152,7 +148,7 @@ DNekMatSharedPtr StdNodalPrismExp::GenNBasisTransMatrix() c[0] = r[j]; c[1] = s[j]; c[2] = t[j]; - (*Mat)(j, i) = StdPrismExp::v_PhysEvaluate(c, tmp_phys); + (*Mat)(j, i) = StdExpansion3D::v_PhysEvaluate(c, tmp_phys); } } diff --git a/library/StdRegions/StdNodalPrismExp.h b/library/StdRegions/StdNodalPrismExp.h index d8300047fcbc36747e1e2ce93bcdeca8782e279a..6c6c2086b344e139768e3c67e5d11fd63e2a50a8 100644 --- a/library/StdRegions/StdNodalPrismExp.h +++ b/library/StdRegions/StdNodalPrismExp.h @@ -42,16 +42,16 @@ namespace Nektar { namespace StdRegions { -class StdNodalPrismExp : public StdPrismExp +class StdNodalPrismExp final : public StdPrismExp { public: - STD_REGIONS_EXPORT StdNodalPrismExp(); + STD_REGIONS_EXPORT StdNodalPrismExp() = default; STD_REGIONS_EXPORT StdNodalPrismExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc, const LibUtilities::PointsType Ntype); STD_REGIONS_EXPORT StdNodalPrismExp(const StdNodalPrismExp &T); - STD_REGIONS_EXPORT ~StdNodalPrismExp(); + STD_REGIONS_EXPORT ~StdNodalPrismExp() override = default; //------------------------------- // Nodal basis specific routines @@ -73,66 +73,66 @@ public: protected: LibUtilities::PointsKey m_nodalPointsKey; - STD_REGIONS_EXPORT virtual const LibUtilities::PointsKey v_GetNodalPointsKey() - const + STD_REGIONS_EXPORT const LibUtilities::PointsKey v_GetNodalPointsKey() + const override { return m_nodalPointsKey; }; - STD_REGIONS_EXPORT virtual bool v_IsNodalNonTensorialExp(); + STD_REGIONS_EXPORT bool v_IsNodalNonTensorialExp() override; //--------------------------------------- // Transforms //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_BwdTrans( + STD_REGIONS_EXPORT void v_BwdTrans( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFac( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_FwdTrans( + Array &outarray) override; + STD_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Inner product functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_IProductWRTBase( + STD_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool mult = true); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + Array &outarray, bool mult = true) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_FillMode( - const int mode, Array &outarray); + STD_REGIONS_EXPORT void v_FillMode( + const int mode, Array &outarray) override; //--------------------------------------- // Mapping functions //--------------------------------------- - STD_REGIONS_EXPORT virtual int v_GetVertexMap(const int localVertexId, - bool useCoeffPacking = false); - STD_REGIONS_EXPORT virtual void v_GetBoundaryMap( - Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetInteriorMap( - Array &outarray); + STD_REGIONS_EXPORT int v_GetVertexMap( + const int localVertexId, bool useCoeffPacking = false) override; + STD_REGIONS_EXPORT void v_GetBoundaryMap( + Array &outarray) override; + STD_REGIONS_EXPORT void v_GetInteriorMap( + Array &outarray) override; //--------------------------------------- // Wrapper functions //--------------------------------------- - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdMatrixKey &mkey); + STD_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdMatrixKey &mkey) override; }; typedef std::shared_ptr StdNodalPrismExpSharedPtr; diff --git a/library/StdRegions/StdNodalTetExp.cpp b/library/StdRegions/StdNodalTetExp.cpp index f7b4633c5d3119228d90da6025dab68a8146c6ff..f513c1c013216638bcd37a15aebeeb3a7d2fb446 100644 --- a/library/StdRegions/StdNodalTetExp.cpp +++ b/library/StdRegions/StdNodalTetExp.cpp @@ -70,10 +70,6 @@ StdNodalTetExp::StdNodalTetExp(const StdNodalTetExp &T) { } -StdNodalTetExp::~StdNodalTetExp() -{ -} - bool StdNodalTetExp::v_IsNodalNonTensorialExp() { return true; @@ -157,7 +153,7 @@ DNekMatSharedPtr StdNodalTetExp::GenNBasisTransMatrix() c[0] = r[j]; c[1] = s[j]; c[2] = t[j]; - (*Mat)(j, i) = StdTetExp::v_PhysEvaluate(c, tmp_phys); + (*Mat)(j, i) = StdExpansion3D::v_PhysEvaluate(c, tmp_phys); } } diff --git a/library/StdRegions/StdNodalTetExp.h b/library/StdRegions/StdNodalTetExp.h index fc4c17c790e5f253ddc874cbbe143b3bec9404c3..34844b1385dc71a9264a264a7cec49fd66730c62 100644 --- a/library/StdRegions/StdNodalTetExp.h +++ b/library/StdRegions/StdNodalTetExp.h @@ -42,16 +42,16 @@ namespace Nektar { namespace StdRegions { -class StdNodalTetExp : public StdTetExp +class StdNodalTetExp : virtual public StdTetExp { public: - STD_REGIONS_EXPORT StdNodalTetExp(); + STD_REGIONS_EXPORT StdNodalTetExp() = default; STD_REGIONS_EXPORT StdNodalTetExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc, const LibUtilities::PointsType Ntype); STD_REGIONS_EXPORT StdNodalTetExp(const StdNodalTetExp &T); - STD_REGIONS_EXPORT ~StdNodalTetExp(); + STD_REGIONS_EXPORT ~StdNodalTetExp() override = default; //------------------------------- // Nodal basis specific routines @@ -73,66 +73,66 @@ public: protected: LibUtilities::PointsKey m_nodalPointsKey; - STD_REGIONS_EXPORT virtual const LibUtilities::PointsKey v_GetNodalPointsKey() - const + STD_REGIONS_EXPORT const LibUtilities::PointsKey v_GetNodalPointsKey() + const override { return m_nodalPointsKey; }; - STD_REGIONS_EXPORT virtual bool v_IsNodalNonTensorialExp(); + STD_REGIONS_EXPORT bool v_IsNodalNonTensorialExp() override; //--------------------------------------- // Transforms //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_BwdTrans( + STD_REGIONS_EXPORT void v_BwdTrans( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFac( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_FwdTrans( + Array &outarray) override; + STD_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Inner product functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_IProductWRTBase( + STD_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool mult = true); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + Array &outarray, bool mult = true) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_FillMode( - const int mode, Array &outarray); + STD_REGIONS_EXPORT void v_FillMode( + const int mode, Array &outarray) override; //--------------------------------------- // Mapping functions //--------------------------------------- - STD_REGIONS_EXPORT virtual int v_GetVertexMap(const int localVertexId, - bool useCoeffPacking = false); - STD_REGIONS_EXPORT virtual void v_GetBoundaryMap( - Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetInteriorMap( - Array &outarray); + STD_REGIONS_EXPORT int v_GetVertexMap( + const int localVertexId, bool useCoeffPacking = false) override; + STD_REGIONS_EXPORT void v_GetBoundaryMap( + Array &outarray) override; + STD_REGIONS_EXPORT void v_GetInteriorMap( + Array &outarray) override; //--------------------------------------- // Wrapper functions //--------------------------------------- - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdMatrixKey &mkey); + STD_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdMatrixKey &mkey) override; }; typedef std::shared_ptr StdNodalTetExpSharedPtr; diff --git a/library/StdRegions/StdNodalTriExp.cpp b/library/StdRegions/StdNodalTriExp.cpp index 8d2d8bd510965d0e5d8027fa8dbbbef3e7d6b4e8..72ab2e140b37a54c2833f32b8f12fa580865de74 100644 --- a/library/StdRegions/StdNodalTriExp.cpp +++ b/library/StdRegions/StdNodalTriExp.cpp @@ -43,10 +43,6 @@ namespace Nektar { namespace StdRegions { -StdNodalTriExp::StdNodalTriExp() : StdTriExp(), m_nodalPointsKey() -{ -} - StdNodalTriExp::StdNodalTriExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, LibUtilities::PointsType Ntype) @@ -69,10 +65,6 @@ StdNodalTriExp::StdNodalTriExp(const StdNodalTriExp &T) { } -StdNodalTriExp::~StdNodalTriExp() -{ -} - bool StdNodalTriExp::v_IsNodalNonTensorialExp() { return true; @@ -154,7 +146,7 @@ DNekMatSharedPtr StdNodalTriExp::GenNBasisTransMatrix() { c[0] = r[j]; c[1] = s[j]; - (*Mat)(j, i) = StdTriExp::v_PhysEvaluate(c, phys); + (*Mat)(j, i) = StdExpansion2D::v_PhysEvaluate(c, phys); } } return Mat; diff --git a/library/StdRegions/StdNodalTriExp.h b/library/StdRegions/StdNodalTriExp.h index 2977a58845e0c7982bae646f46e48ac16350cf5a..1a457ea6b996beb34d4de205b540caccfab4cf82 100644 --- a/library/StdRegions/StdNodalTriExp.h +++ b/library/StdRegions/StdNodalTriExp.h @@ -44,15 +44,15 @@ namespace Nektar { namespace StdRegions { -class StdNodalTriExp : public StdTriExp +class StdNodalTriExp : virtual public StdTriExp { public: - STD_REGIONS_EXPORT StdNodalTriExp(); + STD_REGIONS_EXPORT StdNodalTriExp() = default; STD_REGIONS_EXPORT StdNodalTriExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::PointsType Ntype); STD_REGIONS_EXPORT StdNodalTriExp(const StdNodalTriExp &T); - STD_REGIONS_EXPORT ~StdNodalTriExp(); + STD_REGIONS_EXPORT ~StdNodalTriExp() override = default; //------------------------------- // Nodal basis specific routines @@ -73,100 +73,102 @@ public: protected: LibUtilities::PointsKey m_nodalPointsKey; - STD_REGIONS_EXPORT virtual const LibUtilities::PointsKey v_GetNodalPointsKey() - const + STD_REGIONS_EXPORT const LibUtilities::PointsKey v_GetNodalPointsKey() + const override { return m_nodalPointsKey; }; - STD_REGIONS_EXPORT virtual bool v_IsNodalNonTensorialExp(); + STD_REGIONS_EXPORT bool v_IsNodalNonTensorialExp() override; //--------------------------------------- // Transforms //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_BwdTrans( + STD_REGIONS_EXPORT void v_BwdTrans( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFac( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_FwdTrans( + Array &outarray) override; + STD_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Inner product functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_IProductWRTBase( + STD_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multiplybyweights = true); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + Array &outarray, + bool multiplybyweights = true) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_FillMode( - const int mode, Array &outarray); + STD_REGIONS_EXPORT void v_FillMode( + const int mode, Array &outarray) override; //--------------------------- // Helper functions //--------------------------- - STD_REGIONS_EXPORT virtual int v_NumBndryCoeffs() const; + STD_REGIONS_EXPORT int v_NumBndryCoeffs() const override; //-------------------------- // Mappings //-------------------------- - STD_REGIONS_EXPORT virtual int v_GetVertexMap(int localVertexId, - bool useCoeffPacking = false); + STD_REGIONS_EXPORT int v_GetVertexMap( + int localVertexId, bool useCoeffPacking = false) override; - STD_REGIONS_EXPORT virtual void v_GetTraceToElementMap( + STD_REGIONS_EXPORT void v_GetTraceToElementMap( const int eid, Array &maparray, Array &signarray, Orientation edgeOrient = eForwards, - int P = -1, int Q = -1); + int P = -1, int Q = -1) override; - STD_REGIONS_EXPORT virtual void v_GetTraceInteriorToElementMap( + STD_REGIONS_EXPORT void v_GetTraceInteriorToElementMap( const int eid, Array &maparray, - Array &signarray, const Orientation edgeOrient = eForwards); + Array &signarray, + const Orientation edgeOrient = eForwards) override; - STD_REGIONS_EXPORT virtual void v_GetInteriorMap( - Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetBoundaryMap( - Array &outarray); + STD_REGIONS_EXPORT void v_GetInteriorMap( + Array &outarray) override; + STD_REGIONS_EXPORT void v_GetBoundaryMap( + Array &outarray) override; //--------------------------------------- // Operator evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_MassMatrixOp( + STD_REGIONS_EXPORT void v_MassMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_LaplacianMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_LaplacianMatrixOp( const int k1, const int k2, const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_WeakDerivMatrixOp( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_WeakDerivMatrixOp( const int i, const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_HelmholtzMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); + Array &outarray, const StdMatrixKey &mkey) override; //--------------------------------------- // Wrapper functions //--------------------------------------- - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdMatrixKey &mkey); + STD_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdMatrixKey &mkey) override; }; typedef std::shared_ptr StdNodalTriExpSharedPtr; diff --git a/library/StdRegions/StdPrismExp.cpp b/library/StdRegions/StdPrismExp.cpp index 9df6d34c282b6668cbd4a259a1a0c9ba9b432642..7c53f26cd5a927baca2216777a251f4907aebc17 100644 --- a/library/StdRegions/StdPrismExp.cpp +++ b/library/StdRegions/StdPrismExp.cpp @@ -43,12 +43,6 @@ namespace Nektar { namespace StdRegions { - -StdPrismExp::StdPrismExp() // Deafult construct of standard expansion directly - // called. -{ -} - StdPrismExp::StdPrismExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc) @@ -68,11 +62,6 @@ StdPrismExp::StdPrismExp(const StdPrismExp &T) { } -// Destructor -StdPrismExp::~StdPrismExp() -{ -} - //--------------------------------------- // Differentiation Methods //--------------------------------------- @@ -600,7 +589,6 @@ void StdPrismExp::v_IProductWRTDerivBase_SumFac( m_base[2]->GetBdata(), tmp0, outarray, wsp, true, true, true); break; } - case 1: { MultiplyByQuadratureMetric(inarray, tmp0); @@ -696,6 +684,54 @@ void StdPrismExp::v_GetCoords(Array &xi_x, } } +NekDouble StdPrismExp::v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + // Collapse coordinates + Array coll(3, 0.0); + LocCoordToLocCollapsed(coord, coll); + + // If near singularity do the old interpolation matrix method + // @TODO: Dave thinks there might be a way in the Barycentric to + // mathematically remove this singularity? + if ((1 - coll[2]) < 1e-5) + { + int totPoints = GetTotPoints(); + Array EphysDeriv0(totPoints), EphysDeriv1(totPoints), + EphysDeriv2(totPoints); + PhysDeriv(inarray, EphysDeriv0, EphysDeriv1, EphysDeriv2); + + Array I(3); + I[0] = GetBase()[0]->GetI(coll); + I[1] = GetBase()[1]->GetI(coll + 1); + I[2] = GetBase()[2]->GetI(coll + 2); + + firstOrderDerivs[0] = PhysEvaluate(I, EphysDeriv0); + firstOrderDerivs[1] = PhysEvaluate(I, EphysDeriv1); + firstOrderDerivs[2] = PhysEvaluate(I, EphysDeriv2); + return PhysEvaluate(I, inarray); + } + + NekDouble val = BaryTensorDeriv(coll, inarray, firstOrderDerivs); + + NekDouble dEta_bar1 = firstOrderDerivs[0]; + + NekDouble fac = 2.0 / (1.0 - coll[2]); + firstOrderDerivs[0] = fac * dEta_bar1; + + // divide dEta_Bar1 by (1-eta_z) + fac = 1.0 / (1.0 - coll[2]); + dEta_bar1 = fac * dEta_bar1; + + // Multiply dEta_Bar1 by (1+eta_x) and add ot out_dxi3 + fac = 1.0 + coll[0]; + firstOrderDerivs[2] += fac * dEta_bar1; + + return val; +} + void StdPrismExp::v_FillMode(const int mode, Array &outarray) { Array tmp(m_ncoeffs, 0.0); diff --git a/library/StdRegions/StdPrismExp.h b/library/StdRegions/StdPrismExp.h index 8235809052d58bfb57ebf6307d61b123dff2c10d..34258619ccd7b07eab1a0da848a2bfaead7b93e0 100644 --- a/library/StdRegions/StdPrismExp.h +++ b/library/StdRegions/StdPrismExp.h @@ -49,7 +49,7 @@ class StdPrismExp : virtual public StdExpansion3D { public: - STD_REGIONS_EXPORT StdPrismExp(); + STD_REGIONS_EXPORT StdPrismExp() = default; STD_REGIONS_EXPORT StdPrismExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, @@ -62,164 +62,174 @@ public: STD_REGIONS_EXPORT StdPrismExp(const StdPrismExp &T); - STD_REGIONS_EXPORT ~StdPrismExp(); + STD_REGIONS_EXPORT ~StdPrismExp() override = default; protected: //--------------------------------------- // Differentiation Methods //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + STD_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2); - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + Array &out_d2) override; + STD_REGIONS_EXPORT void v_PhysDeriv( const int dir, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + Array &outarray) override; + STD_REGIONS_EXPORT void v_StdPhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2); - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + Array &out_d2) override; + STD_REGIONS_EXPORT void v_StdPhysDeriv( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Transforms //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_BwdTrans( + STD_REGIONS_EXPORT void v_BwdTrans( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFac( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFacKernel( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFacKernel( const Array &base0, const Array &base1, const Array &base2, const Array &inarray, Array &outarray, Array &wsp, - bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2); - STD_REGIONS_EXPORT virtual void v_FwdTrans( + bool doCheckCollDir0, bool doCheckCollDir1, + bool doCheckCollDir2) override; + STD_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Inner product functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_IProductWRTBase( + STD_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); + Array &outarray) override; STD_REGIONS_EXPORT virtual void v_IProductWRTBase_MatOp( const Array &inarray, Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multiplybyweights = true); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFacKernel( + Array &outarray, + bool multiplybyweights = true) override; + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFacKernel( const Array &base0, const Array &base1, const Array &base2, const Array &inarray, Array &outarray, Array &wsp, - bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + bool doCheckCollDir0, bool doCheckCollDir1, + bool doCheckCollDir2) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_MatOp( const int dir, const Array &inarray, Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_SumFac( + STD_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_LocCoordToLocCollapsed( - const Array &xi, Array &eta); - STD_REGIONS_EXPORT virtual void v_LocCollapsedToLocCoord( - const Array &eta, Array &xi); - STD_REGIONS_EXPORT virtual void v_GetCoords(Array &xi_x, - Array &xi_y, - Array &xi_z); - STD_REGIONS_EXPORT virtual void v_FillMode( - const int mode, Array &outarray); + STD_REGIONS_EXPORT void v_LocCoordToLocCollapsed( + const Array &xi, + Array &eta) override; + STD_REGIONS_EXPORT void v_LocCollapsedToLocCoord( + const Array &eta, + Array &xi) override; + STD_REGIONS_EXPORT void v_GetCoords(Array &xi_x, + Array &xi_y, + Array &xi_z) override; + STD_REGIONS_EXPORT void v_FillMode( + const int mode, Array &outarray) override; STD_REGIONS_EXPORT NekDouble v_PhysEvaluateBasis( const Array &coords, int mode) final; - STD_REGIONS_EXPORT virtual void v_GetTraceNumModes( + STD_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) override; + STD_REGIONS_EXPORT void v_GetTraceNumModes( const int fid, int &numModes0, int &numModes1, - Orientation faceOrient = eDir1FwdDir1_Dir2FwdDir2); + Orientation faceOrient = eDir1FwdDir1_Dir2FwdDir2) override; //--------------------------------------- // Helper functions //--------------------------------------- - STD_REGIONS_EXPORT virtual int v_GetNverts() const; - STD_REGIONS_EXPORT virtual int v_GetNedges() const; - STD_REGIONS_EXPORT virtual int v_GetNtraces() const; - STD_REGIONS_EXPORT virtual LibUtilities::ShapeType v_DetShapeType() const; - STD_REGIONS_EXPORT virtual int v_NumBndryCoeffs() const; - STD_REGIONS_EXPORT virtual int v_NumDGBndryCoeffs() const; - STD_REGIONS_EXPORT virtual int v_GetTraceNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual int v_GetTotalTraceIntNcoeffs() const; - STD_REGIONS_EXPORT virtual int v_GetTraceIntNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual int v_GetTraceNumPoints(const int i) const; + STD_REGIONS_EXPORT int v_GetNverts() const override; + STD_REGIONS_EXPORT int v_GetNedges() const override; + STD_REGIONS_EXPORT int v_GetNtraces() const override; + STD_REGIONS_EXPORT LibUtilities::ShapeType v_DetShapeType() const override; + STD_REGIONS_EXPORT int v_NumBndryCoeffs() const override; + STD_REGIONS_EXPORT int v_NumDGBndryCoeffs() const override; + STD_REGIONS_EXPORT int v_GetTraceNcoeffs(const int i) const override; + STD_REGIONS_EXPORT int v_GetTotalTraceIntNcoeffs() const override; + STD_REGIONS_EXPORT int v_GetTraceIntNcoeffs(const int i) const override; + STD_REGIONS_EXPORT int v_GetTraceNumPoints(const int i) const override; - STD_REGIONS_EXPORT virtual int v_GetEdgeNcoeffs(const int i) const; + STD_REGIONS_EXPORT int v_GetEdgeNcoeffs(const int i) const override; - STD_REGIONS_EXPORT virtual const LibUtilities::BasisKey v_GetTraceBasisKey( - const int i, const int k) const; - STD_REGIONS_EXPORT virtual LibUtilities::PointsKey v_GetTracePointsKey( - const int i, const int j) const; + STD_REGIONS_EXPORT const LibUtilities::BasisKey v_GetTraceBasisKey( + const int i, const int k) const override; + STD_REGIONS_EXPORT LibUtilities::PointsKey v_GetTracePointsKey( + const int i, const int j) const override; - STD_REGIONS_EXPORT virtual int v_CalcNumberOfCoefficients( - const std::vector &nummodes, int &modes_offset); - STD_REGIONS_EXPORT virtual bool v_IsBoundaryInteriorExpansion(); + STD_REGIONS_EXPORT int v_CalcNumberOfCoefficients( + const std::vector &nummodes, int &modes_offset) override; + STD_REGIONS_EXPORT bool v_IsBoundaryInteriorExpansion() override; //--------------------------------------- // Mappings //--------------------------------------- - STD_REGIONS_EXPORT virtual int v_GetVertexMap(int localVertexId, - bool useCoeffPacking = false); - STD_REGIONS_EXPORT virtual void v_GetInteriorMap( - Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetBoundaryMap( - Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetTraceCoeffMap( - const unsigned int fid, Array &maparray); - STD_REGIONS_EXPORT virtual void v_GetElmtTraceToTraceMap( + STD_REGIONS_EXPORT int v_GetVertexMap( + int localVertexId, bool useCoeffPacking = false) override; + STD_REGIONS_EXPORT void v_GetInteriorMap( + Array &outarray) override; + STD_REGIONS_EXPORT void v_GetBoundaryMap( + Array &outarray) override; + STD_REGIONS_EXPORT void v_GetTraceCoeffMap( + const unsigned int fid, Array &maparray) override; + STD_REGIONS_EXPORT void v_GetElmtTraceToTraceMap( const unsigned int fid, Array &maparray, - Array &signarray, Orientation faceOrient, int P, int Q); - STD_REGIONS_EXPORT virtual void v_GetEdgeInteriorToElementMap( + Array &signarray, Orientation faceOrient, int P, + int Q) override; + STD_REGIONS_EXPORT void v_GetEdgeInteriorToElementMap( const int tid, Array &maparray, Array &signarray, - const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2); + const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2) override; - STD_REGIONS_EXPORT virtual void v_GetTraceInteriorToElementMap( + STD_REGIONS_EXPORT void v_GetTraceInteriorToElementMap( const int tid, Array &maparray, Array &signarray, - const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2); + const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2) override; //--------------------------------------- // Wrapper functions //--------------------------------------- - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdMatrixKey &mkey); + STD_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdMatrixKey &mkey) override; - STD_REGIONS_EXPORT virtual void v_MultiplyByStdQuadratureMetric( + STD_REGIONS_EXPORT void v_MultiplyByStdQuadratureMetric( const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT void v_SVVLaplacianFilter(Array &array, - const StdMatrixKey &mkey); + STD_REGIONS_EXPORT void v_SVVLaplacianFilter( + Array &array, const StdMatrixKey &mkey) override; //--------------------------------------- // Method for applying sensors //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_ReduceOrderCoeffs( + STD_REGIONS_EXPORT void v_ReduceOrderCoeffs( int numMin, const Array &inarray, - Array &outarray); + Array &outarray) override; private: //--------------------------------------- diff --git a/library/StdRegions/StdPyrExp.cpp b/library/StdRegions/StdPyrExp.cpp index 2320c07dd30475091d0433097a4c81393746c939..47651f42621327de1a875887d3149ee28bb563b7 100644 --- a/library/StdRegions/StdPyrExp.cpp +++ b/library/StdRegions/StdPyrExp.cpp @@ -44,11 +44,6 @@ namespace Nektar { namespace StdRegions { -StdPyrExp::StdPyrExp() // Deafult construct of standard expansion directly - // called. -{ -} - StdPyrExp::StdPyrExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc) @@ -76,11 +71,6 @@ StdPyrExp::StdPyrExp(const StdPyrExp &T) : StdExpansion(T), StdExpansion3D(T) { } -// Destructor -StdPyrExp::~StdPyrExp() -{ -} - //--------------------------------------- // Differentiation/integration Methods //--------------------------------------- @@ -726,6 +716,47 @@ void StdPyrExp::v_GetCoords(Array &xi_x, } } +NekDouble StdPyrExp::v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + // Collapse coordinates + Array coll(3, 0.0); + LocCoordToLocCollapsed(coord, coll); + + // If near singularity do the old interpolation matrix method + if ((1 - coll[2]) < 1e-5) + { + int totPoints = GetTotPoints(); + Array EphysDeriv0(totPoints), EphysDeriv1(totPoints), + EphysDeriv2(totPoints); + PhysDeriv(inarray, EphysDeriv0, EphysDeriv1, EphysDeriv2); + + Array I(3); + I[0] = GetBase()[0]->GetI(coll); + I[1] = GetBase()[1]->GetI(coll + 1); + I[2] = GetBase()[2]->GetI(coll + 2); + + firstOrderDerivs[0] = PhysEvaluate(I, EphysDeriv0); + firstOrderDerivs[1] = PhysEvaluate(I, EphysDeriv1); + firstOrderDerivs[2] = PhysEvaluate(I, EphysDeriv2); + return PhysEvaluate(I, inarray); + } + + std::array interDeriv; + NekDouble val = StdExpansion3D::BaryTensorDeriv(coll, inarray, interDeriv); + + NekDouble fac = 2.0 / (1.0 - coll[2]); + + firstOrderDerivs[0] = fac * interDeriv[0]; + firstOrderDerivs[1] = fac * interDeriv[1]; + firstOrderDerivs[2] = ((1.0 + coll[0]) / (1.0 - coll[2])) * interDeriv[0] + + ((1.0 + coll[1]) / (1.0 - coll[2])) * interDeriv[1] + + interDeriv[2]; + + return val; +} + void StdPyrExp::v_FillMode(const int mode, Array &outarray) { Array tmp(m_ncoeffs, 0.0); diff --git a/library/StdRegions/StdPyrExp.h b/library/StdRegions/StdPyrExp.h index bb24e4f8d214237434d234265968e64c4a54d42b..ef3f9d3151673d77812ec2e60ddc0a74fcd202ed 100644 --- a/library/StdRegions/StdPyrExp.h +++ b/library/StdRegions/StdPyrExp.h @@ -80,7 +80,7 @@ struct cmpop class StdPyrExp : virtual public StdExpansion3D { public: - STD_REGIONS_EXPORT StdPyrExp(); + STD_REGIONS_EXPORT StdPyrExp() = default; STD_REGIONS_EXPORT StdPyrExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, @@ -93,151 +93,161 @@ public: STD_REGIONS_EXPORT StdPyrExp(const StdPyrExp &T); - STD_REGIONS_EXPORT ~StdPyrExp(); + STD_REGIONS_EXPORT ~StdPyrExp() override = default; protected: //--------------------------------------- // Differentiation/integration Methods //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + STD_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2); - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + Array &out_d2) override; + STD_REGIONS_EXPORT void v_PhysDeriv( const int dir, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + Array &outarray) override; + STD_REGIONS_EXPORT void v_StdPhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2); - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + Array &out_d2) override; + STD_REGIONS_EXPORT void v_StdPhysDeriv( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; STD_REGIONS_EXPORT void v_MultiplyByStdQuadratureMetric( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Transforms //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_BwdTrans( + STD_REGIONS_EXPORT void v_BwdTrans( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFac( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFacKernel( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFacKernel( const Array &base0, const Array &base1, const Array &base2, const Array &inarray, Array &outarray, Array &wsp, - bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2); - STD_REGIONS_EXPORT virtual void v_FwdTrans( + bool doCheckCollDir0, bool doCheckCollDir1, + bool doCheckCollDir2) override; + STD_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Inner product functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_IProductWRTBase( + STD_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multiplybyweights = true); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFacKernel( + Array &outarray, + bool multiplybyweights = true) override; + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFacKernel( const Array &base0, const Array &base1, const Array &base2, const Array &inarray, Array &outarray, Array &wsp, - bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + bool doCheckCollDir0, bool doCheckCollDir1, + bool doCheckCollDir2) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_LocCoordToLocCollapsed( - const Array &xi, Array &eta); - STD_REGIONS_EXPORT virtual void v_LocCollapsedToLocCoord( - const Array &eta, Array &xi); - STD_REGIONS_EXPORT virtual void v_GetCoords(Array &xi_x, - Array &xi_y, - Array &xi_z); - STD_REGIONS_EXPORT virtual void v_FillMode( - const int mode, Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetTraceNumModes( + STD_REGIONS_EXPORT void v_LocCoordToLocCollapsed( + const Array &xi, + Array &eta) override; + STD_REGIONS_EXPORT void v_LocCollapsedToLocCoord( + const Array &eta, + Array &xi) override; + STD_REGIONS_EXPORT void v_GetCoords(Array &xi_x, + Array &xi_y, + Array &xi_z) override; + STD_REGIONS_EXPORT void v_FillMode( + const int mode, Array &outarray) override; + STD_REGIONS_EXPORT void v_GetTraceNumModes( const int fid, int &numModes0, int &numModes1, - Orientation faceOrient = eDir1FwdDir1_Dir2FwdDir2); + Orientation faceOrient = eDir1FwdDir1_Dir2FwdDir2) override; STD_REGIONS_EXPORT NekDouble v_PhysEvaluateBasis( const Array &coords, int mode) final; + STD_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) override; //--------------------------------------- // Helper functions //--------------------------------------- - STD_REGIONS_EXPORT virtual int v_GetNverts() const; - STD_REGIONS_EXPORT virtual int v_GetNedges() const; - STD_REGIONS_EXPORT virtual int v_GetNtraces() const; - STD_REGIONS_EXPORT virtual LibUtilities::ShapeType v_DetShapeType() const; - STD_REGIONS_EXPORT virtual int v_NumBndryCoeffs() const; - STD_REGIONS_EXPORT virtual int v_NumDGBndryCoeffs() const; - STD_REGIONS_EXPORT virtual int v_GetTraceNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual int v_GetTraceIntNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual int v_GetTraceNumPoints(const int i) const; + STD_REGIONS_EXPORT int v_GetNverts() const override; + STD_REGIONS_EXPORT int v_GetNedges() const override; + STD_REGIONS_EXPORT int v_GetNtraces() const override; + STD_REGIONS_EXPORT LibUtilities::ShapeType v_DetShapeType() const override; + STD_REGIONS_EXPORT int v_NumBndryCoeffs() const override; + STD_REGIONS_EXPORT int v_NumDGBndryCoeffs() const override; + STD_REGIONS_EXPORT int v_GetTraceNcoeffs(const int i) const override; + STD_REGIONS_EXPORT int v_GetTraceIntNcoeffs(const int i) const override; + STD_REGIONS_EXPORT int v_GetTraceNumPoints(const int i) const override; - STD_REGIONS_EXPORT virtual int v_GetEdgeNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual int v_CalcNumberOfCoefficients( - const std::vector &nummodes, int &modes_offset); - STD_REGIONS_EXPORT virtual const LibUtilities::BasisKey v_GetTraceBasisKey( - const int i, const int k) const; + STD_REGIONS_EXPORT int v_GetEdgeNcoeffs(const int i) const override; + STD_REGIONS_EXPORT int v_CalcNumberOfCoefficients( + const std::vector &nummodes, int &modes_offset) override; + STD_REGIONS_EXPORT const LibUtilities::BasisKey v_GetTraceBasisKey( + const int i, const int k) const override; //--------------------------------------- // Mappings //--------------------------------------- - STD_REGIONS_EXPORT virtual int v_GetVertexMap(int localVertexId, - bool useCoeffPacking = false); - STD_REGIONS_EXPORT virtual void v_GetInteriorMap( - Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetBoundaryMap( - Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetTraceCoeffMap( - const unsigned int fid, Array &maparray); - STD_REGIONS_EXPORT virtual void v_GetElmtTraceToTraceMap( + STD_REGIONS_EXPORT int v_GetVertexMap( + int localVertexId, bool useCoeffPacking = false) override; + STD_REGIONS_EXPORT void v_GetInteriorMap( + Array &outarray) override; + STD_REGIONS_EXPORT void v_GetBoundaryMap( + Array &outarray) override; + STD_REGIONS_EXPORT void v_GetTraceCoeffMap( + const unsigned int fid, Array &maparray) override; + STD_REGIONS_EXPORT void v_GetElmtTraceToTraceMap( const unsigned int fid, Array &maparray, - Array &signarray, Orientation faceOrient, int P, int Q); - STD_REGIONS_EXPORT virtual void v_GetEdgeInteriorToElementMap( + Array &signarray, Orientation faceOrient, int P, + int Q) override; + STD_REGIONS_EXPORT void v_GetEdgeInteriorToElementMap( const int tid, Array &maparray, Array &signarray, - const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2); - STD_REGIONS_EXPORT virtual void v_GetTraceInteriorToElementMap( + const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2) override; + STD_REGIONS_EXPORT void v_GetTraceInteriorToElementMap( const int tid, Array &maparray, Array &signarray, - const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2); + const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2) override; //--------------------------------------- // Wrapper functions //--------------------------------------- - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdMatrixKey &mkey); + STD_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdMatrixKey &mkey) override; - STD_REGIONS_EXPORT virtual void v_SVVLaplacianFilter( - Array &array, const StdMatrixKey &mkey); + STD_REGIONS_EXPORT void v_SVVLaplacianFilter( + Array &array, const StdMatrixKey &mkey) override; //--------------------------------------- // Method for applying sensors //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_ReduceOrderCoeffs( + STD_REGIONS_EXPORT void v_ReduceOrderCoeffs( int numMin, const Array &inarray, - Array &outarray); + Array &outarray) override; private: //--------------------------------------- diff --git a/library/StdRegions/StdQuadExp.cpp b/library/StdRegions/StdQuadExp.cpp index 43429e33d202e79142d56fe28eb72f09e95362dc..ccd42179ff71b18f50a371e4a4f7408ddd1e4289 100644 --- a/library/StdRegions/StdQuadExp.cpp +++ b/library/StdRegions/StdQuadExp.cpp @@ -45,11 +45,6 @@ namespace Nektar { namespace StdRegions { - -StdQuadExp::StdQuadExp() -{ -} - /** \brief Constructor using BasisKey class for quadrature * points and order definition */ @@ -65,11 +60,6 @@ StdQuadExp::StdQuadExp(const StdQuadExp &T) : StdExpansion(T), StdExpansion2D(T) { } -/** \brief Destructor */ -StdQuadExp::~StdQuadExp() -{ -} - ///////////////////////// // Integration Methods // ///////////////////////// diff --git a/library/StdRegions/StdQuadExp.h b/library/StdRegions/StdQuadExp.h index b1791ef431aecee60e0ee3104e213db2cf99fedd..cb04c171258776db9a8bf9ffa470f6f1ed2acd8f 100644 --- a/library/StdRegions/StdQuadExp.h +++ b/library/StdRegions/StdQuadExp.h @@ -53,83 +53,84 @@ class StdQuadExp : virtual public StdExpansion2D typedef std::shared_ptr StdExpansion1DSharedPtr; public: - STD_REGIONS_EXPORT StdQuadExp(); + STD_REGIONS_EXPORT StdQuadExp() = default; STD_REGIONS_EXPORT StdQuadExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb); STD_REGIONS_EXPORT StdQuadExp(const StdQuadExp &T); - STD_REGIONS_EXPORT ~StdQuadExp(); + STD_REGIONS_EXPORT ~StdQuadExp() override = default; protected: //------------------------------- // Integration Methods //------------------------------- STD_REGIONS_EXPORT NekDouble - v_Integral(const Array &inarray); + v_Integral(const Array &inarray) override; //------------------------------- // Differentiation Methods //------------------------------- - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + STD_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2 = NullNekDouble1DArray); - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + Array &out_d2 = NullNekDouble1DArray) override; + STD_REGIONS_EXPORT void v_PhysDeriv( const int dir, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + Array &outarray) override; + STD_REGIONS_EXPORT void v_StdPhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2 = NullNekDouble1DArray); - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + Array &out_d2 = NullNekDouble1DArray) override; + STD_REGIONS_EXPORT void v_StdPhysDeriv( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Transforms //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_BwdTrans( + STD_REGIONS_EXPORT void v_BwdTrans( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_FwdTransBndConstrained( + Array &outarray) override; + STD_REGIONS_EXPORT void v_FwdTransBndConstrained( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFac( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFacKernel( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFacKernel( const Array &base0, const Array &base1, const Array &inarray, Array &outarray, Array &wsp, - bool doCheckCollDir0, bool doCheckCollDir1); - STD_REGIONS_EXPORT virtual void v_FwdTrans( + bool doCheckCollDir0, bool doCheckCollDir1) override; + STD_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Inner product functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_IProductWRTBase( + STD_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multiplybyweights = true); + Array &outarray, + bool multiplybyweights = true) override; STD_REGIONS_EXPORT virtual void v_IProductWRTBase_MatOp( const Array &inarray, Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFacKernel( + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFacKernel( const Array &base0, const Array &base1, const Array &inarray, Array &outarray, Array &wsp, - bool doCheckCollDir0, bool doCheckCollDir1); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + bool doCheckCollDir0, bool doCheckCollDir1) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_MatOp( const int dir, const Array &inarray, Array &outarray); @@ -138,98 +139,109 @@ protected: // Evaluation functions //--------------------------------------- STD_REGIONS_EXPORT virtual void v_LocCoordToLocCollapsed( - const Array &xi, Array &eta); + const Array &xi, + Array &eta) override; STD_REGIONS_EXPORT virtual void v_LocCollapsedToLocCoord( - const Array &eta, Array &xi); + const Array &eta, + Array &xi) override; - STD_REGIONS_EXPORT virtual void v_FillMode(const int mode, - Array &array); + STD_REGIONS_EXPORT virtual void v_FillMode( + const int mode, Array &array) override; //--------------------------- // Helper functions //--------------------------- - STD_REGIONS_EXPORT virtual int v_GetNverts() const; - STD_REGIONS_EXPORT virtual int v_GetNtraces() const; - STD_REGIONS_EXPORT virtual int v_GetTraceNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual int v_GetTraceNumPoints(const int i) const; - STD_REGIONS_EXPORT virtual int v_NumBndryCoeffs() const; - STD_REGIONS_EXPORT virtual int v_NumDGBndryCoeffs() const; - - STD_REGIONS_EXPORT virtual int v_CalcNumberOfCoefficients( - const std::vector &nummodes, int &modes_offset); - STD_REGIONS_EXPORT virtual const LibUtilities::BasisKey v_GetTraceBasisKey( - const int i, const int j) const; - STD_REGIONS_EXPORT virtual LibUtilities::ShapeType v_DetShapeType() const; - STD_REGIONS_EXPORT virtual bool v_IsBoundaryInteriorExpansion(); - STD_REGIONS_EXPORT virtual void v_GetCoords( + STD_REGIONS_EXPORT int v_GetNverts() const override; + STD_REGIONS_EXPORT int v_GetNtraces() const override; + STD_REGIONS_EXPORT int v_GetTraceNcoeffs(const int i) const override; + STD_REGIONS_EXPORT int v_GetTraceNumPoints(const int i) const override; + STD_REGIONS_EXPORT int v_NumBndryCoeffs() const override; + STD_REGIONS_EXPORT int v_NumDGBndryCoeffs() const override; + + STD_REGIONS_EXPORT int v_CalcNumberOfCoefficients( + const std::vector &nummodes, int &modes_offset) override; + STD_REGIONS_EXPORT const LibUtilities::BasisKey v_GetTraceBasisKey( + const int i, const int j) const override; + STD_REGIONS_EXPORT LibUtilities::ShapeType v_DetShapeType() const override; + STD_REGIONS_EXPORT bool v_IsBoundaryInteriorExpansion() override; + STD_REGIONS_EXPORT void v_GetCoords( Array &coords_0, Array &coords_1, - Array &coords_2); - STD_REGIONS_EXPORT virtual NekDouble v_PhysEvaluateBasis( - const Array &coords, int mode); + Array &coords_2) override; + STD_REGIONS_EXPORT NekDouble v_PhysEvaluateBasis( + const Array &coords, int mode) override; + STD_REGIONS_EXPORT inline NekDouble v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) override + { + return BaryTensorDeriv(coord, inarray, firstOrderDerivs); + } //-------------------------- // Mappings //-------------------------- - STD_REGIONS_EXPORT virtual void v_GetBoundaryMap( - Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetInteriorMap( - Array &outarray); - STD_REGIONS_EXPORT virtual int v_GetVertexMap(int localVertexId, - bool useCoeffPacking = false); - - STD_REGIONS_EXPORT virtual void v_GetTraceCoeffMap( - const unsigned int traceid, Array &maparray); - - STD_REGIONS_EXPORT virtual void v_GetTraceInteriorToElementMap( + STD_REGIONS_EXPORT void v_GetBoundaryMap( + Array &outarray) override; + STD_REGIONS_EXPORT void v_GetInteriorMap( + Array &outarray) override; + STD_REGIONS_EXPORT int v_GetVertexMap( + int localVertexId, bool useCoeffPacking = false) override; + + STD_REGIONS_EXPORT void v_GetTraceCoeffMap( + const unsigned int traceid, + Array &maparray) override; + + STD_REGIONS_EXPORT void v_GetTraceInteriorToElementMap( const int eid, Array &maparray, - Array &signarray, const Orientation edgeOrient = eForwards); + Array &signarray, + const Orientation edgeOrient = eForwards) override; //--------------------------------------- // Wrapper functions //--------------------------------------- - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdMatrixKey &mkey); + STD_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdMatrixKey &mkey) override; //--------------------------------------- // Operator evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_MassMatrixOp( + STD_REGIONS_EXPORT void v_MassMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_LaplacianMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_LaplacianMatrixOp( const int k1, const int k2, const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_WeakDerivMatrixOp( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_WeakDerivMatrixOp( const int i, const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_HelmholtzMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_SVVLaplacianFilter( - Array &array, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_ExponentialFilter( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_SVVLaplacianFilter( + Array &array, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_ExponentialFilter( Array &array, const NekDouble alpha, - const NekDouble exponent, const NekDouble cutoff); - STD_REGIONS_EXPORT virtual void v_ReduceOrderCoeffs( + const NekDouble exponent, const NekDouble cutoff) override; + STD_REGIONS_EXPORT void v_ReduceOrderCoeffs( int numMin, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT void v_GeneralMatrixOp_MatOp( + Array &outarray) override; + STD_REGIONS_EXPORT virtual void v_GeneralMatrixOp_MatOp( const Array &inarray, Array &outarray, const StdMatrixKey &mkey); STD_REGIONS_EXPORT void v_MultiplyByStdQuadratureMetric( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Output interpolation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_GetSimplexEquiSpacedConnectivity( - Array &conn, bool standard = true); + STD_REGIONS_EXPORT void v_GetSimplexEquiSpacedConnectivity( + Array &conn, bool standard = true) override; }; typedef std::shared_ptr StdQuadExpSharedPtr; diff --git a/library/StdRegions/StdSegExp.cpp b/library/StdRegions/StdSegExp.cpp index ab0dcc90e1f63456a417acb8019048735b6d8b01..d6f65b8e8337b27c987c1279818ec1bb431a7ce3 100644 --- a/library/StdRegions/StdSegExp.cpp +++ b/library/StdRegions/StdSegExp.cpp @@ -43,20 +43,12 @@ namespace Nektar { namespace StdRegions { - -/** \brief Default constructor */ - -StdSegExp::StdSegExp() -{ -} - /** \brief Constructor using BasisKey class for quadrature points and * order definition * * \param Ba BasisKey class definition containing order and quadrature * points. */ - StdSegExp::StdSegExp(const LibUtilities::BasisKey &Ba) : StdExpansion(Ba.GetNumModes(), 1, Ba), StdExpansion1D(Ba.GetNumModes(), Ba) @@ -64,15 +56,10 @@ StdSegExp::StdSegExp(const LibUtilities::BasisKey &Ba) } /** \brief Copy Constructor */ - StdSegExp::StdSegExp(const StdSegExp &T) : StdExpansion(T), StdExpansion1D(T) { } -StdSegExp::~StdSegExp() -{ -} - /** \brief Return Shape of region, using ShapeType enum list. * i.e. Segment */ diff --git a/library/StdRegions/StdSegExp.h b/library/StdRegions/StdSegExp.h index d70f81f64b89df0a26c179ab5d1164166db05805..9bd84bd8e8ea07f02bcb5a89f4cf69522052172e 100644 --- a/library/StdRegions/StdSegExp.h +++ b/library/StdRegions/StdSegExp.h @@ -42,203 +42,223 @@ namespace Nektar { namespace StdRegions { - -class StdSegExp; -typedef std::shared_ptr StdSegExpSharedPtr; - /// Class representing a segment element in reference space - /// All interface of this class sits in StdExpansion class - class StdSegExp : virtual public StdExpansion1D { public: - STD_REGIONS_EXPORT StdSegExp(); + STD_REGIONS_EXPORT StdSegExp() = default; STD_REGIONS_EXPORT StdSegExp(const LibUtilities::BasisKey &Ba); STD_REGIONS_EXPORT StdSegExp(const StdSegExp &T); - STD_REGIONS_EXPORT ~StdSegExp(); + STD_REGIONS_EXPORT ~StdSegExp() override = default; protected: //---------------------------- // Integration Methods //---------------------------- - STD_REGIONS_EXPORT virtual NekDouble v_Integral( - const Array &inarray); + STD_REGIONS_EXPORT NekDouble + v_Integral(const Array &inarray) override; //----------------------------- // Differentiation Methods //----------------------------- - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + STD_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1 = NullNekDouble1DArray, - Array &out_d2 = NullNekDouble1DArray); + Array &out_d2 = NullNekDouble1DArray) override; - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + STD_REGIONS_EXPORT void v_PhysDeriv( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + STD_REGIONS_EXPORT void v_StdPhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1 = NullNekDouble1DArray, - Array &out_d2 = NullNekDouble1DArray); + Array &out_d2 = NullNekDouble1DArray) override; - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + STD_REGIONS_EXPORT void v_StdPhysDeriv( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //----------------------------- // Transforms //----------------------------- - STD_REGIONS_EXPORT virtual void v_BwdTrans( + STD_REGIONS_EXPORT void v_BwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_FwdTrans( + STD_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFac( + STD_REGIONS_EXPORT void v_BwdTrans_SumFac( const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_FwdTransBndConstrained( + STD_REGIONS_EXPORT void v_FwdTransBndConstrained( const Array &inarray, - Array &outarray); + Array &outarray) override; //---------------------------- // Inner product functions //---------------------------- - STD_REGIONS_EXPORT virtual void v_IProductWRTBase( + STD_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_IProductWRTBase( + STD_REGIONS_EXPORT void v_IProductWRTBase( const Array &base, const Array &inarray, - Array &outarray, int coll_check); + Array &outarray, int coll_check) override; - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multiplybyweights = true); + Array &outarray, + bool multiplybyweights = true) override; - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + STD_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_SumFac( + STD_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //---------------------------- // Evaluations Methods //--------------------------- - STD_REGIONS_EXPORT virtual void v_LocCoordToLocCollapsed( - const Array &xi, Array &eta); + STD_REGIONS_EXPORT void v_LocCoordToLocCollapsed( + const Array &xi, + Array &eta) override; - STD_REGIONS_EXPORT virtual void v_LocCollapsedToLocCoord( - const Array &eta, Array &xi); + STD_REGIONS_EXPORT void v_LocCollapsedToLocCoord( + const Array &eta, + Array &xi) override; STD_REGIONS_EXPORT NekDouble v_PhysEvaluateBasis( const Array &coords, int mode) final; - STD_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + STD_REGIONS_EXPORT inline NekDouble v_PhysEvaluate( + const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) override + { + return StdExpansion1D::BaryTensorDeriv(coord, inarray, + firstOrderDerivs); + } + + STD_REGIONS_EXPORT inline NekDouble v_PhysEvaluate( + const Array &coord, const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); + std::array &firstOrderDerivs, + std::array &secondOrderDerivs) override + { + return StdExpansion1D::BaryTensorDeriv(coord, inarray, firstOrderDerivs, + secondOrderDerivs); + } + + STD_REGIONS_EXPORT void v_LaplacianMatrixOp( + const Array &inarray, + Array &outarray, const StdMatrixKey &mkey) override; - STD_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp( + STD_REGIONS_EXPORT void v_HelmholtzMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); + Array &outarray, const StdMatrixKey &mkey) override; - STD_REGIONS_EXPORT virtual void v_SVVLaplacianFilter( - Array &array, const StdMatrixKey &mkey); + STD_REGIONS_EXPORT void v_SVVLaplacianFilter( + Array &array, const StdMatrixKey &mkey) override; - STD_REGIONS_EXPORT virtual void v_ExponentialFilter( + STD_REGIONS_EXPORT void v_ExponentialFilter( Array &array, const NekDouble alpha, - const NekDouble exponent, const NekDouble cutoff); + const NekDouble exponent, const NekDouble cutoff) override; - STD_REGIONS_EXPORT virtual void v_MultiplyByStdQuadratureMetric( + STD_REGIONS_EXPORT void v_MultiplyByStdQuadratureMetric( const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_FillMode( - const int mode, Array &outarray); + STD_REGIONS_EXPORT void v_FillMode( + const int mode, Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_GetCoords( + STD_REGIONS_EXPORT void v_GetCoords( Array &coords_0, Array &coords_1, - Array &coords_2); + Array &coords_2) override; //---------------------------- // Public Mappings //--------------------------- - STD_REGIONS_EXPORT virtual void v_GetBoundaryMap( - Array &outarray); + STD_REGIONS_EXPORT void v_GetBoundaryMap( + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_GetInteriorMap( - Array &outarray); + STD_REGIONS_EXPORT void v_GetInteriorMap( + Array &outarray) override; - STD_REGIONS_EXPORT virtual int v_GetVertexMap(int localVertexId, - bool useCoeffPacking = false); + STD_REGIONS_EXPORT int v_GetVertexMap( + int localVertexId, bool useCoeffPacking = false) override; //---------------------------- // Helper functions //--------------------------- - STD_REGIONS_EXPORT virtual int v_GetNverts() const; - STD_REGIONS_EXPORT virtual int v_GetNtraces() const; - STD_REGIONS_EXPORT virtual int v_GetTraceNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual int v_GetTraceNumPoints(const int i) const; - STD_REGIONS_EXPORT virtual int v_NumBndryCoeffs() const; - STD_REGIONS_EXPORT virtual int v_NumDGBndryCoeffs() const; - STD_REGIONS_EXPORT virtual bool v_IsBoundaryInteriorExpansion(); - STD_REGIONS_EXPORT virtual int v_CalcNumberOfCoefficients( - const std::vector &nummodes, int &modes_offset); - STD_REGIONS_EXPORT virtual LibUtilities::ShapeType v_DetShapeType() const; + STD_REGIONS_EXPORT int v_GetNverts() const override; + STD_REGIONS_EXPORT int v_GetNtraces() const override; + STD_REGIONS_EXPORT int v_GetTraceNcoeffs(const int i) const override; + STD_REGIONS_EXPORT int v_GetTraceNumPoints(const int i) const override; + STD_REGIONS_EXPORT int v_NumBndryCoeffs() const override; + STD_REGIONS_EXPORT int v_NumDGBndryCoeffs() const override; + STD_REGIONS_EXPORT bool v_IsBoundaryInteriorExpansion() override; + STD_REGIONS_EXPORT int v_CalcNumberOfCoefficients( + const std::vector &nummodes, int &modes_offset) override; + STD_REGIONS_EXPORT LibUtilities::ShapeType v_DetShapeType() const override; //---------------------------- // Wrapper functions //--------------------------- - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdMatrixKey &mkey); + STD_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdMatrixKey &mkey) override; - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdMatrixKey &mkey); + STD_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdMatrixKey &mkey) override; //--------------------------------------- // Output interpolation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_GetSimplexEquiSpacedConnectivity( - Array &conn, bool standard = true); + STD_REGIONS_EXPORT void v_GetSimplexEquiSpacedConnectivity( + Array &conn, bool standard = true) override; // Operator evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_ReduceOrderCoeffs( + STD_REGIONS_EXPORT void v_ReduceOrderCoeffs( int numMin, const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_GetTraceCoeffMap( - const unsigned int traceid, Array &maparray); + STD_REGIONS_EXPORT void v_GetTraceCoeffMap( + const unsigned int traceid, + Array &maparray) override; - STD_REGIONS_EXPORT virtual void v_GetElmtTraceToTraceMap( + STD_REGIONS_EXPORT void v_GetElmtTraceToTraceMap( const unsigned int eid, Array &maparray, - Array &signarray, Orientation edgeOrient, int P, int Q); + Array &signarray, Orientation edgeOrient, int P, + int Q) override; - STD_REGIONS_EXPORT virtual void v_GetTraceToElementMap( + STD_REGIONS_EXPORT void v_GetTraceToElementMap( const int tid, Array &maparray, - Array &signarray, Orientation edgeOrient, int P, int Q); + Array &signarray, Orientation edgeOrient, int P, + int Q) override; private: }; +typedef std::shared_ptr StdSegExpSharedPtr; } // namespace StdRegions } // namespace Nektar diff --git a/library/StdRegions/StdTetExp.cpp b/library/StdRegions/StdTetExp.cpp index 8372ab48a528e7282618c0f23dbdb1a9c18fbee1..0bc9ef754b6ab41c6414601f23ca7da1414b011a 100644 --- a/library/StdRegions/StdTetExp.cpp +++ b/library/StdRegions/StdTetExp.cpp @@ -43,10 +43,6 @@ namespace Nektar { namespace StdRegions { -StdTetExp::StdTetExp() -{ -} - StdTetExp::StdTetExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc) @@ -72,10 +68,6 @@ StdTetExp::StdTetExp(const StdTetExp &T) : StdExpansion(T), StdExpansion3D(T) { } -StdTetExp::~StdTetExp() -{ -} - //---------------------------- // Differentiation Methods //---------------------------- @@ -912,6 +904,70 @@ NekDouble StdTetExp::v_PhysEvaluateBasis( StdExpansion::BaryEvaluateBasis<2>(coll[2], mode2); } +NekDouble StdTetExp::v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + // Collapse coordinates + Array coll(3, 0.0); + LocCoordToLocCollapsed(coord, coll); + + // If near singularity do the old interpolation matrix method + if ((1 - coll[1]) < 1e-5 || (1 - coll[2]) < 1e-5) + { + int totPoints = GetTotPoints(); + Array EphysDeriv0(totPoints), EphysDeriv1(totPoints), + EphysDeriv2(totPoints); + PhysDeriv(inarray, EphysDeriv0, EphysDeriv1, EphysDeriv2); + + Array I(3); + I[0] = GetBase()[0]->GetI(coll); + I[1] = GetBase()[1]->GetI(coll + 1); + I[2] = GetBase()[2]->GetI(coll + 2); + + firstOrderDerivs[0] = PhysEvaluate(I, EphysDeriv0); + firstOrderDerivs[1] = PhysEvaluate(I, EphysDeriv1); + firstOrderDerivs[2] = PhysEvaluate(I, EphysDeriv2); + return PhysEvaluate(I, inarray); + } + + std::array interDeriv; + NekDouble val = BaryTensorDeriv(coll, inarray, interDeriv); + + // calculate 2.0/((1-eta_1)(1-eta_2)) * Out_dEta0 + NekDouble temp = 2.0 / ((1 - coll[1]) * (1 - coll[2])); + interDeriv[0] *= temp; + + // out_dxi0 = 4.0/((1-eta_1)(1-eta_2)) * Out_dEta0 + firstOrderDerivs[0] = 2 * interDeriv[0]; + + // fac0 = 1 + eta_0 + NekDouble fac0; + fac0 = 1 + coll[0]; + + // calculate 2.0*(1+eta_0)/((1-eta_1)(1-eta_2)) * Out_dEta0 + interDeriv[0] *= fac0; + + // calculate 2/(1.0-eta_2) * out_dEta1 + fac0 = 2 / (1 - coll[2]); + interDeriv[1] *= fac0; + + // calculate out_dxi1 = 2.0(1+eta_0)/((1-eta_1)(1-eta_2)) + // * Out_dEta0 + 2/(1.0-eta_2) out_dEta1 + firstOrderDerivs[1] = interDeriv[0] + interDeriv[1]; + + // calculate (1 + eta_1)/(1 -eta_2)*out_dEta1 + fac0 = (1 + coll[1]) / 2; + interDeriv[1] *= fac0; + + // calculate out_dxi2 = + // 2.0(1+eta_0)/((1-eta_1)(1-eta_2)) Out_dEta0 + + // (1 + eta_1)/(1 -eta_2)*out_dEta1 + out_dEta2 + firstOrderDerivs[2] = interDeriv[0] + interDeriv[1] + interDeriv[2]; + + return val; +} + void StdTetExp::v_GetTraceNumModes(const int fid, int &numModes0, int &numModes1, diff --git a/library/StdRegions/StdTetExp.h b/library/StdRegions/StdTetExp.h index 1a69922ae14282d1784b7fdfb79d250c74ea2ec3..0c64e78e452c12bf8a944ed396e396014bac817c 100644 --- a/library/StdRegions/StdTetExp.h +++ b/library/StdRegions/StdTetExp.h @@ -50,7 +50,7 @@ class StdTetExp : virtual public StdExpansion3D { public: - STD_REGIONS_EXPORT StdTetExp(); + STD_REGIONS_EXPORT StdTetExp() = default; STD_REGIONS_EXPORT StdTetExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc); @@ -59,7 +59,7 @@ public: const LibUtilities::BasisKey &Bc, NekDouble *coeffs, NekDouble *phys); STD_REGIONS_EXPORT StdTetExp(const StdTetExp &T); - STD_REGIONS_EXPORT ~StdTetExp(); + STD_REGIONS_EXPORT ~StdTetExp() override = default; LibUtilities::ShapeType DetShapeType() const { @@ -75,167 +75,177 @@ protected: //---------------------------- // Differentiation Methods //---------------------------- - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + STD_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_dx, Array &out_dy, - Array &out_dz); - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + Array &out_dz) override; + STD_REGIONS_EXPORT void v_PhysDeriv( const int dir, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + Array &outarray) override; + STD_REGIONS_EXPORT void v_StdPhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2); - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + Array &out_d2) override; + STD_REGIONS_EXPORT void v_StdPhysDeriv( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Transforms //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_BwdTrans( + STD_REGIONS_EXPORT void v_BwdTrans( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFac( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFacKernel( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFacKernel( const Array &base0, const Array &base1, const Array &base2, const Array &inarray, Array &outarray, Array &wsp, - bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2); - STD_REGIONS_EXPORT virtual void v_FwdTrans( + bool doCheckCollDir0, bool doCheckCollDir1, + bool doCheckCollDir2) override; + STD_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Inner product functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_IProductWRTBase( + STD_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_MatOp( + Array &outarray) override; + STD_REGIONS_EXPORT void v_IProductWRTBase_MatOp( const Array &inarray, Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multiplybyweights = true); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFacKernel( + Array &outarray, + bool multiplybyweights = true) override; + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFacKernel( const Array &base0, const Array &base1, const Array &base2, const Array &inarray, Array &outarray, Array &wsp, - bool doCheckCollDir0, bool doCheckCollDir1, bool doCheckCollDir2); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + bool doCheckCollDir0, bool doCheckCollDir1, + bool doCheckCollDir2) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_MatOp( + Array &outarray) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase_MatOp( const int dir, const Array &inarray, Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_SumFac( + STD_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_LocCoordToLocCollapsed( - const Array &xi, Array &eta); - STD_REGIONS_EXPORT virtual void v_LocCollapsedToLocCoord( - const Array &eta, Array &xi); - STD_REGIONS_EXPORT virtual void v_GetCoords( + STD_REGIONS_EXPORT void v_LocCoordToLocCollapsed( + const Array &xi, + Array &eta) override; + STD_REGIONS_EXPORT void v_LocCollapsedToLocCoord( + const Array &eta, + Array &xi) override; + STD_REGIONS_EXPORT void v_GetCoords( Array &coords_x, Array &coords_y, - Array &coords_z); - STD_REGIONS_EXPORT virtual void v_FillMode( - const int mode, Array &outarray); + Array &coords_z) override; + STD_REGIONS_EXPORT void v_FillMode( + const int mode, Array &outarray) override; STD_REGIONS_EXPORT NekDouble v_PhysEvaluateBasis( const Array &coords, int mode) final; - STD_REGIONS_EXPORT virtual void v_GetTraceNumModes( + STD_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) override; + + STD_REGIONS_EXPORT void v_GetTraceNumModes( const int fid, int &numModes0, int &numModes1, - Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2); + Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2) override; //--------------------------- // Helper functions //--------------------------- - STD_REGIONS_EXPORT virtual int v_GetNverts() const; - STD_REGIONS_EXPORT virtual int v_GetNedges() const; - STD_REGIONS_EXPORT virtual int v_GetNtraces() const; - STD_REGIONS_EXPORT virtual LibUtilities::ShapeType v_DetShapeType() const; - STD_REGIONS_EXPORT virtual int v_NumBndryCoeffs() const; - STD_REGIONS_EXPORT virtual int v_NumDGBndryCoeffs() const; - STD_REGIONS_EXPORT virtual int v_GetTraceNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual int v_GetTotalTraceIntNcoeffs() const; - STD_REGIONS_EXPORT virtual int v_GetTraceIntNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual int v_GetTraceNumPoints(const int i) const; - STD_REGIONS_EXPORT virtual int v_GetEdgeNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual LibUtilities::PointsKey v_GetTracePointsKey( - const int i, const int j) const; - STD_REGIONS_EXPORT virtual int v_CalcNumberOfCoefficients( - const std::vector &nummodes, int &modes_offset); - STD_REGIONS_EXPORT virtual const LibUtilities::BasisKey v_GetTraceBasisKey( - const int i, const int k) const; - STD_REGIONS_EXPORT virtual bool v_IsBoundaryInteriorExpansion(); + STD_REGIONS_EXPORT int v_GetNverts() const override; + STD_REGIONS_EXPORT int v_GetNedges() const override; + STD_REGIONS_EXPORT int v_GetNtraces() const override; + STD_REGIONS_EXPORT LibUtilities::ShapeType v_DetShapeType() const override; + STD_REGIONS_EXPORT int v_NumBndryCoeffs() const override; + STD_REGIONS_EXPORT int v_NumDGBndryCoeffs() const override; + STD_REGIONS_EXPORT int v_GetTraceNcoeffs(const int i) const override; + STD_REGIONS_EXPORT int v_GetTotalTraceIntNcoeffs() const override; + STD_REGIONS_EXPORT int v_GetTraceIntNcoeffs(const int i) const override; + STD_REGIONS_EXPORT int v_GetTraceNumPoints(const int i) const override; + STD_REGIONS_EXPORT int v_GetEdgeNcoeffs(const int i) const override; + STD_REGIONS_EXPORT LibUtilities::PointsKey v_GetTracePointsKey( + const int i, const int j) const override; + STD_REGIONS_EXPORT int v_CalcNumberOfCoefficients( + const std::vector &nummodes, int &modes_offset) override; + STD_REGIONS_EXPORT const LibUtilities::BasisKey v_GetTraceBasisKey( + const int i, const int k) const override; + STD_REGIONS_EXPORT bool v_IsBoundaryInteriorExpansion() override; //-------------------------- // Mappings //-------------------------- - STD_REGIONS_EXPORT virtual int v_GetVertexMap(int localVertexId, - bool useCoeffPacking = false); - STD_REGIONS_EXPORT virtual void v_GetInteriorMap( - Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetBoundaryMap( - Array &outarray); - STD_REGIONS_EXPORT virtual void v_GetTraceCoeffMap( - const unsigned int fid, Array &maparray); - - STD_REGIONS_EXPORT virtual void v_GetElmtTraceToTraceMap( + STD_REGIONS_EXPORT int v_GetVertexMap( + int localVertexId, bool useCoeffPacking = false) override; + STD_REGIONS_EXPORT void v_GetInteriorMap( + Array &outarray) override; + STD_REGIONS_EXPORT void v_GetBoundaryMap( + Array &outarray) override; + STD_REGIONS_EXPORT void v_GetTraceCoeffMap( + const unsigned int fid, Array &maparray) override; + + STD_REGIONS_EXPORT void v_GetElmtTraceToTraceMap( const unsigned int tid, Array &maparray, Array &signarray, Orientation traceOrient = eForwards, - int P = -1, int Q = -1); + int P = -1, int Q = -1) override; - STD_REGIONS_EXPORT virtual void v_GetEdgeInteriorToElementMap( + STD_REGIONS_EXPORT void v_GetEdgeInteriorToElementMap( const int tid, Array &maparray, Array &signarray, - const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2); + const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2) override; - STD_REGIONS_EXPORT virtual void v_GetTraceInteriorToElementMap( + STD_REGIONS_EXPORT void v_GetTraceInteriorToElementMap( const int tid, Array &maparray, Array &signarray, - const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2); + const Orientation traceOrient = eDir1FwdDir1_Dir2FwdDir2) override; //--------------------------------------- // Wrapper functions //--------------------------------------- - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdMatrixKey &mkey); + STD_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdMatrixKey &mkey) override; - STD_REGIONS_EXPORT virtual void v_MultiplyByStdQuadratureMetric( + STD_REGIONS_EXPORT void v_MultiplyByStdQuadratureMetric( const Array &inarray, - Array &outarray); + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_SVVLaplacianFilter( - Array &array, const StdMatrixKey &mkey); + STD_REGIONS_EXPORT void v_SVVLaplacianFilter( + Array &array, const StdMatrixKey &mkey) override; //--------------------------------------- // Method for applying sensors //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_ReduceOrderCoeffs( + STD_REGIONS_EXPORT void v_ReduceOrderCoeffs( int numMin, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Output interpolation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_GetSimplexEquiSpacedConnectivity( - Array &conn, bool standard = true); + STD_REGIONS_EXPORT void v_GetSimplexEquiSpacedConnectivity( + Array &conn, bool standard = true) override; private: //--------------------------------------- diff --git a/library/StdRegions/StdTriExp.cpp b/library/StdRegions/StdTriExp.cpp index 7d6274a86583ed616314840741a16ba1e5707f5d..866cc370ca97f98ed654e5a6b109aebeb91417ae 100644 --- a/library/StdRegions/StdTriExp.cpp +++ b/library/StdRegions/StdTriExp.cpp @@ -45,11 +45,6 @@ namespace Nektar { namespace StdRegions { - -StdTriExp::StdTriExp() -{ -} - StdTriExp::StdTriExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb) : StdExpansion(LibUtilities::StdTriData::getNumberOfCoefficients( @@ -68,10 +63,6 @@ StdTriExp::StdTriExp(const StdTriExp &T) : StdExpansion(T), StdExpansion2D(T) { } -StdTriExp::~StdTriExp() -{ -} - //------------------------------- // Integration Methods //------------------------------- @@ -739,6 +730,51 @@ NekDouble StdTriExp::v_PhysEvaluateBasis( } } +NekDouble StdTriExp::v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) +{ + // Collapse coordinates + Array coll(2, 0.0); + LocCoordToLocCollapsed(coord, coll); + + // If near singularity do the old interpolation matrix method + if ((1 - coll[1]) < 1e-5) + { + int totPoints = GetTotPoints(); + Array EphysDeriv0(totPoints), EphysDeriv1(totPoints); + PhysDeriv(inarray, EphysDeriv0, EphysDeriv1); + + Array I(2); + I[0] = GetBase()[0]->GetI(coll); + I[1] = GetBase()[1]->GetI(coll + 1); + + firstOrderDerivs[0] = PhysEvaluate(I, EphysDeriv0); + firstOrderDerivs[1] = PhysEvaluate(I, EphysDeriv1); + return PhysEvaluate(I, inarray); + } + + // set up geometric factor: 2.0/(1.0-z1) + NekDouble fac0 = 2 / (1 - coll[1]); + + NekDouble val = BaryTensorDeriv(coll, inarray, firstOrderDerivs); + + // Copy d0 into temp for d1 + NekDouble temp; + temp = firstOrderDerivs[0]; + + // Multiply by geometric factor + firstOrderDerivs[0] = firstOrderDerivs[0] * fac0; + + // set up geometric factor: (1+z0)/(1-z1) + NekDouble fac1 = fac0 * (coll[0] + 1) / 2; + + // Multiply out_d0 by geometric factor and add to out_d1 + firstOrderDerivs[1] += fac1 * temp; + + return val; +} + int StdTriExp::v_GetNverts() const { return 3; diff --git a/library/StdRegions/StdTriExp.h b/library/StdRegions/StdTriExp.h index 1b810b1f06c72a877e851317c24adbbde9d152e5..62b45b0fafd0a11f57e79f952f1abd5274f9d6e9 100644 --- a/library/StdRegions/StdTriExp.h +++ b/library/StdRegions/StdTriExp.h @@ -48,131 +48,140 @@ class StdMatrixKey; class StdTriExp : virtual public StdExpansion2D { public: - STD_REGIONS_EXPORT StdTriExp(); + STD_REGIONS_EXPORT StdTriExp() = default; STD_REGIONS_EXPORT StdTriExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb); STD_REGIONS_EXPORT StdTriExp(const StdTriExp &T); - STD_REGIONS_EXPORT ~StdTriExp(); + STD_REGIONS_EXPORT ~StdTriExp() override = default; protected: //------------------------------- // Integration Methods //------------------------------- - STD_REGIONS_EXPORT virtual NekDouble v_Integral( - const Array &inarray); + STD_REGIONS_EXPORT NekDouble + v_Integral(const Array &inarray) override; //---------------------------- // Differentiation Methods //---------------------------- - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + STD_REGIONS_EXPORT void v_PhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2 = NullNekDouble1DArray); - STD_REGIONS_EXPORT virtual void v_PhysDeriv( + Array &out_d2 = NullNekDouble1DArray) override; + STD_REGIONS_EXPORT void v_PhysDeriv( const int dir, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + Array &outarray) override; + STD_REGIONS_EXPORT void v_StdPhysDeriv( const Array &inarray, Array &out_d0, Array &out_d1, - Array &out_d2 = NullNekDouble1DArray); - STD_REGIONS_EXPORT virtual void v_StdPhysDeriv( + Array &out_d2 = NullNekDouble1DArray) override; + STD_REGIONS_EXPORT void v_StdPhysDeriv( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Transforms //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_BwdTrans( + STD_REGIONS_EXPORT void v_BwdTrans( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFac( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFac( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_BwdTrans_SumFacKernel( + Array &outarray) override; + STD_REGIONS_EXPORT void v_BwdTrans_SumFacKernel( const Array &base0, const Array &base1, const Array &inarray, Array &outarray, Array &wsp, - bool doCheckCollDir0, bool doCheckCollDir1); - STD_REGIONS_EXPORT virtual void v_FwdTrans( + bool doCheckCollDir0, bool doCheckCollDir1) override; + STD_REGIONS_EXPORT void v_FwdTrans( const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_FwdTransBndConstrained( + Array &outarray) override; + STD_REGIONS_EXPORT void v_FwdTransBndConstrained( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Inner product functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_IProductWRTBase( + STD_REGIONS_EXPORT void v_IProductWRTBase( const Array &inarray, - Array &outarray); + Array &outarray) override; STD_REGIONS_EXPORT virtual void v_IProductWRTBase_MatOp( const Array &inarray, Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFac( + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFac( const Array &inarray, - Array &outarray, bool multiplybyweights = true); - STD_REGIONS_EXPORT virtual void v_IProductWRTBase_SumFacKernel( + Array &outarray, + bool multiplybyweights = true) override; + STD_REGIONS_EXPORT void v_IProductWRTBase_SumFacKernel( const Array &base0, const Array &base1, const Array &inarray, Array &outarray, Array &wsp, - bool doCheckCollDir0, bool doCheckCollDir1); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase( + bool doCheckCollDir0, bool doCheckCollDir1) override; + STD_REGIONS_EXPORT void v_IProductWRTDerivBase( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_MatOp( const int dir, const Array &inarray, Array &outarray); - STD_REGIONS_EXPORT virtual void v_IProductWRTDerivBase_SumFac( + STD_REGIONS_EXPORT void v_IProductWRTDerivBase_SumFac( const int dir, const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_LocCoordToLocCollapsed( - const Array &xi, Array &eta); - STD_REGIONS_EXPORT virtual void v_LocCollapsedToLocCoord( - const Array &eta, Array &xi); - STD_REGIONS_EXPORT virtual void v_FillMode( - const int mode, Array &outarray); + STD_REGIONS_EXPORT void v_LocCoordToLocCollapsed( + const Array &xi, + Array &eta) override; + STD_REGIONS_EXPORT void v_LocCollapsedToLocCoord( + const Array &eta, + Array &xi) override; + STD_REGIONS_EXPORT void v_FillMode( + const int mode, Array &outarray) override; STD_REGIONS_EXPORT NekDouble v_PhysEvaluateBasis( const Array &coords, int mode) final; + STD_REGIONS_EXPORT NekDouble + v_PhysEvaluate(const Array &coord, + const Array &inarray, + std::array &firstOrderDerivs) override; + //--------------------------- // Helper functions //--------------------------- - STD_REGIONS_EXPORT virtual int v_GetNverts() const; - STD_REGIONS_EXPORT virtual int v_GetNtraces() const; - STD_REGIONS_EXPORT virtual LibUtilities::ShapeType v_DetShapeType() const; - STD_REGIONS_EXPORT virtual int v_NumBndryCoeffs() const; - STD_REGIONS_EXPORT virtual int v_NumDGBndryCoeffs() const; - STD_REGIONS_EXPORT virtual int v_GetTraceNcoeffs(const int i) const; - STD_REGIONS_EXPORT virtual int v_GetTraceNumPoints(const int i) const; - STD_REGIONS_EXPORT virtual int v_CalcNumberOfCoefficients( - const std::vector &nummodes, int &modes_offset); - STD_REGIONS_EXPORT virtual void v_GetCoords( + STD_REGIONS_EXPORT int v_GetNverts() const override; + STD_REGIONS_EXPORT int v_GetNtraces() const override; + STD_REGIONS_EXPORT LibUtilities::ShapeType v_DetShapeType() const override; + STD_REGIONS_EXPORT int v_NumBndryCoeffs() const override; + STD_REGIONS_EXPORT int v_NumDGBndryCoeffs() const override; + STD_REGIONS_EXPORT int v_GetTraceNcoeffs(const int i) const override; + STD_REGIONS_EXPORT int v_GetTraceNumPoints(const int i) const override; + STD_REGIONS_EXPORT int v_CalcNumberOfCoefficients( + const std::vector &nummodes, int &modes_offset) override; + STD_REGIONS_EXPORT void v_GetCoords( Array &coords_x, Array &coords_y, - Array &coords_z); - STD_REGIONS_EXPORT virtual bool v_IsBoundaryInteriorExpansion(); - STD_REGIONS_EXPORT virtual const LibUtilities::BasisKey v_GetTraceBasisKey( - const int i, const int j) const; + Array &coords_z) override; + STD_REGIONS_EXPORT bool v_IsBoundaryInteriorExpansion() override; + STD_REGIONS_EXPORT const LibUtilities::BasisKey v_GetTraceBasisKey( + const int i, const int j) const override; //-------------------------- // Mappings //-------------------------- - STD_REGIONS_EXPORT virtual int v_GetVertexMap(int localVertexId, - bool useCoeffPacking = false); - STD_REGIONS_EXPORT virtual void v_GetInteriorMap( - Array &outarray); + STD_REGIONS_EXPORT int v_GetVertexMap( + int localVertexId, bool useCoeffPacking = false) override; + STD_REGIONS_EXPORT void v_GetInteriorMap( + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_GetBoundaryMap( - Array &outarray); + STD_REGIONS_EXPORT void v_GetBoundaryMap( + Array &outarray) override; - STD_REGIONS_EXPORT virtual void v_GetTraceCoeffMap( - const unsigned int traceid, Array &maparray); + STD_REGIONS_EXPORT void v_GetTraceCoeffMap( + const unsigned int traceid, + Array &maparray) override; #if 0 STD_REGIONS_EXPORT virtual void v_GetTraceToElementMap( const int eid, @@ -183,54 +192,55 @@ protected: int Q = -1); #endif - STD_REGIONS_EXPORT virtual void v_GetTraceInteriorToElementMap( + STD_REGIONS_EXPORT void v_GetTraceInteriorToElementMap( const int eid, Array &maparray, - Array &signarray, const Orientation edgeOrient = eForwards); + Array &signarray, + const Orientation edgeOrient = eForwards) override; //--------------------------------------- // Wrapper functions //--------------------------------------- - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_GenMatrix( - const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual DNekMatSharedPtr v_CreateStdMatrix( - const StdMatrixKey &mkey); + STD_REGIONS_EXPORT DNekMatSharedPtr + v_GenMatrix(const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT DNekMatSharedPtr + v_CreateStdMatrix(const StdMatrixKey &mkey) override; //--------------------------------------- // Operator evaluation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_MassMatrixOp( + STD_REGIONS_EXPORT void v_MassMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_LaplacianMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_SVVLaplacianFilter( - Array &array, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_ReduceOrderCoeffs( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_SVVLaplacianFilter( + Array &array, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_ReduceOrderCoeffs( int numMin, const Array &inarray, - Array &outarray); - STD_REGIONS_EXPORT virtual void v_LaplacianMatrixOp( + Array &outarray) override; + STD_REGIONS_EXPORT void v_LaplacianMatrixOp( const int k1, const int k2, const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_WeakDerivMatrixOp( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_WeakDerivMatrixOp( const int i, const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_HelmholtzMatrixOp( + Array &outarray, const StdMatrixKey &mkey) override; + STD_REGIONS_EXPORT void v_HelmholtzMatrixOp( const Array &inarray, - Array &outarray, const StdMatrixKey &mkey); + Array &outarray, const StdMatrixKey &mkey) override; STD_REGIONS_EXPORT virtual void v_GeneralMatrixOp_MatOp( const Array &inarray, Array &outarray, const StdMatrixKey &mkey); - STD_REGIONS_EXPORT virtual void v_MultiplyByStdQuadratureMetric( + STD_REGIONS_EXPORT void v_MultiplyByStdQuadratureMetric( const Array &inarray, - Array &outarray); + Array &outarray) override; //--------------------------------------- // Output interpolation functions //--------------------------------------- - STD_REGIONS_EXPORT virtual void v_GetSimplexEquiSpacedConnectivity( - Array &conn, bool standard = true); + STD_REGIONS_EXPORT void v_GetSimplexEquiSpacedConnectivity( + Array &conn, bool standard = true) override; }; typedef std::shared_ptr StdTriExpSharedPtr; } // namespace StdRegions diff --git a/solvers/ADRSolver/ADRSolver.cpp b/solvers/ADRSolver/ADRSolver.cpp index 06cf83d9ba6858040fd9cccfccc82cae4d4ff76c..d76db275f4ee53741cb44a0ad356eb47cd6f81b7 100644 --- a/solvers/ADRSolver/ADRSolver.cpp +++ b/solvers/ADRSolver/ADRSolver.cpp @@ -77,7 +77,10 @@ int main(int argc, char *argv[]) // Print out timings if verbose if (session->DefinesCmdLineArgument("verbose")) { - LibUtilities::Timer::PrintElapsedRegions(session->GetComm()); + int iolevel; + session->LoadParameter("IO_Timer_Level", iolevel, 1); + LibUtilities::Timer::PrintElapsedRegions(session->GetComm(), + std::cout, iolevel); } LIKWID_MARKER_CLOSE; diff --git a/solvers/ADRSolver/CMakeLists.txt b/solvers/ADRSolver/CMakeLists.txt index a4cbab98016815f541297e1e5d2c142f91670c82..4934ab8028e48e6d9fc62ebb3ca506ce82060f5b 100644 --- a/solvers/ADRSolver/CMakeLists.txt +++ b/solvers/ADRSolver/CMakeLists.txt @@ -221,6 +221,15 @@ IF( NEKTAR_SOLVER_ADR ) ADD_NEKTAR_TEST(SVV_Prism) ADD_NEKTAR_TEST(SVV_Tet) + # Movement tests + ADD_NEKTAR_TEST(Movement_fixed_interfaces232_dirichlet) + ADD_NEKTAR_TEST(Movement_fixed_interfaces232_periodic) + ADD_NEKTAR_TEST(Movement_fixed_3D_Hex41) + ADD_NEKTAR_TEST(Movement_fixed_2D_curved_quads) + ADD_NEKTAR_TEST(Movement_fixed_2D_varied) + ADD_NEKTAR_TEST(Movement_fixed_3D_stacked_cylinders_curved) + ADD_NEKTAR_TEST(Movement_translate_interfaces232_dirichlet) + IF (NEKTAR_USE_FFTW) ADD_NEKTAR_TEST(Helmholtz_3DHomo1D_FFT) ADD_NEKTAR_TEST(Helmholtz_3DHomo2D_FFT) @@ -258,8 +267,17 @@ IF( NEKTAR_SOLVER_ADR ) ADD_NEKTAR_TEST(Advection2D_m12_DG_quad_VarP_par) ADD_NEKTAR_TEST(Advection2D_m12_DG_tri_VarP_par) ADD_NEKTAR_TEST(Advection2D_dirichlet_regular_GAUSS_LAGRANGE_10x10_MF_par) + ADD_NEKTAR_TEST(Movement_fixed_interfaces232_periodic_par) + ADD_NEKTAR_TEST(Movement_fixed_3D_Hex41_par) + ADD_NEKTAR_TEST(Movement_fixed_3D_Hex_3zones_Periodic_par) + ADD_NEKTAR_TEST(Movement_fixed_2D_varied_par) + ADD_NEKTAR_TEST(Movement_fixed_3D_stacked_cylinders_curved_par) + ADD_NEKTAR_TEST(Movement_rotate_3D_stacked_cylinders_curved_par) + ADD_NEKTAR_TEST(Movement_translate_interfaces232_dirichlet_par) IF (NEKTAR_USE_HDF5) ADD_NEKTAR_TEST(Advection3D_m10_DG_prism_VarP_hdf) + ADD_NEKTAR_TEST(Movement_fixed_3D_stacked_cylinders_curved_hdf5) + ADD_NEKTAR_TEST(Movement_fixed_3D_stacked_cylinders_curved_hdf5_par) ENDIF() ADD_NEKTAR_TEST(RotPerBcs3D_Annulus LENGTHY) ADD_NEKTAR_TEST(UnsteadyAdvection_WDG_3DHomo1D_MVM_NPZ) diff --git a/solvers/ADRSolver/EquationSystems/UnsteadyAdvection.cpp b/solvers/ADRSolver/EquationSystems/UnsteadyAdvection.cpp index adbd3a8b9a5dd61e8eff63c4115fb6e921fff776..6c3e535d67f315de38a52def0a02ac5971c7a151 100644 --- a/solvers/ADRSolver/EquationSystems/UnsteadyAdvection.cpp +++ b/solvers/ADRSolver/EquationSystems/UnsteadyAdvection.cpp @@ -49,9 +49,9 @@ string UnsteadyAdvection::className = UnsteadyAdvection::UnsteadyAdvection( const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph) - : UnsteadySystem(pSession, pGraph), AdvectionSystem(pSession, pGraph) + : UnsteadySystem(pSession, pGraph), AdvectionSystem(pSession, pGraph), + m_planeNumber(0) { - m_planeNumber = 0; } /** @@ -76,9 +76,9 @@ void UnsteadyAdvection::v_InitObject(bool DeclareFields) m_session->LoadParameter("GJPJumpScale", m_GJPJumpScale, 1.0); std::vector vel; - vel.push_back("Vx"); - vel.push_back("Vy"); - vel.push_back("Vz"); + vel.emplace_back("Vx"); + vel.emplace_back("Vy"); + vel.emplace_back("Vz"); // Resize the advection velocities vector to dimension of the problem vel.resize(m_spacedim); @@ -144,7 +144,6 @@ void UnsteadyAdvection::v_InitObject(bool DeclareFields) riemName, m_session); m_riemannSolver->SetScalar( "Vn", &UnsteadyAdvection::GetNormalVelocity, this); - m_advObject->SetRiemannSolver(m_riemannSolver); m_advObject->InitObject(m_session, m_fields); break; @@ -173,13 +172,6 @@ void UnsteadyAdvection::v_InitObject(bool DeclareFields) } } -/** - * @brief Unsteady linear advection equation destructor. - */ -UnsteadyAdvection::~UnsteadyAdvection() -{ -} - /** * @brief Get the normal velocity for the linear advection equation. */ @@ -188,18 +180,22 @@ Array &UnsteadyAdvection::GetNormalVelocity() // Number of trace (interface) points int i; int nTracePts = GetTraceNpoints(); + int nPts = m_velocity[0].size(); // Auxiliary variable to compute the normal velocity - Array tmp(nTracePts); + Array tmp(nPts), tmp2(nTracePts); // Reset the normal velocity Vmath::Zero(nTracePts, m_traceVn, 1); for (i = 0; i < m_velocity.size(); ++i) { - m_fields[0]->ExtractTracePhys(m_velocity[i], tmp); + // velocity - grid velocity for ALE before getting trace velocity + Vmath::Vsub(nPts, m_velocity[i], 1, m_gridVelocity[i], 1, tmp, 1); + + m_fields[0]->ExtractTracePhys(tmp, tmp2); - Vmath::Vvtvp(nTracePts, m_traceNormals[i], 1, tmp, 1, m_traceVn, 1, + Vmath::Vvtvp(nTracePts, m_traceNormals[i], 1, tmp2, 1, m_traceVn, 1, m_traceVn, 1); } @@ -217,28 +213,35 @@ void UnsteadyAdvection::DoOdeRhs( const Array> &inarray, Array> &outarray, const NekDouble time) { - // Counter variable - int i; - // Number of fields (variables of the problem) int nVariables = inarray.size(); - // Number of solution points - int nSolutionPts = GetNpoints(); - LibUtilities::Timer timer; - timer.Start(); - // RHS computation using the new advection base class - m_advObject->Advect(nVariables, m_fields, m_velocity, inarray, outarray, - time); - timer.Stop(); + if (m_ALESolver) + { + timer.Start(); + Array> tmpIn(nVariables); + // If ALE we must take Mu coefficient space to u physical space + ALEHelper::ALEDoElmtInvMassBwdTrans(inarray, tmpIn); + m_advObject->AdvectCoeffs(nVariables, m_fields, m_velocity, tmpIn, + outarray, time); + timer.Stop(); + } + else + { + timer.Start(); + m_advObject->Advect(nVariables, m_fields, m_velocity, inarray, outarray, + time); + timer.Stop(); + } + // Elapsed time timer.AccumulateRegion("Advect"); // Negate the RHS - for (i = 0; i < nVariables; ++i) + for (int i = 0; i < nVariables; ++i) { - Vmath::Neg(nSolutionPts, outarray[i], 1); + Vmath::Neg(outarray[i].size(), outarray[i], 1); } for (auto &x : m_forcing) @@ -265,6 +268,12 @@ void UnsteadyAdvection::DoOdeProjection( // Number of fields (variables of the problem) int nVariables = inarray.size(); + // Perform ALE movement + if (m_ALESolver) + { + MoveMesh(time, m_traceNormals); + } + // Set the boundary conditions SetBoundaryConditions(time); @@ -274,13 +283,10 @@ void UnsteadyAdvection::DoOdeProjection( // Discontinuous projection case MultiRegions::eDiscontinuous: { - // Number of quadrature points - int nQuadraturePts = GetNpoints(); - // Just copy over array for (i = 0; i < nVariables; ++i) { - Vmath::Vcopy(nQuadraturePts, inarray[i], 1, outarray[i], 1); + Vmath::Vcopy(inarray[i].size(), inarray[i], 1, outarray[i], 1); } break; } @@ -374,7 +380,12 @@ void UnsteadyAdvection::GetFluxVector( { for (j = 0; j < flux[0].size(); ++j) { - Vmath::Vmul(nq, physfield[i], 1, m_velocity[j], 1, flux[i][j], 1); + for (int k = 0; k < nq; ++k) + { + // If ALE we need to take off the grid velocity + flux[i][j][k] = + physfield[i][k] * (m_velocity[j][k] - m_gridVelocity[j][k]); + } } } } @@ -466,4 +477,33 @@ void UnsteadyAdvection::v_GenerateSummary(SolverUtils::SummaryList &s) SolverUtils::AddSummaryItem(s, "GJP Stab. JumpScale", m_GJPJumpScale); } } + +bool UnsteadyAdvection::v_PreIntegrate(int step) +{ + boost::ignore_unused(step); + return false; +} + +void UnsteadyAdvection::v_ExtraFldOutput( + std::vector> &fieldcoeffs, + std::vector &variables) +{ + bool extraFields; + m_session->MatchSolverInfo("OutputExtraFields", "True", extraFields, true); + + if (extraFields && m_ALESolver) + { + int nCoeffs = m_fields[0]->GetNcoeffs(); + + // Adds extra output variables for grid velocity + std::string gridVarName[3] = {"gridVx", "gridVy", "gridVz"}; + for (int i = 0; i < m_spacedim; ++i) + { + Array gridVel(nCoeffs, 0.0); + m_fields[0]->FwdTransLocalElmt(m_gridVelocity[i], gridVel); + fieldcoeffs.emplace_back(gridVel); + variables.emplace_back(gridVarName[i]); + } + } +} } // namespace Nektar diff --git a/solvers/ADRSolver/EquationSystems/UnsteadyAdvection.h b/solvers/ADRSolver/EquationSystems/UnsteadyAdvection.h index 62b5a33ee9aba3d0d08269ac56500b8490ad8693..570a2c5e68c6cce649b333e7c31b5fabda028e2b 100644 --- a/solvers/ADRSolver/EquationSystems/UnsteadyAdvection.h +++ b/solvers/ADRSolver/EquationSystems/UnsteadyAdvection.h @@ -62,7 +62,7 @@ public: static std::string className; /// Destructor - virtual ~UnsteadyAdvection(); + ~UnsteadyAdvection() final = default; protected: bool m_useGJPStabilisation; @@ -113,6 +113,12 @@ protected: /// Print Summary virtual void v_GenerateSummary(SolverUtils::SummaryList &s); + bool v_PreIntegrate(int step) final; + + virtual void v_ExtraFldOutput( + std::vector> &fieldcoeffs, + std::vector &variables); + private: NekDouble m_waveFreq; }; diff --git a/solvers/ADRSolver/EquationSystems/UnsteadyAdvectionDiffusion.cpp b/solvers/ADRSolver/EquationSystems/UnsteadyAdvectionDiffusion.cpp index bbc97dd4a44a5976e43b8153b9d8842fd693e1d5..15702a1f6414c8680d595f7a31aedac7b6ec5a76 100644 --- a/solvers/ADRSolver/EquationSystems/UnsteadyAdvectionDiffusion.cpp +++ b/solvers/ADRSolver/EquationSystems/UnsteadyAdvectionDiffusion.cpp @@ -45,7 +45,8 @@ using namespace LibUtilities; std::string UnsteadyAdvectionDiffusion::className = SolverUtils::GetEquationSystemFactory().RegisterCreatorFunction( - "UnsteadyAdvectionDiffusion", UnsteadyAdvectionDiffusion::create); + "UnsteadyAdvectionDiffusion", UnsteadyAdvectionDiffusion::create, + "Unsteady Advection-Diffusion equation."); UnsteadyAdvectionDiffusion::UnsteadyAdvectionDiffusion( const LibUtilities::SessionReaderSharedPtr &pSession, @@ -64,7 +65,7 @@ void UnsteadyAdvectionDiffusion::v_InitObject(bool DeclareFields) AdvectionSystem::v_InitObject(DeclareFields); m_session->LoadParameter("wavefreq", m_waveFreq, 0.0); - m_session->LoadParameter("epsilon", m_epsilon, 1.0); + m_session->LoadParameter("epsilon", m_epsilon, 1.0); // Diffusion // turn on substepping m_session->MatchSolverInfo("Extrapolation", "SubStepping", @@ -108,6 +109,12 @@ void UnsteadyAdvectionDiffusion::v_InitObject(bool DeclareFields) // Do not forwards transform initial condition m_homoInitialFwd = false; + // Define the normal velocity fields + if (m_fields[0]->GetTrace()) + { + m_traceVn = Array(GetTraceNpoints()); + } + // Advection term std::string advName; std::string riemName; @@ -200,13 +207,6 @@ void UnsteadyAdvectionDiffusion::v_InitObject(bool DeclareFields) } } -/** - * @brief Unsteady linear advection diffusion equation destructor. - */ -UnsteadyAdvectionDiffusion::~UnsteadyAdvectionDiffusion() -{ -} - /** * @brief Get the normal velocity for the unsteady linear advection * diffusion equation. @@ -222,19 +222,23 @@ Array &UnsteadyAdvectionDiffusion::GetNormalVel( // Number of trace (interface) points int i; int nTracePts = GetTraceNpoints(); + int nPts = velfield[0].size(); // Auxiliary variable to compute the normal velocity - Array tmp(nTracePts); - m_traceVn = Array(nTracePts, 0.0); + Array tmp(nPts), tmp2(nTracePts); // Reset the normal velocity Vmath::Zero(nTracePts, m_traceVn, 1); for (i = 0; i < velfield.size(); ++i) { - m_fields[0]->ExtractTracePhys(velfield[i], tmp); + // Subtract grid velocity here from velocity + // velocity - grid velocity + Vmath::Vsub(nPts, velfield[i], 1, m_gridVelocity[i], 1, tmp, 1); - Vmath::Vvtvp(nTracePts, m_traceNormals[i], 1, tmp, 1, m_traceVn, 1, + m_fields[0]->ExtractTracePhys(tmp, tmp2); + + Vmath::Vvtvp(nTracePts, m_traceNormals[i], 1, tmp2, 1, m_traceVn, 1, m_traceVn, 1); } @@ -256,17 +260,25 @@ void UnsteadyAdvectionDiffusion::DoOdeRhs( // Number of fields (variables of the problem) int nVariables = inarray.size(); - // Number of solution points - int nSolutionPts = GetNpoints(); - - // RHS computation using the new advection base class - m_advObject->Advect(nVariables, m_fields, m_velocity, inarray, outarray, - time); + Array> tmpIn(nVariables); + if (m_ALESolver) + { + ALEHelper::ALEDoElmtInvMassBwdTrans(inarray, tmpIn); + m_advObject->AdvectCoeffs(nVariables, m_fields, m_velocity, tmpIn, + outarray, time); + } + else + { + tmpIn = inarray; // If not ALE then we pass through inarray + // RHS computation using the new advection base class + m_advObject->Advect(nVariables, m_fields, m_velocity, inarray, outarray, + time); + } // Negate the RHS for (int i = 0; i < nVariables; ++i) { - Vmath::Neg(nSolutionPts, outarray[i], 1); + Vmath::Neg(outarray[i].size(), outarray[i], 1); } if (m_explicitDiffusion) @@ -274,15 +286,23 @@ void UnsteadyAdvectionDiffusion::DoOdeRhs( Array> outarrayDiff(nVariables); for (int i = 0; i < nVariables; ++i) { - outarrayDiff[i] = Array(nSolutionPts, 0.0); + outarrayDiff[i] = Array(outarray[i].size(), 0.0); } - m_diffusion->Diffuse(nVariables, m_fields, inarray, outarrayDiff); + if (m_ALESolver) + { + m_diffusion->DiffuseCoeffs(nVariables, m_fields, tmpIn, + outarrayDiff); // Using tmpIn from above + } + else + { + m_diffusion->Diffuse(nVariables, m_fields, inarray, outarrayDiff); + } for (int i = 0; i < nVariables; ++i) { - Vmath::Vadd(nSolutionPts, &outarrayDiff[i][0], 1, &outarray[i][0], - 1, &outarray[i][0], 1); + Vmath::Vadd(outarray[i].size(), &outarrayDiff[i][0], 1, + &outarray[i][0], 1, &outarray[i][0], 1); } } @@ -306,19 +326,23 @@ void UnsteadyAdvectionDiffusion::DoOdeProjection( const Array> &inarray, Array> &outarray, const NekDouble time) { - int i; int nvariables = inarray.size(); + + // Perform ALE movement + if (m_ALESolver) + { + MoveMesh(time, m_traceNormals); + } + SetBoundaryConditions(time); + switch (m_projectionType) { case MultiRegions::eDiscontinuous: { - // Just copy over array - int npoints = GetNpoints(); - - for (i = 0; i < nvariables; ++i) + for (int i = 0; i < nvariables; ++i) { - Vmath::Vcopy(npoints, inarray[i], 1, outarray[i], 1); + Vmath::Vcopy(inarray[i].size(), inarray[i], 1, outarray[i], 1); } break; } @@ -327,7 +351,7 @@ void UnsteadyAdvectionDiffusion::DoOdeProjection( { Array coeffs(m_fields[0]->GetNcoeffs()); - for (i = 0; i < nvariables; ++i) + for (int i = 0; i < nvariables; ++i) { m_fields[i]->FwdTrans(inarray[i], coeffs); m_fields[i]->BwdTrans(coeffs, outarray[i]); @@ -424,7 +448,13 @@ void UnsteadyAdvectionDiffusion::GetFluxVectorAdv( { for (int j = 0; j < flux[0].size(); ++j) { - Vmath::Vmul(nq, physfield[i], 1, m_velocity[j], 1, flux[i][j], 1); + + for (int k = 0; k < nq; ++k) + { + // If ALE we need to take off the grid velocity + flux[i][j][k] = + physfield[i][k] * (m_velocity[j][k] - m_gridVelocity[j][k]); + } } } } @@ -470,6 +500,29 @@ void UnsteadyAdvectionDiffusion::v_GenerateSummary(SolverUtils::SummaryList &s) } } +void UnsteadyAdvectionDiffusion::v_ExtraFldOutput( + std::vector> &fieldcoeffs, + std::vector &variables) +{ + bool extraFields; + m_session->MatchSolverInfo("OutputExtraFields", "True", extraFields, true); + + if (extraFields && m_ALESolver) + { + int nCoeffs = m_fields[0]->GetNcoeffs(); + + // Adds extra output variables for grid velocity + std::string gridVarName[3] = {"gridVx", "gridVy", "gridVz"}; + for (int i = 0; i < m_spacedim; ++i) + { + Array gridVel(nCoeffs, 0.0); + m_fields[0]->FwdTransLocalElmt(m_gridVelocity[i], gridVel); + fieldcoeffs.emplace_back(gridVel); + variables.emplace_back(gridVarName[i]); + } + } +} + /** * Perform the extrapolation. */ diff --git a/solvers/ADRSolver/EquationSystems/UnsteadyAdvectionDiffusion.h b/solvers/ADRSolver/EquationSystems/UnsteadyAdvectionDiffusion.h index 8d45f713543107493bad8ff405b9b45f7969c277..81f31856fa46c35b762b797b6a056af57f3fe4ed 100644 --- a/solvers/ADRSolver/EquationSystems/UnsteadyAdvectionDiffusion.h +++ b/solvers/ADRSolver/EquationSystems/UnsteadyAdvectionDiffusion.h @@ -63,7 +63,7 @@ public: static std::string className; /// Destructor - virtual ~UnsteadyAdvectionDiffusion(); + ~UnsteadyAdvectionDiffusion() final = default; protected: bool m_subSteppingScheme; @@ -134,6 +134,10 @@ protected: /// PreIntegration step for substepping. virtual bool v_PreIntegrate(int step); + virtual void v_ExtraFldOutput( + std::vector> &fieldcoeffs, + std::vector &variables); + // SubsStepping methods -> Probably could be set up in separate class void SubStepAdvance(int nstep, NekDouble time); NekDouble GetSubstepTimeStep(); diff --git a/solvers/ADRSolver/Tests/Movement_fixed_2D_curved_quads.tst b/solvers/ADRSolver/Tests/Movement_fixed_2D_curved_quads.tst new file mode 100644 index 0000000000000000000000000000000000000000..36387dd6c914833448f7cf6ac5bf3e7444fc36d5 --- /dev/null +++ b/solvers/ADRSolver/Tests/Movement_fixed_2D_curved_quads.tst @@ -0,0 +1,19 @@ + + + 2D advection with 2 zones and 1 non-conformal curved interfaces with dirichlet BCs on quads + ADRSolver + Movement_fixed_2D_curved_quads.xml + + Movement_fixed_2D_curved_quads.xml + + + + 1.31573e-05 + + + 9.84901e-05 + + + + + diff --git a/solvers/ADRSolver/Tests/Movement_fixed_2D_curved_quads.xml b/solvers/ADRSolver/Tests/Movement_fixed_2D_curved_quads.xml new file mode 100644 index 0000000000000000000000000000000000000000..ad4a1e12fe1350b301b96c858b41a96735f8aab5 --- /dev/null +++ b/solvers/ADRSolver/Tests/Movement_fixed_2D_curved_quads.xml @@ -0,0 +1,390 @@ + + + + + 0.00000000e+00 0.00000000e+00 0.00000000e+00 + 2.50000000e-01 0.00000000e+00 0.00000000e+00 + 5.00000000e-01 0.00000000e+00 0.00000000e+00 + 3.53151292e-01 2.22386302e-01 0.00000000e+00 + 3.53553482e-01 4.85747395e-01 0.00000000e+00 + 4.25285357e-01 7.43277689e-01 0.00000000e+00 + 5.00000000e-01 1.00000000e+00 0.00000000e+00 + 2.50000000e-01 1.00000000e+00 0.00000000e+00 + 0.00000000e+00 1.00000000e+00 0.00000000e+00 + 0.00000000e+00 7.50000000e-01 0.00000000e+00 + 0.00000000e+00 5.00000000e-01 0.00000000e+00 + 0.00000000e+00 2.50000000e-01 0.00000000e+00 + 5.00000000e-01 0.00000000e+00 0.00000000e+00 + 6.25000000e-01 0.00000000e+00 0.00000000e+00 + 7.50000000e-01 0.00000000e+00 0.00000000e+00 + 8.75000000e-01 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 1.66666667e-01 0.00000000e+00 + 1.00000000e+00 3.33333333e-01 0.00000000e+00 + 1.00000000e+00 5.00000000e-01 0.00000000e+00 + 1.00000000e+00 6.66666667e-01 0.00000000e+00 + 1.00000000e+00 8.33333333e-01 0.00000000e+00 + 1.00000000e+00 1.00000000e+00 0.00000000e+00 + 8.75000000e-01 1.00000000e+00 0.00000000e+00 + 7.50000000e-01 1.00000000e+00 0.00000000e+00 + 6.25000000e-01 1.00000000e+00 0.00000000e+00 + 5.00000000e-01 1.00000000e+00 0.00000000e+00 + 4.51425200e-01 8.28493982e-01 0.00000000e+00 + 3.99421772e-01 6.57977469e-01 0.00000000e+00 + 3.53553482e-01 4.85747395e-01 0.00000000e+00 + 3.34147754e-01 3.09117834e-01 0.00000000e+00 + 3.96563471e-01 1.44813573e-01 0.00000000e+00 + 1.00000000e+00 0.00000000e+00 0.00000000e+00 + 1.50000000e+00 0.00000000e+00 0.00000000e+00 + 1.50000000e+00 1.00000000e+00 0.00000000e+00 + 1.00000000e+00 1.00000000e+00 0.00000000e+00 + 1.93601610e-01 4.93113337e-01 0.00000000e+00 + 2.15861429e-01 7.46548464e-01 0.00000000e+00 + 2.04026934e-01 2.43120971e-01 0.00000000e+00 + 5.91214490e-01 8.29999081e-01 0.00000000e+00 + 7.29787077e-01 8.31199374e-01 0.00000000e+00 + 5.60107670e-01 6.60047495e-01 0.00000000e+00 + 7.12718028e-01 6.62519481e-01 0.00000000e+00 + 5.38683400e-01 4.89983720e-01 0.00000000e+00 + 7.03148862e-01 4.94313236e-01 0.00000000e+00 + 5.39517452e-01 3.21366224e-01 0.00000000e+00 + 7.05900860e-01 3.27444582e-01 0.00000000e+00 + 7.23228643e-01 1.62816229e-01 0.00000000e+00 + 5.71536573e-01 1.57900450e-01 0.00000000e+00 + 8.65724424e-01 8.32307359e-01 0.00000000e+00 + 8.58220850e-01 6.64729496e-01 0.00000000e+00 + 8.63746910e-01 1.65135416e-01 0.00000000e+00 + 8.56214575e-01 3.30889246e-01 0.00000000e+00 + 8.54490694e-01 4.97486053e-01 0.00000000e+00 + + + 0 1 + 1 2 + 2 3 + 3 4 + 4 5 + 5 6 + 6 7 + 7 8 + 8 9 + 9 10 + 10 11 + 11 0 + 12 13 + 13 14 + 14 15 + 15 16 + 16 17 + 17 18 + 18 19 + 19 20 + 20 21 + 21 22 + 22 23 + 23 24 + 24 25 + 25 26 + 26 27 + 27 28 + 28 29 + 29 30 + 30 31 + 31 12 + 32 33 + 34 35 + 10 36 + 36 37 + 37 9 + 5 37 + 36 4 + 7 37 + 11 38 + 38 36 + 1 38 + 3 38 + 25 39 + 39 40 + 40 24 + 27 39 + 28 41 + 41 39 + 42 40 + 41 42 + 41 43 + 43 44 + 44 42 + 29 43 + 30 45 + 45 43 + 46 44 + 45 46 + 14 47 + 47 48 + 48 13 + 45 48 + 47 46 + 31 48 + 23 49 + 49 21 + 40 49 + 42 50 + 50 49 + 50 20 + 17 51 + 51 15 + 18 52 + 52 51 + 47 51 + 52 46 + 52 53 + 53 44 + 19 53 + 50 53 + + + 34 35 36 9 + 4 37 35 38 + 6 39 37 5 + 8 36 39 7 + 10 40 41 34 + 0 42 40 11 + 2 43 42 1 + 38 41 43 3 + 24 44 45 46 + 26 47 44 25 + 48 49 47 27 + 50 45 49 51 + 51 52 53 54 + 28 55 52 48 + 56 57 55 29 + 58 53 57 59 + 60 61 62 13 + 59 63 61 64 + 30 65 63 56 + 12 62 65 31 + 22 66 67 21 + 46 68 66 23 + 69 70 68 50 + 20 67 70 71 + 16 72 73 15 + 74 75 72 17 + 64 76 75 77 + 14 73 76 60 + 77 78 79 58 + 18 80 78 74 + 71 81 80 19 + 54 79 81 69 + + + 0.00000000e+00 0.00000000e+00 0.00000000e+00 4.16666667e-02 0.00000000e+00 0.00000000e+00 8.33333333e-02 0.00000000e+00 0.00000000e+00 1.25000000e-01 0.00000000e+00 0.00000000e+00 1.66666667e-01 0.00000000e+00 0.00000000e+00 2.08333333e-01 0.00000000e+00 0.00000000e+00 2.50000000e-01 0.00000000e+00 0.00000000e+00 + 2.50000000e-01 0.00000000e+00 0.00000000e+00 2.91666667e-01 0.00000000e+00 0.00000000e+00 3.33333333e-01 0.00000000e+00 0.00000000e+00 3.75000000e-01 0.00000000e+00 0.00000000e+00 4.16666667e-01 0.00000000e+00 0.00000000e+00 4.58333333e-01 0.00000000e+00 0.00000000e+00 5.00000000e-01 0.00000000e+00 0.00000000e+00 + 5.00000000e-01 0.00000000e+00 0.00000000e+00 4.77516149e-01 3.84473378e-02 0.00000000e+00 4.51320409e-01 7.44915151e-02 0.00000000e+00 4.23610288e-01 1.09396998e-01 0.00000000e+00 3.96563474e-01 1.44813569e-01 0.00000000e+00 3.72377341e-01 1.82222775e-01 0.00000000e+00 3.53151292e-01 2.22386302e-01 0.00000000e+00 + 3.53151292e-01 2.22386302e-01 0.00000000e+00 3.40325109e-01 2.65019871e-01 0.00000000e+00 3.34147748e-01 3.09117924e-01 0.00000000e+00 3.33846334e-01 3.53658633e-01 0.00000000e+00 3.37869219e-01 3.98033069e-01 0.00000000e+00 3.44734586e-01 4.42063566e-01 0.00000000e+00 3.53553482e-01 4.85747395e-01 0.00000000e+00 + 3.53553482e-01 4.85747395e-01 0.00000000e+00 3.63764381e-01 5.29128196e-01 0.00000000e+00 3.74986004e-01 5.72259249e-01 0.00000000e+00 3.86942397e-01 6.15192791e-01 0.00000000e+00 3.99421769e-01 6.57977458e-01 0.00000000e+00 4.12252078e-01 7.00658315e-01 0.00000000e+00 4.25285357e-01 7.43277689e-01 0.00000000e+00 + 4.25285357e-01 7.43277689e-01 0.00000000e+00 4.38386646e-01 7.85876221e-01 0.00000000e+00 4.51425199e-01 8.28493979e-01 0.00000000e+00 4.64266387e-01 8.71171562e-01 0.00000000e+00 4.76762956e-01 9.13951208e-01 0.00000000e+00 4.88744095e-01 9.56877857e-01 0.00000000e+00 5.00000000e-01 1.00000000e+00 0.00000000e+00 + 5.00000000e-01 1.00000000e+00 0.00000000e+00 4.58333333e-01 1.00000000e+00 0.00000000e+00 4.16666667e-01 1.00000000e+00 0.00000000e+00 3.75000000e-01 1.00000000e+00 0.00000000e+00 3.33333333e-01 1.00000000e+00 0.00000000e+00 2.91666667e-01 1.00000000e+00 0.00000000e+00 2.50000000e-01 1.00000000e+00 0.00000000e+00 + 2.50000000e-01 1.00000000e+00 0.00000000e+00 2.08333333e-01 1.00000000e+00 0.00000000e+00 1.66666667e-01 1.00000000e+00 0.00000000e+00 1.25000000e-01 1.00000000e+00 0.00000000e+00 8.33333333e-02 1.00000000e+00 0.00000000e+00 4.16666667e-02 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 + 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 9.58333333e-01 0.00000000e+00 0.00000000e+00 9.16666667e-01 0.00000000e+00 0.00000000e+00 8.75000000e-01 0.00000000e+00 0.00000000e+00 8.33333333e-01 0.00000000e+00 0.00000000e+00 7.91666667e-01 0.00000000e+00 0.00000000e+00 7.50000000e-01 0.00000000e+00 + 0.00000000e+00 7.50000000e-01 0.00000000e+00 0.00000000e+00 7.08333333e-01 0.00000000e+00 0.00000000e+00 6.66666667e-01 0.00000000e+00 0.00000000e+00 6.25000000e-01 0.00000000e+00 0.00000000e+00 5.83333333e-01 0.00000000e+00 0.00000000e+00 5.41666667e-01 0.00000000e+00 0.00000000e+00 5.00000000e-01 0.00000000e+00 + 0.00000000e+00 5.00000000e-01 0.00000000e+00 0.00000000e+00 4.58333333e-01 0.00000000e+00 0.00000000e+00 4.16666667e-01 0.00000000e+00 0.00000000e+00 3.75000000e-01 0.00000000e+00 0.00000000e+00 3.33333333e-01 0.00000000e+00 0.00000000e+00 2.91666667e-01 0.00000000e+00 0.00000000e+00 2.50000000e-01 0.00000000e+00 + 0.00000000e+00 2.50000000e-01 0.00000000e+00 0.00000000e+00 2.08333333e-01 0.00000000e+00 0.00000000e+00 1.66666667e-01 0.00000000e+00 0.00000000e+00 1.25000000e-01 0.00000000e+00 0.00000000e+00 8.33333333e-02 0.00000000e+00 0.00000000e+00 4.16666667e-02 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 + 5.00000000e-01 0.00000000e+00 0.00000000e+00 5.20833333e-01 0.00000000e+00 0.00000000e+00 5.41666667e-01 0.00000000e+00 0.00000000e+00 5.62500000e-01 0.00000000e+00 0.00000000e+00 5.83333333e-01 0.00000000e+00 0.00000000e+00 6.04166667e-01 0.00000000e+00 0.00000000e+00 6.25000000e-01 0.00000000e+00 0.00000000e+00 + 6.25000000e-01 0.00000000e+00 0.00000000e+00 6.45833333e-01 0.00000000e+00 0.00000000e+00 6.66666667e-01 0.00000000e+00 0.00000000e+00 6.87500000e-01 0.00000000e+00 0.00000000e+00 7.08333333e-01 0.00000000e+00 0.00000000e+00 7.29166667e-01 0.00000000e+00 0.00000000e+00 7.50000000e-01 0.00000000e+00 0.00000000e+00 + 7.50000000e-01 0.00000000e+00 0.00000000e+00 7.70833333e-01 0.00000000e+00 0.00000000e+00 7.91666667e-01 0.00000000e+00 0.00000000e+00 8.12500000e-01 0.00000000e+00 0.00000000e+00 8.33333333e-01 0.00000000e+00 0.00000000e+00 8.54166667e-01 0.00000000e+00 0.00000000e+00 8.75000000e-01 0.00000000e+00 0.00000000e+00 + 8.75000000e-01 0.00000000e+00 0.00000000e+00 8.95833333e-01 0.00000000e+00 0.00000000e+00 9.16666667e-01 0.00000000e+00 0.00000000e+00 9.37500000e-01 0.00000000e+00 0.00000000e+00 9.58333333e-01 0.00000000e+00 0.00000000e+00 9.79166667e-01 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 2.77777778e-02 0.00000000e+00 1.00000000e+00 5.55555556e-02 0.00000000e+00 1.00000000e+00 8.33333333e-02 0.00000000e+00 1.00000000e+00 1.11111111e-01 0.00000000e+00 1.00000000e+00 1.38888889e-01 0.00000000e+00 1.00000000e+00 1.66666667e-01 0.00000000e+00 + 1.00000000e+00 1.66666667e-01 0.00000000e+00 1.00000000e+00 1.94444444e-01 0.00000000e+00 1.00000000e+00 2.22222222e-01 0.00000000e+00 1.00000000e+00 2.50000000e-01 0.00000000e+00 1.00000000e+00 2.77777778e-01 0.00000000e+00 1.00000000e+00 3.05555556e-01 0.00000000e+00 1.00000000e+00 3.33333333e-01 0.00000000e+00 + 1.00000000e+00 3.33333333e-01 0.00000000e+00 1.00000000e+00 3.61111111e-01 0.00000000e+00 1.00000000e+00 3.88888889e-01 0.00000000e+00 1.00000000e+00 4.16666667e-01 0.00000000e+00 1.00000000e+00 4.44444444e-01 0.00000000e+00 1.00000000e+00 4.72222222e-01 0.00000000e+00 1.00000000e+00 5.00000000e-01 0.00000000e+00 + 1.00000000e+00 5.00000000e-01 0.00000000e+00 1.00000000e+00 5.27777778e-01 0.00000000e+00 1.00000000e+00 5.55555556e-01 0.00000000e+00 1.00000000e+00 5.83333333e-01 0.00000000e+00 1.00000000e+00 6.11111111e-01 0.00000000e+00 1.00000000e+00 6.38888889e-01 0.00000000e+00 1.00000000e+00 6.66666667e-01 0.00000000e+00 + 1.00000000e+00 6.66666667e-01 0.00000000e+00 1.00000000e+00 6.94444444e-01 0.00000000e+00 1.00000000e+00 7.22222222e-01 0.00000000e+00 1.00000000e+00 7.50000000e-01 0.00000000e+00 1.00000000e+00 7.77777778e-01 0.00000000e+00 1.00000000e+00 8.05555556e-01 0.00000000e+00 1.00000000e+00 8.33333333e-01 0.00000000e+00 + 1.00000000e+00 8.33333333e-01 0.00000000e+00 1.00000000e+00 8.61111111e-01 0.00000000e+00 1.00000000e+00 8.88888889e-01 0.00000000e+00 1.00000000e+00 9.16666667e-01 0.00000000e+00 1.00000000e+00 9.44444444e-01 0.00000000e+00 1.00000000e+00 9.72222222e-01 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 + 1.00000000e+00 1.00000000e+00 0.00000000e+00 9.79166667e-01 1.00000000e+00 0.00000000e+00 9.58333333e-01 1.00000000e+00 0.00000000e+00 9.37500000e-01 1.00000000e+00 0.00000000e+00 9.16666667e-01 1.00000000e+00 0.00000000e+00 8.95833333e-01 1.00000000e+00 0.00000000e+00 8.75000000e-01 1.00000000e+00 0.00000000e+00 + 8.75000000e-01 1.00000000e+00 0.00000000e+00 8.54166667e-01 1.00000000e+00 0.00000000e+00 8.33333333e-01 1.00000000e+00 0.00000000e+00 8.12500000e-01 1.00000000e+00 0.00000000e+00 7.91666667e-01 1.00000000e+00 0.00000000e+00 7.70833333e-01 1.00000000e+00 0.00000000e+00 7.50000000e-01 1.00000000e+00 0.00000000e+00 + 7.50000000e-01 1.00000000e+00 0.00000000e+00 7.29166667e-01 1.00000000e+00 0.00000000e+00 7.08333333e-01 1.00000000e+00 0.00000000e+00 6.87500000e-01 1.00000000e+00 0.00000000e+00 6.66666667e-01 1.00000000e+00 0.00000000e+00 6.45833333e-01 1.00000000e+00 0.00000000e+00 6.25000000e-01 1.00000000e+00 0.00000000e+00 + 6.25000000e-01 1.00000000e+00 0.00000000e+00 6.04166667e-01 1.00000000e+00 0.00000000e+00 5.83333333e-01 1.00000000e+00 0.00000000e+00 5.62500000e-01 1.00000000e+00 0.00000000e+00 5.41666667e-01 1.00000000e+00 0.00000000e+00 5.20833333e-01 1.00000000e+00 0.00000000e+00 5.00000000e-01 1.00000000e+00 0.00000000e+00 + 5.00000000e-01 1.00000000e+00 0.00000000e+00 4.92588523e-01 9.71227678e-01 0.00000000e+00 4.84819587e-01 9.42549727e-01 0.00000000e+00 4.76762956e-01 9.13951208e-01 0.00000000e+00 4.68478029e-01 8.85417950e-01 0.00000000e+00 4.60016645e-01 8.56936494e-01 0.00000000e+00 4.51425200e-01 8.28493982e-01 0.00000000e+00 + 4.51425200e-01 8.28493982e-01 0.00000000e+00 4.42746292e-01 8.00078023e-01 0.00000000e+00 4.34020062e-01 7.71676555e-01 0.00000000e+00 4.25285357e-01 7.43277691e-01 0.00000000e+00 4.16580795e-01 7.14869577e-01 0.00000000e+00 4.07945811e-01 6.86440246e-01 0.00000000e+00 3.99421772e-01 6.57977469e-01 0.00000000e+00 + 3.99421772e-01 6.57977469e-01 0.00000000e+00 3.91053219e-01 6.29468608e-01 0.00000000e+00 3.82889373e-01 6.00900488e-01 0.00000000e+00 3.74986007e-01 5.72259260e-01 0.00000000e+00 3.67407923e-01 5.43530326e-01 0.00000000e+00 3.60232310e-01 5.14698339e-01 0.00000000e+00 3.53553482e-01 4.85747395e-01 0.00000000e+00 + 3.53553482e-01 4.85747395e-01 0.00000000e+00 3.47489779e-01 4.56661658e-01 0.00000000e+00 3.42193928e-01 4.27426732e-01 0.00000000e+00 3.37869220e-01 3.98033079e-01 0.00000000e+00 3.34795535e-01 3.68483563e-01 0.00000000e+00 3.33372554e-01 3.38810967e-01 0.00000000e+00 3.34147754e-01 3.09117834e-01 0.00000000e+00 + 3.34147754e-01 3.09117834e-01 0.00000000e+00 3.37549641e-01 2.79612532e-01 0.00000000e+00 3.43848127e-01 2.50589439e-01 0.00000000e+00 3.53151296e-01 2.22386291e-01 0.00000000e+00 3.65325716e-01 1.95296950e-01 0.00000000e+00 3.79985460e-01 1.69464102e-01 0.00000000e+00 3.96563471e-01 1.44813573e-01 0.00000000e+00 + 3.96563471e-01 1.44813573e-01 0.00000000e+00 4.14413474e-01 1.21063811e-01 0.00000000e+00 4.32880446e-01 9.77883153e-02 0.00000000e+00 4.51320408e-01 7.44915160e-02 0.00000000e+00 4.69088674e-01 5.06808219e-02 0.00000000e+00 4.85529550e-01 2.59389955e-02 0.00000000e+00 5.00000000e-01 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.08333333e+00 0.00000000e+00 0.00000000e+00 1.16666667e+00 0.00000000e+00 0.00000000e+00 1.25000000e+00 0.00000000e+00 0.00000000e+00 1.33333333e+00 0.00000000e+00 0.00000000e+00 1.41666667e+00 0.00000000e+00 0.00000000e+00 1.50000000e+00 0.00000000e+00 0.00000000e+00 + 1.50000000e+00 1.00000000e+00 0.00000000e+00 1.41666667e+00 1.00000000e+00 0.00000000e+00 1.33333333e+00 1.00000000e+00 0.00000000e+00 1.25000000e+00 1.00000000e+00 0.00000000e+00 1.16666667e+00 1.00000000e+00 0.00000000e+00 1.08333333e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 + 0.00000000e+00 5.00000000e-01 0.00000000e+00 3.22669351e-02 4.98852223e-01 0.00000000e+00 6.45338701e-02 4.97704446e-01 0.00000000e+00 9.68008052e-02 4.96556669e-01 0.00000000e+00 1.29067740e-01 4.95408891e-01 0.00000000e+00 1.61334675e-01 4.94261114e-01 0.00000000e+00 1.93601610e-01 4.93113337e-01 0.00000000e+00 + 1.93601610e-01 4.93113337e-01 0.00000000e+00 1.97311580e-01 5.35352525e-01 0.00000000e+00 2.01021550e-01 5.77591713e-01 0.00000000e+00 2.04731520e-01 6.19830901e-01 0.00000000e+00 2.08441489e-01 6.62070089e-01 0.00000000e+00 2.12151459e-01 7.04309277e-01 0.00000000e+00 2.15861429e-01 7.46548464e-01 0.00000000e+00 + 2.15861429e-01 7.46548464e-01 0.00000000e+00 1.79884524e-01 7.47123720e-01 0.00000000e+00 1.43907619e-01 7.47698976e-01 0.00000000e+00 1.07930715e-01 7.48274232e-01 0.00000000e+00 7.19538097e-02 7.48849488e-01 0.00000000e+00 3.59769048e-02 7.49424744e-01 0.00000000e+00 0.00000000e+00 7.50000000e-01 0.00000000e+00 + 4.25285357e-01 7.43277689e-01 0.00000000e+00 3.90381369e-01 7.43822818e-01 0.00000000e+00 3.55477381e-01 7.44367947e-01 0.00000000e+00 3.20573393e-01 7.44913077e-01 0.00000000e+00 2.85669405e-01 7.45458206e-01 0.00000000e+00 2.50765417e-01 7.46003335e-01 0.00000000e+00 2.15861429e-01 7.46548464e-01 0.00000000e+00 + 1.93601610e-01 4.93113337e-01 0.00000000e+00 2.20260256e-01 4.91885680e-01 0.00000000e+00 2.46918901e-01 4.90658023e-01 0.00000000e+00 2.73577546e-01 4.89430366e-01 0.00000000e+00 3.00236191e-01 4.88202709e-01 0.00000000e+00 3.26894837e-01 4.86975052e-01 0.00000000e+00 3.53553482e-01 4.85747395e-01 0.00000000e+00 + 2.50000000e-01 1.00000000e+00 0.00000000e+00 2.44310238e-01 9.57758077e-01 0.00000000e+00 2.38620476e-01 9.15516155e-01 0.00000000e+00 2.32930715e-01 8.73274232e-01 0.00000000e+00 2.27240953e-01 8.31032310e-01 0.00000000e+00 2.21551191e-01 7.88790387e-01 0.00000000e+00 2.15861429e-01 7.46548464e-01 0.00000000e+00 + 0.00000000e+00 2.50000000e-01 0.00000000e+00 3.40044890e-02 2.48853495e-01 0.00000000e+00 6.80089780e-02 2.47706990e-01 0.00000000e+00 1.02013467e-01 2.46560486e-01 0.00000000e+00 1.36017956e-01 2.45413981e-01 0.00000000e+00 1.70022445e-01 2.44267476e-01 0.00000000e+00 2.04026934e-01 2.43120971e-01 0.00000000e+00 + 2.04026934e-01 2.43120971e-01 0.00000000e+00 2.02289380e-01 2.84786366e-01 0.00000000e+00 2.00551826e-01 3.26451760e-01 0.00000000e+00 1.98814272e-01 3.68117154e-01 0.00000000e+00 1.97076718e-01 4.09782549e-01 0.00000000e+00 1.95339164e-01 4.51447943e-01 0.00000000e+00 1.93601610e-01 4.93113337e-01 0.00000000e+00 + 2.50000000e-01 0.00000000e+00 0.00000000e+00 2.42337822e-01 4.05201619e-02 0.00000000e+00 2.34675645e-01 8.10403238e-02 0.00000000e+00 2.27013467e-01 1.21560486e-01 0.00000000e+00 2.19351289e-01 1.62080648e-01 0.00000000e+00 2.11689112e-01 2.02600809e-01 0.00000000e+00 2.04026934e-01 2.43120971e-01 0.00000000e+00 + 3.53151292e-01 2.22386302e-01 0.00000000e+00 3.28297232e-01 2.25842080e-01 0.00000000e+00 3.03443173e-01 2.29297859e-01 0.00000000e+00 2.78589113e-01 2.32753637e-01 0.00000000e+00 2.53735053e-01 2.36209415e-01 0.00000000e+00 2.28880994e-01 2.39665193e-01 0.00000000e+00 2.04026934e-01 2.43120971e-01 0.00000000e+00 + 6.25000000e-01 1.00000000e+00 0.00000000e+00 6.19369082e-01 9.71666513e-01 0.00000000e+00 6.13738163e-01 9.43333027e-01 0.00000000e+00 6.08107245e-01 9.14999540e-01 0.00000000e+00 6.02476327e-01 8.86666054e-01 0.00000000e+00 5.96845409e-01 8.58332567e-01 0.00000000e+00 5.91214490e-01 8.29999081e-01 0.00000000e+00 + 5.91214490e-01 8.29999081e-01 0.00000000e+00 6.14309922e-01 8.30199130e-01 0.00000000e+00 6.37405353e-01 8.30399179e-01 0.00000000e+00 6.60500784e-01 8.30599228e-01 0.00000000e+00 6.83596215e-01 8.30799277e-01 0.00000000e+00 7.06691646e-01 8.30999326e-01 0.00000000e+00 7.29787077e-01 8.31199374e-01 0.00000000e+00 + 7.29787077e-01 8.31199374e-01 0.00000000e+00 7.33155897e-01 8.59332812e-01 0.00000000e+00 7.36524718e-01 8.87466250e-01 0.00000000e+00 7.39893538e-01 9.15599687e-01 0.00000000e+00 7.43262359e-01 9.43733125e-01 0.00000000e+00 7.46631179e-01 9.71866562e-01 0.00000000e+00 7.50000000e-01 1.00000000e+00 0.00000000e+00 + 4.51425200e-01 8.28493982e-01 0.00000000e+00 4.74723415e-01 8.28744831e-01 0.00000000e+00 4.98021630e-01 8.28995681e-01 0.00000000e+00 5.21319845e-01 8.29246531e-01 0.00000000e+00 5.44618060e-01 8.29497381e-01 0.00000000e+00 5.67916275e-01 8.29748231e-01 0.00000000e+00 5.91214490e-01 8.29999081e-01 0.00000000e+00 + 3.99421772e-01 6.57977469e-01 0.00000000e+00 4.26202755e-01 6.58322473e-01 0.00000000e+00 4.52983738e-01 6.58667477e-01 0.00000000e+00 4.79764721e-01 6.59012482e-01 0.00000000e+00 5.06545704e-01 6.59357486e-01 0.00000000e+00 5.33326687e-01 6.59702491e-01 0.00000000e+00 5.60107670e-01 6.60047495e-01 0.00000000e+00 + 5.60107670e-01 6.60047495e-01 0.00000000e+00 5.65292140e-01 6.88372759e-01 0.00000000e+00 5.70476610e-01 7.16698024e-01 0.00000000e+00 5.75661080e-01 7.45023288e-01 0.00000000e+00 5.80845550e-01 7.73348552e-01 0.00000000e+00 5.86030020e-01 8.01673817e-01 0.00000000e+00 5.91214490e-01 8.29999081e-01 0.00000000e+00 + 7.12718028e-01 6.62519481e-01 0.00000000e+00 7.15562869e-01 6.90632797e-01 0.00000000e+00 7.18407711e-01 7.18746112e-01 0.00000000e+00 7.21252552e-01 7.46859428e-01 0.00000000e+00 7.24097394e-01 7.74972743e-01 0.00000000e+00 7.26942235e-01 8.03086059e-01 0.00000000e+00 7.29787077e-01 8.31199374e-01 0.00000000e+00 + 5.60107670e-01 6.60047495e-01 0.00000000e+00 5.85542729e-01 6.60459493e-01 0.00000000e+00 6.10977789e-01 6.60871491e-01 0.00000000e+00 6.36412849e-01 6.61283488e-01 0.00000000e+00 6.61847908e-01 6.61695486e-01 0.00000000e+00 6.87282968e-01 6.62107484e-01 0.00000000e+00 7.12718028e-01 6.62519481e-01 0.00000000e+00 + 5.60107670e-01 6.60047495e-01 0.00000000e+00 5.56536958e-01 6.31703533e-01 0.00000000e+00 5.52966247e-01 6.03359570e-01 0.00000000e+00 5.49395535e-01 5.75015608e-01 0.00000000e+00 5.45824823e-01 5.46671645e-01 0.00000000e+00 5.42254112e-01 5.18327683e-01 0.00000000e+00 5.38683400e-01 4.89983720e-01 0.00000000e+00 + 5.38683400e-01 4.89983720e-01 0.00000000e+00 5.66094311e-01 4.90705306e-01 0.00000000e+00 5.93505221e-01 4.91426892e-01 0.00000000e+00 6.20916131e-01 4.92148478e-01 0.00000000e+00 6.48327041e-01 4.92870064e-01 0.00000000e+00 6.75737952e-01 4.93591650e-01 0.00000000e+00 7.03148862e-01 4.94313236e-01 0.00000000e+00 + 7.03148862e-01 4.94313236e-01 0.00000000e+00 7.04743723e-01 5.22347610e-01 0.00000000e+00 7.06338584e-01 5.50381984e-01 0.00000000e+00 7.07933445e-01 5.78416359e-01 0.00000000e+00 7.09528306e-01 6.06450733e-01 0.00000000e+00 7.11123167e-01 6.34485107e-01 0.00000000e+00 7.12718028e-01 6.62519481e-01 0.00000000e+00 + 3.53553482e-01 4.85747395e-01 0.00000000e+00 3.84408468e-01 4.86453449e-01 0.00000000e+00 4.15263455e-01 4.87159503e-01 0.00000000e+00 4.46118441e-01 4.87865557e-01 0.00000000e+00 4.76973428e-01 4.88571612e-01 0.00000000e+00 5.07828414e-01 4.89277666e-01 0.00000000e+00 5.38683400e-01 4.89983720e-01 0.00000000e+00 + 3.34147754e-01 3.09117834e-01 0.00000000e+00 3.68376037e-01 3.11159233e-01 0.00000000e+00 4.02604320e-01 3.13200631e-01 0.00000000e+00 4.36832603e-01 3.15242029e-01 0.00000000e+00 4.71060886e-01 3.17283427e-01 0.00000000e+00 5.05289169e-01 3.19324826e-01 0.00000000e+00 5.39517452e-01 3.21366224e-01 0.00000000e+00 + 5.39517452e-01 3.21366224e-01 0.00000000e+00 5.39378443e-01 3.49469140e-01 0.00000000e+00 5.39239435e-01 3.77572056e-01 0.00000000e+00 5.39100426e-01 4.05674972e-01 0.00000000e+00 5.38961418e-01 4.33777888e-01 0.00000000e+00 5.38822409e-01 4.61880804e-01 0.00000000e+00 5.38683400e-01 4.89983720e-01 0.00000000e+00 + 7.05900860e-01 3.27444582e-01 0.00000000e+00 7.05442194e-01 3.55256024e-01 0.00000000e+00 7.04983527e-01 3.83067467e-01 0.00000000e+00 7.04524861e-01 4.10878909e-01 0.00000000e+00 7.04066195e-01 4.38690351e-01 0.00000000e+00 7.03607528e-01 4.66501794e-01 0.00000000e+00 7.03148862e-01 4.94313236e-01 0.00000000e+00 + 5.39517452e-01 3.21366224e-01 0.00000000e+00 5.67248020e-01 3.22379283e-01 0.00000000e+00 5.94978588e-01 3.23392343e-01 0.00000000e+00 6.22709156e-01 3.24405403e-01 0.00000000e+00 6.50439724e-01 3.25418462e-01 0.00000000e+00 6.78170292e-01 3.26431522e-01 0.00000000e+00 7.05900860e-01 3.27444582e-01 0.00000000e+00 + 7.50000000e-01 0.00000000e+00 0.00000000e+00 7.45538107e-01 2.71360381e-02 0.00000000e+00 7.41076214e-01 5.42720762e-02 0.00000000e+00 7.36614321e-01 8.14081143e-02 0.00000000e+00 7.32152428e-01 1.08544152e-01 0.00000000e+00 7.27690536e-01 1.35680191e-01 0.00000000e+00 7.23228643e-01 1.62816229e-01 0.00000000e+00 + 7.23228643e-01 1.62816229e-01 0.00000000e+00 6.97946631e-01 1.61996932e-01 0.00000000e+00 6.72664619e-01 1.61177636e-01 0.00000000e+00 6.47382608e-01 1.60358339e-01 0.00000000e+00 6.22100596e-01 1.59539043e-01 0.00000000e+00 5.96818585e-01 1.58719746e-01 0.00000000e+00 5.71536573e-01 1.57900450e-01 0.00000000e+00 + 5.71536573e-01 1.57900450e-01 0.00000000e+00 5.80447144e-01 1.31583708e-01 0.00000000e+00 5.89357715e-01 1.05266966e-01 0.00000000e+00 5.98268287e-01 7.89502248e-02 0.00000000e+00 6.07178858e-01 5.26334832e-02 0.00000000e+00 6.16089429e-01 2.63167416e-02 0.00000000e+00 6.25000000e-01 0.00000000e+00 0.00000000e+00 + 5.39517452e-01 3.21366224e-01 0.00000000e+00 5.44853972e-01 2.94121928e-01 0.00000000e+00 5.50190492e-01 2.66877632e-01 0.00000000e+00 5.55527013e-01 2.39633337e-01 0.00000000e+00 5.60863533e-01 2.12389041e-01 0.00000000e+00 5.66200053e-01 1.85144745e-01 0.00000000e+00 5.71536573e-01 1.57900450e-01 0.00000000e+00 + 7.23228643e-01 1.62816229e-01 0.00000000e+00 7.20340679e-01 1.90254287e-01 0.00000000e+00 7.17452715e-01 2.17692346e-01 0.00000000e+00 7.14564751e-01 2.45130405e-01 0.00000000e+00 7.11676788e-01 2.72568464e-01 0.00000000e+00 7.08788824e-01 3.00006523e-01 0.00000000e+00 7.05900860e-01 3.27444582e-01 0.00000000e+00 + 3.96563471e-01 1.44813573e-01 0.00000000e+00 4.25725655e-01 1.46994719e-01 0.00000000e+00 4.54887839e-01 1.49175865e-01 0.00000000e+00 4.84050022e-01 1.51357011e-01 0.00000000e+00 5.13212206e-01 1.53538157e-01 0.00000000e+00 5.42374390e-01 1.55719303e-01 0.00000000e+00 5.71536573e-01 1.57900450e-01 0.00000000e+00 + 8.75000000e-01 1.00000000e+00 0.00000000e+00 8.73454071e-01 9.72051226e-01 0.00000000e+00 8.71908141e-01 9.44102453e-01 0.00000000e+00 8.70362212e-01 9.16153679e-01 0.00000000e+00 8.68816283e-01 8.88204906e-01 0.00000000e+00 8.67270353e-01 8.60256132e-01 0.00000000e+00 8.65724424e-01 8.32307359e-01 0.00000000e+00 + 8.65724424e-01 8.32307359e-01 0.00000000e+00 8.88103687e-01 8.32478355e-01 0.00000000e+00 9.10482949e-01 8.32649350e-01 0.00000000e+00 9.32862212e-01 8.32820346e-01 0.00000000e+00 9.55241475e-01 8.32991342e-01 0.00000000e+00 9.77620737e-01 8.33162338e-01 0.00000000e+00 1.00000000e+00 8.33333333e-01 0.00000000e+00 + 7.29787077e-01 8.31199374e-01 0.00000000e+00 7.52443301e-01 8.31384039e-01 0.00000000e+00 7.75099526e-01 8.31568703e-01 0.00000000e+00 7.97755750e-01 8.31753367e-01 0.00000000e+00 8.20411975e-01 8.31938031e-01 0.00000000e+00 8.43068200e-01 8.32122695e-01 0.00000000e+00 8.65724424e-01 8.32307359e-01 0.00000000e+00 + 7.12718028e-01 6.62519481e-01 0.00000000e+00 7.36968498e-01 6.62887817e-01 0.00000000e+00 7.61218968e-01 6.63256153e-01 0.00000000e+00 7.85469439e-01 6.63624489e-01 0.00000000e+00 8.09719909e-01 6.63992824e-01 0.00000000e+00 8.33970380e-01 6.64361160e-01 0.00000000e+00 8.58220850e-01 6.64729496e-01 0.00000000e+00 + 8.58220850e-01 6.64729496e-01 0.00000000e+00 8.59471446e-01 6.92659140e-01 0.00000000e+00 8.60722041e-01 7.20588784e-01 0.00000000e+00 8.61972637e-01 7.48518427e-01 0.00000000e+00 8.63223233e-01 7.76448071e-01 0.00000000e+00 8.64473828e-01 8.04377715e-01 0.00000000e+00 8.65724424e-01 8.32307359e-01 0.00000000e+00 + 8.58220850e-01 6.64729496e-01 0.00000000e+00 8.81850708e-01 6.65052358e-01 0.00000000e+00 9.05480567e-01 6.65375219e-01 0.00000000e+00 9.29110425e-01 6.65698081e-01 0.00000000e+00 9.52740283e-01 6.66020943e-01 0.00000000e+00 9.76370142e-01 6.66343805e-01 0.00000000e+00 1.00000000e+00 6.66666667e-01 0.00000000e+00 + 1.00000000e+00 1.66666667e-01 0.00000000e+00 9.77291152e-01 1.66411458e-01 0.00000000e+00 9.54582303e-01 1.66156250e-01 0.00000000e+00 9.31873455e-01 1.65901041e-01 0.00000000e+00 9.09164607e-01 1.65645833e-01 0.00000000e+00 8.86455758e-01 1.65390624e-01 0.00000000e+00 8.63746910e-01 1.65135416e-01 0.00000000e+00 + 8.63746910e-01 1.65135416e-01 0.00000000e+00 8.65622425e-01 1.37612846e-01 0.00000000e+00 8.67497940e-01 1.10090277e-01 0.00000000e+00 8.69373455e-01 8.25677079e-02 0.00000000e+00 8.71248970e-01 5.50451386e-02 0.00000000e+00 8.73124485e-01 2.75225693e-02 0.00000000e+00 8.75000000e-01 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 3.33333333e-01 0.00000000e+00 9.76035763e-01 3.32925985e-01 0.00000000e+00 9.52071525e-01 3.32518637e-01 0.00000000e+00 9.28107288e-01 3.32111289e-01 0.00000000e+00 9.04143050e-01 3.31703942e-01 0.00000000e+00 8.80178813e-01 3.31296594e-01 0.00000000e+00 8.56214575e-01 3.30889246e-01 0.00000000e+00 + 8.56214575e-01 3.30889246e-01 0.00000000e+00 8.57469965e-01 3.03263607e-01 0.00000000e+00 8.58725354e-01 2.75637969e-01 0.00000000e+00 8.59980743e-01 2.48012331e-01 0.00000000e+00 8.61236132e-01 2.20386692e-01 0.00000000e+00 8.62491521e-01 1.92761054e-01 0.00000000e+00 8.63746910e-01 1.65135416e-01 0.00000000e+00 + 7.23228643e-01 1.62816229e-01 0.00000000e+00 7.46648354e-01 1.63202760e-01 0.00000000e+00 7.70068065e-01 1.63589291e-01 0.00000000e+00 7.93487776e-01 1.63975822e-01 0.00000000e+00 8.16907487e-01 1.64362353e-01 0.00000000e+00 8.40327199e-01 1.64748885e-01 0.00000000e+00 8.63746910e-01 1.65135416e-01 0.00000000e+00 + 8.56214575e-01 3.30889246e-01 0.00000000e+00 8.31162290e-01 3.30315135e-01 0.00000000e+00 8.06110004e-01 3.29741024e-01 0.00000000e+00 7.81057718e-01 3.29166914e-01 0.00000000e+00 7.56005432e-01 3.28592803e-01 0.00000000e+00 7.30953146e-01 3.28018692e-01 0.00000000e+00 7.05900860e-01 3.27444582e-01 0.00000000e+00 + 8.56214575e-01 3.30889246e-01 0.00000000e+00 8.55927262e-01 3.58655380e-01 0.00000000e+00 8.55639948e-01 3.86421515e-01 0.00000000e+00 8.55352635e-01 4.14187649e-01 0.00000000e+00 8.55065321e-01 4.41953784e-01 0.00000000e+00 8.54778008e-01 4.69719918e-01 0.00000000e+00 8.54490694e-01 4.97486053e-01 0.00000000e+00 + 8.54490694e-01 4.97486053e-01 0.00000000e+00 8.29267055e-01 4.96957250e-01 0.00000000e+00 8.04043417e-01 4.96428447e-01 0.00000000e+00 7.78819778e-01 4.95899644e-01 0.00000000e+00 7.53596139e-01 4.95370842e-01 0.00000000e+00 7.28372501e-01 4.94842039e-01 0.00000000e+00 7.03148862e-01 4.94313236e-01 0.00000000e+00 + 1.00000000e+00 5.00000000e-01 0.00000000e+00 9.75748449e-01 4.99581009e-01 0.00000000e+00 9.51496898e-01 4.99162018e-01 0.00000000e+00 9.27245347e-01 4.98743026e-01 0.00000000e+00 9.02993796e-01 4.98324035e-01 0.00000000e+00 8.78742245e-01 4.97905044e-01 0.00000000e+00 8.54490694e-01 4.97486053e-01 0.00000000e+00 + 8.58220850e-01 6.64729496e-01 0.00000000e+00 8.57599157e-01 6.36855589e-01 0.00000000e+00 8.56977465e-01 6.08981682e-01 0.00000000e+00 8.56355772e-01 5.81107774e-01 0.00000000e+00 8.55734079e-01 5.53233867e-01 0.00000000e+00 8.55112387e-01 5.25359960e-01 0.00000000e+00 8.54490694e-01 4.97486053e-01 0.00000000e+00 + 0.00000000e+00 5.00000000e-01 0.00000000e+00 3.22669351e-02 4.98852223e-01 0.00000000e+00 6.45338701e-02 4.97704446e-01 0.00000000e+00 9.68008052e-02 4.96556669e-01 0.00000000e+00 1.29067740e-01 4.95408891e-01 0.00000000e+00 1.61334675e-01 4.94261114e-01 0.00000000e+00 1.93601610e-01 4.93113337e-01 0.00000000e+00 0.00000000e+00 5.41666667e-01 0.00000000e+00 3.28852634e-02 5.40614310e-01 0.00000000e+00 6.57705267e-02 5.39561953e-01 0.00000000e+00 9.86557901e-02 5.38509596e-01 0.00000000e+00 1.31541053e-01 5.37457239e-01 0.00000000e+00 1.64426317e-01 5.36404882e-01 0.00000000e+00 1.97311580e-01 5.35352525e-01 0.00000000e+00 0.00000000e+00 5.83333333e-01 0.00000000e+00 3.35035917e-02 5.82376397e-01 0.00000000e+00 6.70071833e-02 5.81419460e-01 0.00000000e+00 1.00510775e-01 5.80462523e-01 0.00000000e+00 1.34014367e-01 5.79505586e-01 0.00000000e+00 1.67517958e-01 5.78548650e-01 0.00000000e+00 2.01021550e-01 5.77591713e-01 0.00000000e+00 0.00000000e+00 6.25000000e-01 0.00000000e+00 3.41219200e-02 6.24138483e-01 0.00000000e+00 6.82438399e-02 6.23276967e-01 0.00000000e+00 1.02365760e-01 6.22415450e-01 0.00000000e+00 1.36487680e-01 6.21553934e-01 0.00000000e+00 1.70609600e-01 6.20692417e-01 0.00000000e+00 2.04731520e-01 6.19830901e-01 0.00000000e+00 0.00000000e+00 6.66666667e-01 0.00000000e+00 3.47402482e-02 6.65900570e-01 0.00000000e+00 6.94804965e-02 6.65134474e-01 0.00000000e+00 1.04220745e-01 6.64368378e-01 0.00000000e+00 1.38960993e-01 6.63602281e-01 0.00000000e+00 1.73701241e-01 6.62836185e-01 0.00000000e+00 2.08441489e-01 6.62070089e-01 0.00000000e+00 0.00000000e+00 7.08333333e-01 0.00000000e+00 3.53585765e-02 7.07662657e-01 0.00000000e+00 7.07171531e-02 7.06991981e-01 0.00000000e+00 1.06075730e-01 7.06321305e-01 0.00000000e+00 1.41434306e-01 7.05650629e-01 0.00000000e+00 1.76792883e-01 7.04979953e-01 0.00000000e+00 2.12151459e-01 7.04309277e-01 0.00000000e+00 0.00000000e+00 7.50000000e-01 0.00000000e+00 3.59769048e-02 7.49424744e-01 0.00000000e+00 7.19538097e-02 7.48849488e-01 0.00000000e+00 1.07930715e-01 7.48274232e-01 0.00000000e+00 1.43907619e-01 7.47698976e-01 0.00000000e+00 1.79884524e-01 7.47123720e-01 0.00000000e+00 2.15861429e-01 7.46548464e-01 0.00000000e+00 + 3.53553482e-01 4.85747395e-01 0.00000000e+00 3.63764381e-01 5.29128196e-01 0.00000000e+00 3.74986004e-01 5.72259249e-01 0.00000000e+00 3.86942397e-01 6.15192791e-01 0.00000000e+00 3.99421769e-01 6.57977458e-01 0.00000000e+00 4.12252078e-01 7.00658315e-01 0.00000000e+00 4.25285357e-01 7.43277689e-01 0.00000000e+00 3.26894837e-01 4.86975052e-01 0.00000000e+00 3.36022248e-01 5.30165584e-01 0.00000000e+00 3.45991928e-01 5.73147993e-01 0.00000000e+00 3.56573918e-01 6.15965809e-01 0.00000000e+00 3.67591722e-01 6.58659563e-01 0.00000000e+00 3.78901975e-01 7.01266809e-01 0.00000000e+00 3.90381369e-01 7.43822818e-01 0.00000000e+00 3.00236191e-01 4.88202709e-01 0.00000000e+00 3.08280114e-01 5.31202972e-01 0.00000000e+00 3.16997853e-01 5.74036737e-01 0.00000000e+00 3.26205438e-01 6.16738828e-01 0.00000000e+00 3.35761676e-01 6.59341668e-01 0.00000000e+00 3.45551872e-01 7.01875302e-01 0.00000000e+00 3.55477381e-01 7.44367947e-01 0.00000000e+00 2.73577546e-01 4.89430366e-01 0.00000000e+00 2.80537981e-01 5.32240360e-01 0.00000000e+00 2.88003777e-01 5.74925481e-01 0.00000000e+00 2.95836958e-01 6.17511846e-01 0.00000000e+00 3.03931629e-01 6.60023773e-01 0.00000000e+00 3.12201768e-01 7.02483796e-01 0.00000000e+00 3.20573393e-01 7.44913077e-01 0.00000000e+00 2.46918901e-01 4.90658023e-01 0.00000000e+00 2.52795847e-01 5.33277749e-01 0.00000000e+00 2.59009701e-01 5.75814225e-01 0.00000000e+00 2.65468479e-01 6.18284864e-01 0.00000000e+00 2.72101583e-01 6.60705878e-01 0.00000000e+00 2.78851665e-01 7.03092289e-01 0.00000000e+00 2.85669405e-01 7.45458206e-01 0.00000000e+00 2.20260256e-01 4.91885680e-01 0.00000000e+00 2.25053714e-01 5.34315137e-01 0.00000000e+00 2.30015626e-01 5.76702969e-01 0.00000000e+00 2.35099999e-01 6.19057882e-01 0.00000000e+00 2.40271536e-01 6.61387984e-01 0.00000000e+00 2.45501562e-01 7.03700783e-01 0.00000000e+00 2.50765417e-01 7.46003335e-01 0.00000000e+00 1.93601610e-01 4.93113337e-01 0.00000000e+00 1.97311580e-01 5.35352525e-01 0.00000000e+00 2.01021550e-01 5.77591713e-01 0.00000000e+00 2.04731520e-01 6.19830901e-01 0.00000000e+00 2.08441489e-01 6.62070089e-01 0.00000000e+00 2.12151459e-01 7.04309277e-01 0.00000000e+00 2.15861429e-01 7.46548464e-01 0.00000000e+00 + 5.00000000e-01 1.00000000e+00 0.00000000e+00 4.58333333e-01 1.00000000e+00 0.00000000e+00 4.16666667e-01 1.00000000e+00 0.00000000e+00 3.75000000e-01 1.00000000e+00 0.00000000e+00 3.33333333e-01 1.00000000e+00 0.00000000e+00 2.91666667e-01 1.00000000e+00 0.00000000e+00 2.50000000e-01 1.00000000e+00 0.00000000e+00 4.88744095e-01 9.56877857e-01 0.00000000e+00 4.48005119e-01 9.57024561e-01 0.00000000e+00 4.07266142e-01 9.57171264e-01 0.00000000e+00 3.66527166e-01 9.57317967e-01 0.00000000e+00 3.25788190e-01 9.57464671e-01 0.00000000e+00 2.85049214e-01 9.57611374e-01 0.00000000e+00 2.44310238e-01 9.57758077e-01 0.00000000e+00 4.76762956e-01 9.13951208e-01 0.00000000e+00 4.37072543e-01 9.14212032e-01 0.00000000e+00 3.97382130e-01 9.14472857e-01 0.00000000e+00 3.57691716e-01 9.14733681e-01 0.00000000e+00 3.18001303e-01 9.14994506e-01 0.00000000e+00 2.78310890e-01 9.15255330e-01 0.00000000e+00 2.38620476e-01 9.15516155e-01 0.00000000e+00 4.64266387e-01 8.71171562e-01 0.00000000e+00 4.25710442e-01 8.71522007e-01 0.00000000e+00 3.87154496e-01 8.71872452e-01 0.00000000e+00 3.48598551e-01 8.72222897e-01 0.00000000e+00 3.10042605e-01 8.72573342e-01 0.00000000e+00 2.71486660e-01 8.72923787e-01 0.00000000e+00 2.32930715e-01 8.73274232e-01 0.00000000e+00 4.51425199e-01 8.28493979e-01 0.00000000e+00 4.14061158e-01 8.28917034e-01 0.00000000e+00 3.76697117e-01 8.29340089e-01 0.00000000e+00 3.39333076e-01 8.29763144e-01 0.00000000e+00 3.01969035e-01 8.30186199e-01 0.00000000e+00 2.64604994e-01 8.30609254e-01 0.00000000e+00 2.27240953e-01 8.31032310e-01 0.00000000e+00 4.38386646e-01 7.85876221e-01 0.00000000e+00 4.02247403e-01 7.86361915e-01 0.00000000e+00 3.66108161e-01 7.86847609e-01 0.00000000e+00 3.29968918e-01 7.87333304e-01 0.00000000e+00 2.93829676e-01 7.87818998e-01 0.00000000e+00 2.57690433e-01 7.88304693e-01 0.00000000e+00 2.21551191e-01 7.88790387e-01 0.00000000e+00 4.25285357e-01 7.43277689e-01 0.00000000e+00 3.90381369e-01 7.43822818e-01 0.00000000e+00 3.55477381e-01 7.44367947e-01 0.00000000e+00 3.20573393e-01 7.44913077e-01 0.00000000e+00 2.85669405e-01 7.45458206e-01 0.00000000e+00 2.50765417e-01 7.46003335e-01 0.00000000e+00 2.15861429e-01 7.46548464e-01 0.00000000e+00 + 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 9.58333333e-01 0.00000000e+00 0.00000000e+00 9.16666667e-01 0.00000000e+00 0.00000000e+00 8.75000000e-01 0.00000000e+00 0.00000000e+00 8.33333333e-01 0.00000000e+00 0.00000000e+00 7.91666667e-01 0.00000000e+00 0.00000000e+00 7.50000000e-01 0.00000000e+00 4.16666667e-02 1.00000000e+00 0.00000000e+00 4.07183730e-02 9.58237457e-01 0.00000000e+00 3.97700794e-02 9.16474915e-01 0.00000000e+00 3.88217858e-02 8.74712372e-01 0.00000000e+00 3.78734921e-02 8.32949829e-01 0.00000000e+00 3.69251985e-02 7.91187287e-01 0.00000000e+00 3.59769048e-02 7.49424744e-01 0.00000000e+00 8.33333333e-02 1.00000000e+00 0.00000000e+00 8.14367461e-02 9.58141581e-01 0.00000000e+00 7.95401588e-02 9.16283163e-01 0.00000000e+00 7.76435715e-02 8.74424744e-01 0.00000000e+00 7.57469842e-02 8.32566325e-01 0.00000000e+00 7.38503969e-02 7.90707907e-01 0.00000000e+00 7.19538097e-02 7.48849488e-01 0.00000000e+00 1.25000000e-01 1.00000000e+00 0.00000000e+00 1.22155119e-01 9.58045705e-01 0.00000000e+00 1.19310238e-01 9.16091411e-01 0.00000000e+00 1.16465357e-01 8.74137116e-01 0.00000000e+00 1.13620476e-01 8.32182821e-01 0.00000000e+00 1.10775595e-01 7.90228527e-01 0.00000000e+00 1.07930715e-01 7.48274232e-01 0.00000000e+00 1.66666667e-01 1.00000000e+00 0.00000000e+00 1.62873492e-01 9.57949829e-01 0.00000000e+00 1.59080318e-01 9.15899659e-01 0.00000000e+00 1.55287143e-01 8.73849488e-01 0.00000000e+00 1.51493968e-01 8.31799318e-01 0.00000000e+00 1.47700794e-01 7.89749147e-01 0.00000000e+00 1.43907619e-01 7.47698976e-01 0.00000000e+00 2.08333333e-01 1.00000000e+00 0.00000000e+00 2.03591865e-01 9.57853953e-01 0.00000000e+00 1.98850397e-01 9.15707907e-01 0.00000000e+00 1.94108929e-01 8.73561860e-01 0.00000000e+00 1.89367461e-01 8.31415814e-01 0.00000000e+00 1.84625992e-01 7.89269767e-01 0.00000000e+00 1.79884524e-01 7.47123720e-01 0.00000000e+00 2.50000000e-01 1.00000000e+00 0.00000000e+00 2.44310238e-01 9.57758077e-01 0.00000000e+00 2.38620476e-01 9.15516155e-01 0.00000000e+00 2.32930715e-01 8.73274232e-01 0.00000000e+00 2.27240953e-01 8.31032310e-01 0.00000000e+00 2.21551191e-01 7.88790387e-01 0.00000000e+00 2.15861429e-01 7.46548464e-01 0.00000000e+00 + 0.00000000e+00 5.00000000e-01 0.00000000e+00 0.00000000e+00 4.58333333e-01 0.00000000e+00 0.00000000e+00 4.16666667e-01 0.00000000e+00 0.00000000e+00 3.75000000e-01 0.00000000e+00 0.00000000e+00 3.33333333e-01 0.00000000e+00 0.00000000e+00 2.91666667e-01 0.00000000e+00 0.00000000e+00 2.50000000e-01 0.00000000e+00 3.22669351e-02 4.98852223e-01 0.00000000e+00 3.25565274e-02 4.57185768e-01 0.00000000e+00 3.28461197e-02 4.15519314e-01 0.00000000e+00 3.31357120e-02 3.73852859e-01 0.00000000e+00 3.34253044e-02 3.32186404e-01 0.00000000e+00 3.37148967e-02 2.90519950e-01 0.00000000e+00 3.40044890e-02 2.48853495e-01 0.00000000e+00 6.45338701e-02 4.97704446e-01 0.00000000e+00 6.51130548e-02 4.56038203e-01 0.00000000e+00 6.56922394e-02 4.14371961e-01 0.00000000e+00 6.62714241e-02 3.72705718e-01 0.00000000e+00 6.68506087e-02 3.31039476e-01 0.00000000e+00 6.74297934e-02 2.89373233e-01 0.00000000e+00 6.80089780e-02 2.47706990e-01 0.00000000e+00 9.68008052e-02 4.96556669e-01 0.00000000e+00 9.76695822e-02 4.54890638e-01 0.00000000e+00 9.85383591e-02 4.13224608e-01 0.00000000e+00 9.94071361e-02 3.71558577e-01 0.00000000e+00 1.00275913e-01 3.29892547e-01 0.00000000e+00 1.01144690e-01 2.88226516e-01 0.00000000e+00 1.02013467e-01 2.46560486e-01 0.00000000e+00 1.29067740e-01 4.95408891e-01 0.00000000e+00 1.30226110e-01 4.53743073e-01 0.00000000e+00 1.31384479e-01 4.12077255e-01 0.00000000e+00 1.32542848e-01 3.70411436e-01 0.00000000e+00 1.33701217e-01 3.28745618e-01 0.00000000e+00 1.34859587e-01 2.87079799e-01 0.00000000e+00 1.36017956e-01 2.45413981e-01 0.00000000e+00 1.61334675e-01 4.94261114e-01 0.00000000e+00 1.62782637e-01 4.52595508e-01 0.00000000e+00 1.64230599e-01 4.10929902e-01 0.00000000e+00 1.65678560e-01 3.69264295e-01 0.00000000e+00 1.67126522e-01 3.27598689e-01 0.00000000e+00 1.68574483e-01 2.85933082e-01 0.00000000e+00 1.70022445e-01 2.44267476e-01 0.00000000e+00 1.93601610e-01 4.93113337e-01 0.00000000e+00 1.95339164e-01 4.51447943e-01 0.00000000e+00 1.97076718e-01 4.09782549e-01 0.00000000e+00 1.98814272e-01 3.68117154e-01 0.00000000e+00 2.00551826e-01 3.26451760e-01 0.00000000e+00 2.02289380e-01 2.84786366e-01 0.00000000e+00 2.04026934e-01 2.43120971e-01 0.00000000e+00 + 0.00000000e+00 0.00000000e+00 0.00000000e+00 4.16666667e-02 0.00000000e+00 0.00000000e+00 8.33333333e-02 0.00000000e+00 0.00000000e+00 1.25000000e-01 0.00000000e+00 0.00000000e+00 1.66666667e-01 0.00000000e+00 0.00000000e+00 2.08333333e-01 0.00000000e+00 0.00000000e+00 2.50000000e-01 0.00000000e+00 0.00000000e+00 0.00000000e+00 4.16666667e-02 0.00000000e+00 4.03896371e-02 4.14755825e-02 0.00000000e+00 8.07792741e-02 4.12844984e-02 0.00000000e+00 1.21168911e-01 4.10934143e-02 0.00000000e+00 1.61558548e-01 4.09023301e-02 0.00000000e+00 2.01948185e-01 4.07112460e-02 0.00000000e+00 2.42337822e-01 4.05201619e-02 0.00000000e+00 0.00000000e+00 8.33333333e-02 0.00000000e+00 3.91126074e-02 8.29511651e-02 0.00000000e+00 7.82252149e-02 8.25689968e-02 0.00000000e+00 1.17337822e-01 8.21868286e-02 0.00000000e+00 1.56450430e-01 8.18046603e-02 0.00000000e+00 1.95563037e-01 8.14224920e-02 0.00000000e+00 2.34675645e-01 8.10403238e-02 0.00000000e+00 0.00000000e+00 1.25000000e-01 0.00000000e+00 3.78355778e-02 1.24426748e-01 0.00000000e+00 7.56711557e-02 1.23853495e-01 0.00000000e+00 1.13506733e-01 1.23280243e-01 0.00000000e+00 1.51342311e-01 1.22706990e-01 0.00000000e+00 1.89177889e-01 1.22133738e-01 0.00000000e+00 2.27013467e-01 1.21560486e-01 0.00000000e+00 0.00000000e+00 1.66666667e-01 0.00000000e+00 3.65585482e-02 1.65902330e-01 0.00000000e+00 7.31170964e-02 1.65137994e-01 0.00000000e+00 1.09675645e-01 1.64373657e-01 0.00000000e+00 1.46234193e-01 1.63609321e-01 0.00000000e+00 1.82792741e-01 1.62844984e-01 0.00000000e+00 2.19351289e-01 1.62080648e-01 0.00000000e+00 0.00000000e+00 2.08333333e-01 0.00000000e+00 3.52815186e-02 2.07377913e-01 0.00000000e+00 7.05630372e-02 2.06422492e-01 0.00000000e+00 1.05844556e-01 2.05467071e-01 0.00000000e+00 1.41126074e-01 2.04511651e-01 0.00000000e+00 1.76407593e-01 2.03556230e-01 0.00000000e+00 2.11689112e-01 2.02600809e-01 0.00000000e+00 0.00000000e+00 2.50000000e-01 0.00000000e+00 3.40044890e-02 2.48853495e-01 0.00000000e+00 6.80089780e-02 2.47706990e-01 0.00000000e+00 1.02013467e-01 2.46560486e-01 0.00000000e+00 1.36017956e-01 2.45413981e-01 0.00000000e+00 1.70022445e-01 2.44267476e-01 0.00000000e+00 2.04026934e-01 2.43120971e-01 0.00000000e+00 + 5.00000000e-01 0.00000000e+00 0.00000000e+00 4.77516149e-01 3.84473378e-02 0.00000000e+00 4.51320409e-01 7.44915151e-02 0.00000000e+00 4.23610288e-01 1.09396998e-01 0.00000000e+00 3.96563474e-01 1.44813569e-01 0.00000000e+00 3.72377341e-01 1.82222775e-01 0.00000000e+00 3.53151292e-01 2.22386302e-01 0.00000000e+00 4.58333333e-01 0.00000000e+00 0.00000000e+00 4.38319761e-01 3.87928085e-02 0.00000000e+00 4.15212948e-01 7.55829832e-02 0.00000000e+00 3.90844151e-01 1.11424246e-01 0.00000000e+00 3.67028110e-01 1.47691416e-01 0.00000000e+00 3.45595970e-01 1.85619114e-01 0.00000000e+00 3.28297232e-01 2.25842080e-01 0.00000000e+00 4.16666667e-01 0.00000000e+00 0.00000000e+00 3.99123373e-01 3.91382791e-02 0.00000000e+00 3.79105487e-01 7.66744513e-02 0.00000000e+00 3.58078014e-01 1.13451494e-01 0.00000000e+00 3.37492746e-01 1.50569262e-01 0.00000000e+00 3.18814598e-01 1.89015453e-01 0.00000000e+00 3.03443173e-01 2.29297859e-01 0.00000000e+00 3.75000000e-01 0.00000000e+00 0.00000000e+00 3.59926986e-01 3.94837498e-02 0.00000000e+00 3.42998027e-01 7.77659195e-02 0.00000000e+00 3.25311878e-01 1.15478742e-01 0.00000000e+00 3.07957382e-01 1.53447108e-01 0.00000000e+00 2.92033227e-01 1.92411792e-01 0.00000000e+00 2.78589113e-01 2.32753637e-01 0.00000000e+00 3.33333333e-01 0.00000000e+00 0.00000000e+00 3.20730598e-01 3.98292205e-02 0.00000000e+00 3.06890566e-01 7.88573876e-02 0.00000000e+00 2.92545741e-01 1.17505990e-01 0.00000000e+00 2.78422017e-01 1.56324955e-01 0.00000000e+00 2.65251855e-01 1.95808131e-01 0.00000000e+00 2.53735053e-01 2.36209415e-01 0.00000000e+00 2.91666667e-01 0.00000000e+00 0.00000000e+00 2.81534210e-01 4.01746912e-02 0.00000000e+00 2.70783105e-01 7.99488557e-02 0.00000000e+00 2.59779604e-01 1.19533238e-01 0.00000000e+00 2.48886653e-01 1.59202801e-01 0.00000000e+00 2.38470483e-01 1.99204470e-01 0.00000000e+00 2.28880994e-01 2.39665193e-01 0.00000000e+00 2.50000000e-01 0.00000000e+00 0.00000000e+00 2.42337822e-01 4.05201619e-02 0.00000000e+00 2.34675645e-01 8.10403238e-02 0.00000000e+00 2.27013467e-01 1.21560486e-01 0.00000000e+00 2.19351289e-01 1.62080648e-01 0.00000000e+00 2.11689112e-01 2.02600809e-01 0.00000000e+00 2.04026934e-01 2.43120971e-01 0.00000000e+00 + 3.53553482e-01 4.85747395e-01 0.00000000e+00 3.26894837e-01 4.86975052e-01 0.00000000e+00 3.00236191e-01 4.88202709e-01 0.00000000e+00 2.73577546e-01 4.89430366e-01 0.00000000e+00 2.46918901e-01 4.90658023e-01 0.00000000e+00 2.20260256e-01 4.91885680e-01 0.00000000e+00 1.93601610e-01 4.93113337e-01 0.00000000e+00 3.44734586e-01 4.42063566e-01 0.00000000e+00 3.19835349e-01 4.43627629e-01 0.00000000e+00 2.94936112e-01 4.45191692e-01 0.00000000e+00 2.70036875e-01 4.46755754e-01 0.00000000e+00 2.45137638e-01 4.48319817e-01 0.00000000e+00 2.20238401e-01 4.49883880e-01 0.00000000e+00 1.95339164e-01 4.51447943e-01 0.00000000e+00 3.37869219e-01 3.98033069e-01 0.00000000e+00 3.14403802e-01 3.99991316e-01 0.00000000e+00 2.90938386e-01 4.01949562e-01 0.00000000e+00 2.67472969e-01 4.03907809e-01 0.00000000e+00 2.44007552e-01 4.05866055e-01 0.00000000e+00 2.20542135e-01 4.07824302e-01 0.00000000e+00 1.97076718e-01 4.09782549e-01 0.00000000e+00 3.33846334e-01 3.53658633e-01 0.00000000e+00 3.11340990e-01 3.56068387e-01 0.00000000e+00 2.88835647e-01 3.58478140e-01 0.00000000e+00 2.66330303e-01 3.60887894e-01 0.00000000e+00 2.43824959e-01 3.63297647e-01 0.00000000e+00 2.21319616e-01 3.65707401e-01 0.00000000e+00 1.98814272e-01 3.68117154e-01 0.00000000e+00 3.34147748e-01 3.09117924e-01 0.00000000e+00 3.11881761e-01 3.12006897e-01 0.00000000e+00 2.89615774e-01 3.14895869e-01 0.00000000e+00 2.67349787e-01 3.17784842e-01 0.00000000e+00 2.45083800e-01 3.20673815e-01 0.00000000e+00 2.22817813e-01 3.23562787e-01 0.00000000e+00 2.00551826e-01 3.26451760e-01 0.00000000e+00 3.40325109e-01 2.65019871e-01 0.00000000e+00 3.17319154e-01 2.68314287e-01 0.00000000e+00 2.94313200e-01 2.71608703e-01 0.00000000e+00 2.71307245e-01 2.74903119e-01 0.00000000e+00 2.48301290e-01 2.78197534e-01 0.00000000e+00 2.25295335e-01 2.81491950e-01 0.00000000e+00 2.02289380e-01 2.84786366e-01 0.00000000e+00 3.53151292e-01 2.22386302e-01 0.00000000e+00 3.28297232e-01 2.25842080e-01 0.00000000e+00 3.03443173e-01 2.29297859e-01 0.00000000e+00 2.78589113e-01 2.32753637e-01 0.00000000e+00 2.53735053e-01 2.36209415e-01 0.00000000e+00 2.28880994e-01 2.39665193e-01 0.00000000e+00 2.04026934e-01 2.43120971e-01 0.00000000e+00 + 7.50000000e-01 1.00000000e+00 0.00000000e+00 7.29166667e-01 1.00000000e+00 0.00000000e+00 7.08333333e-01 1.00000000e+00 0.00000000e+00 6.87500000e-01 1.00000000e+00 0.00000000e+00 6.66666667e-01 1.00000000e+00 0.00000000e+00 6.45833333e-01 1.00000000e+00 0.00000000e+00 6.25000000e-01 1.00000000e+00 0.00000000e+00 7.46631179e-01 9.71866562e-01 0.00000000e+00 7.25420830e-01 9.71833221e-01 0.00000000e+00 7.04210480e-01 9.71799879e-01 0.00000000e+00 6.83000131e-01 9.71766538e-01 0.00000000e+00 6.61789781e-01 9.71733196e-01 0.00000000e+00 6.40579431e-01 9.71699855e-01 0.00000000e+00 6.19369082e-01 9.71666513e-01 0.00000000e+00 7.43262359e-01 9.43733125e-01 0.00000000e+00 7.21674993e-01 9.43666442e-01 0.00000000e+00 7.00087627e-01 9.43599759e-01 0.00000000e+00 6.78500261e-01 9.43533076e-01 0.00000000e+00 6.56912895e-01 9.43466393e-01 0.00000000e+00 6.35325529e-01 9.43399710e-01 0.00000000e+00 6.13738163e-01 9.43333027e-01 0.00000000e+00 7.39893538e-01 9.15599687e-01 0.00000000e+00 7.17929156e-01 9.15499663e-01 0.00000000e+00 6.95964774e-01 9.15399638e-01 0.00000000e+00 6.74000392e-01 9.15299614e-01 0.00000000e+00 6.52036010e-01 9.15199589e-01 0.00000000e+00 6.30071627e-01 9.15099565e-01 0.00000000e+00 6.08107245e-01 9.14999540e-01 0.00000000e+00 7.36524718e-01 8.87466250e-01 0.00000000e+00 7.14183319e-01 8.87332884e-01 0.00000000e+00 6.91841921e-01 8.87199518e-01 0.00000000e+00 6.69500522e-01 8.87066152e-01 0.00000000e+00 6.47159124e-01 8.86932786e-01 0.00000000e+00 6.24817725e-01 8.86799420e-01 0.00000000e+00 6.02476327e-01 8.86666054e-01 0.00000000e+00 7.33155897e-01 8.59332812e-01 0.00000000e+00 7.10437483e-01 8.59166105e-01 0.00000000e+00 6.87719068e-01 8.58999397e-01 0.00000000e+00 6.65000653e-01 8.58832690e-01 0.00000000e+00 6.42282238e-01 8.58665982e-01 0.00000000e+00 6.19563824e-01 8.58499275e-01 0.00000000e+00 5.96845409e-01 8.58332567e-01 0.00000000e+00 7.29787077e-01 8.31199374e-01 0.00000000e+00 7.06691646e-01 8.30999326e-01 0.00000000e+00 6.83596215e-01 8.30799277e-01 0.00000000e+00 6.60500784e-01 8.30599228e-01 0.00000000e+00 6.37405353e-01 8.30399179e-01 0.00000000e+00 6.14309922e-01 8.30199130e-01 0.00000000e+00 5.91214490e-01 8.29999081e-01 0.00000000e+00 + 5.00000000e-01 1.00000000e+00 0.00000000e+00 4.92588523e-01 9.71227678e-01 0.00000000e+00 4.84819587e-01 9.42549727e-01 0.00000000e+00 4.76762956e-01 9.13951208e-01 0.00000000e+00 4.68478029e-01 8.85417950e-01 0.00000000e+00 4.60016645e-01 8.56936494e-01 0.00000000e+00 4.51425200e-01 8.28493982e-01 0.00000000e+00 5.20833333e-01 1.00000000e+00 0.00000000e+00 5.13718616e-01 9.71300817e-01 0.00000000e+00 5.06306016e-01 9.42680277e-01 0.00000000e+00 4.98653671e-01 9.14125930e-01 0.00000000e+00 4.90811079e-01 8.85625968e-01 0.00000000e+00 4.82821439e-01 8.57169173e-01 0.00000000e+00 4.74723415e-01 8.28744831e-01 0.00000000e+00 5.41666667e-01 1.00000000e+00 0.00000000e+00 5.34848709e-01 9.71373957e-01 0.00000000e+00 5.27792446e-01 9.42810827e-01 0.00000000e+00 5.20544386e-01 9.14300652e-01 0.00000000e+00 5.13144128e-01 8.85833985e-01 0.00000000e+00 5.05626233e-01 8.57401852e-01 0.00000000e+00 4.98021630e-01 8.28995681e-01 0.00000000e+00 5.62500000e-01 1.00000000e+00 0.00000000e+00 5.55978803e-01 9.71447096e-01 0.00000000e+00 5.49278875e-01 9.42941377e-01 0.00000000e+00 5.42435101e-01 9.14475374e-01 0.00000000e+00 5.35477178e-01 8.86042002e-01 0.00000000e+00 5.28431027e-01 8.57634531e-01 0.00000000e+00 5.21319845e-01 8.29246531e-01 0.00000000e+00 5.83333333e-01 1.00000000e+00 0.00000000e+00 5.77108896e-01 9.71520235e-01 0.00000000e+00 5.70765305e-01 9.43071927e-01 0.00000000e+00 5.64325816e-01 9.14650096e-01 0.00000000e+00 5.57810228e-01 8.86250019e-01 0.00000000e+00 5.51235821e-01 8.57867210e-01 0.00000000e+00 5.44618060e-01 8.29497381e-01 0.00000000e+00 6.04166667e-01 1.00000000e+00 0.00000000e+00 5.98238989e-01 9.71593374e-01 0.00000000e+00 5.92251734e-01 9.43202477e-01 0.00000000e+00 5.86216530e-01 9.14824818e-01 0.00000000e+00 5.80143277e-01 8.86458037e-01 0.00000000e+00 5.74040615e-01 8.58099889e-01 0.00000000e+00 5.67916275e-01 8.29748231e-01 0.00000000e+00 6.25000000e-01 1.00000000e+00 0.00000000e+00 6.19369082e-01 9.71666513e-01 0.00000000e+00 6.13738163e-01 9.43333027e-01 0.00000000e+00 6.08107245e-01 9.14999540e-01 0.00000000e+00 6.02476327e-01 8.86666054e-01 0.00000000e+00 5.96845409e-01 8.58332567e-01 0.00000000e+00 5.91214490e-01 8.29999081e-01 0.00000000e+00 + 3.99421772e-01 6.57977469e-01 0.00000000e+00 4.26202755e-01 6.58322473e-01 0.00000000e+00 4.52983738e-01 6.58667477e-01 0.00000000e+00 4.79764721e-01 6.59012482e-01 0.00000000e+00 5.06545704e-01 6.59357486e-01 0.00000000e+00 5.33326687e-01 6.59702491e-01 0.00000000e+00 5.60107670e-01 6.60047495e-01 0.00000000e+00 4.07945811e-01 6.86440246e-01 0.00000000e+00 4.34170199e-01 6.86762332e-01 0.00000000e+00 4.60394588e-01 6.87084417e-01 0.00000000e+00 4.86618976e-01 6.87406503e-01 0.00000000e+00 5.12843364e-01 6.87728588e-01 0.00000000e+00 5.39067752e-01 6.88050674e-01 0.00000000e+00 5.65292140e-01 6.88372759e-01 0.00000000e+00 4.16580795e-01 7.14869577e-01 0.00000000e+00 4.42230097e-01 7.15174319e-01 0.00000000e+00 4.67879400e-01 7.15479060e-01 0.00000000e+00 4.93528702e-01 7.15783801e-01 0.00000000e+00 5.19178005e-01 7.16088542e-01 0.00000000e+00 5.44827307e-01 7.16393283e-01 0.00000000e+00 5.70476610e-01 7.16698024e-01 0.00000000e+00 4.25285357e-01 7.43277691e-01 0.00000000e+00 4.50347978e-01 7.43568624e-01 0.00000000e+00 4.75410598e-01 7.43859557e-01 0.00000000e+00 5.00473219e-01 7.44150490e-01 0.00000000e+00 5.25535839e-01 7.44441422e-01 0.00000000e+00 5.50598460e-01 7.44732355e-01 0.00000000e+00 5.75661080e-01 7.45023288e-01 0.00000000e+00 4.34020062e-01 7.71676555e-01 0.00000000e+00 4.58490977e-01 7.71955221e-01 0.00000000e+00 4.82961891e-01 7.72233887e-01 0.00000000e+00 5.07432806e-01 7.72512554e-01 0.00000000e+00 5.31903721e-01 7.72791220e-01 0.00000000e+00 5.56374635e-01 7.73069886e-01 0.00000000e+00 5.80845550e-01 7.73348552e-01 0.00000000e+00 4.42746292e-01 8.00078023e-01 0.00000000e+00 4.66626913e-01 8.00343989e-01 0.00000000e+00 4.90507535e-01 8.00609954e-01 0.00000000e+00 5.14388156e-01 8.00875920e-01 0.00000000e+00 5.38268777e-01 8.01141886e-01 0.00000000e+00 5.62149399e-01 8.01407851e-01 0.00000000e+00 5.86030020e-01 8.01673817e-01 0.00000000e+00 4.51425200e-01 8.28493982e-01 0.00000000e+00 4.74723415e-01 8.28744831e-01 0.00000000e+00 4.98021630e-01 8.28995681e-01 0.00000000e+00 5.21319845e-01 8.29246531e-01 0.00000000e+00 5.44618060e-01 8.29497381e-01 0.00000000e+00 5.67916275e-01 8.29748231e-01 0.00000000e+00 5.91214490e-01 8.29999081e-01 0.00000000e+00 + 7.12718028e-01 6.62519481e-01 0.00000000e+00 7.15562869e-01 6.90632797e-01 0.00000000e+00 7.18407711e-01 7.18746112e-01 0.00000000e+00 7.21252552e-01 7.46859428e-01 0.00000000e+00 7.24097394e-01 7.74972743e-01 0.00000000e+00 7.26942235e-01 8.03086059e-01 0.00000000e+00 7.29787077e-01 8.31199374e-01 0.00000000e+00 6.87282968e-01 6.62107484e-01 0.00000000e+00 6.90517748e-01 6.90256124e-01 0.00000000e+00 6.93752527e-01 7.18404764e-01 0.00000000e+00 6.96987307e-01 7.46553405e-01 0.00000000e+00 7.00222087e-01 7.74702045e-01 0.00000000e+00 7.03456866e-01 8.02850685e-01 0.00000000e+00 7.06691646e-01 8.30999326e-01 0.00000000e+00 6.61847908e-01 6.61695486e-01 0.00000000e+00 6.65472626e-01 6.89879451e-01 0.00000000e+00 6.69097344e-01 7.18063416e-01 0.00000000e+00 6.72722062e-01 7.46247381e-01 0.00000000e+00 6.76346779e-01 7.74431346e-01 0.00000000e+00 6.79971497e-01 8.02615312e-01 0.00000000e+00 6.83596215e-01 8.30799277e-01 0.00000000e+00 6.36412849e-01 6.61283488e-01 0.00000000e+00 6.40427505e-01 6.89502778e-01 0.00000000e+00 6.44442160e-01 7.17722068e-01 0.00000000e+00 6.48456816e-01 7.45941358e-01 0.00000000e+00 6.52471472e-01 7.74160648e-01 0.00000000e+00 6.56486128e-01 8.02379938e-01 0.00000000e+00 6.60500784e-01 8.30599228e-01 0.00000000e+00 6.10977789e-01 6.60871491e-01 0.00000000e+00 6.15382383e-01 6.89126105e-01 0.00000000e+00 6.19786977e-01 7.17380720e-01 0.00000000e+00 6.24191571e-01 7.45635335e-01 0.00000000e+00 6.28596165e-01 7.73889949e-01 0.00000000e+00 6.33000759e-01 8.02144564e-01 0.00000000e+00 6.37405353e-01 8.30399179e-01 0.00000000e+00 5.85542729e-01 6.60459493e-01 0.00000000e+00 5.90337261e-01 6.88749432e-01 0.00000000e+00 5.95131793e-01 7.17039372e-01 0.00000000e+00 5.99926325e-01 7.45329311e-01 0.00000000e+00 6.04720857e-01 7.73619251e-01 0.00000000e+00 6.09515389e-01 8.01909190e-01 0.00000000e+00 6.14309922e-01 8.30199130e-01 0.00000000e+00 5.60107670e-01 6.60047495e-01 0.00000000e+00 5.65292140e-01 6.88372759e-01 0.00000000e+00 5.70476610e-01 7.16698024e-01 0.00000000e+00 5.75661080e-01 7.45023288e-01 0.00000000e+00 5.80845550e-01 7.73348552e-01 0.00000000e+00 5.86030020e-01 8.01673817e-01 0.00000000e+00 5.91214490e-01 8.29999081e-01 0.00000000e+00 + 7.12718028e-01 6.62519481e-01 0.00000000e+00 6.87282968e-01 6.62107484e-01 0.00000000e+00 6.61847908e-01 6.61695486e-01 0.00000000e+00 6.36412849e-01 6.61283488e-01 0.00000000e+00 6.10977789e-01 6.60871491e-01 0.00000000e+00 5.85542729e-01 6.60459493e-01 0.00000000e+00 5.60107670e-01 6.60047495e-01 0.00000000e+00 7.11123167e-01 6.34485107e-01 0.00000000e+00 6.85358799e-01 6.34021511e-01 0.00000000e+00 6.59594431e-01 6.33557916e-01 0.00000000e+00 6.33830062e-01 6.33094320e-01 0.00000000e+00 6.08065694e-01 6.32630724e-01 0.00000000e+00 5.82301326e-01 6.32167128e-01 0.00000000e+00 5.56536958e-01 6.31703533e-01 0.00000000e+00 7.09528306e-01 6.06450733e-01 0.00000000e+00 6.83434629e-01 6.05935539e-01 0.00000000e+00 6.57340953e-01 6.05420345e-01 0.00000000e+00 6.31247276e-01 6.04905152e-01 0.00000000e+00 6.05153600e-01 6.04389958e-01 0.00000000e+00 5.79059923e-01 6.03874764e-01 0.00000000e+00 5.52966247e-01 6.03359570e-01 0.00000000e+00 7.07933445e-01 5.78416359e-01 0.00000000e+00 6.81510460e-01 5.77849567e-01 0.00000000e+00 6.55087475e-01 5.77282775e-01 0.00000000e+00 6.28664490e-01 5.76715983e-01 0.00000000e+00 6.02241505e-01 5.76149191e-01 0.00000000e+00 5.75818520e-01 5.75582399e-01 0.00000000e+00 5.49395535e-01 5.75015608e-01 0.00000000e+00 7.06338584e-01 5.50381984e-01 0.00000000e+00 6.79586290e-01 5.49763595e-01 0.00000000e+00 6.52833997e-01 5.49145205e-01 0.00000000e+00 6.26081704e-01 5.48526815e-01 0.00000000e+00 5.99329410e-01 5.47908425e-01 0.00000000e+00 5.72577117e-01 5.47290035e-01 0.00000000e+00 5.45824823e-01 5.46671645e-01 0.00000000e+00 7.04743723e-01 5.22347610e-01 0.00000000e+00 6.77662121e-01 5.21677622e-01 0.00000000e+00 6.50580519e-01 5.21007634e-01 0.00000000e+00 6.23498917e-01 5.20337646e-01 0.00000000e+00 5.96417316e-01 5.19667658e-01 0.00000000e+00 5.69335714e-01 5.18997671e-01 0.00000000e+00 5.42254112e-01 5.18327683e-01 0.00000000e+00 7.03148862e-01 4.94313236e-01 0.00000000e+00 6.75737952e-01 4.93591650e-01 0.00000000e+00 6.48327041e-01 4.92870064e-01 0.00000000e+00 6.20916131e-01 4.92148478e-01 0.00000000e+00 5.93505221e-01 4.91426892e-01 0.00000000e+00 5.66094311e-01 4.90705306e-01 0.00000000e+00 5.38683400e-01 4.89983720e-01 0.00000000e+00 + 3.99421772e-01 6.57977469e-01 0.00000000e+00 3.91053219e-01 6.29468608e-01 0.00000000e+00 3.82889373e-01 6.00900488e-01 0.00000000e+00 3.74986007e-01 5.72259260e-01 0.00000000e+00 3.67407923e-01 5.43530326e-01 0.00000000e+00 3.60232310e-01 5.14698339e-01 0.00000000e+00 3.53553482e-01 4.85747395e-01 0.00000000e+00 4.26202755e-01 6.58322473e-01 0.00000000e+00 4.18633843e-01 6.29841096e-01 0.00000000e+00 4.11235518e-01 6.01310335e-01 0.00000000e+00 4.04054262e-01 5.72718651e-01 0.00000000e+00 3.97144073e-01 5.44053879e-01 0.00000000e+00 3.90569277e-01 5.15303230e-01 0.00000000e+00 3.84408468e-01 4.86453449e-01 0.00000000e+00 4.52983738e-01 6.58667477e-01 0.00000000e+00 4.46214466e-01 6.30213583e-01 0.00000000e+00 4.39581664e-01 6.01720182e-01 0.00000000e+00 4.33122516e-01 5.73178042e-01 0.00000000e+00 4.26880223e-01 5.44577432e-01 0.00000000e+00 4.20906244e-01 5.15908120e-01 0.00000000e+00 4.15263455e-01 4.87159503e-01 0.00000000e+00 4.79764721e-01 6.59012482e-01 0.00000000e+00 4.73795089e-01 6.30586071e-01 0.00000000e+00 4.67927810e-01 6.02130029e-01 0.00000000e+00 4.62190771e-01 5.73637434e-01 0.00000000e+00 4.56616373e-01 5.45100986e-01 0.00000000e+00 4.51243211e-01 5.16513011e-01 0.00000000e+00 4.46118441e-01 4.87865557e-01 0.00000000e+00 5.06545704e-01 6.59357486e-01 0.00000000e+00 5.01375712e-01 6.30958558e-01 0.00000000e+00 4.96273955e-01 6.02539876e-01 0.00000000e+00 4.91259026e-01 5.74096825e-01 0.00000000e+00 4.86352523e-01 5.45624539e-01 0.00000000e+00 4.81580178e-01 5.17117901e-01 0.00000000e+00 4.76973428e-01 4.88571612e-01 0.00000000e+00 5.33326687e-01 6.59702491e-01 0.00000000e+00 5.28956335e-01 6.31331045e-01 0.00000000e+00 5.24620101e-01 6.02949723e-01 0.00000000e+00 5.20327280e-01 5.74556216e-01 0.00000000e+00 5.16088673e-01 5.46148092e-01 0.00000000e+00 5.11917145e-01 5.17722792e-01 0.00000000e+00 5.07828414e-01 4.89277666e-01 0.00000000e+00 5.60107670e-01 6.60047495e-01 0.00000000e+00 5.56536958e-01 6.31703533e-01 0.00000000e+00 5.52966247e-01 6.03359570e-01 0.00000000e+00 5.49395535e-01 5.75015608e-01 0.00000000e+00 5.45824823e-01 5.46671645e-01 0.00000000e+00 5.42254112e-01 5.18327683e-01 0.00000000e+00 5.38683400e-01 4.89983720e-01 0.00000000e+00 + 3.34147754e-01 3.09117834e-01 0.00000000e+00 3.68376037e-01 3.11159233e-01 0.00000000e+00 4.02604320e-01 3.13200631e-01 0.00000000e+00 4.36832603e-01 3.15242029e-01 0.00000000e+00 4.71060886e-01 3.17283427e-01 0.00000000e+00 5.05289169e-01 3.19324826e-01 0.00000000e+00 5.39517452e-01 3.21366224e-01 0.00000000e+00 3.33372554e-01 3.38810967e-01 0.00000000e+00 3.67706869e-01 3.40587329e-01 0.00000000e+00 4.02041184e-01 3.42363691e-01 0.00000000e+00 4.36375499e-01 3.44140053e-01 0.00000000e+00 4.70709814e-01 3.45916415e-01 0.00000000e+00 5.05044129e-01 3.47692778e-01 0.00000000e+00 5.39378443e-01 3.49469140e-01 0.00000000e+00 3.34795535e-01 3.68483563e-01 0.00000000e+00 3.68869518e-01 3.69998312e-01 0.00000000e+00 4.02943502e-01 3.71513061e-01 0.00000000e+00 4.37017485e-01 3.73027810e-01 0.00000000e+00 4.71091468e-01 3.74542558e-01 0.00000000e+00 5.05165452e-01 3.76057307e-01 0.00000000e+00 5.39239435e-01 3.77572056e-01 0.00000000e+00 3.37869220e-01 3.98033079e-01 0.00000000e+00 3.71407755e-01 3.99306728e-01 0.00000000e+00 4.04946289e-01 4.00580376e-01 0.00000000e+00 4.38484823e-01 4.01854025e-01 0.00000000e+00 4.72023358e-01 4.03127674e-01 0.00000000e+00 5.05561892e-01 4.04401323e-01 0.00000000e+00 5.39100426e-01 4.05674972e-01 0.00000000e+00 3.42193928e-01 4.27426732e-01 0.00000000e+00 3.74988510e-01 4.28485258e-01 0.00000000e+00 4.07783091e-01 4.29543784e-01 0.00000000e+00 4.40577673e-01 4.30602310e-01 0.00000000e+00 4.73372254e-01 4.31660836e-01 0.00000000e+00 5.06166836e-01 4.32719362e-01 0.00000000e+00 5.38961418e-01 4.33777888e-01 0.00000000e+00 3.47489779e-01 4.56661658e-01 0.00000000e+00 3.79378551e-01 4.57531516e-01 0.00000000e+00 4.11267322e-01 4.58401374e-01 0.00000000e+00 4.43156094e-01 4.59271231e-01 0.00000000e+00 4.75044866e-01 4.60141089e-01 0.00000000e+00 5.06933637e-01 4.61010946e-01 0.00000000e+00 5.38822409e-01 4.61880804e-01 0.00000000e+00 3.53553482e-01 4.85747395e-01 0.00000000e+00 3.84408468e-01 4.86453449e-01 0.00000000e+00 4.15263455e-01 4.87159503e-01 0.00000000e+00 4.46118441e-01 4.87865557e-01 0.00000000e+00 4.76973428e-01 4.88571612e-01 0.00000000e+00 5.07828414e-01 4.89277666e-01 0.00000000e+00 5.38683400e-01 4.89983720e-01 0.00000000e+00 + 7.05900860e-01 3.27444582e-01 0.00000000e+00 7.05442194e-01 3.55256024e-01 0.00000000e+00 7.04983527e-01 3.83067467e-01 0.00000000e+00 7.04524861e-01 4.10878909e-01 0.00000000e+00 7.04066195e-01 4.38690351e-01 0.00000000e+00 7.03607528e-01 4.66501794e-01 0.00000000e+00 7.03148862e-01 4.94313236e-01 0.00000000e+00 6.78170292e-01 3.26431522e-01 0.00000000e+00 6.77764902e-01 3.54291543e-01 0.00000000e+00 6.77359512e-01 3.82151565e-01 0.00000000e+00 6.76954122e-01 4.10011586e-01 0.00000000e+00 6.76548732e-01 4.37871607e-01 0.00000000e+00 6.76143342e-01 4.65731629e-01 0.00000000e+00 6.75737952e-01 4.93591650e-01 0.00000000e+00 6.50439724e-01 3.25418462e-01 0.00000000e+00 6.50087610e-01 3.53327063e-01 0.00000000e+00 6.49735497e-01 3.81235663e-01 0.00000000e+00 6.49383383e-01 4.09144263e-01 0.00000000e+00 6.49031269e-01 4.37052864e-01 0.00000000e+00 6.48679155e-01 4.64961464e-01 0.00000000e+00 6.48327041e-01 4.92870064e-01 0.00000000e+00 6.22709156e-01 3.24405403e-01 0.00000000e+00 6.22410319e-01 3.52362582e-01 0.00000000e+00 6.22111481e-01 3.80319761e-01 0.00000000e+00 6.21812644e-01 4.08276940e-01 0.00000000e+00 6.21513806e-01 4.36234120e-01 0.00000000e+00 6.21214969e-01 4.64191299e-01 0.00000000e+00 6.20916131e-01 4.92148478e-01 0.00000000e+00 5.94978588e-01 3.23392343e-01 0.00000000e+00 5.94733027e-01 3.51398101e-01 0.00000000e+00 5.94487466e-01 3.79403859e-01 0.00000000e+00 5.94241905e-01 4.07409618e-01 0.00000000e+00 5.93996343e-01 4.35415376e-01 0.00000000e+00 5.93750782e-01 4.63421134e-01 0.00000000e+00 5.93505221e-01 4.91426892e-01 0.00000000e+00 5.67248020e-01 3.22379283e-01 0.00000000e+00 5.67055735e-01 3.50433621e-01 0.00000000e+00 5.66863450e-01 3.78487958e-01 0.00000000e+00 5.66671165e-01 4.06542295e-01 0.00000000e+00 5.66478880e-01 4.34596632e-01 0.00000000e+00 5.66286596e-01 4.62650969e-01 0.00000000e+00 5.66094311e-01 4.90705306e-01 0.00000000e+00 5.39517452e-01 3.21366224e-01 0.00000000e+00 5.39378443e-01 3.49469140e-01 0.00000000e+00 5.39239435e-01 3.77572056e-01 0.00000000e+00 5.39100426e-01 4.05674972e-01 0.00000000e+00 5.38961418e-01 4.33777888e-01 0.00000000e+00 5.38822409e-01 4.61880804e-01 0.00000000e+00 5.38683400e-01 4.89983720e-01 0.00000000e+00 + 7.50000000e-01 0.00000000e+00 0.00000000e+00 7.45538107e-01 2.71360381e-02 0.00000000e+00 7.41076214e-01 5.42720762e-02 0.00000000e+00 7.36614321e-01 8.14081143e-02 0.00000000e+00 7.32152428e-01 1.08544152e-01 0.00000000e+00 7.27690536e-01 1.35680191e-01 0.00000000e+00 7.23228643e-01 1.62816229e-01 0.00000000e+00 7.29166667e-01 0.00000000e+00 0.00000000e+00 7.23963327e-01 2.69994887e-02 0.00000000e+00 7.18759988e-01 5.39989774e-02 0.00000000e+00 7.13556649e-01 8.09984661e-02 0.00000000e+00 7.08353310e-01 1.07997955e-01 0.00000000e+00 7.03149970e-01 1.34997443e-01 0.00000000e+00 6.97946631e-01 1.61996932e-01 0.00000000e+00 7.08333333e-01 0.00000000e+00 0.00000000e+00 7.02388548e-01 2.68629393e-02 0.00000000e+00 6.96443762e-01 5.37258785e-02 0.00000000e+00 6.90498976e-01 8.05888178e-02 0.00000000e+00 6.84554191e-01 1.07451757e-01 0.00000000e+00 6.78609405e-01 1.34314696e-01 0.00000000e+00 6.72664619e-01 1.61177636e-01 0.00000000e+00 6.87500000e-01 0.00000000e+00 0.00000000e+00 6.80813768e-01 2.67263899e-02 0.00000000e+00 6.74127536e-01 5.34527797e-02 0.00000000e+00 6.67441304e-01 8.01791696e-02 0.00000000e+00 6.60755072e-01 1.06905559e-01 0.00000000e+00 6.54068840e-01 1.33631949e-01 0.00000000e+00 6.47382608e-01 1.60358339e-01 0.00000000e+00 6.66666667e-01 0.00000000e+00 0.00000000e+00 6.59238988e-01 2.65898404e-02 0.00000000e+00 6.51811310e-01 5.31796809e-02 0.00000000e+00 6.44383632e-01 7.97695213e-02 0.00000000e+00 6.36955953e-01 1.06359362e-01 0.00000000e+00 6.29528275e-01 1.32949202e-01 0.00000000e+00 6.22100596e-01 1.59539043e-01 0.00000000e+00 6.45833333e-01 0.00000000e+00 0.00000000e+00 6.37664209e-01 2.64532910e-02 0.00000000e+00 6.29495084e-01 5.29065820e-02 0.00000000e+00 6.21325959e-01 7.93598730e-02 0.00000000e+00 6.13156834e-01 1.05813164e-01 0.00000000e+00 6.04987710e-01 1.32266455e-01 0.00000000e+00 5.96818585e-01 1.58719746e-01 0.00000000e+00 6.25000000e-01 0.00000000e+00 0.00000000e+00 6.16089429e-01 2.63167416e-02 0.00000000e+00 6.07178858e-01 5.26334832e-02 0.00000000e+00 5.98268287e-01 7.89502248e-02 0.00000000e+00 5.89357715e-01 1.05266966e-01 0.00000000e+00 5.80447144e-01 1.31583708e-01 0.00000000e+00 5.71536573e-01 1.57900450e-01 0.00000000e+00 + 7.05900860e-01 3.27444582e-01 0.00000000e+00 6.78170292e-01 3.26431522e-01 0.00000000e+00 6.50439724e-01 3.25418462e-01 0.00000000e+00 6.22709156e-01 3.24405403e-01 0.00000000e+00 5.94978588e-01 3.23392343e-01 0.00000000e+00 5.67248020e-01 3.22379283e-01 0.00000000e+00 5.39517452e-01 3.21366224e-01 0.00000000e+00 7.08788824e-01 3.00006523e-01 0.00000000e+00 6.81466349e-01 2.99025757e-01 0.00000000e+00 6.54143873e-01 2.98044991e-01 0.00000000e+00 6.26821398e-01 2.97064226e-01 0.00000000e+00 5.99498923e-01 2.96083460e-01 0.00000000e+00 5.72176448e-01 2.95102694e-01 0.00000000e+00 5.44853972e-01 2.94121928e-01 0.00000000e+00 7.11676788e-01 2.72568464e-01 0.00000000e+00 6.84762405e-01 2.71619992e-01 0.00000000e+00 6.57848023e-01 2.70671520e-01 0.00000000e+00 6.30933640e-01 2.69723048e-01 0.00000000e+00 6.04019258e-01 2.68774576e-01 0.00000000e+00 5.77104875e-01 2.67826104e-01 0.00000000e+00 5.50190492e-01 2.66877632e-01 0.00000000e+00 7.14564751e-01 2.45130405e-01 0.00000000e+00 6.88058462e-01 2.44214227e-01 0.00000000e+00 6.61552172e-01 2.43298049e-01 0.00000000e+00 6.35045882e-01 2.42381871e-01 0.00000000e+00 6.08539592e-01 2.41465693e-01 0.00000000e+00 5.82033302e-01 2.40549515e-01 0.00000000e+00 5.55527013e-01 2.39633337e-01 0.00000000e+00 7.17452715e-01 2.17692346e-01 0.00000000e+00 6.91354518e-01 2.16808462e-01 0.00000000e+00 6.65256321e-01 2.15924578e-01 0.00000000e+00 6.39158124e-01 2.15040694e-01 0.00000000e+00 6.13059927e-01 2.14156809e-01 0.00000000e+00 5.86961730e-01 2.13272925e-01 0.00000000e+00 5.60863533e-01 2.12389041e-01 0.00000000e+00 7.20340679e-01 1.90254287e-01 0.00000000e+00 6.94650575e-01 1.89402697e-01 0.00000000e+00 6.68960470e-01 1.88551107e-01 0.00000000e+00 6.43270366e-01 1.87699516e-01 0.00000000e+00 6.17580262e-01 1.86847926e-01 0.00000000e+00 5.91890157e-01 1.85996336e-01 0.00000000e+00 5.66200053e-01 1.85144745e-01 0.00000000e+00 7.23228643e-01 1.62816229e-01 0.00000000e+00 6.97946631e-01 1.61996932e-01 0.00000000e+00 6.72664619e-01 1.61177636e-01 0.00000000e+00 6.47382608e-01 1.60358339e-01 0.00000000e+00 6.22100596e-01 1.59539043e-01 0.00000000e+00 5.96818585e-01 1.58719746e-01 0.00000000e+00 5.71536573e-01 1.57900450e-01 0.00000000e+00 + 3.34147754e-01 3.09117834e-01 0.00000000e+00 3.37549641e-01 2.79612532e-01 0.00000000e+00 3.43848127e-01 2.50589439e-01 0.00000000e+00 3.53151296e-01 2.22386291e-01 0.00000000e+00 3.65325716e-01 1.95296950e-01 0.00000000e+00 3.79985460e-01 1.69464102e-01 0.00000000e+00 3.96563471e-01 1.44813573e-01 0.00000000e+00 3.68376037e-01 3.11159233e-01 0.00000000e+00 3.72100363e-01 2.82030765e-01 0.00000000e+00 3.78238521e-01 2.53304138e-01 0.00000000e+00 3.86880582e-01 2.25260798e-01 0.00000000e+00 3.97915352e-01 1.98145632e-01 0.00000000e+00 4.11021226e-01 1.72077542e-01 0.00000000e+00 4.25725655e-01 1.46994719e-01 0.00000000e+00 4.02604320e-01 3.13200631e-01 0.00000000e+00 4.06651085e-01 2.84448997e-01 0.00000000e+00 4.12628915e-01 2.56018837e-01 0.00000000e+00 4.20609868e-01 2.28135306e-01 0.00000000e+00 4.30504988e-01 2.00994313e-01 0.00000000e+00 4.42056991e-01 1.74690983e-01 0.00000000e+00 4.54887839e-01 1.49175865e-01 0.00000000e+00 4.36832603e-01 3.15242029e-01 0.00000000e+00 4.41201807e-01 2.86867230e-01 0.00000000e+00 4.47019310e-01 2.58733536e-01 0.00000000e+00 4.54339154e-01 2.31009814e-01 0.00000000e+00 4.63094624e-01 2.03842995e-01 0.00000000e+00 4.73092757e-01 1.77304424e-01 0.00000000e+00 4.84050022e-01 1.51357011e-01 0.00000000e+00 4.71060886e-01 3.17283427e-01 0.00000000e+00 4.75752528e-01 2.89285463e-01 0.00000000e+00 4.81409704e-01 2.61448235e-01 0.00000000e+00 4.88068441e-01 2.33884321e-01 0.00000000e+00 4.95684261e-01 2.06691677e-01 0.00000000e+00 5.04128522e-01 1.79917864e-01 0.00000000e+00 5.13212206e-01 1.53538157e-01 0.00000000e+00 5.05289169e-01 3.19324826e-01 0.00000000e+00 5.10303250e-01 2.91703695e-01 0.00000000e+00 5.15800098e-01 2.64162933e-01 0.00000000e+00 5.21797727e-01 2.36758829e-01 0.00000000e+00 5.28273897e-01 2.09540359e-01 0.00000000e+00 5.35164288e-01 1.82531305e-01 0.00000000e+00 5.42374390e-01 1.55719303e-01 0.00000000e+00 5.39517452e-01 3.21366224e-01 0.00000000e+00 5.44853972e-01 2.94121928e-01 0.00000000e+00 5.50190492e-01 2.66877632e-01 0.00000000e+00 5.55527013e-01 2.39633337e-01 0.00000000e+00 5.60863533e-01 2.12389041e-01 0.00000000e+00 5.66200053e-01 1.85144745e-01 0.00000000e+00 5.71536573e-01 1.57900450e-01 0.00000000e+00 + 5.00000000e-01 0.00000000e+00 0.00000000e+00 5.20833333e-01 0.00000000e+00 0.00000000e+00 5.41666667e-01 0.00000000e+00 0.00000000e+00 5.62500000e-01 0.00000000e+00 0.00000000e+00 5.83333333e-01 0.00000000e+00 0.00000000e+00 6.04166667e-01 0.00000000e+00 0.00000000e+00 6.25000000e-01 0.00000000e+00 0.00000000e+00 4.85529550e-01 2.59389955e-02 0.00000000e+00 5.07289530e-01 2.60019531e-02 0.00000000e+00 5.29049510e-01 2.60649108e-02 0.00000000e+00 5.50809489e-01 2.61278685e-02 0.00000000e+00 5.72569469e-01 2.61908262e-02 0.00000000e+00 5.94329449e-01 2.62537839e-02 0.00000000e+00 6.16089429e-01 2.63167416e-02 0.00000000e+00 4.69088674e-01 5.06808219e-02 0.00000000e+00 4.92103704e-01 5.10062654e-02 0.00000000e+00 5.15118735e-01 5.13317090e-02 0.00000000e+00 5.38133766e-01 5.16571525e-02 0.00000000e+00 5.61148796e-01 5.19825961e-02 0.00000000e+00 5.84163827e-01 5.23080396e-02 0.00000000e+00 6.07178858e-01 5.26334832e-02 0.00000000e+00 4.51320408e-01 7.44915160e-02 0.00000000e+00 4.75811721e-01 7.52346341e-02 0.00000000e+00 5.00303034e-01 7.59777522e-02 0.00000000e+00 5.24794347e-01 7.67208704e-02 0.00000000e+00 5.49285660e-01 7.74639885e-02 0.00000000e+00 5.73776973e-01 7.82071067e-02 0.00000000e+00 5.98268287e-01 7.89502248e-02 0.00000000e+00 4.32880446e-01 9.77883153e-02 0.00000000e+00 4.58959991e-01 9.90347571e-02 0.00000000e+00 4.85039536e-01 1.00281199e-01 0.00000000e+00 5.11119081e-01 1.01527641e-01 0.00000000e+00 5.37198626e-01 1.02774083e-01 0.00000000e+00 5.63278171e-01 1.04020525e-01 0.00000000e+00 5.89357715e-01 1.05266966e-01 0.00000000e+00 4.14413474e-01 1.21063811e-01 0.00000000e+00 4.42085753e-01 1.22817127e-01 0.00000000e+00 4.69758031e-01 1.24570443e-01 0.00000000e+00 4.97430309e-01 1.26323760e-01 0.00000000e+00 5.25102588e-01 1.28077076e-01 0.00000000e+00 5.52774866e-01 1.29830392e-01 0.00000000e+00 5.80447144e-01 1.31583708e-01 0.00000000e+00 3.96563471e-01 1.44813573e-01 0.00000000e+00 4.25725655e-01 1.46994719e-01 0.00000000e+00 4.54887839e-01 1.49175865e-01 0.00000000e+00 4.84050022e-01 1.51357011e-01 0.00000000e+00 5.13212206e-01 1.53538157e-01 0.00000000e+00 5.42374390e-01 1.55719303e-01 0.00000000e+00 5.71536573e-01 1.57900450e-01 0.00000000e+00 + 1.00000000e+00 1.00000000e+00 0.00000000e+00 9.79166667e-01 1.00000000e+00 0.00000000e+00 9.58333333e-01 1.00000000e+00 0.00000000e+00 9.37500000e-01 1.00000000e+00 0.00000000e+00 9.16666667e-01 1.00000000e+00 0.00000000e+00 8.95833333e-01 1.00000000e+00 0.00000000e+00 8.75000000e-01 1.00000000e+00 0.00000000e+00 1.00000000e+00 9.72222222e-01 0.00000000e+00 9.78909012e-01 9.72193723e-01 0.00000000e+00 9.57818024e-01 9.72165224e-01 0.00000000e+00 9.36727035e-01 9.72136724e-01 0.00000000e+00 9.15636047e-01 9.72108225e-01 0.00000000e+00 8.94545059e-01 9.72079726e-01 0.00000000e+00 8.73454071e-01 9.72051226e-01 0.00000000e+00 1.00000000e+00 9.44444444e-01 0.00000000e+00 9.78651357e-01 9.44387446e-01 0.00000000e+00 9.57302714e-01 9.44330447e-01 0.00000000e+00 9.35954071e-01 9.44273449e-01 0.00000000e+00 9.14605428e-01 9.44216450e-01 0.00000000e+00 8.93256784e-01 9.44159452e-01 0.00000000e+00 8.71908141e-01 9.44102453e-01 0.00000000e+00 1.00000000e+00 9.16666667e-01 0.00000000e+00 9.78393702e-01 9.16581169e-01 0.00000000e+00 9.56787404e-01 9.16495671e-01 0.00000000e+00 9.35181106e-01 9.16410173e-01 0.00000000e+00 9.13574808e-01 9.16324675e-01 0.00000000e+00 8.91968510e-01 9.16239177e-01 0.00000000e+00 8.70362212e-01 9.16153679e-01 0.00000000e+00 1.00000000e+00 8.88888889e-01 0.00000000e+00 9.78136047e-01 8.88774892e-01 0.00000000e+00 9.56272094e-01 8.88660895e-01 0.00000000e+00 9.34408141e-01 8.88546897e-01 0.00000000e+00 9.12544188e-01 8.88432900e-01 0.00000000e+00 8.90680236e-01 8.88318903e-01 0.00000000e+00 8.68816283e-01 8.88204906e-01 0.00000000e+00 1.00000000e+00 8.61111111e-01 0.00000000e+00 9.77878392e-01 8.60968615e-01 0.00000000e+00 9.55756784e-01 8.60826118e-01 0.00000000e+00 9.33635177e-01 8.60683622e-01 0.00000000e+00 9.11513569e-01 8.60541125e-01 0.00000000e+00 8.89391961e-01 8.60398629e-01 0.00000000e+00 8.67270353e-01 8.60256132e-01 0.00000000e+00 1.00000000e+00 8.33333333e-01 0.00000000e+00 9.77620737e-01 8.33162338e-01 0.00000000e+00 9.55241475e-01 8.32991342e-01 0.00000000e+00 9.32862212e-01 8.32820346e-01 0.00000000e+00 9.10482949e-01 8.32649350e-01 0.00000000e+00 8.88103687e-01 8.32478355e-01 0.00000000e+00 8.65724424e-01 8.32307359e-01 0.00000000e+00 + 7.50000000e-01 1.00000000e+00 0.00000000e+00 7.46631179e-01 9.71866562e-01 0.00000000e+00 7.43262359e-01 9.43733125e-01 0.00000000e+00 7.39893538e-01 9.15599687e-01 0.00000000e+00 7.36524718e-01 8.87466250e-01 0.00000000e+00 7.33155897e-01 8.59332812e-01 0.00000000e+00 7.29787077e-01 8.31199374e-01 0.00000000e+00 7.70833333e-01 1.00000000e+00 0.00000000e+00 7.67768328e-01 9.71897340e-01 0.00000000e+00 7.64703323e-01 9.43794680e-01 0.00000000e+00 7.61638317e-01 9.15692019e-01 0.00000000e+00 7.58573312e-01 8.87589359e-01 0.00000000e+00 7.55508307e-01 8.59486699e-01 0.00000000e+00 7.52443301e-01 8.31384039e-01 0.00000000e+00 7.91666667e-01 1.00000000e+00 0.00000000e+00 7.88905477e-01 9.71928117e-01 0.00000000e+00 7.86144286e-01 9.43856234e-01 0.00000000e+00 7.83383096e-01 9.15784351e-01 0.00000000e+00 7.80621906e-01 8.87712468e-01 0.00000000e+00 7.77860716e-01 8.59640586e-01 0.00000000e+00 7.75099526e-01 8.31568703e-01 0.00000000e+00 8.12500000e-01 1.00000000e+00 0.00000000e+00 8.10042625e-01 9.71958894e-01 0.00000000e+00 8.07585250e-01 9.43917789e-01 0.00000000e+00 8.05127875e-01 9.15876683e-01 0.00000000e+00 8.02670500e-01 8.87835578e-01 0.00000000e+00 8.00213125e-01 8.59794472e-01 0.00000000e+00 7.97755750e-01 8.31753367e-01 0.00000000e+00 8.33333333e-01 1.00000000e+00 0.00000000e+00 8.31179774e-01 9.71989672e-01 0.00000000e+00 8.29026214e-01 9.43979344e-01 0.00000000e+00 8.26872654e-01 9.15969015e-01 0.00000000e+00 8.24719094e-01 8.87958687e-01 0.00000000e+00 8.22565535e-01 8.59948359e-01 0.00000000e+00 8.20411975e-01 8.31938031e-01 0.00000000e+00 8.54166667e-01 1.00000000e+00 0.00000000e+00 8.52316922e-01 9.72020449e-01 0.00000000e+00 8.50467178e-01 9.44040898e-01 0.00000000e+00 8.48617433e-01 9.16061347e-01 0.00000000e+00 8.46767689e-01 8.88081797e-01 0.00000000e+00 8.44917944e-01 8.60102246e-01 0.00000000e+00 8.43068200e-01 8.32122695e-01 0.00000000e+00 8.75000000e-01 1.00000000e+00 0.00000000e+00 8.73454071e-01 9.72051226e-01 0.00000000e+00 8.71908141e-01 9.44102453e-01 0.00000000e+00 8.70362212e-01 9.16153679e-01 0.00000000e+00 8.68816283e-01 8.88204906e-01 0.00000000e+00 8.67270353e-01 8.60256132e-01 0.00000000e+00 8.65724424e-01 8.32307359e-01 0.00000000e+00 + 7.12718028e-01 6.62519481e-01 0.00000000e+00 7.36968498e-01 6.62887817e-01 0.00000000e+00 7.61218968e-01 6.63256153e-01 0.00000000e+00 7.85469439e-01 6.63624489e-01 0.00000000e+00 8.09719909e-01 6.63992824e-01 0.00000000e+00 8.33970380e-01 6.64361160e-01 0.00000000e+00 8.58220850e-01 6.64729496e-01 0.00000000e+00 7.15562869e-01 6.90632797e-01 0.00000000e+00 7.39547632e-01 6.90970521e-01 0.00000000e+00 7.63532395e-01 6.91308245e-01 0.00000000e+00 7.87517157e-01 6.91645968e-01 0.00000000e+00 8.11501920e-01 6.91983692e-01 0.00000000e+00 8.35486683e-01 6.92321416e-01 0.00000000e+00 8.59471446e-01 6.92659140e-01 0.00000000e+00 7.18407711e-01 7.18746112e-01 0.00000000e+00 7.42126766e-01 7.19053224e-01 0.00000000e+00 7.65845821e-01 7.19360336e-01 0.00000000e+00 7.89564876e-01 7.19667448e-01 0.00000000e+00 8.13283931e-01 7.19974560e-01 0.00000000e+00 8.37002986e-01 7.20281672e-01 0.00000000e+00 8.60722041e-01 7.20588784e-01 0.00000000e+00 7.21252552e-01 7.46859428e-01 0.00000000e+00 7.44705900e-01 7.47135928e-01 0.00000000e+00 7.68159247e-01 7.47412428e-01 0.00000000e+00 7.91612595e-01 7.47688928e-01 0.00000000e+00 8.15065942e-01 7.47965428e-01 0.00000000e+00 8.38519290e-01 7.48241928e-01 0.00000000e+00 8.61972637e-01 7.48518427e-01 0.00000000e+00 7.24097394e-01 7.74972743e-01 0.00000000e+00 7.47285034e-01 7.75218631e-01 0.00000000e+00 7.70472673e-01 7.75464519e-01 0.00000000e+00 7.93660313e-01 7.75710407e-01 0.00000000e+00 8.16847953e-01 7.75956295e-01 0.00000000e+00 8.40035593e-01 7.76202183e-01 0.00000000e+00 8.63223233e-01 7.76448071e-01 0.00000000e+00 7.26942235e-01 8.03086059e-01 0.00000000e+00 7.49864167e-01 8.03301335e-01 0.00000000e+00 7.72786100e-01 8.03516611e-01 0.00000000e+00 7.95708032e-01 8.03731887e-01 0.00000000e+00 8.18629964e-01 8.03947163e-01 0.00000000e+00 8.41551896e-01 8.04162439e-01 0.00000000e+00 8.64473828e-01 8.04377715e-01 0.00000000e+00 7.29787077e-01 8.31199374e-01 0.00000000e+00 7.52443301e-01 8.31384039e-01 0.00000000e+00 7.75099526e-01 8.31568703e-01 0.00000000e+00 7.97755750e-01 8.31753367e-01 0.00000000e+00 8.20411975e-01 8.31938031e-01 0.00000000e+00 8.43068200e-01 8.32122695e-01 0.00000000e+00 8.65724424e-01 8.32307359e-01 0.00000000e+00 + 1.00000000e+00 6.66666667e-01 0.00000000e+00 1.00000000e+00 6.94444444e-01 0.00000000e+00 1.00000000e+00 7.22222222e-01 0.00000000e+00 1.00000000e+00 7.50000000e-01 0.00000000e+00 1.00000000e+00 7.77777778e-01 0.00000000e+00 1.00000000e+00 8.05555556e-01 0.00000000e+00 1.00000000e+00 8.33333333e-01 0.00000000e+00 9.76370142e-01 6.66343805e-01 0.00000000e+00 9.76578574e-01 6.94146894e-01 0.00000000e+00 9.76787007e-01 7.21949982e-01 0.00000000e+00 9.76995439e-01 7.49753071e-01 0.00000000e+00 9.77203872e-01 7.77556160e-01 0.00000000e+00 9.77412305e-01 8.05359249e-01 0.00000000e+00 9.77620737e-01 8.33162338e-01 0.00000000e+00 9.52740283e-01 6.66020943e-01 0.00000000e+00 9.53157149e-01 6.93849343e-01 0.00000000e+00 9.53574014e-01 7.21677743e-01 0.00000000e+00 9.53990879e-01 7.49506142e-01 0.00000000e+00 9.54407744e-01 7.77334542e-01 0.00000000e+00 9.54824609e-01 8.05162942e-01 0.00000000e+00 9.55241475e-01 8.32991342e-01 0.00000000e+00 9.29110425e-01 6.65698081e-01 0.00000000e+00 9.29735723e-01 6.93551792e-01 0.00000000e+00 9.30361021e-01 7.21405503e-01 0.00000000e+00 9.30986318e-01 7.49259214e-01 0.00000000e+00 9.31611616e-01 7.77112925e-01 0.00000000e+00 9.32236914e-01 8.04966635e-01 0.00000000e+00 9.32862212e-01 8.32820346e-01 0.00000000e+00 9.05480567e-01 6.65375219e-01 0.00000000e+00 9.06314297e-01 6.93254241e-01 0.00000000e+00 9.07148028e-01 7.21133263e-01 0.00000000e+00 9.07981758e-01 7.49012285e-01 0.00000000e+00 9.08815488e-01 7.76891307e-01 0.00000000e+00 9.09649219e-01 8.04770329e-01 0.00000000e+00 9.10482949e-01 8.32649350e-01 0.00000000e+00 8.81850708e-01 6.65052358e-01 0.00000000e+00 8.82892871e-01 6.92956691e-01 0.00000000e+00 8.83935034e-01 7.20861023e-01 0.00000000e+00 8.84977197e-01 7.48765356e-01 0.00000000e+00 8.86019361e-01 7.76669689e-01 0.00000000e+00 8.87061524e-01 8.04574022e-01 0.00000000e+00 8.88103687e-01 8.32478355e-01 0.00000000e+00 8.58220850e-01 6.64729496e-01 0.00000000e+00 8.59471446e-01 6.92659140e-01 0.00000000e+00 8.60722041e-01 7.20588784e-01 0.00000000e+00 8.61972637e-01 7.48518427e-01 0.00000000e+00 8.63223233e-01 7.76448071e-01 0.00000000e+00 8.64473828e-01 8.04377715e-01 0.00000000e+00 8.65724424e-01 8.32307359e-01 0.00000000e+00 + 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 2.77777778e-02 0.00000000e+00 1.00000000e+00 5.55555556e-02 0.00000000e+00 1.00000000e+00 8.33333333e-02 0.00000000e+00 1.00000000e+00 1.11111111e-01 0.00000000e+00 1.00000000e+00 1.38888889e-01 0.00000000e+00 1.00000000e+00 1.66666667e-01 0.00000000e+00 9.79166667e-01 0.00000000e+00 0.00000000e+00 9.78854081e-01 2.77352430e-02 0.00000000e+00 9.78541495e-01 5.54704861e-02 0.00000000e+00 9.78228909e-01 8.32057291e-02 0.00000000e+00 9.77916323e-01 1.10940972e-01 0.00000000e+00 9.77603737e-01 1.38676215e-01 0.00000000e+00 9.77291152e-01 1.66411458e-01 0.00000000e+00 9.58333333e-01 0.00000000e+00 0.00000000e+00 9.57708162e-01 2.76927083e-02 0.00000000e+00 9.57082990e-01 5.53854166e-02 0.00000000e+00 9.56457818e-01 8.30781249e-02 0.00000000e+00 9.55832647e-01 1.10770833e-01 0.00000000e+00 9.55207475e-01 1.38463541e-01 0.00000000e+00 9.54582303e-01 1.66156250e-01 0.00000000e+00 9.37500000e-01 0.00000000e+00 0.00000000e+00 9.36562242e-01 2.76501735e-02 0.00000000e+00 9.35624485e-01 5.53003471e-02 0.00000000e+00 9.34686727e-01 8.29505206e-02 0.00000000e+00 9.33748970e-01 1.10600694e-01 0.00000000e+00 9.32811212e-01 1.38250868e-01 0.00000000e+00 9.31873455e-01 1.65901041e-01 0.00000000e+00 9.16666667e-01 0.00000000e+00 0.00000000e+00 9.15416323e-01 2.76076388e-02 0.00000000e+00 9.14165980e-01 5.52152776e-02 0.00000000e+00 9.12915637e-01 8.28229164e-02 0.00000000e+00 9.11665293e-01 1.10430555e-01 0.00000000e+00 9.10414950e-01 1.38038194e-01 0.00000000e+00 9.09164607e-01 1.65645833e-01 0.00000000e+00 8.95833333e-01 0.00000000e+00 0.00000000e+00 8.94270404e-01 2.75651040e-02 0.00000000e+00 8.92707475e-01 5.51302081e-02 0.00000000e+00 8.91144546e-01 8.26953121e-02 0.00000000e+00 8.89581617e-01 1.10260416e-01 0.00000000e+00 8.88018687e-01 1.37825520e-01 0.00000000e+00 8.86455758e-01 1.65390624e-01 0.00000000e+00 8.75000000e-01 0.00000000e+00 0.00000000e+00 8.73124485e-01 2.75225693e-02 0.00000000e+00 8.71248970e-01 5.50451386e-02 0.00000000e+00 8.69373455e-01 8.25677079e-02 0.00000000e+00 8.67497940e-01 1.10090277e-01 0.00000000e+00 8.65622425e-01 1.37612846e-01 0.00000000e+00 8.63746910e-01 1.65135416e-01 0.00000000e+00 + 1.00000000e+00 3.33333333e-01 0.00000000e+00 9.76035763e-01 3.32925985e-01 0.00000000e+00 9.52071525e-01 3.32518637e-01 0.00000000e+00 9.28107288e-01 3.32111289e-01 0.00000000e+00 9.04143050e-01 3.31703942e-01 0.00000000e+00 8.80178813e-01 3.31296594e-01 0.00000000e+00 8.56214575e-01 3.30889246e-01 0.00000000e+00 1.00000000e+00 3.05555556e-01 0.00000000e+00 9.76244994e-01 3.05173564e-01 0.00000000e+00 9.52489988e-01 3.04791573e-01 0.00000000e+00 9.28734982e-01 3.04409581e-01 0.00000000e+00 9.04979976e-01 3.04027590e-01 0.00000000e+00 8.81224970e-01 3.03645599e-01 0.00000000e+00 8.57469965e-01 3.03263607e-01 0.00000000e+00 1.00000000e+00 2.77777778e-01 0.00000000e+00 9.76454226e-01 2.77421143e-01 0.00000000e+00 9.52908451e-01 2.77064508e-01 0.00000000e+00 9.29362677e-01 2.76707873e-01 0.00000000e+00 9.05816902e-01 2.76351239e-01 0.00000000e+00 8.82271128e-01 2.75994604e-01 0.00000000e+00 8.58725354e-01 2.75637969e-01 0.00000000e+00 1.00000000e+00 2.50000000e-01 0.00000000e+00 9.76663457e-01 2.49668722e-01 0.00000000e+00 9.53326914e-01 2.49337444e-01 0.00000000e+00 9.29990371e-01 2.49006165e-01 0.00000000e+00 9.06653828e-01 2.48674887e-01 0.00000000e+00 8.83317286e-01 2.48343609e-01 0.00000000e+00 8.59980743e-01 2.48012331e-01 0.00000000e+00 1.00000000e+00 2.22222222e-01 0.00000000e+00 9.76872689e-01 2.21916301e-01 0.00000000e+00 9.53745377e-01 2.21610379e-01 0.00000000e+00 9.30618066e-01 2.21304457e-01 0.00000000e+00 9.07490755e-01 2.20998536e-01 0.00000000e+00 8.84363443e-01 2.20692614e-01 0.00000000e+00 8.61236132e-01 2.20386692e-01 0.00000000e+00 1.00000000e+00 1.94444444e-01 0.00000000e+00 9.77081920e-01 1.94163879e-01 0.00000000e+00 9.54163840e-01 1.93883314e-01 0.00000000e+00 9.31245760e-01 1.93602749e-01 0.00000000e+00 9.08327681e-01 1.93322184e-01 0.00000000e+00 8.85409601e-01 1.93041619e-01 0.00000000e+00 8.62491521e-01 1.92761054e-01 0.00000000e+00 1.00000000e+00 1.66666667e-01 0.00000000e+00 9.77291152e-01 1.66411458e-01 0.00000000e+00 9.54582303e-01 1.66156250e-01 0.00000000e+00 9.31873455e-01 1.65901041e-01 0.00000000e+00 9.09164607e-01 1.65645833e-01 0.00000000e+00 8.86455758e-01 1.65390624e-01 0.00000000e+00 8.63746910e-01 1.65135416e-01 0.00000000e+00 + 7.05900860e-01 3.27444582e-01 0.00000000e+00 7.08788824e-01 3.00006523e-01 0.00000000e+00 7.11676788e-01 2.72568464e-01 0.00000000e+00 7.14564751e-01 2.45130405e-01 0.00000000e+00 7.17452715e-01 2.17692346e-01 0.00000000e+00 7.20340679e-01 1.90254287e-01 0.00000000e+00 7.23228643e-01 1.62816229e-01 0.00000000e+00 7.30953146e-01 3.28018692e-01 0.00000000e+00 7.33569014e-01 3.00549370e-01 0.00000000e+00 7.36184882e-01 2.73080048e-01 0.00000000e+00 7.38800750e-01 2.45610726e-01 0.00000000e+00 7.41416618e-01 2.18141404e-01 0.00000000e+00 7.44032486e-01 1.90672082e-01 0.00000000e+00 7.46648354e-01 1.63202760e-01 0.00000000e+00 7.56005432e-01 3.28592803e-01 0.00000000e+00 7.58349204e-01 3.01092218e-01 0.00000000e+00 7.60692976e-01 2.73591632e-01 0.00000000e+00 7.63036749e-01 2.46091047e-01 0.00000000e+00 7.65380521e-01 2.18590462e-01 0.00000000e+00 7.67724293e-01 1.91089876e-01 0.00000000e+00 7.70068065e-01 1.63589291e-01 0.00000000e+00 7.81057718e-01 3.29166914e-01 0.00000000e+00 7.83129394e-01 3.01635065e-01 0.00000000e+00 7.85201071e-01 2.74103217e-01 0.00000000e+00 7.87272747e-01 2.46571368e-01 0.00000000e+00 7.89344423e-01 2.19039519e-01 0.00000000e+00 7.91416100e-01 1.91507671e-01 0.00000000e+00 7.93487776e-01 1.63975822e-01 0.00000000e+00 8.06110004e-01 3.29741024e-01 0.00000000e+00 8.07909584e-01 3.02177913e-01 0.00000000e+00 8.09709165e-01 2.74614801e-01 0.00000000e+00 8.11508746e-01 2.47051689e-01 0.00000000e+00 8.13308326e-01 2.19488577e-01 0.00000000e+00 8.15107907e-01 1.91925465e-01 0.00000000e+00 8.16907487e-01 1.64362353e-01 0.00000000e+00 8.31162290e-01 3.30315135e-01 0.00000000e+00 8.32689774e-01 3.02720760e-01 0.00000000e+00 8.34217259e-01 2.75126385e-01 0.00000000e+00 8.35744744e-01 2.47532010e-01 0.00000000e+00 8.37272229e-01 2.19937635e-01 0.00000000e+00 8.38799714e-01 1.92343260e-01 0.00000000e+00 8.40327199e-01 1.64748885e-01 0.00000000e+00 8.56214575e-01 3.30889246e-01 0.00000000e+00 8.57469965e-01 3.03263607e-01 0.00000000e+00 8.58725354e-01 2.75637969e-01 0.00000000e+00 8.59980743e-01 2.48012331e-01 0.00000000e+00 8.61236132e-01 2.20386692e-01 0.00000000e+00 8.62491521e-01 1.92761054e-01 0.00000000e+00 8.63746910e-01 1.65135416e-01 0.00000000e+00 + 7.50000000e-01 0.00000000e+00 0.00000000e+00 7.70833333e-01 0.00000000e+00 0.00000000e+00 7.91666667e-01 0.00000000e+00 0.00000000e+00 8.12500000e-01 0.00000000e+00 0.00000000e+00 8.33333333e-01 0.00000000e+00 0.00000000e+00 8.54166667e-01 0.00000000e+00 0.00000000e+00 8.75000000e-01 0.00000000e+00 0.00000000e+00 7.45538107e-01 2.71360381e-02 0.00000000e+00 7.66802503e-01 2.72004600e-02 0.00000000e+00 7.88066900e-01 2.72648818e-02 0.00000000e+00 8.09331296e-01 2.73293037e-02 0.00000000e+00 8.30595692e-01 2.73937256e-02 0.00000000e+00 8.51860089e-01 2.74581474e-02 0.00000000e+00 8.73124485e-01 2.75225693e-02 0.00000000e+00 7.41076214e-01 5.42720762e-02 0.00000000e+00 7.62771674e-01 5.44009199e-02 0.00000000e+00 7.84467133e-01 5.45297637e-02 0.00000000e+00 8.06162592e-01 5.46586074e-02 0.00000000e+00 8.27858051e-01 5.47874511e-02 0.00000000e+00 8.49553511e-01 5.49162949e-02 0.00000000e+00 8.71248970e-01 5.50451386e-02 0.00000000e+00 7.36614321e-01 8.14081143e-02 0.00000000e+00 7.58740844e-01 8.16013799e-02 0.00000000e+00 7.80867366e-01 8.17946455e-02 0.00000000e+00 8.02993888e-01 8.19879111e-02 0.00000000e+00 8.25120410e-01 8.21811767e-02 0.00000000e+00 8.47246933e-01 8.23744423e-02 0.00000000e+00 8.69373455e-01 8.25677079e-02 0.00000000e+00 7.32152428e-01 1.08544152e-01 0.00000000e+00 7.54710014e-01 1.08801840e-01 0.00000000e+00 7.77267599e-01 1.09059527e-01 0.00000000e+00 7.99825184e-01 1.09317215e-01 0.00000000e+00 8.22382769e-01 1.09574902e-01 0.00000000e+00 8.44940355e-01 1.09832590e-01 0.00000000e+00 8.67497940e-01 1.10090277e-01 0.00000000e+00 7.27690536e-01 1.35680191e-01 0.00000000e+00 7.50679184e-01 1.36002300e-01 0.00000000e+00 7.73667832e-01 1.36324409e-01 0.00000000e+00 7.96656480e-01 1.36646519e-01 0.00000000e+00 8.19645128e-01 1.36968628e-01 0.00000000e+00 8.42633777e-01 1.37290737e-01 0.00000000e+00 8.65622425e-01 1.37612846e-01 0.00000000e+00 7.23228643e-01 1.62816229e-01 0.00000000e+00 7.46648354e-01 1.63202760e-01 0.00000000e+00 7.70068065e-01 1.63589291e-01 0.00000000e+00 7.93487776e-01 1.63975822e-01 0.00000000e+00 8.16907487e-01 1.64362353e-01 0.00000000e+00 8.40327199e-01 1.64748885e-01 0.00000000e+00 8.63746910e-01 1.65135416e-01 0.00000000e+00 + 7.05900860e-01 3.27444582e-01 0.00000000e+00 7.30953146e-01 3.28018692e-01 0.00000000e+00 7.56005432e-01 3.28592803e-01 0.00000000e+00 7.81057718e-01 3.29166914e-01 0.00000000e+00 8.06110004e-01 3.29741024e-01 0.00000000e+00 8.31162290e-01 3.30315135e-01 0.00000000e+00 8.56214575e-01 3.30889246e-01 0.00000000e+00 7.05442194e-01 3.55256024e-01 0.00000000e+00 7.30523038e-01 3.55822583e-01 0.00000000e+00 7.55603883e-01 3.56389143e-01 0.00000000e+00 7.80684728e-01 3.56955702e-01 0.00000000e+00 8.05765573e-01 3.57522262e-01 0.00000000e+00 8.30846417e-01 3.58088821e-01 0.00000000e+00 8.55927262e-01 3.58655380e-01 0.00000000e+00 7.04983527e-01 3.83067467e-01 0.00000000e+00 7.30092931e-01 3.83626475e-01 0.00000000e+00 7.55202334e-01 3.84185483e-01 0.00000000e+00 7.80311738e-01 3.84744491e-01 0.00000000e+00 8.05421141e-01 3.85303499e-01 0.00000000e+00 8.30530545e-01 3.85862507e-01 0.00000000e+00 8.55639948e-01 3.86421515e-01 0.00000000e+00 7.04524861e-01 4.10878909e-01 0.00000000e+00 7.29662823e-01 4.11430366e-01 0.00000000e+00 7.54800786e-01 4.11981822e-01 0.00000000e+00 7.79938748e-01 4.12533279e-01 0.00000000e+00 8.05076710e-01 4.13084736e-01 0.00000000e+00 8.30214672e-01 4.13636193e-01 0.00000000e+00 8.55352635e-01 4.14187649e-01 0.00000000e+00 7.04066195e-01 4.38690351e-01 0.00000000e+00 7.29232716e-01 4.39234257e-01 0.00000000e+00 7.54399237e-01 4.39778162e-01 0.00000000e+00 7.79565758e-01 4.40322068e-01 0.00000000e+00 8.04732279e-01 4.40865973e-01 0.00000000e+00 8.29898800e-01 4.41409878e-01 0.00000000e+00 8.55065321e-01 4.41953784e-01 0.00000000e+00 7.03607528e-01 4.66501794e-01 0.00000000e+00 7.28802608e-01 4.67038148e-01 0.00000000e+00 7.53997688e-01 4.67574502e-01 0.00000000e+00 7.79192768e-01 4.68110856e-01 0.00000000e+00 8.04387848e-01 4.68647210e-01 0.00000000e+00 8.29582928e-01 4.69183564e-01 0.00000000e+00 8.54778008e-01 4.69719918e-01 0.00000000e+00 7.03148862e-01 4.94313236e-01 0.00000000e+00 7.28372501e-01 4.94842039e-01 0.00000000e+00 7.53596139e-01 4.95370842e-01 0.00000000e+00 7.78819778e-01 4.95899644e-01 0.00000000e+00 8.04043417e-01 4.96428447e-01 0.00000000e+00 8.29267055e-01 4.96957250e-01 0.00000000e+00 8.54490694e-01 4.97486053e-01 0.00000000e+00 + 1.00000000e+00 3.33333333e-01 0.00000000e+00 1.00000000e+00 3.61111111e-01 0.00000000e+00 1.00000000e+00 3.88888889e-01 0.00000000e+00 1.00000000e+00 4.16666667e-01 0.00000000e+00 1.00000000e+00 4.44444444e-01 0.00000000e+00 1.00000000e+00 4.72222222e-01 0.00000000e+00 1.00000000e+00 5.00000000e-01 0.00000000e+00 9.76035763e-01 3.32925985e-01 0.00000000e+00 9.75987877e-01 3.60701823e-01 0.00000000e+00 9.75939991e-01 3.88477660e-01 0.00000000e+00 9.75892106e-01 4.16253497e-01 0.00000000e+00 9.75844220e-01 4.44029334e-01 0.00000000e+00 9.75796335e-01 4.71805172e-01 0.00000000e+00 9.75748449e-01 4.99581009e-01 0.00000000e+00 9.52071525e-01 3.32518637e-01 0.00000000e+00 9.51975754e-01 3.60292534e-01 0.00000000e+00 9.51879983e-01 3.88066431e-01 0.00000000e+00 9.51784212e-01 4.15840328e-01 0.00000000e+00 9.51688440e-01 4.43614224e-01 0.00000000e+00 9.51592669e-01 4.71388121e-01 0.00000000e+00 9.51496898e-01 4.99162018e-01 0.00000000e+00 9.28107288e-01 3.32111289e-01 0.00000000e+00 9.27963631e-01 3.59883246e-01 0.00000000e+00 9.27819974e-01 3.87655202e-01 0.00000000e+00 9.27676317e-01 4.15427158e-01 0.00000000e+00 9.27532661e-01 4.43199114e-01 0.00000000e+00 9.27389004e-01 4.70971070e-01 0.00000000e+00 9.27245347e-01 4.98743026e-01 0.00000000e+00 9.04143050e-01 3.31703942e-01 0.00000000e+00 9.03951508e-01 3.59473957e-01 0.00000000e+00 9.03759966e-01 3.87243973e-01 0.00000000e+00 9.03568423e-01 4.15013988e-01 0.00000000e+00 9.03376881e-01 4.42784004e-01 0.00000000e+00 9.03185338e-01 4.70554020e-01 0.00000000e+00 9.02993796e-01 4.98324035e-01 0.00000000e+00 8.80178813e-01 3.31296594e-01 0.00000000e+00 8.79939385e-01 3.59064669e-01 0.00000000e+00 8.79699957e-01 3.86832744e-01 0.00000000e+00 8.79460529e-01 4.14600819e-01 0.00000000e+00 8.79221101e-01 4.42368894e-01 0.00000000e+00 8.78981673e-01 4.70136969e-01 0.00000000e+00 8.78742245e-01 4.97905044e-01 0.00000000e+00 8.56214575e-01 3.30889246e-01 0.00000000e+00 8.55927262e-01 3.58655380e-01 0.00000000e+00 8.55639948e-01 3.86421515e-01 0.00000000e+00 8.55352635e-01 4.14187649e-01 0.00000000e+00 8.55065321e-01 4.41953784e-01 0.00000000e+00 8.54778008e-01 4.69719918e-01 0.00000000e+00 8.54490694e-01 4.97486053e-01 0.00000000e+00 + 1.00000000e+00 6.66666667e-01 0.00000000e+00 9.76370142e-01 6.66343805e-01 0.00000000e+00 9.52740283e-01 6.66020943e-01 0.00000000e+00 9.29110425e-01 6.65698081e-01 0.00000000e+00 9.05480567e-01 6.65375219e-01 0.00000000e+00 8.81850708e-01 6.65052358e-01 0.00000000e+00 8.58220850e-01 6.64729496e-01 0.00000000e+00 1.00000000e+00 6.38888889e-01 0.00000000e+00 9.76266526e-01 6.38550006e-01 0.00000000e+00 9.52533052e-01 6.38211122e-01 0.00000000e+00 9.28799579e-01 6.37872239e-01 0.00000000e+00 9.05066105e-01 6.37533355e-01 0.00000000e+00 8.81332631e-01 6.37194472e-01 0.00000000e+00 8.57599157e-01 6.36855589e-01 0.00000000e+00 1.00000000e+00 6.11111111e-01 0.00000000e+00 9.76162911e-01 6.10756206e-01 0.00000000e+00 9.52325822e-01 6.10401301e-01 0.00000000e+00 9.28488732e-01 6.10046396e-01 0.00000000e+00 9.04651643e-01 6.09691491e-01 0.00000000e+00 8.80814554e-01 6.09336587e-01 0.00000000e+00 8.56977465e-01 6.08981682e-01 0.00000000e+00 1.00000000e+00 5.83333333e-01 0.00000000e+00 9.76059295e-01 5.82962407e-01 0.00000000e+00 9.52118591e-01 5.82591480e-01 0.00000000e+00 9.28177886e-01 5.82220554e-01 0.00000000e+00 9.04237181e-01 5.81849627e-01 0.00000000e+00 8.80296477e-01 5.81478701e-01 0.00000000e+00 8.56355772e-01 5.81107774e-01 0.00000000e+00 1.00000000e+00 5.55555556e-01 0.00000000e+00 9.75955680e-01 5.55168608e-01 0.00000000e+00 9.51911360e-01 5.54781659e-01 0.00000000e+00 9.27867040e-01 5.54394711e-01 0.00000000e+00 9.03822720e-01 5.54007763e-01 0.00000000e+00 8.79778399e-01 5.53620815e-01 0.00000000e+00 8.55734079e-01 5.53233867e-01 0.00000000e+00 1.00000000e+00 5.27777778e-01 0.00000000e+00 9.75852064e-01 5.27374808e-01 0.00000000e+00 9.51704129e-01 5.26971839e-01 0.00000000e+00 9.27556193e-01 5.26568869e-01 0.00000000e+00 9.03408258e-01 5.26165899e-01 0.00000000e+00 8.79260322e-01 5.25762930e-01 0.00000000e+00 8.55112387e-01 5.25359960e-01 0.00000000e+00 1.00000000e+00 5.00000000e-01 0.00000000e+00 9.75748449e-01 4.99581009e-01 0.00000000e+00 9.51496898e-01 4.99162018e-01 0.00000000e+00 9.27245347e-01 4.98743026e-01 0.00000000e+00 9.02993796e-01 4.98324035e-01 0.00000000e+00 8.78742245e-01 4.97905044e-01 0.00000000e+00 8.54490694e-01 4.97486053e-01 0.00000000e+00 + 7.12718028e-01 6.62519481e-01 0.00000000e+00 7.11123167e-01 6.34485107e-01 0.00000000e+00 7.09528306e-01 6.06450733e-01 0.00000000e+00 7.07933445e-01 5.78416359e-01 0.00000000e+00 7.06338584e-01 5.50381984e-01 0.00000000e+00 7.04743723e-01 5.22347610e-01 0.00000000e+00 7.03148862e-01 4.94313236e-01 0.00000000e+00 7.36968498e-01 6.62887817e-01 0.00000000e+00 7.35535832e-01 6.34880187e-01 0.00000000e+00 7.34103166e-01 6.06872558e-01 0.00000000e+00 7.32670499e-01 5.78864928e-01 0.00000000e+00 7.31237833e-01 5.50857298e-01 0.00000000e+00 7.29805167e-01 5.22849669e-01 0.00000000e+00 7.28372501e-01 4.94842039e-01 0.00000000e+00 7.61218968e-01 6.63256153e-01 0.00000000e+00 7.59948497e-01 6.35275268e-01 0.00000000e+00 7.58678025e-01 6.07294382e-01 0.00000000e+00 7.57407554e-01 5.79313497e-01 0.00000000e+00 7.56137082e-01 5.51332612e-01 0.00000000e+00 7.54866611e-01 5.23351727e-01 0.00000000e+00 7.53596139e-01 4.95370842e-01 0.00000000e+00 7.85469439e-01 6.63624489e-01 0.00000000e+00 7.84361162e-01 6.35670348e-01 0.00000000e+00 7.83252885e-01 6.07716207e-01 0.00000000e+00 7.82144608e-01 5.79762067e-01 0.00000000e+00 7.81036332e-01 5.51807926e-01 0.00000000e+00 7.79928055e-01 5.23853785e-01 0.00000000e+00 7.78819778e-01 4.95899644e-01 0.00000000e+00 8.09719909e-01 6.63992824e-01 0.00000000e+00 8.08773827e-01 6.36065428e-01 0.00000000e+00 8.07827745e-01 6.08138032e-01 0.00000000e+00 8.06881663e-01 5.80210636e-01 0.00000000e+00 8.05935581e-01 5.52283240e-01 0.00000000e+00 8.04989499e-01 5.24355843e-01 0.00000000e+00 8.04043417e-01 4.96428447e-01 0.00000000e+00 8.33970380e-01 6.64361160e-01 0.00000000e+00 8.33186492e-01 6.36460508e-01 0.00000000e+00 8.32402605e-01 6.08559857e-01 0.00000000e+00 8.31618717e-01 5.80659205e-01 0.00000000e+00 8.30834830e-01 5.52758553e-01 0.00000000e+00 8.30050943e-01 5.24857902e-01 0.00000000e+00 8.29267055e-01 4.96957250e-01 0.00000000e+00 8.58220850e-01 6.64729496e-01 0.00000000e+00 8.57599157e-01 6.36855589e-01 0.00000000e+00 8.56977465e-01 6.08981682e-01 0.00000000e+00 8.56355772e-01 5.81107774e-01 0.00000000e+00 8.55734079e-01 5.53233867e-01 0.00000000e+00 8.55112387e-01 5.25359960e-01 0.00000000e+00 8.54490694e-01 4.97486053e-01 0.00000000e+00 + + + E[8-11] + E[6-7,22-25] + E[0-1,12-15,32] + E[2-5] + E[26-31] + E[16-21] + Q[0-7] + Q[8-31] + + + C[409] + C[410] + + + + + + 12e49d1fdba69f4059fb63283125517d696b13c2 + Edwards-MacBook-Pro.local + 5.0.0 + 18-Jan-2021 11:52:31 + + basic.msh basic.xml:xml:uncompress + + + + + + + + + + + + + + + + + + + + + +

FinTime = 1

+

TimeStep = 0.001

+

NumSteps = FinTime/TimeStep

+

IO_CheckSteps = 9999

+

IO_InfoSteps = 100

+

advx = 1

+

advy = 0

+

k = 2*PI

+
+ + + + + + + + + + + + u + + + + C[401] + C[407] + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/solvers/ADRSolver/Tests/Movement_fixed_2D_varied.tst b/solvers/ADRSolver/Tests/Movement_fixed_2D_varied.tst new file mode 100644 index 0000000000000000000000000000000000000000..fc0ea9bc7ed1ad752166b1a3fab287179dac89bf --- /dev/null +++ b/solvers/ADRSolver/Tests/Movement_fixed_2D_varied.tst @@ -0,0 +1,21 @@ + + + 2D advection with 3 zones and 2 non-conformal interfaces (one curved) with 2 fields + ADRSolver + Movement_fixed_2D_varied.xml + + Movement_fixed_2D_varied.xml + + + + 3.98672e-06 + 2.70806e-06 + + + 6.90779e-05 + 1.78188e-05 + + + + + diff --git a/solvers/ADRSolver/Tests/Movement_fixed_2D_varied.xml b/solvers/ADRSolver/Tests/Movement_fixed_2D_varied.xml new file mode 100644 index 0000000000000000000000000000000000000000..92ac096d9dadb8530585178b1e3506f9ff22743d --- /dev/null +++ b/solvers/ADRSolver/Tests/Movement_fixed_2D_varied.xml @@ -0,0 +1,415 @@ + + + + + 0.00000000e+00 5.00000000e-01 0.00000000e+00 + 1.93601610e-01 4.93113337e-01 0.00000000e+00 + 2.15861429e-01 7.46548464e-01 0.00000000e+00 + 0.00000000e+00 7.50000000e-01 0.00000000e+00 + 3.53553482e-01 4.85747395e-01 0.00000000e+00 + 4.25285357e-01 7.43277689e-01 0.00000000e+00 + 5.00000000e-01 1.00000000e+00 0.00000000e+00 + 2.50000000e-01 1.00000000e+00 0.00000000e+00 + 0.00000000e+00 1.00000000e+00 0.00000000e+00 + 0.00000000e+00 2.50000000e-01 0.00000000e+00 + 2.04026934e-01 2.43120971e-01 0.00000000e+00 + 0.00000000e+00 0.00000000e+00 0.00000000e+00 + 2.50000000e-01 0.00000000e+00 0.00000000e+00 + 5.00000000e-01 0.00000000e+00 0.00000000e+00 + 3.53151292e-01 2.22386302e-01 0.00000000e+00 + 7.50000000e-01 1.00000000e+00 0.00000000e+00 + 6.25000000e-01 1.00000000e+00 0.00000000e+00 + 5.91214490e-01 8.29999081e-01 0.00000000e+00 + 7.29787077e-01 8.31199374e-01 0.00000000e+00 + 4.51425200e-01 8.28493982e-01 0.00000000e+00 + 3.99421772e-01 6.57977469e-01 0.00000000e+00 + 5.60107670e-01 6.60047495e-01 0.00000000e+00 + 7.12718028e-01 6.62519481e-01 0.00000000e+00 + 5.38683400e-01 4.89983720e-01 0.00000000e+00 + 7.03148862e-01 4.94313236e-01 0.00000000e+00 + 3.53553482e-01 4.85747395e-01 0.00000000e+00 + 3.34147754e-01 3.09117834e-01 0.00000000e+00 + 5.39517452e-01 3.21366224e-01 0.00000000e+00 + 7.05900860e-01 3.27444582e-01 0.00000000e+00 + 7.50000000e-01 0.00000000e+00 0.00000000e+00 + 7.23228643e-01 1.62816229e-01 0.00000000e+00 + 5.71536573e-01 1.57900450e-01 0.00000000e+00 + 6.25000000e-01 0.00000000e+00 0.00000000e+00 + 3.96563471e-01 1.44813573e-01 0.00000000e+00 + 1.00000000e+00 1.00000000e+00 0.00000000e+00 + 8.75000000e-01 1.00000000e+00 0.00000000e+00 + 8.65724424e-01 8.32307359e-01 0.00000000e+00 + 1.00000000e+00 8.33333333e-01 0.00000000e+00 + 8.58220850e-01 6.64729496e-01 0.00000000e+00 + 1.00000000e+00 6.66666667e-01 0.00000000e+00 + 1.00000000e+00 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 1.66666667e-01 0.00000000e+00 + 8.63746910e-01 1.65135416e-01 0.00000000e+00 + 8.75000000e-01 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 3.33333333e-01 0.00000000e+00 + 8.56214575e-01 3.30889246e-01 0.00000000e+00 + 8.54490694e-01 4.97486053e-01 0.00000000e+00 + 1.00000000e+00 5.00000000e-01 0.00000000e+00 + 1.25000000e+00 0.00000000e+00 0.00000000e+00 + 1.25000000e+00 5.00000000e-01 0.00000000e+00 + 1.00000000e+00 5.00000000e-01 0.00000000e+00 + 1.50000000e+00 0.00000000e+00 0.00000000e+00 + 1.50000000e+00 5.00000000e-01 0.00000000e+00 + 1.50000000e+00 1.00000000e+00 0.00000000e+00 + 1.25000000e+00 1.00000000e+00 0.00000000e+00 + + + 0 1 + 1 2 + 2 3 + 3 0 + 4 5 + 5 2 + 1 4 + 6 7 + 7 2 + 5 6 + 8 3 + 7 8 + 0 9 + 9 10 + 10 1 + 11 12 + 12 10 + 9 11 + 13 14 + 14 10 + 12 13 + 14 4 + 15 16 + 16 17 + 17 18 + 18 15 + 6 19 + 19 17 + 16 6 + 20 21 + 21 17 + 19 20 + 22 18 + 21 22 + 21 23 + 23 24 + 24 22 + 20 25 + 25 23 + 26 27 + 27 23 + 25 26 + 28 24 + 27 28 + 29 30 + 30 31 + 31 32 + 32 29 + 27 31 + 30 28 + 26 33 + 33 31 + 13 32 + 33 13 + 34 35 + 35 36 + 36 37 + 37 34 + 18 36 + 35 15 + 22 38 + 38 36 + 39 37 + 38 39 + 40 41 + 41 42 + 42 43 + 43 40 + 44 45 + 45 42 + 41 44 + 30 42 + 45 28 + 29 43 + 45 46 + 46 24 + 44 47 + 47 46 + 38 46 + 47 39 + 40 48 + 48 49 + 49 50 + 50 40 + 51 52 + 52 49 + 48 51 + 53 54 + 54 49 + 52 53 + 34 50 + 54 34 + + + 0 1 2 3 + 4 5 1 6 + 7 8 5 9 + 10 2 8 11 + 12 13 14 0 + 15 16 13 17 + 18 19 16 20 + 6 14 19 21 + 22 23 24 25 + 26 27 23 28 + 29 30 27 31 + 32 24 30 33 + 33 34 35 36 + 37 38 34 29 + 39 40 38 41 + 42 35 40 43 + 44 45 46 47 + 43 48 45 49 + 50 51 48 39 + 52 46 51 53 + 54 55 56 57 + 25 58 55 59 + 60 61 58 32 + 62 56 61 63 + 64 65 66 67 + 68 69 65 70 + 49 71 69 72 + 73 66 71 44 + 72 74 75 42 + 76 77 74 68 + 63 78 77 79 + 36 75 78 60 + 80 81 82 83 + 84 85 81 86 + 87 88 85 89 + 90 82 88 91 + + + 0.00000000e+00 5.00000000e-01 0.00000000e+00 3.22669351e-02 4.98852223e-01 0.00000000e+00 6.45338701e-02 4.97704446e-01 0.00000000e+00 9.68008052e-02 4.96556669e-01 0.00000000e+00 1.29067740e-01 4.95408891e-01 0.00000000e+00 1.61334675e-01 4.94261114e-01 0.00000000e+00 1.93601610e-01 4.93113337e-01 0.00000000e+00 + 1.93601610e-01 4.93113337e-01 0.00000000e+00 1.97311580e-01 5.35352525e-01 0.00000000e+00 2.01021550e-01 5.77591713e-01 0.00000000e+00 2.04731520e-01 6.19830901e-01 0.00000000e+00 2.08441489e-01 6.62070089e-01 0.00000000e+00 2.12151459e-01 7.04309277e-01 0.00000000e+00 2.15861429e-01 7.46548464e-01 0.00000000e+00 + 2.15861429e-01 7.46548464e-01 0.00000000e+00 1.79884524e-01 7.47123720e-01 0.00000000e+00 1.43907619e-01 7.47698976e-01 0.00000000e+00 1.07930715e-01 7.48274232e-01 0.00000000e+00 7.19538097e-02 7.48849488e-01 0.00000000e+00 3.59769048e-02 7.49424744e-01 0.00000000e+00 0.00000000e+00 7.50000000e-01 0.00000000e+00 + 0.00000000e+00 7.50000000e-01 0.00000000e+00 0.00000000e+00 7.08333333e-01 0.00000000e+00 0.00000000e+00 6.66666667e-01 0.00000000e+00 0.00000000e+00 6.25000000e-01 0.00000000e+00 0.00000000e+00 5.83333333e-01 0.00000000e+00 0.00000000e+00 5.41666667e-01 0.00000000e+00 0.00000000e+00 5.00000000e-01 0.00000000e+00 + 3.53553482e-01 4.85747395e-01 0.00000000e+00 3.63764381e-01 5.29128196e-01 0.00000000e+00 3.74986004e-01 5.72259249e-01 0.00000000e+00 3.86942397e-01 6.15192791e-01 0.00000000e+00 3.99421769e-01 6.57977458e-01 0.00000000e+00 4.12252078e-01 7.00658315e-01 0.00000000e+00 4.25285357e-01 7.43277689e-01 0.00000000e+00 + 4.25285357e-01 7.43277689e-01 0.00000000e+00 3.90381369e-01 7.43822818e-01 0.00000000e+00 3.55477381e-01 7.44367947e-01 0.00000000e+00 3.20573393e-01 7.44913077e-01 0.00000000e+00 2.85669405e-01 7.45458206e-01 0.00000000e+00 2.50765417e-01 7.46003335e-01 0.00000000e+00 2.15861429e-01 7.46548464e-01 0.00000000e+00 + 1.93601610e-01 4.93113337e-01 0.00000000e+00 2.20260256e-01 4.91885680e-01 0.00000000e+00 2.46918901e-01 4.90658023e-01 0.00000000e+00 2.73577546e-01 4.89430366e-01 0.00000000e+00 3.00236191e-01 4.88202709e-01 0.00000000e+00 3.26894837e-01 4.86975052e-01 0.00000000e+00 3.53553482e-01 4.85747395e-01 0.00000000e+00 + 5.00000000e-01 1.00000000e+00 0.00000000e+00 4.58333333e-01 1.00000000e+00 0.00000000e+00 4.16666667e-01 1.00000000e+00 0.00000000e+00 3.75000000e-01 1.00000000e+00 0.00000000e+00 3.33333333e-01 1.00000000e+00 0.00000000e+00 2.91666667e-01 1.00000000e+00 0.00000000e+00 2.50000000e-01 1.00000000e+00 0.00000000e+00 + 2.50000000e-01 1.00000000e+00 0.00000000e+00 2.44310238e-01 9.57758077e-01 0.00000000e+00 2.38620476e-01 9.15516155e-01 0.00000000e+00 2.32930715e-01 8.73274232e-01 0.00000000e+00 2.27240953e-01 8.31032310e-01 0.00000000e+00 2.21551191e-01 7.88790387e-01 0.00000000e+00 2.15861429e-01 7.46548464e-01 0.00000000e+00 + 4.25285357e-01 7.43277689e-01 0.00000000e+00 4.38386646e-01 7.85876221e-01 0.00000000e+00 4.51425199e-01 8.28493979e-01 0.00000000e+00 4.64266387e-01 8.71171562e-01 0.00000000e+00 4.76762956e-01 9.13951208e-01 0.00000000e+00 4.88744095e-01 9.56877857e-01 0.00000000e+00 5.00000000e-01 1.00000000e+00 0.00000000e+00 + 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 9.58333333e-01 0.00000000e+00 0.00000000e+00 9.16666667e-01 0.00000000e+00 0.00000000e+00 8.75000000e-01 0.00000000e+00 0.00000000e+00 8.33333333e-01 0.00000000e+00 0.00000000e+00 7.91666667e-01 0.00000000e+00 0.00000000e+00 7.50000000e-01 0.00000000e+00 + 2.50000000e-01 1.00000000e+00 0.00000000e+00 2.08333333e-01 1.00000000e+00 0.00000000e+00 1.66666667e-01 1.00000000e+00 0.00000000e+00 1.25000000e-01 1.00000000e+00 0.00000000e+00 8.33333333e-02 1.00000000e+00 0.00000000e+00 4.16666667e-02 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 + 0.00000000e+00 5.00000000e-01 0.00000000e+00 0.00000000e+00 4.58333333e-01 0.00000000e+00 0.00000000e+00 4.16666667e-01 0.00000000e+00 0.00000000e+00 3.75000000e-01 0.00000000e+00 0.00000000e+00 3.33333333e-01 0.00000000e+00 0.00000000e+00 2.91666667e-01 0.00000000e+00 0.00000000e+00 2.50000000e-01 0.00000000e+00 + 0.00000000e+00 2.50000000e-01 0.00000000e+00 3.40044890e-02 2.48853495e-01 0.00000000e+00 6.80089780e-02 2.47706990e-01 0.00000000e+00 1.02013467e-01 2.46560486e-01 0.00000000e+00 1.36017956e-01 2.45413981e-01 0.00000000e+00 1.70022445e-01 2.44267476e-01 0.00000000e+00 2.04026934e-01 2.43120971e-01 0.00000000e+00 + 2.04026934e-01 2.43120971e-01 0.00000000e+00 2.02289380e-01 2.84786366e-01 0.00000000e+00 2.00551826e-01 3.26451760e-01 0.00000000e+00 1.98814272e-01 3.68117154e-01 0.00000000e+00 1.97076718e-01 4.09782549e-01 0.00000000e+00 1.95339164e-01 4.51447943e-01 0.00000000e+00 1.93601610e-01 4.93113337e-01 0.00000000e+00 + 0.00000000e+00 0.00000000e+00 0.00000000e+00 4.16666667e-02 0.00000000e+00 0.00000000e+00 8.33333333e-02 0.00000000e+00 0.00000000e+00 1.25000000e-01 0.00000000e+00 0.00000000e+00 1.66666667e-01 0.00000000e+00 0.00000000e+00 2.08333333e-01 0.00000000e+00 0.00000000e+00 2.50000000e-01 0.00000000e+00 0.00000000e+00 + 2.50000000e-01 0.00000000e+00 0.00000000e+00 2.42337822e-01 4.05201619e-02 0.00000000e+00 2.34675645e-01 8.10403238e-02 0.00000000e+00 2.27013467e-01 1.21560486e-01 0.00000000e+00 2.19351289e-01 1.62080648e-01 0.00000000e+00 2.11689112e-01 2.02600809e-01 0.00000000e+00 2.04026934e-01 2.43120971e-01 0.00000000e+00 + 0.00000000e+00 2.50000000e-01 0.00000000e+00 0.00000000e+00 2.08333333e-01 0.00000000e+00 0.00000000e+00 1.66666667e-01 0.00000000e+00 0.00000000e+00 1.25000000e-01 0.00000000e+00 0.00000000e+00 8.33333333e-02 0.00000000e+00 0.00000000e+00 4.16666667e-02 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 + 5.00000000e-01 0.00000000e+00 0.00000000e+00 4.77516149e-01 3.84473378e-02 0.00000000e+00 4.51320409e-01 7.44915152e-02 0.00000000e+00 4.23610288e-01 1.09396998e-01 0.00000000e+00 3.96563474e-01 1.44813569e-01 0.00000000e+00 3.72377341e-01 1.82222775e-01 0.00000000e+00 3.53151292e-01 2.22386302e-01 0.00000000e+00 + 3.53151292e-01 2.22386302e-01 0.00000000e+00 3.28297232e-01 2.25842080e-01 0.00000000e+00 3.03443173e-01 2.29297859e-01 0.00000000e+00 2.78589113e-01 2.32753637e-01 0.00000000e+00 2.53735053e-01 2.36209415e-01 0.00000000e+00 2.28880994e-01 2.39665193e-01 0.00000000e+00 2.04026934e-01 2.43120971e-01 0.00000000e+00 + 3.53151292e-01 2.22386302e-01 0.00000000e+00 3.40325109e-01 2.65019871e-01 0.00000000e+00 3.34147748e-01 3.09117924e-01 0.00000000e+00 3.33846334e-01 3.53658633e-01 0.00000000e+00 3.37869219e-01 3.98033069e-01 0.00000000e+00 3.44734586e-01 4.42063566e-01 0.00000000e+00 3.53553482e-01 4.85747395e-01 0.00000000e+00 + 2.50000000e-01 0.00000000e+00 0.00000000e+00 2.91666667e-01 0.00000000e+00 0.00000000e+00 3.33333333e-01 0.00000000e+00 0.00000000e+00 3.75000000e-01 0.00000000e+00 0.00000000e+00 4.16666667e-01 0.00000000e+00 0.00000000e+00 4.58333333e-01 0.00000000e+00 0.00000000e+00 5.00000000e-01 0.00000000e+00 0.00000000e+00 + 7.50000000e-01 1.00000000e+00 0.00000000e+00 7.29166667e-01 1.00000000e+00 0.00000000e+00 7.08333333e-01 1.00000000e+00 0.00000000e+00 6.87500000e-01 1.00000000e+00 0.00000000e+00 6.66666667e-01 1.00000000e+00 0.00000000e+00 6.45833333e-01 1.00000000e+00 0.00000000e+00 6.25000000e-01 1.00000000e+00 0.00000000e+00 + 6.25000000e-01 1.00000000e+00 0.00000000e+00 6.04166667e-01 1.00000000e+00 0.00000000e+00 5.83333333e-01 1.00000000e+00 0.00000000e+00 5.62500000e-01 1.00000000e+00 0.00000000e+00 5.41666667e-01 1.00000000e+00 0.00000000e+00 5.20833333e-01 1.00000000e+00 0.00000000e+00 5.00000000e-01 1.00000000e+00 0.00000000e+00 + 6.25000000e-01 1.00000000e+00 0.00000000e+00 6.19369082e-01 9.71666513e-01 0.00000000e+00 6.13738163e-01 9.43333027e-01 0.00000000e+00 6.08107245e-01 9.14999540e-01 0.00000000e+00 6.02476327e-01 8.86666054e-01 0.00000000e+00 5.96845409e-01 8.58332567e-01 0.00000000e+00 5.91214490e-01 8.29999081e-01 0.00000000e+00 + 5.91214490e-01 8.29999081e-01 0.00000000e+00 6.14309922e-01 8.30199130e-01 0.00000000e+00 6.37405353e-01 8.30399179e-01 0.00000000e+00 6.60500784e-01 8.30599228e-01 0.00000000e+00 6.83596215e-01 8.30799277e-01 0.00000000e+00 7.06691646e-01 8.30999326e-01 0.00000000e+00 7.29787077e-01 8.31199374e-01 0.00000000e+00 + 7.29787077e-01 8.31199374e-01 0.00000000e+00 7.33155897e-01 8.59332812e-01 0.00000000e+00 7.36524718e-01 8.87466250e-01 0.00000000e+00 7.39893538e-01 9.15599687e-01 0.00000000e+00 7.43262359e-01 9.43733125e-01 0.00000000e+00 7.46631179e-01 9.71866562e-01 0.00000000e+00 7.50000000e-01 1.00000000e+00 0.00000000e+00 + 5.00000000e-01 1.00000000e+00 0.00000000e+00 4.92588523e-01 9.71227678e-01 0.00000000e+00 4.84819587e-01 9.42549727e-01 0.00000000e+00 4.76762956e-01 9.13951208e-01 0.00000000e+00 4.68478029e-01 8.85417950e-01 0.00000000e+00 4.60016645e-01 8.56936494e-01 0.00000000e+00 4.51425200e-01 8.28493982e-01 0.00000000e+00 + 4.51425200e-01 8.28493982e-01 0.00000000e+00 4.74723415e-01 8.28744831e-01 0.00000000e+00 4.98021630e-01 8.28995681e-01 0.00000000e+00 5.21319845e-01 8.29246531e-01 0.00000000e+00 5.44618060e-01 8.29497381e-01 0.00000000e+00 5.67916275e-01 8.29748231e-01 0.00000000e+00 5.91214490e-01 8.29999081e-01 0.00000000e+00 + 3.99421772e-01 6.57977469e-01 0.00000000e+00 4.26202755e-01 6.58322473e-01 0.00000000e+00 4.52983738e-01 6.58667477e-01 0.00000000e+00 4.79764721e-01 6.59012482e-01 0.00000000e+00 5.06545704e-01 6.59357486e-01 0.00000000e+00 5.33326687e-01 6.59702491e-01 0.00000000e+00 5.60107670e-01 6.60047495e-01 0.00000000e+00 + 5.60107670e-01 6.60047495e-01 0.00000000e+00 5.65292140e-01 6.88372759e-01 0.00000000e+00 5.70476610e-01 7.16698024e-01 0.00000000e+00 5.75661080e-01 7.45023288e-01 0.00000000e+00 5.80845550e-01 7.73348552e-01 0.00000000e+00 5.86030020e-01 8.01673817e-01 0.00000000e+00 5.91214490e-01 8.29999081e-01 0.00000000e+00 + 4.51425200e-01 8.28493982e-01 0.00000000e+00 4.42746292e-01 8.00078023e-01 0.00000000e+00 4.34020062e-01 7.71676555e-01 0.00000000e+00 4.25285357e-01 7.43277691e-01 0.00000000e+00 4.16580795e-01 7.14869577e-01 0.00000000e+00 4.07945811e-01 6.86440246e-01 0.00000000e+00 3.99421772e-01 6.57977469e-01 0.00000000e+00 + 7.12718028e-01 6.62519481e-01 0.00000000e+00 7.15562869e-01 6.90632797e-01 0.00000000e+00 7.18407711e-01 7.18746112e-01 0.00000000e+00 7.21252552e-01 7.46859428e-01 0.00000000e+00 7.24097394e-01 7.74972743e-01 0.00000000e+00 7.26942235e-01 8.03086059e-01 0.00000000e+00 7.29787077e-01 8.31199374e-01 0.00000000e+00 + 5.60107670e-01 6.60047495e-01 0.00000000e+00 5.85542729e-01 6.60459493e-01 0.00000000e+00 6.10977789e-01 6.60871491e-01 0.00000000e+00 6.36412849e-01 6.61283488e-01 0.00000000e+00 6.61847908e-01 6.61695486e-01 0.00000000e+00 6.87282968e-01 6.62107484e-01 0.00000000e+00 7.12718028e-01 6.62519481e-01 0.00000000e+00 + 5.60107670e-01 6.60047495e-01 0.00000000e+00 5.56536958e-01 6.31703533e-01 0.00000000e+00 5.52966247e-01 6.03359570e-01 0.00000000e+00 5.49395535e-01 5.75015608e-01 0.00000000e+00 5.45824823e-01 5.46671645e-01 0.00000000e+00 5.42254112e-01 5.18327683e-01 0.00000000e+00 5.38683400e-01 4.89983720e-01 0.00000000e+00 + 5.38683400e-01 4.89983720e-01 0.00000000e+00 5.66094311e-01 4.90705306e-01 0.00000000e+00 5.93505221e-01 4.91426892e-01 0.00000000e+00 6.20916131e-01 4.92148478e-01 0.00000000e+00 6.48327041e-01 4.92870064e-01 0.00000000e+00 6.75737952e-01 4.93591650e-01 0.00000000e+00 7.03148862e-01 4.94313236e-01 0.00000000e+00 + + 7.03148862e-01 4.94313236e-01 0.00000000e+00 + 7.04743723e-01 5.22347610e-01 0.00000000e+00 + 7.06338584e-01 5.50381984e-01 0.00000000e+00 + 7.07933445e-01 5.78416359e-01 0.00000000e+00 + 7.09528306e-01 6.06450733e-01 0.00000000e+00 + 7.11123167e-01 6.34485107e-01 0.00000000e+00 + 7.12718028e-01 6.62519481e-01 0.00000000e+00 + 3.99421772e-01 6.57977469e-01 0.00000000e+00 3.91053219e-01 6.29468608e-01 0.00000000e+00 3.82889373e-01 6.00900488e-01 0.00000000e+00 3.74986007e-01 5.72259260e-01 0.00000000e+00 3.67407923e-01 5.43530326e-01 0.00000000e+00 3.60232310e-01 5.14698339e-01 0.00000000e+00 3.53553482e-01 4.85747395e-01 0.00000000e+00 + 3.53553482e-01 4.85747395e-01 0.00000000e+00 3.84408468e-01 4.86453449e-01 0.00000000e+00 4.15263455e-01 4.87159503e-01 0.00000000e+00 4.46118441e-01 4.87865557e-01 0.00000000e+00 4.76973428e-01 4.88571612e-01 0.00000000e+00 5.07828414e-01 4.89277666e-01 0.00000000e+00 5.38683400e-01 4.89983720e-01 0.00000000e+00 + 3.34147754e-01 3.09117834e-01 0.00000000e+00 3.68376037e-01 3.11159233e-01 0.00000000e+00 4.02604320e-01 3.13200631e-01 0.00000000e+00 4.36832603e-01 3.15242029e-01 0.00000000e+00 4.71060886e-01 3.17283427e-01 0.00000000e+00 5.05289169e-01 3.19324826e-01 0.00000000e+00 5.39517452e-01 3.21366224e-01 0.00000000e+00 + 5.39517452e-01 3.21366224e-01 0.00000000e+00 5.39378443e-01 3.49469140e-01 0.00000000e+00 5.39239435e-01 3.77572056e-01 0.00000000e+00 5.39100426e-01 4.05674972e-01 0.00000000e+00 5.38961418e-01 4.33777888e-01 0.00000000e+00 5.38822409e-01 4.61880804e-01 0.00000000e+00 5.38683400e-01 4.89983720e-01 0.00000000e+00 + 3.53553482e-01 4.85747395e-01 0.00000000e+00 3.47489779e-01 4.56661658e-01 0.00000000e+00 3.42193928e-01 4.27426732e-01 0.00000000e+00 3.37869220e-01 3.98033079e-01 0.00000000e+00 3.34795535e-01 3.68483563e-01 0.00000000e+00 3.33372554e-01 3.38810967e-01 0.00000000e+00 3.34147754e-01 3.09117834e-01 0.00000000e+00 + 7.05900860e-01 3.27444582e-01 0.00000000e+00 7.05442194e-01 3.55256024e-01 0.00000000e+00 7.04983527e-01 3.83067467e-01 0.00000000e+00 7.04524861e-01 4.10878909e-01 0.00000000e+00 7.04066195e-01 4.38690351e-01 0.00000000e+00 7.03607528e-01 4.66501794e-01 0.00000000e+00 7.03148862e-01 4.94313236e-01 0.00000000e+00 + 5.39517452e-01 3.21366224e-01 0.00000000e+00 5.67248020e-01 3.22379283e-01 0.00000000e+00 5.94978588e-01 3.23392343e-01 0.00000000e+00 6.22709156e-01 3.24405403e-01 0.00000000e+00 6.50439724e-01 3.25418462e-01 0.00000000e+00 6.78170292e-01 3.26431522e-01 0.00000000e+00 7.05900860e-01 3.27444582e-01 0.00000000e+00 + 7.50000000e-01 0.00000000e+00 0.00000000e+00 7.45538107e-01 2.71360381e-02 0.00000000e+00 7.41076214e-01 5.42720762e-02 0.00000000e+00 7.36614321e-01 8.14081143e-02 0.00000000e+00 7.32152428e-01 1.08544152e-01 0.00000000e+00 7.27690536e-01 1.35680191e-01 0.00000000e+00 7.23228643e-01 1.62816229e-01 0.00000000e+00 + 7.23228643e-01 1.62816229e-01 0.00000000e+00 7.20340679e-01 1.90254287e-01 0.00000000e+00 7.17452715e-01 2.17692346e-01 0.00000000e+00 7.14564751e-01 2.45130405e-01 0.00000000e+00 7.11676788e-01 2.72568464e-01 0.00000000e+00 7.08788824e-01 3.00006523e-01 0.00000000e+00 7.05900860e-01 3.27444582e-01 0.00000000e+00 + 7.23228643e-01 1.62816229e-01 0.00000000e+00 6.97946631e-01 1.61996932e-01 0.00000000e+00 6.72664619e-01 1.61177636e-01 0.00000000e+00 6.47382608e-01 1.60358339e-01 0.00000000e+00 6.22100596e-01 1.59539043e-01 0.00000000e+00 5.96818585e-01 1.58719746e-01 0.00000000e+00 5.71536573e-01 1.57900450e-01 0.00000000e+00 + 5.39517452e-01 3.21366224e-01 0.00000000e+00 5.44853972e-01 2.94121928e-01 0.00000000e+00 5.50190492e-01 2.66877632e-01 0.00000000e+00 5.55527013e-01 2.39633337e-01 0.00000000e+00 5.60863533e-01 2.12389041e-01 0.00000000e+00 5.66200053e-01 1.85144745e-01 0.00000000e+00 5.71536573e-01 1.57900450e-01 0.00000000e+00 + 5.71536573e-01 1.57900450e-01 0.00000000e+00 5.80447144e-01 1.31583708e-01 0.00000000e+00 5.89357715e-01 1.05266966e-01 0.00000000e+00 5.98268287e-01 7.89502248e-02 0.00000000e+00 6.07178858e-01 5.26334832e-02 0.00000000e+00 6.16089429e-01 2.63167416e-02 0.00000000e+00 6.25000000e-01 0.00000000e+00 0.00000000e+00 + 6.25000000e-01 0.00000000e+00 0.00000000e+00 6.45833333e-01 0.00000000e+00 0.00000000e+00 6.66666667e-01 0.00000000e+00 0.00000000e+00 6.87500000e-01 0.00000000e+00 0.00000000e+00 7.08333333e-01 0.00000000e+00 0.00000000e+00 7.29166667e-01 0.00000000e+00 0.00000000e+00 7.50000000e-01 0.00000000e+00 0.00000000e+00 + 5.00000000e-01 0.00000000e+00 0.00000000e+00 5.20833333e-01 0.00000000e+00 0.00000000e+00 5.41666667e-01 0.00000000e+00 0.00000000e+00 5.62500000e-01 0.00000000e+00 0.00000000e+00 5.83333333e-01 0.00000000e+00 0.00000000e+00 6.04166667e-01 0.00000000e+00 0.00000000e+00 6.25000000e-01 0.00000000e+00 0.00000000e+00 + 3.34147754e-01 3.09117834e-01 0.00000000e+00 3.37549641e-01 2.79612532e-01 0.00000000e+00 3.43848127e-01 2.50589439e-01 0.00000000e+00 3.53151296e-01 2.22386291e-01 0.00000000e+00 3.65325716e-01 1.95296950e-01 0.00000000e+00 3.79985460e-01 1.69464102e-01 0.00000000e+00 3.96563471e-01 1.44813573e-01 0.00000000e+00 + 3.96563471e-01 1.44813573e-01 0.00000000e+00 4.25725655e-01 1.46994719e-01 0.00000000e+00 4.54887839e-01 1.49175865e-01 0.00000000e+00 4.84050022e-01 1.51357011e-01 0.00000000e+00 5.13212206e-01 1.53538157e-01 0.00000000e+00 5.42374390e-01 1.55719303e-01 0.00000000e+00 5.71536573e-01 1.57900450e-01 0.00000000e+00 + 3.96563471e-01 1.44813573e-01 0.00000000e+00 4.14413474e-01 1.21063811e-01 0.00000000e+00 4.32880446e-01 9.77883153e-02 0.00000000e+00 4.51320408e-01 7.44915160e-02 0.00000000e+00 4.69088674e-01 5.06808219e-02 0.00000000e+00 4.85529550e-01 2.59389955e-02 0.00000000e+00 5.00000000e-01 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 1.00000000e+00 0.00000000e+00 9.79166667e-01 1.00000000e+00 0.00000000e+00 9.58333333e-01 1.00000000e+00 0.00000000e+00 9.37500000e-01 1.00000000e+00 0.00000000e+00 9.16666667e-01 1.00000000e+00 0.00000000e+00 8.95833333e-01 1.00000000e+00 0.00000000e+00 8.75000000e-01 1.00000000e+00 0.00000000e+00 + 8.75000000e-01 1.00000000e+00 0.00000000e+00 8.54166667e-01 1.00000000e+00 0.00000000e+00 8.33333333e-01 1.00000000e+00 0.00000000e+00 8.12500000e-01 1.00000000e+00 0.00000000e+00 7.91666667e-01 1.00000000e+00 0.00000000e+00 7.70833333e-01 1.00000000e+00 0.00000000e+00 7.50000000e-01 1.00000000e+00 0.00000000e+00 + 8.75000000e-01 1.00000000e+00 0.00000000e+00 8.73454071e-01 9.72051226e-01 0.00000000e+00 8.71908141e-01 9.44102453e-01 0.00000000e+00 8.70362212e-01 9.16153679e-01 0.00000000e+00 8.68816283e-01 8.88204906e-01 0.00000000e+00 8.67270353e-01 8.60256132e-01 0.00000000e+00 8.65724424e-01 8.32307359e-01 0.00000000e+00 + 7.29787077e-01 8.31199374e-01 0.00000000e+00 7.52443301e-01 8.31384039e-01 0.00000000e+00 7.75099526e-01 8.31568703e-01 0.00000000e+00 7.97755750e-01 8.31753367e-01 0.00000000e+00 8.20411975e-01 8.31938031e-01 0.00000000e+00 8.43068200e-01 8.32122695e-01 0.00000000e+00 8.65724424e-01 8.32307359e-01 0.00000000e+00 + 8.65724424e-01 8.32307359e-01 0.00000000e+00 8.88103687e-01 8.32478355e-01 0.00000000e+00 9.10482949e-01 8.32649350e-01 0.00000000e+00 9.32862212e-01 8.32820346e-01 0.00000000e+00 9.55241475e-01 8.32991342e-01 0.00000000e+00 9.77620737e-01 8.33162338e-01 0.00000000e+00 1.00000000e+00 8.33333333e-01 0.00000000e+00 + 1.00000000e+00 8.33333333e-01 0.00000000e+00 1.00000000e+00 8.61111111e-01 0.00000000e+00 1.00000000e+00 8.88888889e-01 0.00000000e+00 1.00000000e+00 9.16666667e-01 0.00000000e+00 1.00000000e+00 9.44444444e-01 0.00000000e+00 1.00000000e+00 9.72222222e-01 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 + 7.12718028e-01 6.62519481e-01 0.00000000e+00 7.36968498e-01 6.62887817e-01 0.00000000e+00 7.61218968e-01 6.63256153e-01 0.00000000e+00 7.85469439e-01 6.63624489e-01 0.00000000e+00 8.09719909e-01 6.63992824e-01 0.00000000e+00 8.33970380e-01 6.64361160e-01 0.00000000e+00 8.58220850e-01 6.64729496e-01 0.00000000e+00 + 8.58220850e-01 6.64729496e-01 0.00000000e+00 8.59471446e-01 6.92659140e-01 0.00000000e+00 8.60722041e-01 7.20588784e-01 0.00000000e+00 8.61972637e-01 7.48518427e-01 0.00000000e+00 8.63223233e-01 7.76448071e-01 0.00000000e+00 8.64473828e-01 8.04377715e-01 0.00000000e+00 8.65724424e-01 8.32307359e-01 0.00000000e+00 + 1.00000000e+00 6.66666667e-01 0.00000000e+00 1.00000000e+00 6.94444444e-01 0.00000000e+00 1.00000000e+00 7.22222222e-01 0.00000000e+00 1.00000000e+00 7.50000000e-01 0.00000000e+00 1.00000000e+00 7.77777778e-01 0.00000000e+00 1.00000000e+00 8.05555556e-01 0.00000000e+00 1.00000000e+00 8.33333333e-01 0.00000000e+00 + 8.58220850e-01 6.64729496e-01 0.00000000e+00 8.81850708e-01 6.65052358e-01 0.00000000e+00 9.05480567e-01 6.65375219e-01 0.00000000e+00 9.29110425e-01 6.65698081e-01 0.00000000e+00 9.52740283e-01 6.66020943e-01 0.00000000e+00 9.76370142e-01 6.66343805e-01 0.00000000e+00 1.00000000e+00 6.66666667e-01 0.00000000e+00 + 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 2.77777778e-02 0.00000000e+00 1.00000000e+00 5.55555556e-02 0.00000000e+00 1.00000000e+00 8.33333333e-02 0.00000000e+00 1.00000000e+00 1.11111111e-01 0.00000000e+00 1.00000000e+00 1.38888889e-01 0.00000000e+00 1.00000000e+00 1.66666667e-01 0.00000000e+00 + 1.00000000e+00 1.66666667e-01 0.00000000e+00 9.77291152e-01 1.66411458e-01 0.00000000e+00 9.54582303e-01 1.66156250e-01 0.00000000e+00 9.31873455e-01 1.65901041e-01 0.00000000e+00 9.09164607e-01 1.65645833e-01 0.00000000e+00 8.86455758e-01 1.65390624e-01 0.00000000e+00 8.63746910e-01 1.65135416e-01 0.00000000e+00 + 7.23228643e-01 1.62816229e-01 0.00000000e+00 7.46648354e-01 1.63202760e-01 0.00000000e+00 7.70068065e-01 1.63589291e-01 0.00000000e+00 7.93487776e-01 1.63975822e-01 0.00000000e+00 8.16907487e-01 1.64362353e-01 0.00000000e+00 8.40327199e-01 1.64748885e-01 0.00000000e+00 8.63746910e-01 1.65135416e-01 0.00000000e+00 + 8.63746910e-01 1.65135416e-01 0.00000000e+00 8.65622425e-01 1.37612846e-01 0.00000000e+00 8.67497940e-01 1.10090277e-01 0.00000000e+00 8.69373455e-01 8.25677079e-02 0.00000000e+00 8.71248970e-01 5.50451386e-02 0.00000000e+00 8.73124485e-01 2.75225693e-02 0.00000000e+00 8.75000000e-01 0.00000000e+00 0.00000000e+00 + 8.75000000e-01 0.00000000e+00 0.00000000e+00 8.95833333e-01 0.00000000e+00 0.00000000e+00 9.16666667e-01 0.00000000e+00 0.00000000e+00 9.37500000e-01 0.00000000e+00 0.00000000e+00 9.58333333e-01 0.00000000e+00 0.00000000e+00 9.79166667e-01 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 + 7.50000000e-01 0.00000000e+00 0.00000000e+00 7.70833333e-01 0.00000000e+00 0.00000000e+00 7.91666667e-01 0.00000000e+00 0.00000000e+00 8.12500000e-01 0.00000000e+00 0.00000000e+00 8.33333333e-01 0.00000000e+00 0.00000000e+00 8.54166667e-01 0.00000000e+00 0.00000000e+00 8.75000000e-01 0.00000000e+00 0.00000000e+00 + 8.56214575e-01 3.30889246e-01 0.00000000e+00 8.57469965e-01 3.03263607e-01 0.00000000e+00 8.58725354e-01 2.75637969e-01 0.00000000e+00 8.59980743e-01 2.48012331e-01 0.00000000e+00 8.61236132e-01 2.20386692e-01 0.00000000e+00 8.62491521e-01 1.92761054e-01 0.00000000e+00 8.63746910e-01 1.65135416e-01 0.00000000e+00 + 8.56214575e-01 3.30889246e-01 0.00000000e+00 8.31162290e-01 3.30315135e-01 0.00000000e+00 8.06110004e-01 3.29741024e-01 0.00000000e+00 7.81057718e-01 3.29166914e-01 0.00000000e+00 7.56005432e-01 3.28592803e-01 0.00000000e+00 7.30953146e-01 3.28018692e-01 0.00000000e+00 7.05900860e-01 3.27444582e-01 0.00000000e+00 + 1.00000000e+00 1.66666667e-01 0.00000000e+00 1.00000000e+00 1.94444444e-01 0.00000000e+00 1.00000000e+00 2.22222222e-01 0.00000000e+00 1.00000000e+00 2.50000000e-01 0.00000000e+00 1.00000000e+00 2.77777778e-01 0.00000000e+00 1.00000000e+00 3.05555556e-01 0.00000000e+00 1.00000000e+00 3.33333333e-01 0.00000000e+00 + 8.56214575e-01 3.30889246e-01 0.00000000e+00 8.55927262e-01 3.58655380e-01 0.00000000e+00 8.55639948e-01 3.86421515e-01 0.00000000e+00 8.55352635e-01 4.14187649e-01 0.00000000e+00 8.55065321e-01 4.41953784e-01 0.00000000e+00 8.54778008e-01 4.69719918e-01 0.00000000e+00 8.54490694e-01 4.97486053e-01 0.00000000e+00 + 8.54490694e-01 4.97486053e-01 0.00000000e+00 8.29267055e-01 4.96957250e-01 0.00000000e+00 8.04043417e-01 4.96428447e-01 0.00000000e+00 7.78819778e-01 4.95899644e-01 0.00000000e+00 7.53596139e-01 4.95370842e-01 0.00000000e+00 7.28372501e-01 4.94842039e-01 0.00000000e+00 7.03148862e-01 4.94313236e-01 0.00000000e+00 + 8.58220850e-01 6.64729496e-01 0.00000000e+00 8.57599157e-01 6.36855589e-01 0.00000000e+00 8.56977465e-01 6.08981682e-01 0.00000000e+00 8.56355772e-01 5.81107774e-01 0.00000000e+00 8.55734079e-01 5.53233867e-01 0.00000000e+00 8.55112387e-01 5.25359960e-01 0.00000000e+00 8.54490694e-01 4.97486053e-01 0.00000000e+00 + 1.00000000e+00 3.33333333e-01 0.00000000e+00 1.00000000e+00 3.61111111e-01 0.00000000e+00 1.00000000e+00 3.88888889e-01 0.00000000e+00 1.00000000e+00 4.16666667e-01 0.00000000e+00 1.00000000e+00 4.44444444e-01 0.00000000e+00 1.00000000e+00 4.72222222e-01 0.00000000e+00 1.00000000e+00 5.00000000e-01 0.00000000e+00 + 1.00000000e+00 5.00000000e-01 0.00000000e+00 9.75748449e-01 4.99581009e-01 0.00000000e+00 9.51496898e-01 4.99162018e-01 0.00000000e+00 9.27245347e-01 4.98743026e-01 0.00000000e+00 9.02993796e-01 4.98324035e-01 0.00000000e+00 8.78742245e-01 4.97905044e-01 0.00000000e+00 8.54490694e-01 4.97486053e-01 0.00000000e+00 + 1.00000000e+00 5.00000000e-01 0.00000000e+00 1.00000000e+00 5.27777778e-01 0.00000000e+00 1.00000000e+00 5.55555556e-01 0.00000000e+00 1.00000000e+00 5.83333333e-01 0.00000000e+00 1.00000000e+00 6.11111111e-01 0.00000000e+00 1.00000000e+00 6.38888889e-01 0.00000000e+00 1.00000000e+00 6.66666667e-01 0.00000000e+00 + 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.04166667e+00 0.00000000e+00 0.00000000e+00 1.08333333e+00 0.00000000e+00 0.00000000e+00 1.12500000e+00 0.00000000e+00 0.00000000e+00 1.16666667e+00 0.00000000e+00 0.00000000e+00 1.20833333e+00 0.00000000e+00 0.00000000e+00 1.25000000e+00 0.00000000e+00 0.00000000e+00 + 1.25000000e+00 0.00000000e+00 0.00000000e+00 1.25000000e+00 8.33333333e-02 0.00000000e+00 1.25000000e+00 1.66666667e-01 0.00000000e+00 1.25000000e+00 2.50000000e-01 0.00000000e+00 1.25000000e+00 3.33333333e-01 0.00000000e+00 1.25000000e+00 4.16666667e-01 0.00000000e+00 1.25000000e+00 5.00000000e-01 0.00000000e+00 + 1.25000000e+00 5.00000000e-01 0.00000000e+00 1.20833333e+00 5.00000000e-01 0.00000000e+00 1.16666667e+00 5.00000000e-01 0.00000000e+00 1.12500000e+00 5.00000000e-01 0.00000000e+00 1.08333333e+00 5.00000000e-01 0.00000000e+00 1.04166667e+00 5.00000000e-01 0.00000000e+00 1.00000000e+00 5.00000000e-01 0.00000000e+00 + 1.00000000e+00 5.00000000e-01 0.00000000e+00 1.00000000e+00 4.16666667e-01 0.00000000e+00 1.00000000e+00 3.33333333e-01 0.00000000e+00 1.00000000e+00 2.50000000e-01 0.00000000e+00 1.00000000e+00 1.66666667e-01 0.00000000e+00 1.00000000e+00 8.33333333e-02 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 9.16666667e-01 0.00000000e+00 1.00000000e+00 8.33333333e-01 0.00000000e+00 1.00000000e+00 7.50000000e-01 0.00000000e+00 1.00000000e+00 6.66666667e-01 0.00000000e+00 1.00000000e+00 5.83333333e-01 0.00000000e+00 1.00000000e+00 5.00000000e-01 0.00000000e+00 + 1.50000000e+00 0.00000000e+00 0.00000000e+00 1.50000000e+00 8.33333333e-02 0.00000000e+00 1.50000000e+00 1.66666667e-01 0.00000000e+00 1.50000000e+00 2.50000000e-01 0.00000000e+00 1.50000000e+00 3.33333333e-01 0.00000000e+00 1.50000000e+00 4.16666667e-01 0.00000000e+00 1.50000000e+00 5.00000000e-01 0.00000000e+00 + 1.50000000e+00 5.00000000e-01 0.00000000e+00 1.45833333e+00 5.00000000e-01 0.00000000e+00 1.41666667e+00 5.00000000e-01 0.00000000e+00 1.37500000e+00 5.00000000e-01 0.00000000e+00 1.33333333e+00 5.00000000e-01 0.00000000e+00 1.29166667e+00 5.00000000e-01 0.00000000e+00 1.25000000e+00 5.00000000e-01 0.00000000e+00 + 1.50000000e+00 1.00000000e+00 0.00000000e+00 1.45833333e+00 1.00000000e+00 0.00000000e+00 1.41666667e+00 1.00000000e+00 0.00000000e+00 1.37500000e+00 1.00000000e+00 0.00000000e+00 1.33333333e+00 1.00000000e+00 0.00000000e+00 1.29166667e+00 1.00000000e+00 0.00000000e+00 1.25000000e+00 1.00000000e+00 0.00000000e+00 + 1.25000000e+00 1.00000000e+00 0.00000000e+00 1.25000000e+00 9.16666667e-01 0.00000000e+00 1.25000000e+00 8.33333333e-01 0.00000000e+00 1.25000000e+00 7.50000000e-01 0.00000000e+00 1.25000000e+00 6.66666667e-01 0.00000000e+00 1.25000000e+00 5.83333333e-01 0.00000000e+00 1.25000000e+00 5.00000000e-01 0.00000000e+00 + 1.25000000e+00 0.00000000e+00 0.00000000e+00 1.29166667e+00 0.00000000e+00 0.00000000e+00 1.33333333e+00 0.00000000e+00 0.00000000e+00 1.37500000e+00 0.00000000e+00 0.00000000e+00 1.41666667e+00 0.00000000e+00 0.00000000e+00 1.45833333e+00 0.00000000e+00 0.00000000e+00 1.50000000e+00 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 3.33333333e-01 0.00000000e+00 9.76035763e-01 3.32925985e-01 0.00000000e+00 9.52071525e-01 3.32518637e-01 0.00000000e+00 9.28107288e-01 3.32111289e-01 0.00000000e+00 9.04143050e-01 3.31703942e-01 0.00000000e+00 8.80178813e-01 3.31296594e-01 0.00000000e+00 8.56214575e-01 3.30889246e-01 0.00000000e+00 + 1.25000000e+00 1.00000000e+00 0.00000000e+00 1.20833333e+00 1.00000000e+00 0.00000000e+00 1.16666667e+00 1.00000000e+00 0.00000000e+00 1.12500000e+00 1.00000000e+00 0.00000000e+00 1.08333333e+00 1.00000000e+00 0.00000000e+00 1.04166667e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 + 1.50000000e+00 5.00000000e-01 0.00000000e+00 1.50000000e+00 5.83333333e-01 0.00000000e+00 1.50000000e+00 6.66666667e-01 0.00000000e+00 1.50000000e+00 7.50000000e-01 0.00000000e+00 1.50000000e+00 8.33333333e-01 0.00000000e+00 1.50000000e+00 9.16666667e-01 0.00000000e+00 1.50000000e+00 1.00000000e+00 0.00000000e+00 + + + E[10,3,12,17] + E[84,89] + E[7,11,54,59,22,28,87,91] + E[15,20,52,47,73,67,80,86] + E[18,21,4,9] + E[26,31,37,41,50,53] + E[64,70,76,79,62,57] + E[90,83] + Q[0-7] + Q[8-31] + Q[32-35] + + + C[409] + C[410] + C[411] + + + + + refs/heads/feature/Moving-geometry + cfa86575403703d9a2872df9aeea74e407963066 + Edwards-MacBook-Pro.local + 4.5.0 + 05-Jun-2019 15:22:16 + + basic.msh basic.xml:xml:uncompress + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

FinTime = 1

+

TimeStep = 0.001

+

NumSteps = FinTime/TimeStep

+

IO_CheckSteps = 9999

+

IO_InfoSteps = 100

+

advx = 1

+

advy = 1

+

k = PI

+
+ + + + + + + + + + + + u + v + + + + C[401] + C[402] + C[403] + C[404] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/solvers/ADRSolver/Tests/Movement_fixed_2D_varied_par.tst b/solvers/ADRSolver/Tests/Movement_fixed_2D_varied_par.tst new file mode 100644 index 0000000000000000000000000000000000000000..868992abdd857d11c52a400930892399645d40d5 --- /dev/null +++ b/solvers/ADRSolver/Tests/Movement_fixed_2D_varied_par.tst @@ -0,0 +1,22 @@ + + + 2D advection with 3 zones and 2 non-conformal interfaces (one curved) with 2 fields + ADRSolver + Movement_fixed_2D_varied.xml + 4 + + Movement_fixed_2D_varied.xml + + + + 3.98672e-06 + 2.70806e-06 + + + 6.90779e-05 + 1.78188e-05 + + + + + diff --git a/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex41.tst b/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex41.tst new file mode 100644 index 0000000000000000000000000000000000000000..7bc74ba1b0f5a33156801eff55b0e2f0c1c0ccf9 --- /dev/null +++ b/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex41.tst @@ -0,0 +1,19 @@ + + + 3D advection with 2 zones and 1 non-conformal interfaces with dirichlet BCs on hexes + ADRSolver + Movement_fixed_3D_Hex41.xml + + Movement_fixed_3D_Hex41.xml + + + + 5.4459e-06 + + + 3.65216e-05 + + + + + diff --git a/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex41.xml b/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex41.xml new file mode 100644 index 0000000000000000000000000000000000000000..f612f7d2f4cbea3345bad510d88429a26b267c83 --- /dev/null +++ b/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex41.xml @@ -0,0 +1,214 @@ + + + + + 0.00000000e+00 0.00000000e+00 5.00000000e-01 + 5.00000000e-01 0.00000000e+00 5.00000000e-01 + 5.00000000e-01 0.00000000e+00 0.00000000e+00 + 0.00000000e+00 0.00000000e+00 0.00000000e+00 + 0.00000000e+00 5.00000000e-01 5.00000000e-01 + 5.00000000e-01 5.00000000e-01 5.00000000e-01 + 5.00000000e-01 5.00000000e-01 0.00000000e+00 + 0.00000000e+00 5.00000000e-01 0.00000000e+00 + 0.00000000e+00 1.00000000e+00 5.00000000e-01 + 5.00000000e-01 1.00000000e+00 5.00000000e-01 + 5.00000000e-01 1.00000000e+00 0.00000000e+00 + 0.00000000e+00 1.00000000e+00 0.00000000e+00 + 0.00000000e+00 0.00000000e+00 1.00000000e+00 + 5.00000000e-01 0.00000000e+00 1.00000000e+00 + 0.00000000e+00 5.00000000e-01 1.00000000e+00 + 5.00000000e-01 5.00000000e-01 1.00000000e+00 + 0.00000000e+00 1.00000000e+00 1.00000000e+00 + 5.00000000e-01 1.00000000e+00 1.00000000e+00 + + 5.00000000e-01 0.00000000e+00 1.00000000e+00 + 1.00000000e+00 0.00000000e+00 1.00000000e+00 + 1.00000000e+00 0.00000000e+00 0.00000000e+00 + 5.00000000e-01 0.00000000e+00 0.00000000e+00 + 5.00000000e-01 1.00000000e+00 1.00000000e+00 + 1.00000000e+00 1.00000000e+00 1.00000000e+00 + 1.00000000e+00 1.00000000e+00 0.00000000e+00 + 5.00000000e-01 1.00000000e+00 0.00000000e+00 + + + 0 1 + 1 2 + 2 3 + 3 0 + 0 4 + 1 5 + 2 6 + 3 7 + 4 5 + 5 6 + 6 7 + 7 4 + 4 8 + 5 9 + 6 10 + 7 11 + 8 9 + 9 10 + 10 11 + 11 8 + 12 13 + 13 1 + 0 12 + 12 14 + 13 15 + 14 15 + 15 5 + 4 14 + 14 16 + 15 17 + 16 17 + 17 9 + 8 16 + + 18 19 + 19 20 + 20 21 + 21 18 + 18 22 + 19 23 + 20 24 + 21 25 + 22 23 + 23 24 + 24 25 + 25 22 + + + 0 1 2 3 + 0 5 8 4 + 1 6 9 5 + 2 6 10 7 + 3 7 11 4 + 8 9 10 11 + 8 13 16 12 + 9 14 17 13 + 10 14 18 15 + 11 15 19 12 + 16 17 18 19 + 20 21 0 22 + 20 24 25 23 + 21 5 26 24 + 22 4 27 23 + 25 26 8 27 + 25 29 30 28 + 26 13 31 29 + 27 12 32 28 + 30 31 16 32 + + 33 34 35 36 + 33 38 41 37 + 34 39 42 38 + 35 39 43 40 + 36 40 44 37 + 41 42 43 44 + + + 0 1 2 3 4 5 + 5 6 7 8 9 10 + 11 12 13 1 14 15 + 15 16 17 6 18 19 + + 20 21 22 23 24 25 + + + + F[0,3-4,8-12,14-16,18-19] + F[20-23,25] + + F[2,7,13,17] + F[24] + + H[0-3] + H[4] + + + + C[10] + C[11] + + + + + refs/heads/feature/Moving-geometry + 4010859a4dd7218c178588a6f7de92227c605093 + Edwards-MacBook-Pro.local + 5.0.0 + 24-Jul-2020 12:01:28 + + cube.msh cube.xml:xml:uncompress + + + + + + + + + + + + + + + + + + + + + +

FinTime = 0.2

+

TimeStep = 0.001

+

NumSteps = FinTime/TimeStep

+

IO_CheckSteps = 9999

+

IO_InfoSteps = 100

+

advx = 1

+

advy = 1

+

advz = 1

+

k = 2*PI

+
+ + + + + + + + + + + + u + + + + C[1,2] + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex41_par.tst b/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex41_par.tst new file mode 100644 index 0000000000000000000000000000000000000000..1f8b2cd6792832ef7fbce73e9572c6ce234c24bc --- /dev/null +++ b/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex41_par.tst @@ -0,0 +1,20 @@ + + + 3D advection with 2 zones and 1 non-conformal interfaces with dirichlet BCs on hexes on 4 processes + ADRSolver + Movement_fixed_3D_Hex41.xml + 4 + + Movement_fixed_3D_Hex41.xml + + + + 5.43568e-06 + + + 3.57418e-05 + + + + + diff --git a/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex_3zones_Periodic_par.tst b/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex_3zones_Periodic_par.tst new file mode 100644 index 0000000000000000000000000000000000000000..d2c3adf483092650daecd610589e34208f9c986a --- /dev/null +++ b/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex_3zones_Periodic_par.tst @@ -0,0 +1,20 @@ + + + 3D advection with 3 zones and 2 non-conformal interfaces with periodic BCs on hexes on 4 processes + ADRSolver + Movement_fixed_3D_Hex_3zones_Periodic_par.xml + 4 + + Movement_fixed_3D_Hex_3zones_Periodic_par.xml + + + + 1.58599e-06 + + + 3.03816e-05 + + + + + diff --git a/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex_3zones_Periodic_par.xml b/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex_3zones_Periodic_par.xml new file mode 100644 index 0000000000000000000000000000000000000000..91a323d2725c4c643cdd864337aeae6db883b729 --- /dev/null +++ b/solvers/ADRSolver/Tests/Movement_fixed_3D_Hex_3zones_Periodic_par.xml @@ -0,0 +1,5990 @@ + + + + + 0.00000000e+00 0.00000000e+00 0.00000000e+00 + 1.25000000e-01 0.00000000e+00 0.00000000e+00 + 1.25000000e-01 1.25000000e-01 0.00000000e+00 + 0.00000000e+00 1.25000000e-01 0.00000000e+00 + 0.00000000e+00 0.00000000e+00 1.25000000e-01 + 1.25000000e-01 0.00000000e+00 1.25000000e-01 + 1.25000000e-01 1.25000000e-01 1.25000000e-01 + 0.00000000e+00 1.25000000e-01 1.25000000e-01 + 0.00000000e+00 0.00000000e+00 2.50000000e-01 + 1.25000000e-01 0.00000000e+00 2.50000000e-01 + 1.25000000e-01 1.25000000e-01 2.50000000e-01 + 0.00000000e+00 1.25000000e-01 2.50000000e-01 + 0.00000000e+00 0.00000000e+00 3.75000000e-01 + 1.25000000e-01 0.00000000e+00 3.75000000e-01 + 1.25000000e-01 1.25000000e-01 3.75000000e-01 + 0.00000000e+00 1.25000000e-01 3.75000000e-01 + 1.25000000e-01 2.50000000e-01 0.00000000e+00 + 0.00000000e+00 2.50000000e-01 0.00000000e+00 + 1.25000000e-01 2.50000000e-01 1.25000000e-01 + 0.00000000e+00 2.50000000e-01 1.25000000e-01 + 1.25000000e-01 2.50000000e-01 2.50000000e-01 + 0.00000000e+00 2.50000000e-01 2.50000000e-01 + 1.25000000e-01 2.50000000e-01 3.75000000e-01 + 0.00000000e+00 2.50000000e-01 3.75000000e-01 + 1.25000000e-01 3.75000000e-01 0.00000000e+00 + 0.00000000e+00 3.75000000e-01 0.00000000e+00 + 1.25000000e-01 3.75000000e-01 1.25000000e-01 + 0.00000000e+00 3.75000000e-01 1.25000000e-01 + 1.25000000e-01 3.75000000e-01 2.50000000e-01 + 0.00000000e+00 3.75000000e-01 2.50000000e-01 + 1.25000000e-01 3.75000000e-01 3.75000000e-01 + 0.00000000e+00 3.75000000e-01 3.75000000e-01 + 1.25000000e-01 5.00000000e-01 0.00000000e+00 + 0.00000000e+00 5.00000000e-01 0.00000000e+00 + 1.25000000e-01 5.00000000e-01 1.25000000e-01 + 0.00000000e+00 5.00000000e-01 1.25000000e-01 + 1.25000000e-01 5.00000000e-01 2.50000000e-01 + 0.00000000e+00 5.00000000e-01 2.50000000e-01 + 1.25000000e-01 5.00000000e-01 3.75000000e-01 + 0.00000000e+00 5.00000000e-01 3.75000000e-01 + 1.25000000e-01 6.25000000e-01 0.00000000e+00 + 0.00000000e+00 6.25000000e-01 0.00000000e+00 + 1.25000000e-01 6.25000000e-01 1.25000000e-01 + 0.00000000e+00 6.25000000e-01 1.25000000e-01 + 1.25000000e-01 6.25000000e-01 2.50000000e-01 + 0.00000000e+00 6.25000000e-01 2.50000000e-01 + 1.25000000e-01 6.25000000e-01 3.75000000e-01 + 0.00000000e+00 6.25000000e-01 3.75000000e-01 + 1.25000000e-01 7.50000000e-01 0.00000000e+00 + 0.00000000e+00 7.50000000e-01 0.00000000e+00 + 1.25000000e-01 7.50000000e-01 1.25000000e-01 + 0.00000000e+00 7.50000000e-01 1.25000000e-01 + 1.25000000e-01 7.50000000e-01 2.50000000e-01 + 0.00000000e+00 7.50000000e-01 2.50000000e-01 + 1.25000000e-01 7.50000000e-01 3.75000000e-01 + 0.00000000e+00 7.50000000e-01 3.75000000e-01 + 1.25000000e-01 8.75000000e-01 0.00000000e+00 + 0.00000000e+00 8.75000000e-01 0.00000000e+00 + 1.25000000e-01 8.75000000e-01 1.25000000e-01 + 0.00000000e+00 8.75000000e-01 1.25000000e-01 + 1.25000000e-01 8.75000000e-01 2.50000000e-01 + 0.00000000e+00 8.75000000e-01 2.50000000e-01 + 1.25000000e-01 8.75000000e-01 3.75000000e-01 + 0.00000000e+00 8.75000000e-01 3.75000000e-01 + 1.25000000e-01 1.00000000e+00 0.00000000e+00 + 0.00000000e+00 1.00000000e+00 0.00000000e+00 + 1.25000000e-01 1.00000000e+00 1.25000000e-01 + 0.00000000e+00 1.00000000e+00 1.25000000e-01 + 1.25000000e-01 1.00000000e+00 2.50000000e-01 + 0.00000000e+00 1.00000000e+00 2.50000000e-01 + 1.25000000e-01 1.00000000e+00 3.75000000e-01 + 0.00000000e+00 1.00000000e+00 3.75000000e-01 + 2.50000000e-01 0.00000000e+00 0.00000000e+00 + 2.50000000e-01 1.25000000e-01 0.00000000e+00 + 2.50000000e-01 0.00000000e+00 1.25000000e-01 + 2.50000000e-01 1.25000000e-01 1.25000000e-01 + 2.50000000e-01 0.00000000e+00 2.50000000e-01 + 2.50000000e-01 1.25000000e-01 2.50000000e-01 + 2.50000000e-01 0.00000000e+00 3.75000000e-01 + 2.50000000e-01 1.25000000e-01 3.75000000e-01 + 2.50000000e-01 2.50000000e-01 0.00000000e+00 + 2.50000000e-01 2.50000000e-01 1.25000000e-01 + 2.50000000e-01 2.50000000e-01 2.50000000e-01 + 2.50000000e-01 2.50000000e-01 3.75000000e-01 + 2.50000000e-01 3.75000000e-01 0.00000000e+00 + 2.50000000e-01 3.75000000e-01 1.25000000e-01 + 2.50000000e-01 3.75000000e-01 2.50000000e-01 + 2.50000000e-01 3.75000000e-01 3.75000000e-01 + 2.50000000e-01 5.00000000e-01 0.00000000e+00 + 2.50000000e-01 5.00000000e-01 1.25000000e-01 + 2.50000000e-01 5.00000000e-01 2.50000000e-01 + 2.50000000e-01 5.00000000e-01 3.75000000e-01 + 2.50000000e-01 6.25000000e-01 0.00000000e+00 + 2.50000000e-01 6.25000000e-01 1.25000000e-01 + 2.50000000e-01 6.25000000e-01 2.50000000e-01 + 2.50000000e-01 6.25000000e-01 3.75000000e-01 + 2.50000000e-01 7.50000000e-01 0.00000000e+00 + 2.50000000e-01 7.50000000e-01 1.25000000e-01 + 2.50000000e-01 7.50000000e-01 2.50000000e-01 + 2.50000000e-01 7.50000000e-01 3.75000000e-01 + 2.50000000e-01 8.75000000e-01 0.00000000e+00 + 2.50000000e-01 8.75000000e-01 1.25000000e-01 + 2.50000000e-01 8.75000000e-01 2.50000000e-01 + 2.50000000e-01 8.75000000e-01 3.75000000e-01 + 2.50000000e-01 1.00000000e+00 0.00000000e+00 + 2.50000000e-01 1.00000000e+00 1.25000000e-01 + 2.50000000e-01 1.00000000e+00 2.50000000e-01 + 2.50000000e-01 1.00000000e+00 3.75000000e-01 + 3.75000000e-01 0.00000000e+00 0.00000000e+00 + 3.75000000e-01 1.25000000e-01 0.00000000e+00 + 3.75000000e-01 0.00000000e+00 1.25000000e-01 + 3.75000000e-01 1.25000000e-01 1.25000000e-01 + 3.75000000e-01 0.00000000e+00 2.50000000e-01 + 3.75000000e-01 1.25000000e-01 2.50000000e-01 + 3.75000000e-01 0.00000000e+00 3.75000000e-01 + 3.75000000e-01 1.25000000e-01 3.75000000e-01 + 3.75000000e-01 2.50000000e-01 0.00000000e+00 + 3.75000000e-01 2.50000000e-01 1.25000000e-01 + 3.75000000e-01 2.50000000e-01 2.50000000e-01 + 3.75000000e-01 2.50000000e-01 3.75000000e-01 + 3.75000000e-01 3.75000000e-01 0.00000000e+00 + 3.75000000e-01 3.75000000e-01 1.25000000e-01 + 3.75000000e-01 3.75000000e-01 2.50000000e-01 + 3.75000000e-01 3.75000000e-01 3.75000000e-01 + 3.75000000e-01 5.00000000e-01 0.00000000e+00 + 3.75000000e-01 5.00000000e-01 1.25000000e-01 + 3.75000000e-01 5.00000000e-01 2.50000000e-01 + 3.75000000e-01 5.00000000e-01 3.75000000e-01 + 3.75000000e-01 6.25000000e-01 0.00000000e+00 + 3.75000000e-01 6.25000000e-01 1.25000000e-01 + 3.75000000e-01 6.25000000e-01 2.50000000e-01 + 3.75000000e-01 6.25000000e-01 3.75000000e-01 + 3.75000000e-01 7.50000000e-01 0.00000000e+00 + 3.75000000e-01 7.50000000e-01 1.25000000e-01 + 3.75000000e-01 7.50000000e-01 2.50000000e-01 + 3.75000000e-01 7.50000000e-01 3.75000000e-01 + 3.75000000e-01 8.75000000e-01 0.00000000e+00 + 3.75000000e-01 8.75000000e-01 1.25000000e-01 + 3.75000000e-01 8.75000000e-01 2.50000000e-01 + 3.75000000e-01 8.75000000e-01 3.75000000e-01 + 3.75000000e-01 1.00000000e+00 0.00000000e+00 + 3.75000000e-01 1.00000000e+00 1.25000000e-01 + 3.75000000e-01 1.00000000e+00 2.50000000e-01 + 3.75000000e-01 1.00000000e+00 3.75000000e-01 + 5.00000000e-01 0.00000000e+00 0.00000000e+00 + 5.00000000e-01 1.25000000e-01 0.00000000e+00 + 5.00000000e-01 0.00000000e+00 1.25000000e-01 + 5.00000000e-01 1.25000000e-01 1.25000000e-01 + 5.00000000e-01 0.00000000e+00 2.50000000e-01 + 5.00000000e-01 1.25000000e-01 2.50000000e-01 + 5.00000000e-01 0.00000000e+00 3.75000000e-01 + 5.00000000e-01 1.25000000e-01 3.75000000e-01 + 5.00000000e-01 2.50000000e-01 0.00000000e+00 + 5.00000000e-01 2.50000000e-01 1.25000000e-01 + 5.00000000e-01 2.50000000e-01 2.50000000e-01 + 5.00000000e-01 2.50000000e-01 3.75000000e-01 + 5.00000000e-01 3.75000000e-01 0.00000000e+00 + 5.00000000e-01 3.75000000e-01 1.25000000e-01 + 5.00000000e-01 3.75000000e-01 2.50000000e-01 + 5.00000000e-01 3.75000000e-01 3.75000000e-01 + 5.00000000e-01 5.00000000e-01 0.00000000e+00 + 5.00000000e-01 5.00000000e-01 1.25000000e-01 + 5.00000000e-01 5.00000000e-01 2.50000000e-01 + 5.00000000e-01 5.00000000e-01 3.75000000e-01 + 5.00000000e-01 6.25000000e-01 0.00000000e+00 + 5.00000000e-01 6.25000000e-01 1.25000000e-01 + 5.00000000e-01 6.25000000e-01 2.50000000e-01 + 5.00000000e-01 6.25000000e-01 3.75000000e-01 + 5.00000000e-01 7.50000000e-01 0.00000000e+00 + 5.00000000e-01 7.50000000e-01 1.25000000e-01 + 5.00000000e-01 7.50000000e-01 2.50000000e-01 + 5.00000000e-01 7.50000000e-01 3.75000000e-01 + 5.00000000e-01 8.75000000e-01 0.00000000e+00 + 5.00000000e-01 8.75000000e-01 1.25000000e-01 + 5.00000000e-01 8.75000000e-01 2.50000000e-01 + 5.00000000e-01 8.75000000e-01 3.75000000e-01 + 5.00000000e-01 1.00000000e+00 0.00000000e+00 + 5.00000000e-01 1.00000000e+00 1.25000000e-01 + 5.00000000e-01 1.00000000e+00 2.50000000e-01 + 5.00000000e-01 1.00000000e+00 3.75000000e-01 + 6.25000000e-01 0.00000000e+00 0.00000000e+00 + 6.25000000e-01 1.25000000e-01 0.00000000e+00 + 6.25000000e-01 0.00000000e+00 1.25000000e-01 + 6.25000000e-01 1.25000000e-01 1.25000000e-01 + 6.25000000e-01 0.00000000e+00 2.50000000e-01 + 6.25000000e-01 1.25000000e-01 2.50000000e-01 + 6.25000000e-01 0.00000000e+00 3.75000000e-01 + 6.25000000e-01 1.25000000e-01 3.75000000e-01 + 6.25000000e-01 2.50000000e-01 0.00000000e+00 + 6.25000000e-01 2.50000000e-01 1.25000000e-01 + 6.25000000e-01 2.50000000e-01 2.50000000e-01 + 6.25000000e-01 2.50000000e-01 3.75000000e-01 + 6.25000000e-01 3.75000000e-01 0.00000000e+00 + 6.25000000e-01 3.75000000e-01 1.25000000e-01 + 6.25000000e-01 3.75000000e-01 2.50000000e-01 + 6.25000000e-01 3.75000000e-01 3.75000000e-01 + 6.25000000e-01 5.00000000e-01 0.00000000e+00 + 6.25000000e-01 5.00000000e-01 1.25000000e-01 + 6.25000000e-01 5.00000000e-01 2.50000000e-01 + 6.25000000e-01 5.00000000e-01 3.75000000e-01 + 6.25000000e-01 6.25000000e-01 0.00000000e+00 + 6.25000000e-01 6.25000000e-01 1.25000000e-01 + 6.25000000e-01 6.25000000e-01 2.50000000e-01 + 6.25000000e-01 6.25000000e-01 3.75000000e-01 + 6.25000000e-01 7.50000000e-01 0.00000000e+00 + 6.25000000e-01 7.50000000e-01 1.25000000e-01 + 6.25000000e-01 7.50000000e-01 2.50000000e-01 + 6.25000000e-01 7.50000000e-01 3.75000000e-01 + 6.25000000e-01 8.75000000e-01 0.00000000e+00 + 6.25000000e-01 8.75000000e-01 1.25000000e-01 + 6.25000000e-01 8.75000000e-01 2.50000000e-01 + 6.25000000e-01 8.75000000e-01 3.75000000e-01 + 6.25000000e-01 1.00000000e+00 0.00000000e+00 + 6.25000000e-01 1.00000000e+00 1.25000000e-01 + 6.25000000e-01 1.00000000e+00 2.50000000e-01 + 6.25000000e-01 1.00000000e+00 3.75000000e-01 + 7.50000000e-01 0.00000000e+00 0.00000000e+00 + 7.50000000e-01 1.25000000e-01 0.00000000e+00 + 7.50000000e-01 0.00000000e+00 1.25000000e-01 + 7.50000000e-01 1.25000000e-01 1.25000000e-01 + 7.50000000e-01 0.00000000e+00 2.50000000e-01 + 7.50000000e-01 1.25000000e-01 2.50000000e-01 + 7.50000000e-01 0.00000000e+00 3.75000000e-01 + 7.50000000e-01 1.25000000e-01 3.75000000e-01 + 7.50000000e-01 2.50000000e-01 0.00000000e+00 + 7.50000000e-01 2.50000000e-01 1.25000000e-01 + 7.50000000e-01 2.50000000e-01 2.50000000e-01 + 7.50000000e-01 2.50000000e-01 3.75000000e-01 + 7.50000000e-01 3.75000000e-01 0.00000000e+00 + 7.50000000e-01 3.75000000e-01 1.25000000e-01 + 7.50000000e-01 3.75000000e-01 2.50000000e-01 + 7.50000000e-01 3.75000000e-01 3.75000000e-01 + 7.50000000e-01 5.00000000e-01 0.00000000e+00 + 7.50000000e-01 5.00000000e-01 1.25000000e-01 + 7.50000000e-01 5.00000000e-01 2.50000000e-01 + 7.50000000e-01 5.00000000e-01 3.75000000e-01 + 7.50000000e-01 6.25000000e-01 0.00000000e+00 + 7.50000000e-01 6.25000000e-01 1.25000000e-01 + 7.50000000e-01 6.25000000e-01 2.50000000e-01 + 7.50000000e-01 6.25000000e-01 3.75000000e-01 + 7.50000000e-01 7.50000000e-01 0.00000000e+00 + 7.50000000e-01 7.50000000e-01 1.25000000e-01 + 7.50000000e-01 7.50000000e-01 2.50000000e-01 + 7.50000000e-01 7.50000000e-01 3.75000000e-01 + 7.50000000e-01 8.75000000e-01 0.00000000e+00 + 7.50000000e-01 8.75000000e-01 1.25000000e-01 + 7.50000000e-01 8.75000000e-01 2.50000000e-01 + 7.50000000e-01 8.75000000e-01 3.75000000e-01 + 7.50000000e-01 1.00000000e+00 0.00000000e+00 + 7.50000000e-01 1.00000000e+00 1.25000000e-01 + 7.50000000e-01 1.00000000e+00 2.50000000e-01 + 7.50000000e-01 1.00000000e+00 3.75000000e-01 + 8.75000000e-01 0.00000000e+00 0.00000000e+00 + 8.75000000e-01 1.25000000e-01 0.00000000e+00 + 8.75000000e-01 0.00000000e+00 1.25000000e-01 + 8.75000000e-01 1.25000000e-01 1.25000000e-01 + 8.75000000e-01 0.00000000e+00 2.50000000e-01 + 8.75000000e-01 1.25000000e-01 2.50000000e-01 + 8.75000000e-01 0.00000000e+00 3.75000000e-01 + 8.75000000e-01 1.25000000e-01 3.75000000e-01 + 8.75000000e-01 2.50000000e-01 0.00000000e+00 + 8.75000000e-01 2.50000000e-01 1.25000000e-01 + 8.75000000e-01 2.50000000e-01 2.50000000e-01 + 8.75000000e-01 2.50000000e-01 3.75000000e-01 + 8.75000000e-01 3.75000000e-01 0.00000000e+00 + 8.75000000e-01 3.75000000e-01 1.25000000e-01 + 8.75000000e-01 3.75000000e-01 2.50000000e-01 + 8.75000000e-01 3.75000000e-01 3.75000000e-01 + 8.75000000e-01 5.00000000e-01 0.00000000e+00 + 8.75000000e-01 5.00000000e-01 1.25000000e-01 + 8.75000000e-01 5.00000000e-01 2.50000000e-01 + 8.75000000e-01 5.00000000e-01 3.75000000e-01 + 8.75000000e-01 6.25000000e-01 0.00000000e+00 + 8.75000000e-01 6.25000000e-01 1.25000000e-01 + 8.75000000e-01 6.25000000e-01 2.50000000e-01 + 8.75000000e-01 6.25000000e-01 3.75000000e-01 + 8.75000000e-01 7.50000000e-01 0.00000000e+00 + 8.75000000e-01 7.50000000e-01 1.25000000e-01 + 8.75000000e-01 7.50000000e-01 2.50000000e-01 + 8.75000000e-01 7.50000000e-01 3.75000000e-01 + 8.75000000e-01 8.75000000e-01 0.00000000e+00 + 8.75000000e-01 8.75000000e-01 1.25000000e-01 + 8.75000000e-01 8.75000000e-01 2.50000000e-01 + 8.75000000e-01 8.75000000e-01 3.75000000e-01 + 8.75000000e-01 1.00000000e+00 0.00000000e+00 + 8.75000000e-01 1.00000000e+00 1.25000000e-01 + 8.75000000e-01 1.00000000e+00 2.50000000e-01 + 8.75000000e-01 1.00000000e+00 3.75000000e-01 + 1.00000000e+00 0.00000000e+00 0.00000000e+00 + 1.00000000e+00 1.25000000e-01 0.00000000e+00 + 1.00000000e+00 0.00000000e+00 1.25000000e-01 + 1.00000000e+00 1.25000000e-01 1.25000000e-01 + 1.00000000e+00 0.00000000e+00 2.50000000e-01 + 1.00000000e+00 1.25000000e-01 2.50000000e-01 + 1.00000000e+00 0.00000000e+00 3.75000000e-01 + 1.00000000e+00 1.25000000e-01 3.75000000e-01 + 1.00000000e+00 2.50000000e-01 0.00000000e+00 + 1.00000000e+00 2.50000000e-01 1.25000000e-01 + 1.00000000e+00 2.50000000e-01 2.50000000e-01 + 1.00000000e+00 2.50000000e-01 3.75000000e-01 + 1.00000000e+00 3.75000000e-01 0.00000000e+00 + 1.00000000e+00 3.75000000e-01 1.25000000e-01 + 1.00000000e+00 3.75000000e-01 2.50000000e-01 + 1.00000000e+00 3.75000000e-01 3.75000000e-01 + 1.00000000e+00 5.00000000e-01 0.00000000e+00 + 1.00000000e+00 5.00000000e-01 1.25000000e-01 + 1.00000000e+00 5.00000000e-01 2.50000000e-01 + 1.00000000e+00 5.00000000e-01 3.75000000e-01 + 1.00000000e+00 6.25000000e-01 0.00000000e+00 + 1.00000000e+00 6.25000000e-01 1.25000000e-01 + 1.00000000e+00 6.25000000e-01 2.50000000e-01 + 1.00000000e+00 6.25000000e-01 3.75000000e-01 + 1.00000000e+00 7.50000000e-01 0.00000000e+00 + 1.00000000e+00 7.50000000e-01 1.25000000e-01 + 1.00000000e+00 7.50000000e-01 2.50000000e-01 + 1.00000000e+00 7.50000000e-01 3.75000000e-01 + 1.00000000e+00 8.75000000e-01 0.00000000e+00 + 1.00000000e+00 8.75000000e-01 1.25000000e-01 + 1.00000000e+00 8.75000000e-01 2.50000000e-01 + 1.00000000e+00 8.75000000e-01 3.75000000e-01 + 1.00000000e+00 1.00000000e+00 0.00000000e+00 + 1.00000000e+00 1.00000000e+00 1.25000000e-01 + 1.00000000e+00 1.00000000e+00 2.50000000e-01 + 1.00000000e+00 1.00000000e+00 3.75000000e-01 + 0 0 3.75000000e-01 + 6.25000000e-02 0 3.75000000e-01 + 6.25000000e-02 6.25000000e-02 3.75000000e-01 + 0 6.25000000e-02 3.75000000e-01 + 0 0 5.00000000e-01 + 6.25000000e-02 0 5.00000000e-01 + 6.25000000e-02 6.25000000e-02 5.00000000e-01 + 0 6.25000000e-02 5.00000000e-01 + 0 0 6.25000000e-01 + 6.25000000e-02 0 6.25000000e-01 + 6.25000000e-02 6.25000000e-02 6.25000000e-01 + 0 6.25000000e-02 6.25000000e-01 + 6.25000000e-02 1.87500000e-01 3.75000000e-01 + 0 1.87500000e-01 3.75000000e-01 + 6.25000000e-02 1.87500000e-01 5.00000000e-01 + 0 1.87500000e-01 5.00000000e-01 + 6.25000000e-02 1.87500000e-01 6.25000000e-01 + 0 1.87500000e-01 6.25000000e-01 + 6.25000000e-02 3.12500000e-01 3.75000000e-01 + 0 3.12500000e-01 3.75000000e-01 + 6.25000000e-02 3.12500000e-01 5.00000000e-01 + 0 3.12500000e-01 5.00000000e-01 + 6.25000000e-02 3.12500000e-01 6.25000000e-01 + 0 3.12500000e-01 6.25000000e-01 + 6.25000000e-02 4.37500000e-01 3.75000000e-01 + 0 4.37500000e-01 3.75000000e-01 + 6.25000000e-02 4.37500000e-01 5.00000000e-01 + 0 4.37500000e-01 5.00000000e-01 + 6.25000000e-02 4.37500000e-01 6.25000000e-01 + 0 4.37500000e-01 6.25000000e-01 + 6.25000000e-02 5.62500000e-01 3.75000000e-01 + 0 5.62500000e-01 3.75000000e-01 + 6.25000000e-02 5.62500000e-01 5.00000000e-01 + 0 5.62500000e-01 5.00000000e-01 + 6.25000000e-02 5.62500000e-01 6.25000000e-01 + 0 5.62500000e-01 6.25000000e-01 + 6.25000000e-02 6.87500000e-01 3.75000000e-01 + 0 6.87500000e-01 3.75000000e-01 + 6.25000000e-02 6.87500000e-01 5.00000000e-01 + 0 6.87500000e-01 5.00000000e-01 + 6.25000000e-02 6.87500000e-01 6.25000000e-01 + 0 6.87500000e-01 6.25000000e-01 + 6.25000000e-02 8.12500000e-01 3.75000000e-01 + 0 8.12500000e-01 3.75000000e-01 + 6.25000000e-02 8.12500000e-01 5.00000000e-01 + 0 8.12500000e-01 5.00000000e-01 + 6.25000000e-02 8.12500000e-01 6.25000000e-01 + 0 8.12500000e-01 6.25000000e-01 + 6.25000000e-02 9.37500000e-01 3.75000000e-01 + 0 9.37500000e-01 3.75000000e-01 + 6.25000000e-02 9.37500000e-01 5.00000000e-01 + 0 9.37500000e-01 5.00000000e-01 + 6.25000000e-02 9.37500000e-01 6.25000000e-01 + 0 9.37500000e-01 6.25000000e-01 + 6.25000000e-02 1 3.75000000e-01 + 0 1 3.75000000e-01 + 6.25000000e-02 1 5.00000000e-01 + 0 1 5.00000000e-01 + 6.25000000e-02 1 6.25000000e-01 + 0 1 6.25000000e-01 + 1.87500000e-01 0 3.75000000e-01 + 1.87500000e-01 6.25000000e-02 3.75000000e-01 + 1.87500000e-01 0 5.00000000e-01 + 1.87500000e-01 6.25000000e-02 5.00000000e-01 + 1.87500000e-01 0 6.25000000e-01 + 1.87500000e-01 6.25000000e-02 6.25000000e-01 + 1.87500000e-01 1.87500000e-01 3.75000000e-01 + 1.87500000e-01 1.87500000e-01 5.00000000e-01 + 1.87500000e-01 1.87500000e-01 6.25000000e-01 + 1.87500000e-01 3.12500000e-01 3.75000000e-01 + 1.87500000e-01 3.12500000e-01 5.00000000e-01 + 1.87500000e-01 3.12500000e-01 6.25000000e-01 + 1.87500000e-01 4.37500000e-01 3.75000000e-01 + 1.87500000e-01 4.37500000e-01 5.00000000e-01 + 1.87500000e-01 4.37500000e-01 6.25000000e-01 + 1.87500000e-01 5.62500000e-01 3.75000000e-01 + 1.87500000e-01 5.62500000e-01 5.00000000e-01 + 1.87500000e-01 5.62500000e-01 6.25000000e-01 + 1.87500000e-01 6.87500000e-01 3.75000000e-01 + 1.87500000e-01 6.87500000e-01 5.00000000e-01 + 1.87500000e-01 6.87500000e-01 6.25000000e-01 + 1.87500000e-01 8.12500000e-01 3.75000000e-01 + 1.87500000e-01 8.12500000e-01 5.00000000e-01 + 1.87500000e-01 8.12500000e-01 6.25000000e-01 + 1.87500000e-01 9.37500000e-01 3.75000000e-01 + 1.87500000e-01 9.37500000e-01 5.00000000e-01 + 1.87500000e-01 9.37500000e-01 6.25000000e-01 + 1.87500000e-01 1 3.75000000e-01 + 1.87500000e-01 1 5.00000000e-01 + 1.87500000e-01 1 6.25000000e-01 + 3.12500000e-01 0 3.75000000e-01 + 3.12500000e-01 6.25000000e-02 3.75000000e-01 + 3.12500000e-01 0 5.00000000e-01 + 3.12500000e-01 6.25000000e-02 5.00000000e-01 + 3.12500000e-01 0 6.25000000e-01 + 3.12500000e-01 6.25000000e-02 6.25000000e-01 + 3.12500000e-01 1.87500000e-01 3.75000000e-01 + 3.12500000e-01 1.87500000e-01 5.00000000e-01 + 3.12500000e-01 1.87500000e-01 6.25000000e-01 + 3.12500000e-01 3.12500000e-01 3.75000000e-01 + 3.12500000e-01 3.12500000e-01 5.00000000e-01 + 3.12500000e-01 3.12500000e-01 6.25000000e-01 + 3.12500000e-01 4.37500000e-01 3.75000000e-01 + 3.12500000e-01 4.37500000e-01 5.00000000e-01 + 3.12500000e-01 4.37500000e-01 6.25000000e-01 + 3.12500000e-01 5.62500000e-01 3.75000000e-01 + 3.12500000e-01 5.62500000e-01 5.00000000e-01 + 3.12500000e-01 5.62500000e-01 6.25000000e-01 + 3.12500000e-01 6.87500000e-01 3.75000000e-01 + 3.12500000e-01 6.87500000e-01 5.00000000e-01 + 3.12500000e-01 6.87500000e-01 6.25000000e-01 + 3.12500000e-01 8.12500000e-01 3.75000000e-01 + 3.12500000e-01 8.12500000e-01 5.00000000e-01 + 3.12500000e-01 8.12500000e-01 6.25000000e-01 + 3.12500000e-01 9.37500000e-01 3.75000000e-01 + 3.12500000e-01 9.37500000e-01 5.00000000e-01 + 3.12500000e-01 9.37500000e-01 6.25000000e-01 + 3.12500000e-01 1 3.75000000e-01 + 3.12500000e-01 1 5.00000000e-01 + 3.12500000e-01 1 6.25000000e-01 + 4.37500000e-01 0 3.75000000e-01 + 4.37500000e-01 6.25000000e-02 3.75000000e-01 + 4.37500000e-01 0 5.00000000e-01 + 4.37500000e-01 6.25000000e-02 5.00000000e-01 + 4.37500000e-01 0 6.25000000e-01 + 4.37500000e-01 6.25000000e-02 6.25000000e-01 + 4.37500000e-01 1.87500000e-01 3.75000000e-01 + 4.37500000e-01 1.87500000e-01 5.00000000e-01 + 4.37500000e-01 1.87500000e-01 6.25000000e-01 + 4.37500000e-01 3.12500000e-01 3.75000000e-01 + 4.37500000e-01 3.12500000e-01 5.00000000e-01 + 4.37500000e-01 3.12500000e-01 6.25000000e-01 + 4.37500000e-01 4.37500000e-01 3.75000000e-01 + 4.37500000e-01 4.37500000e-01 5.00000000e-01 + 4.37500000e-01 4.37500000e-01 6.25000000e-01 + 4.37500000e-01 5.62500000e-01 3.75000000e-01 + 4.37500000e-01 5.62500000e-01 5.00000000e-01 + 4.37500000e-01 5.62500000e-01 6.25000000e-01 + 4.37500000e-01 6.87500000e-01 3.75000000e-01 + 4.37500000e-01 6.87500000e-01 5.00000000e-01 + 4.37500000e-01 6.87500000e-01 6.25000000e-01 + 4.37500000e-01 8.12500000e-01 3.75000000e-01 + 4.37500000e-01 8.12500000e-01 5.00000000e-01 + 4.37500000e-01 8.12500000e-01 6.25000000e-01 + 4.37500000e-01 9.37500000e-01 3.75000000e-01 + 4.37500000e-01 9.37500000e-01 5.00000000e-01 + 4.37500000e-01 9.37500000e-01 6.25000000e-01 + 4.37500000e-01 1 3.75000000e-01 + 4.37500000e-01 1 5.00000000e-01 + 4.37500000e-01 1 6.25000000e-01 + 5.62500000e-01 0 3.75000000e-01 + 5.62500000e-01 6.25000000e-02 3.75000000e-01 + 5.62500000e-01 0 5.00000000e-01 + 5.62500000e-01 6.25000000e-02 5.00000000e-01 + 5.62500000e-01 0 6.25000000e-01 + 5.62500000e-01 6.25000000e-02 6.25000000e-01 + 5.62500000e-01 1.87500000e-01 3.75000000e-01 + 5.62500000e-01 1.87500000e-01 5.00000000e-01 + 5.62500000e-01 1.87500000e-01 6.25000000e-01 + 5.62500000e-01 3.12500000e-01 3.75000000e-01 + 5.62500000e-01 3.12500000e-01 5.00000000e-01 + 5.62500000e-01 3.12500000e-01 6.25000000e-01 + 5.62500000e-01 4.37500000e-01 3.75000000e-01 + 5.62500000e-01 4.37500000e-01 5.00000000e-01 + 5.62500000e-01 4.37500000e-01 6.25000000e-01 + 5.62500000e-01 5.62500000e-01 3.75000000e-01 + 5.62500000e-01 5.62500000e-01 5.00000000e-01 + 5.62500000e-01 5.62500000e-01 6.25000000e-01 + 5.62500000e-01 6.87500000e-01 3.75000000e-01 + 5.62500000e-01 6.87500000e-01 5.00000000e-01 + 5.62500000e-01 6.87500000e-01 6.25000000e-01 + 5.62500000e-01 8.12500000e-01 3.75000000e-01 + 5.62500000e-01 8.12500000e-01 5.00000000e-01 + 5.62500000e-01 8.12500000e-01 6.25000000e-01 + 5.62500000e-01 9.37500000e-01 3.75000000e-01 + 5.62500000e-01 9.37500000e-01 5.00000000e-01 + 5.62500000e-01 9.37500000e-01 6.25000000e-01 + 5.62500000e-01 1 3.75000000e-01 + 5.62500000e-01 1 5.00000000e-01 + 5.62500000e-01 1 6.25000000e-01 + 6.87500000e-01 0 3.75000000e-01 + 6.87500000e-01 6.25000000e-02 3.75000000e-01 + 6.87500000e-01 0 5.00000000e-01 + 6.87500000e-01 6.25000000e-02 5.00000000e-01 + 6.87500000e-01 0 6.25000000e-01 + 6.87500000e-01 6.25000000e-02 6.25000000e-01 + 6.87500000e-01 1.87500000e-01 3.75000000e-01 + 6.87500000e-01 1.87500000e-01 5.00000000e-01 + 6.87500000e-01 1.87500000e-01 6.25000000e-01 + 6.87500000e-01 3.12500000e-01 3.75000000e-01 + 6.87500000e-01 3.12500000e-01 5.00000000e-01 + 6.87500000e-01 3.12500000e-01 6.25000000e-01 + 6.87500000e-01 4.37500000e-01 3.75000000e-01 + 6.87500000e-01 4.37500000e-01 5.00000000e-01 + 6.87500000e-01 4.37500000e-01 6.25000000e-01 + 6.87500000e-01 5.62500000e-01 3.75000000e-01 + 6.87500000e-01 5.62500000e-01 5.00000000e-01 + 6.87500000e-01 5.62500000e-01 6.25000000e-01 + 6.87500000e-01 6.87500000e-01 3.75000000e-01 + 6.87500000e-01 6.87500000e-01 5.00000000e-01 + 6.87500000e-01 6.87500000e-01 6.25000000e-01 + 6.87500000e-01 8.12500000e-01 3.75000000e-01 + 6.87500000e-01 8.12500000e-01 5.00000000e-01 + 6.87500000e-01 8.12500000e-01 6.25000000e-01 + 6.87500000e-01 9.37500000e-01 3.75000000e-01 + 6.87500000e-01 9.37500000e-01 5.00000000e-01 + 6.87500000e-01 9.37500000e-01 6.25000000e-01 + 6.87500000e-01 1 3.75000000e-01 + 6.87500000e-01 1 5.00000000e-01 + 6.87500000e-01 1 6.25000000e-01 + 8.12500000e-01 0 3.75000000e-01 + 8.12500000e-01 6.25000000e-02 3.75000000e-01 + 8.12500000e-01 0 5.00000000e-01 + 8.12500000e-01 6.25000000e-02 5.00000000e-01 + 8.12500000e-01 0 6.25000000e-01 + 8.12500000e-01 6.25000000e-02 6.25000000e-01 + 8.12500000e-01 1.87500000e-01 3.75000000e-01 + 8.12500000e-01 1.87500000e-01 5.00000000e-01 + 8.12500000e-01 1.87500000e-01 6.25000000e-01 + 8.12500000e-01 3.12500000e-01 3.75000000e-01 + 8.12500000e-01 3.12500000e-01 5.00000000e-01 + 8.12500000e-01 3.12500000e-01 6.25000000e-01 + 8.12500000e-01 4.37500000e-01 3.75000000e-01 + 8.12500000e-01 4.37500000e-01 5.00000000e-01 + 8.12500000e-01 4.37500000e-01 6.25000000e-01 + 8.12500000e-01 5.62500000e-01 3.75000000e-01 + 8.12500000e-01 5.62500000e-01 5.00000000e-01 + 8.12500000e-01 5.62500000e-01 6.25000000e-01 + 8.12500000e-01 6.87500000e-01 3.75000000e-01 + 8.12500000e-01 6.87500000e-01 5.00000000e-01 + 8.12500000e-01 6.87500000e-01 6.25000000e-01 + 8.12500000e-01 8.12500000e-01 3.75000000e-01 + 8.12500000e-01 8.12500000e-01 5.00000000e-01 + 8.12500000e-01 8.12500000e-01 6.25000000e-01 + 8.12500000e-01 9.37500000e-01 3.75000000e-01 + 8.12500000e-01 9.37500000e-01 5.00000000e-01 + 8.12500000e-01 9.37500000e-01 6.25000000e-01 + 8.12500000e-01 1 3.75000000e-01 + 8.12500000e-01 1 5.00000000e-01 + 8.12500000e-01 1 6.25000000e-01 + 9.37500000e-01 0 3.75000000e-01 + 9.37500000e-01 6.25000000e-02 3.75000000e-01 + 9.37500000e-01 0 5.00000000e-01 + 9.37500000e-01 6.25000000e-02 5.00000000e-01 + 9.37500000e-01 0 6.25000000e-01 + 9.37500000e-01 6.25000000e-02 6.25000000e-01 + 9.37500000e-01 1.87500000e-01 3.75000000e-01 + 9.37500000e-01 1.87500000e-01 5.00000000e-01 + 9.37500000e-01 1.87500000e-01 6.25000000e-01 + 9.37500000e-01 3.12500000e-01 3.75000000e-01 + 9.37500000e-01 3.12500000e-01 5.00000000e-01 + 9.37500000e-01 3.12500000e-01 6.25000000e-01 + 9.37500000e-01 4.37500000e-01 3.75000000e-01 + 9.37500000e-01 4.37500000e-01 5.00000000e-01 + 9.37500000e-01 4.37500000e-01 6.25000000e-01 + 9.37500000e-01 5.62500000e-01 3.75000000e-01 + 9.37500000e-01 5.62500000e-01 5.00000000e-01 + 9.37500000e-01 5.62500000e-01 6.25000000e-01 + 9.37500000e-01 6.87500000e-01 3.75000000e-01 + 9.37500000e-01 6.87500000e-01 5.00000000e-01 + 9.37500000e-01 6.87500000e-01 6.25000000e-01 + 9.37500000e-01 8.12500000e-01 3.75000000e-01 + 9.37500000e-01 8.12500000e-01 5.00000000e-01 + 9.37500000e-01 8.12500000e-01 6.25000000e-01 + 9.37500000e-01 9.37500000e-01 3.75000000e-01 + 9.37500000e-01 9.37500000e-01 5.00000000e-01 + 9.37500000e-01 9.37500000e-01 6.25000000e-01 + 9.37500000e-01 1 3.75000000e-01 + 9.37500000e-01 1 5.00000000e-01 + 9.37500000e-01 1 6.25000000e-01 + 1 0 3.75000000e-01 + 1 6.25000000e-02 3.75000000e-01 + 1 0 5.00000000e-01 + 1 6.25000000e-02 5.00000000e-01 + 1 0 6.25000000e-01 + 1 6.25000000e-02 6.25000000e-01 + 1 1.87500000e-01 3.75000000e-01 + 1 1.87500000e-01 5.00000000e-01 + 1 1.87500000e-01 6.25000000e-01 + 1 3.12500000e-01 3.75000000e-01 + 1 3.12500000e-01 5.00000000e-01 + 1 3.12500000e-01 6.25000000e-01 + 1 4.37500000e-01 3.75000000e-01 + 1 4.37500000e-01 5.00000000e-01 + 1 4.37500000e-01 6.25000000e-01 + 1 5.62500000e-01 3.75000000e-01 + 1 5.62500000e-01 5.00000000e-01 + 1 5.62500000e-01 6.25000000e-01 + 1 6.87500000e-01 3.75000000e-01 + 1 6.87500000e-01 5.00000000e-01 + 1 6.87500000e-01 6.25000000e-01 + 1 8.12500000e-01 3.75000000e-01 + 1 8.12500000e-01 5.00000000e-01 + 1 8.12500000e-01 6.25000000e-01 + 1 9.37500000e-01 3.75000000e-01 + 1 9.37500000e-01 5.00000000e-01 + 1 9.37500000e-01 6.25000000e-01 + 1 1 3.75000000e-01 + 1 1 5.00000000e-01 + 1 1 6.25000000e-01 + 0.00000000e+00 0.00000000e+00 6.25000000e-01 + 1.25000000e-01 0.00000000e+00 6.25000000e-01 + 1.25000000e-01 1.25000000e-01 6.25000000e-01 + 0.00000000e+00 1.25000000e-01 6.25000000e-01 + 0.00000000e+00 0.00000000e+00 7.50000000e-01 + 1.25000000e-01 0.00000000e+00 7.50000000e-01 + 1.25000000e-01 1.25000000e-01 7.50000000e-01 + 0.00000000e+00 1.25000000e-01 7.50000000e-01 + 0.00000000e+00 0.00000000e+00 8.75000000e-01 + 1.25000000e-01 0.00000000e+00 8.75000000e-01 + 1.25000000e-01 1.25000000e-01 8.75000000e-01 + 0.00000000e+00 1.25000000e-01 8.75000000e-01 + 0.00000000e+00 0.00000000e+00 1.00000000e+00 + 1.25000000e-01 0.00000000e+00 1.00000000e+00 + 1.25000000e-01 1.25000000e-01 1.00000000e+00 + 0.00000000e+00 1.25000000e-01 1.00000000e+00 + 1.25000000e-01 2.50000000e-01 6.25000000e-01 + 0.00000000e+00 2.50000000e-01 6.25000000e-01 + 1.25000000e-01 2.50000000e-01 7.50000000e-01 + 0.00000000e+00 2.50000000e-01 7.50000000e-01 + 1.25000000e-01 2.50000000e-01 8.75000000e-01 + 0.00000000e+00 2.50000000e-01 8.75000000e-01 + 1.25000000e-01 2.50000000e-01 1.00000000e+00 + 0.00000000e+00 2.50000000e-01 1.00000000e+00 + 1.25000000e-01 3.75000000e-01 6.25000000e-01 + 0.00000000e+00 3.75000000e-01 6.25000000e-01 + 1.25000000e-01 3.75000000e-01 7.50000000e-01 + 0.00000000e+00 3.75000000e-01 7.50000000e-01 + 1.25000000e-01 3.75000000e-01 8.75000000e-01 + 0.00000000e+00 3.75000000e-01 8.75000000e-01 + 1.25000000e-01 3.75000000e-01 1.00000000e+00 + 0.00000000e+00 3.75000000e-01 1.00000000e+00 + 1.25000000e-01 5.00000000e-01 6.25000000e-01 + 0.00000000e+00 5.00000000e-01 6.25000000e-01 + 1.25000000e-01 5.00000000e-01 7.50000000e-01 + 0.00000000e+00 5.00000000e-01 7.50000000e-01 + 1.25000000e-01 5.00000000e-01 8.75000000e-01 + 0.00000000e+00 5.00000000e-01 8.75000000e-01 + 1.25000000e-01 5.00000000e-01 1.00000000e+00 + 0.00000000e+00 5.00000000e-01 1.00000000e+00 + 1.25000000e-01 6.25000000e-01 6.25000000e-01 + 0.00000000e+00 6.25000000e-01 6.25000000e-01 + 1.25000000e-01 6.25000000e-01 7.50000000e-01 + 0.00000000e+00 6.25000000e-01 7.50000000e-01 + 1.25000000e-01 6.25000000e-01 8.75000000e-01 + 0.00000000e+00 6.25000000e-01 8.75000000e-01 + 1.25000000e-01 6.25000000e-01 1.00000000e+00 + 0.00000000e+00 6.25000000e-01 1.00000000e+00 + 1.25000000e-01 7.50000000e-01 6.25000000e-01 + 0.00000000e+00 7.50000000e-01 6.25000000e-01 + 1.25000000e-01 7.50000000e-01 7.50000000e-01 + 0.00000000e+00 7.50000000e-01 7.50000000e-01 + 1.25000000e-01 7.50000000e-01 8.75000000e-01 + 0.00000000e+00 7.50000000e-01 8.75000000e-01 + 1.25000000e-01 7.50000000e-01 1.00000000e+00 + 0.00000000e+00 7.50000000e-01 1.00000000e+00 + 1.25000000e-01 8.75000000e-01 6.25000000e-01 + 0.00000000e+00 8.75000000e-01 6.25000000e-01 + 1.25000000e-01 8.75000000e-01 7.50000000e-01 + 0.00000000e+00 8.75000000e-01 7.50000000e-01 + 1.25000000e-01 8.75000000e-01 8.75000000e-01 + 0.00000000e+00 8.75000000e-01 8.75000000e-01 + 1.25000000e-01 8.75000000e-01 1.00000000e+00 + 0.00000000e+00 8.75000000e-01 1.00000000e+00 + 1.25000000e-01 1.00000000e+00 6.25000000e-01 + 0.00000000e+00 1.00000000e+00 6.25000000e-01 + 1.25000000e-01 1.00000000e+00 7.50000000e-01 + 0.00000000e+00 1.00000000e+00 7.50000000e-01 + 1.25000000e-01 1.00000000e+00 8.75000000e-01 + 0.00000000e+00 1.00000000e+00 8.75000000e-01 + 1.25000000e-01 1.00000000e+00 1.00000000e+00 + 0.00000000e+00 1.00000000e+00 1.00000000e+00 + 2.50000000e-01 0.00000000e+00 6.25000000e-01 + 2.50000000e-01 1.25000000e-01 6.25000000e-01 + 2.50000000e-01 0.00000000e+00 7.50000000e-01 + 2.50000000e-01 1.25000000e-01 7.50000000e-01 + 2.50000000e-01 0.00000000e+00 8.75000000e-01 + 2.50000000e-01 1.25000000e-01 8.75000000e-01 + 2.50000000e-01 0.00000000e+00 1.00000000e+00 + 2.50000000e-01 1.25000000e-01 1.00000000e+00 + 2.50000000e-01 2.50000000e-01 6.25000000e-01 + 2.50000000e-01 2.50000000e-01 7.50000000e-01 + 2.50000000e-01 2.50000000e-01 8.75000000e-01 + 2.50000000e-01 2.50000000e-01 1.00000000e+00 + 2.50000000e-01 3.75000000e-01 6.25000000e-01 + 2.50000000e-01 3.75000000e-01 7.50000000e-01 + 2.50000000e-01 3.75000000e-01 8.75000000e-01 + 2.50000000e-01 3.75000000e-01 1.00000000e+00 + 2.50000000e-01 5.00000000e-01 6.25000000e-01 + 2.50000000e-01 5.00000000e-01 7.50000000e-01 + 2.50000000e-01 5.00000000e-01 8.75000000e-01 + 2.50000000e-01 5.00000000e-01 1.00000000e+00 + 2.50000000e-01 6.25000000e-01 6.25000000e-01 + 2.50000000e-01 6.25000000e-01 7.50000000e-01 + 2.50000000e-01 6.25000000e-01 8.75000000e-01 + 2.50000000e-01 6.25000000e-01 1.00000000e+00 + 2.50000000e-01 7.50000000e-01 6.25000000e-01 + 2.50000000e-01 7.50000000e-01 7.50000000e-01 + 2.50000000e-01 7.50000000e-01 8.75000000e-01 + 2.50000000e-01 7.50000000e-01 1.00000000e+00 + 2.50000000e-01 8.75000000e-01 6.25000000e-01 + 2.50000000e-01 8.75000000e-01 7.50000000e-01 + 2.50000000e-01 8.75000000e-01 8.75000000e-01 + 2.50000000e-01 8.75000000e-01 1.00000000e+00 + 2.50000000e-01 1.00000000e+00 6.25000000e-01 + 2.50000000e-01 1.00000000e+00 7.50000000e-01 + 2.50000000e-01 1.00000000e+00 8.75000000e-01 + 2.50000000e-01 1.00000000e+00 1.00000000e+00 + 3.75000000e-01 0.00000000e+00 6.25000000e-01 + 3.75000000e-01 1.25000000e-01 6.25000000e-01 + 3.75000000e-01 0.00000000e+00 7.50000000e-01 + 3.75000000e-01 1.25000000e-01 7.50000000e-01 + 3.75000000e-01 0.00000000e+00 8.75000000e-01 + 3.75000000e-01 1.25000000e-01 8.75000000e-01 + 3.75000000e-01 0.00000000e+00 1.00000000e+00 + 3.75000000e-01 1.25000000e-01 1.00000000e+00 + 3.75000000e-01 2.50000000e-01 6.25000000e-01 + 3.75000000e-01 2.50000000e-01 7.50000000e-01 + 3.75000000e-01 2.50000000e-01 8.75000000e-01 + 3.75000000e-01 2.50000000e-01 1.00000000e+00 + 3.75000000e-01 3.75000000e-01 6.25000000e-01 + 3.75000000e-01 3.75000000e-01 7.50000000e-01 + 3.75000000e-01 3.75000000e-01 8.75000000e-01 + 3.75000000e-01 3.75000000e-01 1.00000000e+00 + 3.75000000e-01 5.00000000e-01 6.25000000e-01 + 3.75000000e-01 5.00000000e-01 7.50000000e-01 + 3.75000000e-01 5.00000000e-01 8.75000000e-01 + 3.75000000e-01 5.00000000e-01 1.00000000e+00 + 3.75000000e-01 6.25000000e-01 6.25000000e-01 + 3.75000000e-01 6.25000000e-01 7.50000000e-01 + 3.75000000e-01 6.25000000e-01 8.75000000e-01 + 3.75000000e-01 6.25000000e-01 1.00000000e+00 + 3.75000000e-01 7.50000000e-01 6.25000000e-01 + 3.75000000e-01 7.50000000e-01 7.50000000e-01 + 3.75000000e-01 7.50000000e-01 8.75000000e-01 + 3.75000000e-01 7.50000000e-01 1.00000000e+00 + 3.75000000e-01 8.75000000e-01 6.25000000e-01 + 3.75000000e-01 8.75000000e-01 7.50000000e-01 + 3.75000000e-01 8.75000000e-01 8.75000000e-01 + 3.75000000e-01 8.75000000e-01 1.00000000e+00 + 3.75000000e-01 1.00000000e+00 6.25000000e-01 + 3.75000000e-01 1.00000000e+00 7.50000000e-01 + 3.75000000e-01 1.00000000e+00 8.75000000e-01 + 3.75000000e-01 1.00000000e+00 1.00000000e+00 + 5.00000000e-01 0.00000000e+00 6.25000000e-01 + 5.00000000e-01 1.25000000e-01 6.25000000e-01 + 5.00000000e-01 0.00000000e+00 7.50000000e-01 + 5.00000000e-01 1.25000000e-01 7.50000000e-01 + 5.00000000e-01 0.00000000e+00 8.75000000e-01 + 5.00000000e-01 1.25000000e-01 8.75000000e-01 + 5.00000000e-01 0.00000000e+00 1.00000000e+00 + 5.00000000e-01 1.25000000e-01 1.00000000e+00 + 5.00000000e-01 2.50000000e-01 6.25000000e-01 + 5.00000000e-01 2.50000000e-01 7.50000000e-01 + 5.00000000e-01 2.50000000e-01 8.75000000e-01 + 5.00000000e-01 2.50000000e-01 1.00000000e+00 + 5.00000000e-01 3.75000000e-01 6.25000000e-01 + 5.00000000e-01 3.75000000e-01 7.50000000e-01 + 5.00000000e-01 3.75000000e-01 8.75000000e-01 + 5.00000000e-01 3.75000000e-01 1.00000000e+00 + 5.00000000e-01 5.00000000e-01 6.25000000e-01 + 5.00000000e-01 5.00000000e-01 7.50000000e-01 + 5.00000000e-01 5.00000000e-01 8.75000000e-01 + 5.00000000e-01 5.00000000e-01 1.00000000e+00 + 5.00000000e-01 6.25000000e-01 6.25000000e-01 + 5.00000000e-01 6.25000000e-01 7.50000000e-01 + 5.00000000e-01 6.25000000e-01 8.75000000e-01 + 5.00000000e-01 6.25000000e-01 1.00000000e+00 + 5.00000000e-01 7.50000000e-01 6.25000000e-01 + 5.00000000e-01 7.50000000e-01 7.50000000e-01 + 5.00000000e-01 7.50000000e-01 8.75000000e-01 + 5.00000000e-01 7.50000000e-01 1.00000000e+00 + 5.00000000e-01 8.75000000e-01 6.25000000e-01 + 5.00000000e-01 8.75000000e-01 7.50000000e-01 + 5.00000000e-01 8.75000000e-01 8.75000000e-01 + 5.00000000e-01 8.75000000e-01 1.00000000e+00 + 5.00000000e-01 1.00000000e+00 6.25000000e-01 + 5.00000000e-01 1.00000000e+00 7.50000000e-01 + 5.00000000e-01 1.00000000e+00 8.75000000e-01 + 5.00000000e-01 1.00000000e+00 1.00000000e+00 + 6.25000000e-01 0.00000000e+00 6.25000000e-01 + 6.25000000e-01 1.25000000e-01 6.25000000e-01 + 6.25000000e-01 0.00000000e+00 7.50000000e-01 + 6.25000000e-01 1.25000000e-01 7.50000000e-01 + 6.25000000e-01 0.00000000e+00 8.75000000e-01 + 6.25000000e-01 1.25000000e-01 8.75000000e-01 + 6.25000000e-01 0.00000000e+00 1.00000000e+00 + 6.25000000e-01 1.25000000e-01 1.00000000e+00 + 6.25000000e-01 2.50000000e-01 6.25000000e-01 + 6.25000000e-01 2.50000000e-01 7.50000000e-01 + 6.25000000e-01 2.50000000e-01 8.75000000e-01 + 6.25000000e-01 2.50000000e-01 1.00000000e+00 + 6.25000000e-01 3.75000000e-01 6.25000000e-01 + 6.25000000e-01 3.75000000e-01 7.50000000e-01 + 6.25000000e-01 3.75000000e-01 8.75000000e-01 + 6.25000000e-01 3.75000000e-01 1.00000000e+00 + 6.25000000e-01 5.00000000e-01 6.25000000e-01 + 6.25000000e-01 5.00000000e-01 7.50000000e-01 + 6.25000000e-01 5.00000000e-01 8.75000000e-01 + 6.25000000e-01 5.00000000e-01 1.00000000e+00 + 6.25000000e-01 6.25000000e-01 6.25000000e-01 + 6.25000000e-01 6.25000000e-01 7.50000000e-01 + 6.25000000e-01 6.25000000e-01 8.75000000e-01 + 6.25000000e-01 6.25000000e-01 1.00000000e+00 + 6.25000000e-01 7.50000000e-01 6.25000000e-01 + 6.25000000e-01 7.50000000e-01 7.50000000e-01 + 6.25000000e-01 7.50000000e-01 8.75000000e-01 + 6.25000000e-01 7.50000000e-01 1.00000000e+00 + 6.25000000e-01 8.75000000e-01 6.25000000e-01 + 6.25000000e-01 8.75000000e-01 7.50000000e-01 + 6.25000000e-01 8.75000000e-01 8.75000000e-01 + 6.25000000e-01 8.75000000e-01 1.00000000e+00 + 6.25000000e-01 1.00000000e+00 6.25000000e-01 + 6.25000000e-01 1.00000000e+00 7.50000000e-01 + 6.25000000e-01 1.00000000e+00 8.75000000e-01 + 6.25000000e-01 1.00000000e+00 1.00000000e+00 + 7.50000000e-01 0.00000000e+00 6.25000000e-01 + 7.50000000e-01 1.25000000e-01 6.25000000e-01 + 7.50000000e-01 0.00000000e+00 7.50000000e-01 + 7.50000000e-01 1.25000000e-01 7.50000000e-01 + 7.50000000e-01 0.00000000e+00 8.75000000e-01 + 7.50000000e-01 1.25000000e-01 8.75000000e-01 + 7.50000000e-01 0.00000000e+00 1.00000000e+00 + 7.50000000e-01 1.25000000e-01 1.00000000e+00 + 7.50000000e-01 2.50000000e-01 6.25000000e-01 + 7.50000000e-01 2.50000000e-01 7.50000000e-01 + 7.50000000e-01 2.50000000e-01 8.75000000e-01 + 7.50000000e-01 2.50000000e-01 1.00000000e+00 + 7.50000000e-01 3.75000000e-01 6.25000000e-01 + 7.50000000e-01 3.75000000e-01 7.50000000e-01 + 7.50000000e-01 3.75000000e-01 8.75000000e-01 + 7.50000000e-01 3.75000000e-01 1.00000000e+00 + 7.50000000e-01 5.00000000e-01 6.25000000e-01 + 7.50000000e-01 5.00000000e-01 7.50000000e-01 + 7.50000000e-01 5.00000000e-01 8.75000000e-01 + 7.50000000e-01 5.00000000e-01 1.00000000e+00 + 7.50000000e-01 6.25000000e-01 6.25000000e-01 + 7.50000000e-01 6.25000000e-01 7.50000000e-01 + 7.50000000e-01 6.25000000e-01 8.75000000e-01 + 7.50000000e-01 6.25000000e-01 1.00000000e+00 + 7.50000000e-01 7.50000000e-01 6.25000000e-01 + 7.50000000e-01 7.50000000e-01 7.50000000e-01 + 7.50000000e-01 7.50000000e-01 8.75000000e-01 + 7.50000000e-01 7.50000000e-01 1.00000000e+00 + 7.50000000e-01 8.75000000e-01 6.25000000e-01 + 7.50000000e-01 8.75000000e-01 7.50000000e-01 + 7.50000000e-01 8.75000000e-01 8.75000000e-01 + 7.50000000e-01 8.75000000e-01 1.00000000e+00 + 7.50000000e-01 1.00000000e+00 6.25000000e-01 + 7.50000000e-01 1.00000000e+00 7.50000000e-01 + 7.50000000e-01 1.00000000e+00 8.75000000e-01 + 7.50000000e-01 1.00000000e+00 1.00000000e+00 + 8.75000000e-01 0.00000000e+00 6.25000000e-01 + 8.75000000e-01 1.25000000e-01 6.25000000e-01 + 8.75000000e-01 0.00000000e+00 7.50000000e-01 + 8.75000000e-01 1.25000000e-01 7.50000000e-01 + 8.75000000e-01 0.00000000e+00 8.75000000e-01 + 8.75000000e-01 1.25000000e-01 8.75000000e-01 + 8.75000000e-01 0.00000000e+00 1.00000000e+00 + 8.75000000e-01 1.25000000e-01 1.00000000e+00 + 8.75000000e-01 2.50000000e-01 6.25000000e-01 + 8.75000000e-01 2.50000000e-01 7.50000000e-01 + 8.75000000e-01 2.50000000e-01 8.75000000e-01 + 8.75000000e-01 2.50000000e-01 1.00000000e+00 + 8.75000000e-01 3.75000000e-01 6.25000000e-01 + 8.75000000e-01 3.75000000e-01 7.50000000e-01 + 8.75000000e-01 3.75000000e-01 8.75000000e-01 + 8.75000000e-01 3.75000000e-01 1.00000000e+00 + 8.75000000e-01 5.00000000e-01 6.25000000e-01 + 8.75000000e-01 5.00000000e-01 7.50000000e-01 + 8.75000000e-01 5.00000000e-01 8.75000000e-01 + 8.75000000e-01 5.00000000e-01 1.00000000e+00 + 8.75000000e-01 6.25000000e-01 6.25000000e-01 + 8.75000000e-01 6.25000000e-01 7.50000000e-01 + 8.75000000e-01 6.25000000e-01 8.75000000e-01 + 8.75000000e-01 6.25000000e-01 1.00000000e+00 + 8.75000000e-01 7.50000000e-01 6.25000000e-01 + 8.75000000e-01 7.50000000e-01 7.50000000e-01 + 8.75000000e-01 7.50000000e-01 8.75000000e-01 + 8.75000000e-01 7.50000000e-01 1.00000000e+00 + 8.75000000e-01 8.75000000e-01 6.25000000e-01 + 8.75000000e-01 8.75000000e-01 7.50000000e-01 + 8.75000000e-01 8.75000000e-01 8.75000000e-01 + 8.75000000e-01 8.75000000e-01 1.00000000e+00 + 8.75000000e-01 1.00000000e+00 6.25000000e-01 + 8.75000000e-01 1.00000000e+00 7.50000000e-01 + 8.75000000e-01 1.00000000e+00 8.75000000e-01 + 8.75000000e-01 1.00000000e+00 1.00000000e+00 + 1.00000000e+00 0.00000000e+00 6.25000000e-01 + 1.00000000e+00 1.25000000e-01 6.25000000e-01 + 1.00000000e+00 0.00000000e+00 7.50000000e-01 + 1.00000000e+00 1.25000000e-01 7.50000000e-01 + 1.00000000e+00 0.00000000e+00 8.75000000e-01 + 1.00000000e+00 1.25000000e-01 8.75000000e-01 + 1.00000000e+00 0.00000000e+00 1.00000000e+00 + 1.00000000e+00 1.25000000e-01 1.00000000e+00 + 1.00000000e+00 2.50000000e-01 6.25000000e-01 + 1.00000000e+00 2.50000000e-01 7.50000000e-01 + 1.00000000e+00 2.50000000e-01 8.75000000e-01 + 1.00000000e+00 2.50000000e-01 1.00000000e+00 + 1.00000000e+00 3.75000000e-01 6.25000000e-01 + 1.00000000e+00 3.75000000e-01 7.50000000e-01 + 1.00000000e+00 3.75000000e-01 8.75000000e-01 + 1.00000000e+00 3.75000000e-01 1.00000000e+00 + 1.00000000e+00 5.00000000e-01 6.25000000e-01 + 1.00000000e+00 5.00000000e-01 7.50000000e-01 + 1.00000000e+00 5.00000000e-01 8.75000000e-01 + 1.00000000e+00 5.00000000e-01 1.00000000e+00 + 1.00000000e+00 6.25000000e-01 6.25000000e-01 + 1.00000000e+00 6.25000000e-01 7.50000000e-01 + 1.00000000e+00 6.25000000e-01 8.75000000e-01 + 1.00000000e+00 6.25000000e-01 1.00000000e+00 + 1.00000000e+00 7.50000000e-01 6.25000000e-01 + 1.00000000e+00 7.50000000e-01 7.50000000e-01 + 1.00000000e+00 7.50000000e-01 8.75000000e-01 + 1.00000000e+00 7.50000000e-01 1.00000000e+00 + 1.00000000e+00 8.75000000e-01 6.25000000e-01 + 1.00000000e+00 8.75000000e-01 7.50000000e-01 + 1.00000000e+00 8.75000000e-01 8.75000000e-01 + 1.00000000e+00 8.75000000e-01 1.00000000e+00 + 1.00000000e+00 1.00000000e+00 6.25000000e-01 + 1.00000000e+00 1.00000000e+00 7.50000000e-01 + 1.00000000e+00 1.00000000e+00 8.75000000e-01 + 1.00000000e+00 1.00000000e+00 1.00000000e+00 + + + 0 1 + 1 2 + 2 3 + 3 0 + 0 4 + 1 5 + 2 6 + 3 7 + 4 5 + 5 6 + 6 7 + 7 4 + 4 8 + 5 9 + 6 10 + 7 11 + 8 9 + 9 10 + 10 11 + 11 8 + 8 12 + 9 13 + 10 14 + 11 15 + 12 13 + 13 14 + 14 15 + 15 12 + 2 16 + 16 17 + 17 3 + 16 18 + 17 19 + 6 18 + 18 19 + 19 7 + 18 20 + 19 21 + 10 20 + 20 21 + 21 11 + 20 22 + 21 23 + 14 22 + 22 23 + 23 15 + 16 24 + 24 25 + 25 17 + 24 26 + 25 27 + 18 26 + 26 27 + 27 19 + 26 28 + 27 29 + 20 28 + 28 29 + 29 21 + 28 30 + 29 31 + 22 30 + 30 31 + 31 23 + 24 32 + 32 33 + 33 25 + 32 34 + 33 35 + 26 34 + 34 35 + 35 27 + 34 36 + 35 37 + 28 36 + 36 37 + 37 29 + 36 38 + 37 39 + 30 38 + 38 39 + 39 31 + 32 40 + 40 41 + 41 33 + 40 42 + 41 43 + 34 42 + 42 43 + 43 35 + 42 44 + 43 45 + 36 44 + 44 45 + 45 37 + 44 46 + 45 47 + 38 46 + 46 47 + 47 39 + 40 48 + 48 49 + 49 41 + 48 50 + 49 51 + 42 50 + 50 51 + 51 43 + 50 52 + 51 53 + 44 52 + 52 53 + 53 45 + 52 54 + 53 55 + 46 54 + 54 55 + 55 47 + 48 56 + 56 57 + 57 49 + 56 58 + 57 59 + 50 58 + 58 59 + 59 51 + 58 60 + 59 61 + 52 60 + 60 61 + 61 53 + 60 62 + 61 63 + 54 62 + 62 63 + 63 55 + 56 64 + 64 65 + 65 57 + 64 66 + 65 67 + 58 66 + 66 67 + 67 59 + 66 68 + 67 69 + 60 68 + 68 69 + 69 61 + 68 70 + 69 71 + 62 70 + 70 71 + 71 63 + 1 72 + 72 73 + 73 2 + 72 74 + 73 75 + 5 74 + 74 75 + 75 6 + 74 76 + 75 77 + 9 76 + 76 77 + 77 10 + 76 78 + 77 79 + 13 78 + 78 79 + 79 14 + 73 80 + 80 16 + 80 81 + 75 81 + 81 18 + 81 82 + 77 82 + 82 20 + 82 83 + 79 83 + 83 22 + 80 84 + 84 24 + 84 85 + 81 85 + 85 26 + 85 86 + 82 86 + 86 28 + 86 87 + 83 87 + 87 30 + 84 88 + 88 32 + 88 89 + 85 89 + 89 34 + 89 90 + 86 90 + 90 36 + 90 91 + 87 91 + 91 38 + 88 92 + 92 40 + 92 93 + 89 93 + 93 42 + 93 94 + 90 94 + 94 44 + 94 95 + 91 95 + 95 46 + 92 96 + 96 48 + 96 97 + 93 97 + 97 50 + 97 98 + 94 98 + 98 52 + 98 99 + 95 99 + 99 54 + 96 100 + 100 56 + 100 101 + 97 101 + 101 58 + 101 102 + 98 102 + 102 60 + 102 103 + 99 103 + 103 62 + 100 104 + 104 64 + 104 105 + 101 105 + 105 66 + 105 106 + 102 106 + 106 68 + 106 107 + 103 107 + 107 70 + 72 108 + 108 109 + 109 73 + 108 110 + 109 111 + 74 110 + 110 111 + 111 75 + 110 112 + 111 113 + 76 112 + 112 113 + 113 77 + 112 114 + 113 115 + 78 114 + 114 115 + 115 79 + 109 116 + 116 80 + 116 117 + 111 117 + 117 81 + 117 118 + 113 118 + 118 82 + 118 119 + 115 119 + 119 83 + 116 120 + 120 84 + 120 121 + 117 121 + 121 85 + 121 122 + 118 122 + 122 86 + 122 123 + 119 123 + 123 87 + 120 124 + 124 88 + 124 125 + 121 125 + 125 89 + 125 126 + 122 126 + 126 90 + 126 127 + 123 127 + 127 91 + 124 128 + 128 92 + 128 129 + 125 129 + 129 93 + 129 130 + 126 130 + 130 94 + 130 131 + 127 131 + 131 95 + 128 132 + 132 96 + 132 133 + 129 133 + 133 97 + 133 134 + 130 134 + 134 98 + 134 135 + 131 135 + 135 99 + 132 136 + 136 100 + 136 137 + 133 137 + 137 101 + 137 138 + 134 138 + 138 102 + 138 139 + 135 139 + 139 103 + 136 140 + 140 104 + 140 141 + 137 141 + 141 105 + 141 142 + 138 142 + 142 106 + 142 143 + 139 143 + 143 107 + 108 144 + 144 145 + 145 109 + 144 146 + 145 147 + 110 146 + 146 147 + 147 111 + 146 148 + 147 149 + 112 148 + 148 149 + 149 113 + 148 150 + 149 151 + 114 150 + 150 151 + 151 115 + 145 152 + 152 116 + 152 153 + 147 153 + 153 117 + 153 154 + 149 154 + 154 118 + 154 155 + 151 155 + 155 119 + 152 156 + 156 120 + 156 157 + 153 157 + 157 121 + 157 158 + 154 158 + 158 122 + 158 159 + 155 159 + 159 123 + 156 160 + 160 124 + 160 161 + 157 161 + 161 125 + 161 162 + 158 162 + 162 126 + 162 163 + 159 163 + 163 127 + 160 164 + 164 128 + 164 165 + 161 165 + 165 129 + 165 166 + 162 166 + 166 130 + 166 167 + 163 167 + 167 131 + 164 168 + 168 132 + 168 169 + 165 169 + 169 133 + 169 170 + 166 170 + 170 134 + 170 171 + 167 171 + 171 135 + 168 172 + 172 136 + 172 173 + 169 173 + 173 137 + 173 174 + 170 174 + 174 138 + 174 175 + 171 175 + 175 139 + 172 176 + 176 140 + 176 177 + 173 177 + 177 141 + 177 178 + 174 178 + 178 142 + 178 179 + 175 179 + 179 143 + 144 180 + 180 181 + 181 145 + 180 182 + 181 183 + 146 182 + 182 183 + 183 147 + 182 184 + 183 185 + 148 184 + 184 185 + 185 149 + 184 186 + 185 187 + 150 186 + 186 187 + 187 151 + 181 188 + 188 152 + 188 189 + 183 189 + 189 153 + 189 190 + 185 190 + 190 154 + 190 191 + 187 191 + 191 155 + 188 192 + 192 156 + 192 193 + 189 193 + 193 157 + 193 194 + 190 194 + 194 158 + 194 195 + 191 195 + 195 159 + 192 196 + 196 160 + 196 197 + 193 197 + 197 161 + 197 198 + 194 198 + 198 162 + 198 199 + 195 199 + 199 163 + 196 200 + 200 164 + 200 201 + 197 201 + 201 165 + 201 202 + 198 202 + 202 166 + 202 203 + 199 203 + 203 167 + 200 204 + 204 168 + 204 205 + 201 205 + 205 169 + 205 206 + 202 206 + 206 170 + 206 207 + 203 207 + 207 171 + 204 208 + 208 172 + 208 209 + 205 209 + 209 173 + 209 210 + 206 210 + 210 174 + 210 211 + 207 211 + 211 175 + 208 212 + 212 176 + 212 213 + 209 213 + 213 177 + 213 214 + 210 214 + 214 178 + 214 215 + 211 215 + 215 179 + 180 216 + 216 217 + 217 181 + 216 218 + 217 219 + 182 218 + 218 219 + 219 183 + 218 220 + 219 221 + 184 220 + 220 221 + 221 185 + 220 222 + 221 223 + 186 222 + 222 223 + 223 187 + 217 224 + 224 188 + 224 225 + 219 225 + 225 189 + 225 226 + 221 226 + 226 190 + 226 227 + 223 227 + 227 191 + 224 228 + 228 192 + 228 229 + 225 229 + 229 193 + 229 230 + 226 230 + 230 194 + 230 231 + 227 231 + 231 195 + 228 232 + 232 196 + 232 233 + 229 233 + 233 197 + 233 234 + 230 234 + 234 198 + 234 235 + 231 235 + 235 199 + 232 236 + 236 200 + 236 237 + 233 237 + 237 201 + 237 238 + 234 238 + 238 202 + 238 239 + 235 239 + 239 203 + 236 240 + 240 204 + 240 241 + 237 241 + 241 205 + 241 242 + 238 242 + 242 206 + 242 243 + 239 243 + 243 207 + 240 244 + 244 208 + 244 245 + 241 245 + 245 209 + 245 246 + 242 246 + 246 210 + 246 247 + 243 247 + 247 211 + 244 248 + 248 212 + 248 249 + 245 249 + 249 213 + 249 250 + 246 250 + 250 214 + 250 251 + 247 251 + 251 215 + 216 252 + 252 253 + 253 217 + 252 254 + 253 255 + 218 254 + 254 255 + 255 219 + 254 256 + 255 257 + 220 256 + 256 257 + 257 221 + 256 258 + 257 259 + 222 258 + 258 259 + 259 223 + 253 260 + 260 224 + 260 261 + 255 261 + 261 225 + 261 262 + 257 262 + 262 226 + 262 263 + 259 263 + 263 227 + 260 264 + 264 228 + 264 265 + 261 265 + 265 229 + 265 266 + 262 266 + 266 230 + 266 267 + 263 267 + 267 231 + 264 268 + 268 232 + 268 269 + 265 269 + 269 233 + 269 270 + 266 270 + 270 234 + 270 271 + 267 271 + 271 235 + 268 272 + 272 236 + 272 273 + 269 273 + 273 237 + 273 274 + 270 274 + 274 238 + 274 275 + 271 275 + 275 239 + 272 276 + 276 240 + 276 277 + 273 277 + 277 241 + 277 278 + 274 278 + 278 242 + 278 279 + 275 279 + 279 243 + 276 280 + 280 244 + 280 281 + 277 281 + 281 245 + 281 282 + 278 282 + 282 246 + 282 283 + 279 283 + 283 247 + 280 284 + 284 248 + 284 285 + 281 285 + 285 249 + 285 286 + 282 286 + 286 250 + 286 287 + 283 287 + 287 251 + 252 288 + 288 289 + 289 253 + 288 290 + 289 291 + 254 290 + 290 291 + 291 255 + 290 292 + 291 293 + 256 292 + 292 293 + 293 257 + 292 294 + 293 295 + 258 294 + 294 295 + 295 259 + 289 296 + 296 260 + 296 297 + 291 297 + 297 261 + 297 298 + 293 298 + 298 262 + 298 299 + 295 299 + 299 263 + 296 300 + 300 264 + 300 301 + 297 301 + 301 265 + 301 302 + 298 302 + 302 266 + 302 303 + 299 303 + 303 267 + 300 304 + 304 268 + 304 305 + 301 305 + 305 269 + 305 306 + 302 306 + 306 270 + 306 307 + 303 307 + 307 271 + 304 308 + 308 272 + 308 309 + 305 309 + 309 273 + 309 310 + 306 310 + 310 274 + 310 311 + 307 311 + 311 275 + 308 312 + 312 276 + 312 313 + 309 313 + 313 277 + 313 314 + 310 314 + 314 278 + 314 315 + 311 315 + 315 279 + 312 316 + 316 280 + 316 317 + 313 317 + 317 281 + 317 318 + 314 318 + 318 282 + 318 319 + 315 319 + 319 283 + 316 320 + 320 284 + 320 321 + 317 321 + 321 285 + 321 322 + 318 322 + 322 286 + 322 323 + 319 323 + 323 287 + 324 325 + 325 326 + 326 327 + 327 324 + 324 328 + 325 329 + 326 330 + 327 331 + 328 329 + 329 330 + 330 331 + 331 328 + 328 332 + 329 333 + 330 334 + 331 335 + 332 333 + 333 334 + 334 335 + 335 332 + 326 336 + 336 337 + 337 327 + 336 338 + 337 339 + 330 338 + 338 339 + 339 331 + 338 340 + 339 341 + 334 340 + 340 341 + 341 335 + 336 342 + 342 343 + 343 337 + 342 344 + 343 345 + 338 344 + 344 345 + 345 339 + 344 346 + 345 347 + 340 346 + 346 347 + 347 341 + 342 348 + 348 349 + 349 343 + 348 350 + 349 351 + 344 350 + 350 351 + 351 345 + 350 352 + 351 353 + 346 352 + 352 353 + 353 347 + 348 354 + 354 355 + 355 349 + 354 356 + 355 357 + 350 356 + 356 357 + 357 351 + 356 358 + 357 359 + 352 358 + 358 359 + 359 353 + 354 360 + 360 361 + 361 355 + 360 362 + 361 363 + 356 362 + 362 363 + 363 357 + 362 364 + 363 365 + 358 364 + 364 365 + 365 359 + 360 366 + 366 367 + 367 361 + 366 368 + 367 369 + 362 368 + 368 369 + 369 363 + 368 370 + 369 371 + 364 370 + 370 371 + 371 365 + 366 372 + 372 373 + 373 367 + 372 374 + 373 375 + 368 374 + 374 375 + 375 369 + 374 376 + 375 377 + 370 376 + 376 377 + 377 371 + 372 378 + 378 379 + 379 373 + 378 380 + 379 381 + 374 380 + 380 381 + 381 375 + 380 382 + 381 383 + 376 382 + 382 383 + 383 377 + 325 384 + 384 385 + 385 326 + 384 386 + 385 387 + 329 386 + 386 387 + 387 330 + 386 388 + 387 389 + 333 388 + 388 389 + 389 334 + 385 390 + 390 336 + 390 391 + 387 391 + 391 338 + 391 392 + 389 392 + 392 340 + 390 393 + 393 342 + 393 394 + 391 394 + 394 344 + 394 395 + 392 395 + 395 346 + 393 396 + 396 348 + 396 397 + 394 397 + 397 350 + 397 398 + 395 398 + 398 352 + 396 399 + 399 354 + 399 400 + 397 400 + 400 356 + 400 401 + 398 401 + 401 358 + 399 402 + 402 360 + 402 403 + 400 403 + 403 362 + 403 404 + 401 404 + 404 364 + 402 405 + 405 366 + 405 406 + 403 406 + 406 368 + 406 407 + 404 407 + 407 370 + 405 408 + 408 372 + 408 409 + 406 409 + 409 374 + 409 410 + 407 410 + 410 376 + 408 411 + 411 378 + 411 412 + 409 412 + 412 380 + 412 413 + 410 413 + 413 382 + 384 414 + 414 415 + 415 385 + 414 416 + 415 417 + 386 416 + 416 417 + 417 387 + 416 418 + 417 419 + 388 418 + 418 419 + 419 389 + 415 420 + 420 390 + 420 421 + 417 421 + 421 391 + 421 422 + 419 422 + 422 392 + 420 423 + 423 393 + 423 424 + 421 424 + 424 394 + 424 425 + 422 425 + 425 395 + 423 426 + 426 396 + 426 427 + 424 427 + 427 397 + 427 428 + 425 428 + 428 398 + 426 429 + 429 399 + 429 430 + 427 430 + 430 400 + 430 431 + 428 431 + 431 401 + 429 432 + 432 402 + 432 433 + 430 433 + 433 403 + 433 434 + 431 434 + 434 404 + 432 435 + 435 405 + 435 436 + 433 436 + 436 406 + 436 437 + 434 437 + 437 407 + 435 438 + 438 408 + 438 439 + 436 439 + 439 409 + 439 440 + 437 440 + 440 410 + 438 441 + 441 411 + 441 442 + 439 442 + 442 412 + 442 443 + 440 443 + 443 413 + 414 444 + 444 445 + 445 415 + 444 446 + 445 447 + 416 446 + 446 447 + 447 417 + 446 448 + 447 449 + 418 448 + 448 449 + 449 419 + 445 450 + 450 420 + 450 451 + 447 451 + 451 421 + 451 452 + 449 452 + 452 422 + 450 453 + 453 423 + 453 454 + 451 454 + 454 424 + 454 455 + 452 455 + 455 425 + 453 456 + 456 426 + 456 457 + 454 457 + 457 427 + 457 458 + 455 458 + 458 428 + 456 459 + 459 429 + 459 460 + 457 460 + 460 430 + 460 461 + 458 461 + 461 431 + 459 462 + 462 432 + 462 463 + 460 463 + 463 433 + 463 464 + 461 464 + 464 434 + 462 465 + 465 435 + 465 466 + 463 466 + 466 436 + 466 467 + 464 467 + 467 437 + 465 468 + 468 438 + 468 469 + 466 469 + 469 439 + 469 470 + 467 470 + 470 440 + 468 471 + 471 441 + 471 472 + 469 472 + 472 442 + 472 473 + 470 473 + 473 443 + 444 474 + 474 475 + 475 445 + 474 476 + 475 477 + 446 476 + 476 477 + 477 447 + 476 478 + 477 479 + 448 478 + 478 479 + 479 449 + 475 480 + 480 450 + 480 481 + 477 481 + 481 451 + 481 482 + 479 482 + 482 452 + 480 483 + 483 453 + 483 484 + 481 484 + 484 454 + 484 485 + 482 485 + 485 455 + 483 486 + 486 456 + 486 487 + 484 487 + 487 457 + 487 488 + 485 488 + 488 458 + 486 489 + 489 459 + 489 490 + 487 490 + 490 460 + 490 491 + 488 491 + 491 461 + 489 492 + 492 462 + 492 493 + 490 493 + 493 463 + 493 494 + 491 494 + 494 464 + 492 495 + 495 465 + 495 496 + 493 496 + 496 466 + 496 497 + 494 497 + 497 467 + 495 498 + 498 468 + 498 499 + 496 499 + 499 469 + 499 500 + 497 500 + 500 470 + 498 501 + 501 471 + 501 502 + 499 502 + 502 472 + 502 503 + 500 503 + 503 473 + 474 504 + 504 505 + 505 475 + 504 506 + 505 507 + 476 506 + 506 507 + 507 477 + 506 508 + 507 509 + 478 508 + 508 509 + 509 479 + 505 510 + 510 480 + 510 511 + 507 511 + 511 481 + 511 512 + 509 512 + 512 482 + 510 513 + 513 483 + 513 514 + 511 514 + 514 484 + 514 515 + 512 515 + 515 485 + 513 516 + 516 486 + 516 517 + 514 517 + 517 487 + 517 518 + 515 518 + 518 488 + 516 519 + 519 489 + 519 520 + 517 520 + 520 490 + 520 521 + 518 521 + 521 491 + 519 522 + 522 492 + 522 523 + 520 523 + 523 493 + 523 524 + 521 524 + 524 494 + 522 525 + 525 495 + 525 526 + 523 526 + 526 496 + 526 527 + 524 527 + 527 497 + 525 528 + 528 498 + 528 529 + 526 529 + 529 499 + 529 530 + 527 530 + 530 500 + 528 531 + 531 501 + 531 532 + 529 532 + 532 502 + 532 533 + 530 533 + 533 503 + 504 534 + 534 535 + 535 505 + 534 536 + 535 537 + 506 536 + 536 537 + 537 507 + 536 538 + 537 539 + 508 538 + 538 539 + 539 509 + 535 540 + 540 510 + 540 541 + 537 541 + 541 511 + 541 542 + 539 542 + 542 512 + 540 543 + 543 513 + 543 544 + 541 544 + 544 514 + 544 545 + 542 545 + 545 515 + 543 546 + 546 516 + 546 547 + 544 547 + 547 517 + 547 548 + 545 548 + 548 518 + 546 549 + 549 519 + 549 550 + 547 550 + 550 520 + 550 551 + 548 551 + 551 521 + 549 552 + 552 522 + 552 553 + 550 553 + 553 523 + 553 554 + 551 554 + 554 524 + 552 555 + 555 525 + 555 556 + 553 556 + 556 526 + 556 557 + 554 557 + 557 527 + 555 558 + 558 528 + 558 559 + 556 559 + 559 529 + 559 560 + 557 560 + 560 530 + 558 561 + 561 531 + 561 562 + 559 562 + 562 532 + 562 563 + 560 563 + 563 533 + 534 564 + 564 565 + 565 535 + 564 566 + 565 567 + 536 566 + 566 567 + 567 537 + 566 568 + 567 569 + 538 568 + 568 569 + 569 539 + 565 570 + 570 540 + 570 571 + 567 571 + 571 541 + 571 572 + 569 572 + 572 542 + 570 573 + 573 543 + 573 574 + 571 574 + 574 544 + 574 575 + 572 575 + 575 545 + 573 576 + 576 546 + 576 577 + 574 577 + 577 547 + 577 578 + 575 578 + 578 548 + 576 579 + 579 549 + 579 580 + 577 580 + 580 550 + 580 581 + 578 581 + 581 551 + 579 582 + 582 552 + 582 583 + 580 583 + 583 553 + 583 584 + 581 584 + 584 554 + 582 585 + 585 555 + 585 586 + 583 586 + 586 556 + 586 587 + 584 587 + 587 557 + 585 588 + 588 558 + 588 589 + 586 589 + 589 559 + 589 590 + 587 590 + 590 560 + 588 591 + 591 561 + 591 592 + 589 592 + 592 562 + 592 593 + 590 593 + 593 563 + 564 594 + 594 595 + 595 565 + 594 596 + 595 597 + 566 596 + 596 597 + 597 567 + 596 598 + 597 599 + 568 598 + 598 599 + 599 569 + 595 600 + 600 570 + 600 601 + 597 601 + 601 571 + 601 602 + 599 602 + 602 572 + 600 603 + 603 573 + 603 604 + 601 604 + 604 574 + 604 605 + 602 605 + 605 575 + 603 606 + 606 576 + 606 607 + 604 607 + 607 577 + 607 608 + 605 608 + 608 578 + 606 609 + 609 579 + 609 610 + 607 610 + 610 580 + 610 611 + 608 611 + 611 581 + 609 612 + 612 582 + 612 613 + 610 613 + 613 583 + 613 614 + 611 614 + 614 584 + 612 615 + 615 585 + 615 616 + 613 616 + 616 586 + 616 617 + 614 617 + 617 587 + 615 618 + 618 588 + 618 619 + 616 619 + 619 589 + 619 620 + 617 620 + 620 590 + 618 621 + 621 591 + 621 622 + 619 622 + 622 592 + 622 623 + 620 623 + 623 593 + 624 625 + 625 626 + 626 627 + 627 624 + 624 628 + 625 629 + 626 630 + 627 631 + 628 629 + 629 630 + 630 631 + 631 628 + 628 632 + 629 633 + 630 634 + 631 635 + 632 633 + 633 634 + 634 635 + 635 632 + 632 636 + 633 637 + 634 638 + 635 639 + 636 637 + 637 638 + 638 639 + 639 636 + 626 640 + 640 641 + 641 627 + 640 642 + 641 643 + 630 642 + 642 643 + 643 631 + 642 644 + 643 645 + 634 644 + 644 645 + 645 635 + 644 646 + 645 647 + 638 646 + 646 647 + 647 639 + 640 648 + 648 649 + 649 641 + 648 650 + 649 651 + 642 650 + 650 651 + 651 643 + 650 652 + 651 653 + 644 652 + 652 653 + 653 645 + 652 654 + 653 655 + 646 654 + 654 655 + 655 647 + 648 656 + 656 657 + 657 649 + 656 658 + 657 659 + 650 658 + 658 659 + 659 651 + 658 660 + 659 661 + 652 660 + 660 661 + 661 653 + 660 662 + 661 663 + 654 662 + 662 663 + 663 655 + 656 664 + 664 665 + 665 657 + 664 666 + 665 667 + 658 666 + 666 667 + 667 659 + 666 668 + 667 669 + 660 668 + 668 669 + 669 661 + 668 670 + 669 671 + 662 670 + 670 671 + 671 663 + 664 672 + 672 673 + 673 665 + 672 674 + 673 675 + 666 674 + 674 675 + 675 667 + 674 676 + 675 677 + 668 676 + 676 677 + 677 669 + 676 678 + 677 679 + 670 678 + 678 679 + 679 671 + 672 680 + 680 681 + 681 673 + 680 682 + 681 683 + 674 682 + 682 683 + 683 675 + 682 684 + 683 685 + 676 684 + 684 685 + 685 677 + 684 686 + 685 687 + 678 686 + 686 687 + 687 679 + 680 688 + 688 689 + 689 681 + 688 690 + 689 691 + 682 690 + 690 691 + 691 683 + 690 692 + 691 693 + 684 692 + 692 693 + 693 685 + 692 694 + 693 695 + 686 694 + 694 695 + 695 687 + 625 696 + 696 697 + 697 626 + 696 698 + 697 699 + 629 698 + 698 699 + 699 630 + 698 700 + 699 701 + 633 700 + 700 701 + 701 634 + 700 702 + 701 703 + 637 702 + 702 703 + 703 638 + 697 704 + 704 640 + 704 705 + 699 705 + 705 642 + 705 706 + 701 706 + 706 644 + 706 707 + 703 707 + 707 646 + 704 708 + 708 648 + 708 709 + 705 709 + 709 650 + 709 710 + 706 710 + 710 652 + 710 711 + 707 711 + 711 654 + 708 712 + 712 656 + 712 713 + 709 713 + 713 658 + 713 714 + 710 714 + 714 660 + 714 715 + 711 715 + 715 662 + 712 716 + 716 664 + 716 717 + 713 717 + 717 666 + 717 718 + 714 718 + 718 668 + 718 719 + 715 719 + 719 670 + 716 720 + 720 672 + 720 721 + 717 721 + 721 674 + 721 722 + 718 722 + 722 676 + 722 723 + 719 723 + 723 678 + 720 724 + 724 680 + 724 725 + 721 725 + 725 682 + 725 726 + 722 726 + 726 684 + 726 727 + 723 727 + 727 686 + 724 728 + 728 688 + 728 729 + 725 729 + 729 690 + 729 730 + 726 730 + 730 692 + 730 731 + 727 731 + 731 694 + 696 732 + 732 733 + 733 697 + 732 734 + 733 735 + 698 734 + 734 735 + 735 699 + 734 736 + 735 737 + 700 736 + 736 737 + 737 701 + 736 738 + 737 739 + 702 738 + 738 739 + 739 703 + 733 740 + 740 704 + 740 741 + 735 741 + 741 705 + 741 742 + 737 742 + 742 706 + 742 743 + 739 743 + 743 707 + 740 744 + 744 708 + 744 745 + 741 745 + 745 709 + 745 746 + 742 746 + 746 710 + 746 747 + 743 747 + 747 711 + 744 748 + 748 712 + 748 749 + 745 749 + 749 713 + 749 750 + 746 750 + 750 714 + 750 751 + 747 751 + 751 715 + 748 752 + 752 716 + 752 753 + 749 753 + 753 717 + 753 754 + 750 754 + 754 718 + 754 755 + 751 755 + 755 719 + 752 756 + 756 720 + 756 757 + 753 757 + 757 721 + 757 758 + 754 758 + 758 722 + 758 759 + 755 759 + 759 723 + 756 760 + 760 724 + 760 761 + 757 761 + 761 725 + 761 762 + 758 762 + 762 726 + 762 763 + 759 763 + 763 727 + 760 764 + 764 728 + 764 765 + 761 765 + 765 729 + 765 766 + 762 766 + 766 730 + 766 767 + 763 767 + 767 731 + 732 768 + 768 769 + 769 733 + 768 770 + 769 771 + 734 770 + 770 771 + 771 735 + 770 772 + 771 773 + 736 772 + 772 773 + 773 737 + 772 774 + 773 775 + 738 774 + 774 775 + 775 739 + 769 776 + 776 740 + 776 777 + 771 777 + 777 741 + 777 778 + 773 778 + 778 742 + 778 779 + 775 779 + 779 743 + 776 780 + 780 744 + 780 781 + 777 781 + 781 745 + 781 782 + 778 782 + 782 746 + 782 783 + 779 783 + 783 747 + 780 784 + 784 748 + 784 785 + 781 785 + 785 749 + 785 786 + 782 786 + 786 750 + 786 787 + 783 787 + 787 751 + 784 788 + 788 752 + 788 789 + 785 789 + 789 753 + 789 790 + 786 790 + 790 754 + 790 791 + 787 791 + 791 755 + 788 792 + 792 756 + 792 793 + 789 793 + 793 757 + 793 794 + 790 794 + 794 758 + 794 795 + 791 795 + 795 759 + 792 796 + 796 760 + 796 797 + 793 797 + 797 761 + 797 798 + 794 798 + 798 762 + 798 799 + 795 799 + 799 763 + 796 800 + 800 764 + 800 801 + 797 801 + 801 765 + 801 802 + 798 802 + 802 766 + 802 803 + 799 803 + 803 767 + 768 804 + 804 805 + 805 769 + 804 806 + 805 807 + 770 806 + 806 807 + 807 771 + 806 808 + 807 809 + 772 808 + 808 809 + 809 773 + 808 810 + 809 811 + 774 810 + 810 811 + 811 775 + 805 812 + 812 776 + 812 813 + 807 813 + 813 777 + 813 814 + 809 814 + 814 778 + 814 815 + 811 815 + 815 779 + 812 816 + 816 780 + 816 817 + 813 817 + 817 781 + 817 818 + 814 818 + 818 782 + 818 819 + 815 819 + 819 783 + 816 820 + 820 784 + 820 821 + 817 821 + 821 785 + 821 822 + 818 822 + 822 786 + 822 823 + 819 823 + 823 787 + 820 824 + 824 788 + 824 825 + 821 825 + 825 789 + 825 826 + 822 826 + 826 790 + 826 827 + 823 827 + 827 791 + 824 828 + 828 792 + 828 829 + 825 829 + 829 793 + 829 830 + 826 830 + 830 794 + 830 831 + 827 831 + 831 795 + 828 832 + 832 796 + 832 833 + 829 833 + 833 797 + 833 834 + 830 834 + 834 798 + 834 835 + 831 835 + 835 799 + 832 836 + 836 800 + 836 837 + 833 837 + 837 801 + 837 838 + 834 838 + 838 802 + 838 839 + 835 839 + 839 803 + 804 840 + 840 841 + 841 805 + 840 842 + 841 843 + 806 842 + 842 843 + 843 807 + 842 844 + 843 845 + 808 844 + 844 845 + 845 809 + 844 846 + 845 847 + 810 846 + 846 847 + 847 811 + 841 848 + 848 812 + 848 849 + 843 849 + 849 813 + 849 850 + 845 850 + 850 814 + 850 851 + 847 851 + 851 815 + 848 852 + 852 816 + 852 853 + 849 853 + 853 817 + 853 854 + 850 854 + 854 818 + 854 855 + 851 855 + 855 819 + 852 856 + 856 820 + 856 857 + 853 857 + 857 821 + 857 858 + 854 858 + 858 822 + 858 859 + 855 859 + 859 823 + 856 860 + 860 824 + 860 861 + 857 861 + 861 825 + 861 862 + 858 862 + 862 826 + 862 863 + 859 863 + 863 827 + 860 864 + 864 828 + 864 865 + 861 865 + 865 829 + 865 866 + 862 866 + 866 830 + 866 867 + 863 867 + 867 831 + 864 868 + 868 832 + 868 869 + 865 869 + 869 833 + 869 870 + 866 870 + 870 834 + 870 871 + 867 871 + 871 835 + 868 872 + 872 836 + 872 873 + 869 873 + 873 837 + 873 874 + 870 874 + 874 838 + 874 875 + 871 875 + 875 839 + 840 876 + 876 877 + 877 841 + 876 878 + 877 879 + 842 878 + 878 879 + 879 843 + 878 880 + 879 881 + 844 880 + 880 881 + 881 845 + 880 882 + 881 883 + 846 882 + 882 883 + 883 847 + 877 884 + 884 848 + 884 885 + 879 885 + 885 849 + 885 886 + 881 886 + 886 850 + 886 887 + 883 887 + 887 851 + 884 888 + 888 852 + 888 889 + 885 889 + 889 853 + 889 890 + 886 890 + 890 854 + 890 891 + 887 891 + 891 855 + 888 892 + 892 856 + 892 893 + 889 893 + 893 857 + 893 894 + 890 894 + 894 858 + 894 895 + 891 895 + 895 859 + 892 896 + 896 860 + 896 897 + 893 897 + 897 861 + 897 898 + 894 898 + 898 862 + 898 899 + 895 899 + 899 863 + 896 900 + 900 864 + 900 901 + 897 901 + 901 865 + 901 902 + 898 902 + 902 866 + 902 903 + 899 903 + 903 867 + 900 904 + 904 868 + 904 905 + 901 905 + 905 869 + 905 906 + 902 906 + 906 870 + 906 907 + 903 907 + 907 871 + 904 908 + 908 872 + 908 909 + 905 909 + 909 873 + 909 910 + 906 910 + 910 874 + 910 911 + 907 911 + 911 875 + 876 912 + 912 913 + 913 877 + 912 914 + 913 915 + 878 914 + 914 915 + 915 879 + 914 916 + 915 917 + 880 916 + 916 917 + 917 881 + 916 918 + 917 919 + 882 918 + 918 919 + 919 883 + 913 920 + 920 884 + 920 921 + 915 921 + 921 885 + 921 922 + 917 922 + 922 886 + 922 923 + 919 923 + 923 887 + 920 924 + 924 888 + 924 925 + 921 925 + 925 889 + 925 926 + 922 926 + 926 890 + 926 927 + 923 927 + 927 891 + 924 928 + 928 892 + 928 929 + 925 929 + 929 893 + 929 930 + 926 930 + 930 894 + 930 931 + 927 931 + 931 895 + 928 932 + 932 896 + 932 933 + 929 933 + 933 897 + 933 934 + 930 934 + 934 898 + 934 935 + 931 935 + 935 899 + 932 936 + 936 900 + 936 937 + 933 937 + 937 901 + 937 938 + 934 938 + 938 902 + 938 939 + 935 939 + 939 903 + 936 940 + 940 904 + 940 941 + 937 941 + 941 905 + 941 942 + 938 942 + 942 906 + 942 943 + 939 943 + 943 907 + 940 944 + 944 908 + 944 945 + 941 945 + 945 909 + 945 946 + 942 946 + 946 910 + 946 947 + 943 947 + 947 911 + + + 0 1 2 3 + 0 5 8 4 + 1 6 9 5 + 2 6 10 7 + 3 7 11 4 + 8 9 10 11 + 8 13 16 12 + 9 14 17 13 + 10 14 18 15 + 11 15 19 12 + 16 17 18 19 + 16 21 24 20 + 17 22 25 21 + 18 22 26 23 + 19 23 27 20 + 24 25 26 27 + 2 28 29 30 + 28 31 33 6 + 29 31 34 32 + 30 32 35 7 + 10 33 34 35 + 33 36 38 14 + 34 36 39 37 + 35 37 40 15 + 18 38 39 40 + 38 41 43 22 + 39 41 44 42 + 40 42 45 23 + 26 43 44 45 + 29 46 47 48 + 46 49 51 31 + 47 49 52 50 + 48 50 53 32 + 34 51 52 53 + 51 54 56 36 + 52 54 57 55 + 53 55 58 37 + 39 56 57 58 + 56 59 61 41 + 57 59 62 60 + 58 60 63 42 + 44 61 62 63 + 47 64 65 66 + 64 67 69 49 + 65 67 70 68 + 66 68 71 50 + 52 69 70 71 + 69 72 74 54 + 70 72 75 73 + 71 73 76 55 + 57 74 75 76 + 74 77 79 59 + 75 77 80 78 + 76 78 81 60 + 62 79 80 81 + 65 82 83 84 + 82 85 87 67 + 83 85 88 86 + 84 86 89 68 + 70 87 88 89 + 87 90 92 72 + 88 90 93 91 + 89 91 94 73 + 75 92 93 94 + 92 95 97 77 + 93 95 98 96 + 94 96 99 78 + 80 97 98 99 + 83 100 101 102 + 100 103 105 85 + 101 103 106 104 + 102 104 107 86 + 88 105 106 107 + 105 108 110 90 + 106 108 111 109 + 107 109 112 91 + 93 110 111 112 + 110 113 115 95 + 111 113 116 114 + 112 114 117 96 + 98 115 116 117 + 101 118 119 120 + 118 121 123 103 + 119 121 124 122 + 120 122 125 104 + 106 123 124 125 + 123 126 128 108 + 124 126 129 127 + 125 127 130 109 + 111 128 129 130 + 128 131 133 113 + 129 131 134 132 + 130 132 135 114 + 116 133 134 135 + 119 136 137 138 + 136 139 141 121 + 137 139 142 140 + 138 140 143 122 + 124 141 142 143 + 141 144 146 126 + 142 144 147 145 + 143 145 148 127 + 129 146 147 148 + 146 149 151 131 + 147 149 152 150 + 148 150 153 132 + 134 151 152 153 + 154 155 156 1 + 154 157 159 5 + 155 158 160 157 + 156 158 161 6 + 159 160 161 9 + 159 162 164 13 + 160 163 165 162 + 161 163 166 14 + 164 165 166 17 + 164 167 169 21 + 165 168 170 167 + 166 168 171 22 + 169 170 171 25 + 156 172 173 28 + 172 174 175 158 + 173 174 176 31 + 161 175 176 33 + 175 177 178 163 + 176 177 179 36 + 166 178 179 38 + 178 180 181 168 + 179 180 182 41 + 171 181 182 43 + 173 183 184 46 + 183 185 186 174 + 184 185 187 49 + 176 186 187 51 + 186 188 189 177 + 187 188 190 54 + 179 189 190 56 + 189 191 192 180 + 190 191 193 59 + 182 192 193 61 + 184 194 195 64 + 194 196 197 185 + 195 196 198 67 + 187 197 198 69 + 197 199 200 188 + 198 199 201 72 + 190 200 201 74 + 200 202 203 191 + 201 202 204 77 + 193 203 204 79 + 195 205 206 82 + 205 207 208 196 + 206 207 209 85 + 198 208 209 87 + 208 210 211 199 + 209 210 212 90 + 201 211 212 92 + 211 213 214 202 + 212 213 215 95 + 204 214 215 97 + 206 216 217 100 + 216 218 219 207 + 217 218 220 103 + 209 219 220 105 + 219 221 222 210 + 220 221 223 108 + 212 222 223 110 + 222 224 225 213 + 223 224 226 113 + 215 225 226 115 + 217 227 228 118 + 227 229 230 218 + 228 229 231 121 + 220 230 231 123 + 230 232 233 221 + 231 232 234 126 + 223 233 234 128 + 233 235 236 224 + 234 235 237 131 + 226 236 237 133 + 228 238 239 136 + 238 240 241 229 + 239 240 242 139 + 231 241 242 141 + 241 243 244 232 + 242 243 245 144 + 234 244 245 146 + 244 246 247 235 + 245 246 248 149 + 237 247 248 151 + 249 250 251 155 + 249 252 254 157 + 250 253 255 252 + 251 253 256 158 + 254 255 256 160 + 254 257 259 162 + 255 258 260 257 + 256 258 261 163 + 259 260 261 165 + 259 262 264 167 + 260 263 265 262 + 261 263 266 168 + 264 265 266 170 + 251 267 268 172 + 267 269 270 253 + 268 269 271 174 + 256 270 271 175 + 270 272 273 258 + 271 272 274 177 + 261 273 274 178 + 273 275 276 263 + 274 275 277 180 + 266 276 277 181 + 268 278 279 183 + 278 280 281 269 + 279 280 282 185 + 271 281 282 186 + 281 283 284 272 + 282 283 285 188 + 274 284 285 189 + 284 286 287 275 + 285 286 288 191 + 277 287 288 192 + 279 289 290 194 + 289 291 292 280 + 290 291 293 196 + 282 292 293 197 + 292 294 295 283 + 293 294 296 199 + 285 295 296 200 + 295 297 298 286 + 296 297 299 202 + 288 298 299 203 + 290 300 301 205 + 300 302 303 291 + 301 302 304 207 + 293 303 304 208 + 303 305 306 294 + 304 305 307 210 + 296 306 307 211 + 306 308 309 297 + 307 308 310 213 + 299 309 310 214 + 301 311 312 216 + 311 313 314 302 + 312 313 315 218 + 304 314 315 219 + 314 316 317 305 + 315 316 318 221 + 307 317 318 222 + 317 319 320 308 + 318 319 321 224 + 310 320 321 225 + 312 322 323 227 + 322 324 325 313 + 323 324 326 229 + 315 325 326 230 + 325 327 328 316 + 326 327 329 232 + 318 328 329 233 + 328 330 331 319 + 329 330 332 235 + 321 331 332 236 + 323 333 334 238 + 333 335 336 324 + 334 335 337 240 + 326 336 337 241 + 336 338 339 327 + 337 338 340 243 + 329 339 340 244 + 339 341 342 330 + 340 341 343 246 + 332 342 343 247 + 344 345 346 250 + 344 347 349 252 + 345 348 350 347 + 346 348 351 253 + 349 350 351 255 + 349 352 354 257 + 350 353 355 352 + 351 353 356 258 + 354 355 356 260 + 354 357 359 262 + 355 358 360 357 + 356 358 361 263 + 359 360 361 265 + 346 362 363 267 + 362 364 365 348 + 363 364 366 269 + 351 365 366 270 + 365 367 368 353 + 366 367 369 272 + 356 368 369 273 + 368 370 371 358 + 369 370 372 275 + 361 371 372 276 + 363 373 374 278 + 373 375 376 364 + 374 375 377 280 + 366 376 377 281 + 376 378 379 367 + 377 378 380 283 + 369 379 380 284 + 379 381 382 370 + 380 381 383 286 + 372 382 383 287 + 374 384 385 289 + 384 386 387 375 + 385 386 388 291 + 377 387 388 292 + 387 389 390 378 + 388 389 391 294 + 380 390 391 295 + 390 392 393 381 + 391 392 394 297 + 383 393 394 298 + 385 395 396 300 + 395 397 398 386 + 396 397 399 302 + 388 398 399 303 + 398 400 401 389 + 399 400 402 305 + 391 401 402 306 + 401 403 404 392 + 402 403 405 308 + 394 404 405 309 + 396 406 407 311 + 406 408 409 397 + 407 408 410 313 + 399 409 410 314 + 409 411 412 400 + 410 411 413 316 + 402 412 413 317 + 412 414 415 403 + 413 414 416 319 + 405 415 416 320 + 407 417 418 322 + 417 419 420 408 + 418 419 421 324 + 410 420 421 325 + 420 422 423 411 + 421 422 424 327 + 413 423 424 328 + 423 425 426 414 + 424 425 427 330 + 416 426 427 331 + 418 428 429 333 + 428 430 431 419 + 429 430 432 335 + 421 431 432 336 + 431 433 434 422 + 432 433 435 338 + 424 434 435 339 + 434 436 437 425 + 435 436 438 341 + 427 437 438 342 + 439 440 441 345 + 439 442 444 347 + 440 443 445 442 + 441 443 446 348 + 444 445 446 350 + 444 447 449 352 + 445 448 450 447 + 446 448 451 353 + 449 450 451 355 + 449 452 454 357 + 450 453 455 452 + 451 453 456 358 + 454 455 456 360 + 441 457 458 362 + 457 459 460 443 + 458 459 461 364 + 446 460 461 365 + 460 462 463 448 + 461 462 464 367 + 451 463 464 368 + 463 465 466 453 + 464 465 467 370 + 456 466 467 371 + 458 468 469 373 + 468 470 471 459 + 469 470 472 375 + 461 471 472 376 + 471 473 474 462 + 472 473 475 378 + 464 474 475 379 + 474 476 477 465 + 475 476 478 381 + 467 477 478 382 + 469 479 480 384 + 479 481 482 470 + 480 481 483 386 + 472 482 483 387 + 482 484 485 473 + 483 484 486 389 + 475 485 486 390 + 485 487 488 476 + 486 487 489 392 + 478 488 489 393 + 480 490 491 395 + 490 492 493 481 + 491 492 494 397 + 483 493 494 398 + 493 495 496 484 + 494 495 497 400 + 486 496 497 401 + 496 498 499 487 + 497 498 500 403 + 489 499 500 404 + 491 501 502 406 + 501 503 504 492 + 502 503 505 408 + 494 504 505 409 + 504 506 507 495 + 505 506 508 411 + 497 507 508 412 + 507 509 510 498 + 508 509 511 414 + 500 510 511 415 + 502 512 513 417 + 512 514 515 503 + 513 514 516 419 + 505 515 516 420 + 515 517 518 506 + 516 517 519 422 + 508 518 519 423 + 518 520 521 509 + 519 520 522 425 + 511 521 522 426 + 513 523 524 428 + 523 525 526 514 + 524 525 527 430 + 516 526 527 431 + 526 528 529 517 + 527 528 530 433 + 519 529 530 434 + 529 531 532 520 + 530 531 533 436 + 522 532 533 437 + 534 535 536 440 + 534 537 539 442 + 535 538 540 537 + 536 538 541 443 + 539 540 541 445 + 539 542 544 447 + 540 543 545 542 + 541 543 546 448 + 544 545 546 450 + 544 547 549 452 + 545 548 550 547 + 546 548 551 453 + 549 550 551 455 + 536 552 553 457 + 552 554 555 538 + 553 554 556 459 + 541 555 556 460 + 555 557 558 543 + 556 557 559 462 + 546 558 559 463 + 558 560 561 548 + 559 560 562 465 + 551 561 562 466 + 553 563 564 468 + 563 565 566 554 + 564 565 567 470 + 556 566 567 471 + 566 568 569 557 + 567 568 570 473 + 559 569 570 474 + 569 571 572 560 + 570 571 573 476 + 562 572 573 477 + 564 574 575 479 + 574 576 577 565 + 575 576 578 481 + 567 577 578 482 + 577 579 580 568 + 578 579 581 484 + 570 580 581 485 + 580 582 583 571 + 581 582 584 487 + 573 583 584 488 + 575 585 586 490 + 585 587 588 576 + 586 587 589 492 + 578 588 589 493 + 588 590 591 579 + 589 590 592 495 + 581 591 592 496 + 591 593 594 582 + 592 593 595 498 + 584 594 595 499 + 586 596 597 501 + 596 598 599 587 + 597 598 600 503 + 589 599 600 504 + 599 601 602 590 + 600 601 603 506 + 592 602 603 507 + 602 604 605 593 + 603 604 606 509 + 595 605 606 510 + 597 607 608 512 + 607 609 610 598 + 608 609 611 514 + 600 610 611 515 + 610 612 613 601 + 611 612 614 517 + 603 613 614 518 + 613 615 616 604 + 614 615 617 520 + 606 616 617 521 + 608 618 619 523 + 618 620 621 609 + 619 620 622 525 + 611 621 622 526 + 621 623 624 612 + 622 623 625 528 + 614 624 625 529 + 624 626 627 615 + 625 626 628 531 + 617 627 628 532 + 629 630 631 535 + 629 632 634 537 + 630 633 635 632 + 631 633 636 538 + 634 635 636 540 + 634 637 639 542 + 635 638 640 637 + 636 638 641 543 + 639 640 641 545 + 639 642 644 547 + 640 643 645 642 + 641 643 646 548 + 644 645 646 550 + 631 647 648 552 + 647 649 650 633 + 648 649 651 554 + 636 650 651 555 + 650 652 653 638 + 651 652 654 557 + 641 653 654 558 + 653 655 656 643 + 654 655 657 560 + 646 656 657 561 + 648 658 659 563 + 658 660 661 649 + 659 660 662 565 + 651 661 662 566 + 661 663 664 652 + 662 663 665 568 + 654 664 665 569 + 664 666 667 655 + 665 666 668 571 + 657 667 668 572 + 659 669 670 574 + 669 671 672 660 + 670 671 673 576 + 662 672 673 577 + 672 674 675 663 + 673 674 676 579 + 665 675 676 580 + 675 677 678 666 + 676 677 679 582 + 668 678 679 583 + 670 680 681 585 + 680 682 683 671 + 681 682 684 587 + 673 683 684 588 + 683 685 686 674 + 684 685 687 590 + 676 686 687 591 + 686 688 689 677 + 687 688 690 593 + 679 689 690 594 + 681 691 692 596 + 691 693 694 682 + 692 693 695 598 + 684 694 695 599 + 694 696 697 685 + 695 696 698 601 + 687 697 698 602 + 697 699 700 688 + 698 699 701 604 + 690 700 701 605 + 692 702 703 607 + 702 704 705 693 + 703 704 706 609 + 695 705 706 610 + 705 707 708 696 + 706 707 709 612 + 698 708 709 613 + 708 710 711 699 + 709 710 712 615 + 701 711 712 616 + 703 713 714 618 + 713 715 716 704 + 714 715 717 620 + 706 716 717 621 + 716 718 719 707 + 717 718 720 623 + 709 719 720 624 + 719 721 722 710 + 720 721 723 626 + 712 722 723 627 + 724 725 726 630 + 724 727 729 632 + 725 728 730 727 + 726 728 731 633 + 729 730 731 635 + 729 732 734 637 + 730 733 735 732 + 731 733 736 638 + 734 735 736 640 + 734 737 739 642 + 735 738 740 737 + 736 738 741 643 + 739 740 741 645 + 726 742 743 647 + 742 744 745 728 + 743 744 746 649 + 731 745 746 650 + 745 747 748 733 + 746 747 749 652 + 736 748 749 653 + 748 750 751 738 + 749 750 752 655 + 741 751 752 656 + 743 753 754 658 + 753 755 756 744 + 754 755 757 660 + 746 756 757 661 + 756 758 759 747 + 757 758 760 663 + 749 759 760 664 + 759 761 762 750 + 760 761 763 666 + 752 762 763 667 + 754 764 765 669 + 764 766 767 755 + 765 766 768 671 + 757 767 768 672 + 767 769 770 758 + 768 769 771 674 + 760 770 771 675 + 770 772 773 761 + 771 772 774 677 + 763 773 774 678 + 765 775 776 680 + 775 777 778 766 + 776 777 779 682 + 768 778 779 683 + 778 780 781 769 + 779 780 782 685 + 771 781 782 686 + 781 783 784 772 + 782 783 785 688 + 774 784 785 689 + 776 786 787 691 + 786 788 789 777 + 787 788 790 693 + 779 789 790 694 + 789 791 792 780 + 790 791 793 696 + 782 792 793 697 + 792 794 795 783 + 793 794 796 699 + 785 795 796 700 + 787 797 798 702 + 797 799 800 788 + 798 799 801 704 + 790 800 801 705 + 800 802 803 791 + 801 802 804 707 + 793 803 804 708 + 803 805 806 794 + 804 805 807 710 + 796 806 807 711 + 798 808 809 713 + 808 810 811 799 + 809 810 812 715 + 801 811 812 716 + 811 813 814 802 + 812 813 815 718 + 804 814 815 719 + 814 816 817 805 + 815 816 818 721 + 807 817 818 722 + 819 820 821 822 + 819 824 827 823 + 820 825 828 824 + 821 825 829 826 + 822 826 830 823 + 827 828 829 830 + 827 832 835 831 + 828 833 836 832 + 829 833 837 834 + 830 834 838 831 + 835 836 837 838 + 821 839 840 841 + 839 842 844 825 + 840 842 845 843 + 841 843 846 826 + 829 844 845 846 + 844 847 849 833 + 845 847 850 848 + 846 848 851 834 + 837 849 850 851 + 840 852 853 854 + 852 855 857 842 + 853 855 858 856 + 854 856 859 843 + 845 857 858 859 + 857 860 862 847 + 858 860 863 861 + 859 861 864 848 + 850 862 863 864 + 853 865 866 867 + 865 868 870 855 + 866 868 871 869 + 867 869 872 856 + 858 870 871 872 + 870 873 875 860 + 871 873 876 874 + 872 874 877 861 + 863 875 876 877 + 866 878 879 880 + 878 881 883 868 + 879 881 884 882 + 880 882 885 869 + 871 883 884 885 + 883 886 888 873 + 884 886 889 887 + 885 887 890 874 + 876 888 889 890 + 879 891 892 893 + 891 894 896 881 + 892 894 897 895 + 893 895 898 882 + 884 896 897 898 + 896 899 901 886 + 897 899 902 900 + 898 900 903 887 + 889 901 902 903 + 892 904 905 906 + 904 907 909 894 + 905 907 910 908 + 906 908 911 895 + 897 909 910 911 + 909 912 914 899 + 910 912 915 913 + 911 913 916 900 + 902 914 915 916 + 905 917 918 919 + 917 920 922 907 + 918 920 923 921 + 919 921 924 908 + 910 922 923 924 + 922 925 927 912 + 923 925 928 926 + 924 926 929 913 + 915 927 928 929 + 918 930 931 932 + 930 933 935 920 + 931 933 936 934 + 932 934 937 921 + 923 935 936 937 + 935 938 940 925 + 936 938 941 939 + 937 939 942 926 + 928 940 941 942 + 943 944 945 820 + 943 946 948 824 + 944 947 949 946 + 945 947 950 825 + 948 949 950 828 + 948 951 953 832 + 949 952 954 951 + 950 952 955 833 + 953 954 955 836 + 945 956 957 839 + 956 958 959 947 + 957 958 960 842 + 950 959 960 844 + 959 961 962 952 + 960 961 963 847 + 955 962 963 849 + 957 964 965 852 + 964 966 967 958 + 965 966 968 855 + 960 967 968 857 + 967 969 970 961 + 968 969 971 860 + 963 970 971 862 + 965 972 973 865 + 972 974 975 966 + 973 974 976 868 + 968 975 976 870 + 975 977 978 969 + 976 977 979 873 + 971 978 979 875 + 973 980 981 878 + 980 982 983 974 + 981 982 984 881 + 976 983 984 883 + 983 985 986 977 + 984 985 987 886 + 979 986 987 888 + 981 988 989 891 + 988 990 991 982 + 989 990 992 894 + 984 991 992 896 + 991 993 994 985 + 992 993 995 899 + 987 994 995 901 + 989 996 997 904 + 996 998 999 990 + 997 998 1000 907 + 992 999 1000 909 + 999 1001 1002 993 + 1000 1001 1003 912 + 995 1002 1003 914 + 997 1004 1005 917 + 1004 1006 1007 998 + 1005 1006 1008 920 + 1000 1007 1008 922 + 1007 1009 1010 1001 + 1008 1009 1011 925 + 1003 1010 1011 927 + 1005 1012 1013 930 + 1012 1014 1015 1006 + 1013 1014 1016 933 + 1008 1015 1016 935 + 1015 1017 1018 1009 + 1016 1017 1019 938 + 1011 1018 1019 940 + 1020 1021 1022 944 + 1020 1023 1025 946 + 1021 1024 1026 1023 + 1022 1024 1027 947 + 1025 1026 1027 949 + 1025 1028 1030 951 + 1026 1029 1031 1028 + 1027 1029 1032 952 + 1030 1031 1032 954 + 1022 1033 1034 956 + 1033 1035 1036 1024 + 1034 1035 1037 958 + 1027 1036 1037 959 + 1036 1038 1039 1029 + 1037 1038 1040 961 + 1032 1039 1040 962 + 1034 1041 1042 964 + 1041 1043 1044 1035 + 1042 1043 1045 966 + 1037 1044 1045 967 + 1044 1046 1047 1038 + 1045 1046 1048 969 + 1040 1047 1048 970 + 1042 1049 1050 972 + 1049 1051 1052 1043 + 1050 1051 1053 974 + 1045 1052 1053 975 + 1052 1054 1055 1046 + 1053 1054 1056 977 + 1048 1055 1056 978 + 1050 1057 1058 980 + 1057 1059 1060 1051 + 1058 1059 1061 982 + 1053 1060 1061 983 + 1060 1062 1063 1054 + 1061 1062 1064 985 + 1056 1063 1064 986 + 1058 1065 1066 988 + 1065 1067 1068 1059 + 1066 1067 1069 990 + 1061 1068 1069 991 + 1068 1070 1071 1062 + 1069 1070 1072 993 + 1064 1071 1072 994 + 1066 1073 1074 996 + 1073 1075 1076 1067 + 1074 1075 1077 998 + 1069 1076 1077 999 + 1076 1078 1079 1070 + 1077 1078 1080 1001 + 1072 1079 1080 1002 + 1074 1081 1082 1004 + 1081 1083 1084 1075 + 1082 1083 1085 1006 + 1077 1084 1085 1007 + 1084 1086 1087 1078 + 1085 1086 1088 1009 + 1080 1087 1088 1010 + 1082 1089 1090 1012 + 1089 1091 1092 1083 + 1090 1091 1093 1014 + 1085 1092 1093 1015 + 1092 1094 1095 1086 + 1093 1094 1096 1017 + 1088 1095 1096 1018 + 1097 1098 1099 1021 + 1097 1100 1102 1023 + 1098 1101 1103 1100 + 1099 1101 1104 1024 + 1102 1103 1104 1026 + 1102 1105 1107 1028 + 1103 1106 1108 1105 + 1104 1106 1109 1029 + 1107 1108 1109 1031 + 1099 1110 1111 1033 + 1110 1112 1113 1101 + 1111 1112 1114 1035 + 1104 1113 1114 1036 + 1113 1115 1116 1106 + 1114 1115 1117 1038 + 1109 1116 1117 1039 + 1111 1118 1119 1041 + 1118 1120 1121 1112 + 1119 1120 1122 1043 + 1114 1121 1122 1044 + 1121 1123 1124 1115 + 1122 1123 1125 1046 + 1117 1124 1125 1047 + 1119 1126 1127 1049 + 1126 1128 1129 1120 + 1127 1128 1130 1051 + 1122 1129 1130 1052 + 1129 1131 1132 1123 + 1130 1131 1133 1054 + 1125 1132 1133 1055 + 1127 1134 1135 1057 + 1134 1136 1137 1128 + 1135 1136 1138 1059 + 1130 1137 1138 1060 + 1137 1139 1140 1131 + 1138 1139 1141 1062 + 1133 1140 1141 1063 + 1135 1142 1143 1065 + 1142 1144 1145 1136 + 1143 1144 1146 1067 + 1138 1145 1146 1068 + 1145 1147 1148 1139 + 1146 1147 1149 1070 + 1141 1148 1149 1071 + 1143 1150 1151 1073 + 1150 1152 1153 1144 + 1151 1152 1154 1075 + 1146 1153 1154 1076 + 1153 1155 1156 1147 + 1154 1155 1157 1078 + 1149 1156 1157 1079 + 1151 1158 1159 1081 + 1158 1160 1161 1152 + 1159 1160 1162 1083 + 1154 1161 1162 1084 + 1161 1163 1164 1155 + 1162 1163 1165 1086 + 1157 1164 1165 1087 + 1159 1166 1167 1089 + 1166 1168 1169 1160 + 1167 1168 1170 1091 + 1162 1169 1170 1092 + 1169 1171 1172 1163 + 1170 1171 1173 1094 + 1165 1172 1173 1095 + 1174 1175 1176 1098 + 1174 1177 1179 1100 + 1175 1178 1180 1177 + 1176 1178 1181 1101 + 1179 1180 1181 1103 + 1179 1182 1184 1105 + 1180 1183 1185 1182 + 1181 1183 1186 1106 + 1184 1185 1186 1108 + 1176 1187 1188 1110 + 1187 1189 1190 1178 + 1188 1189 1191 1112 + 1181 1190 1191 1113 + 1190 1192 1193 1183 + 1191 1192 1194 1115 + 1186 1193 1194 1116 + 1188 1195 1196 1118 + 1195 1197 1198 1189 + 1196 1197 1199 1120 + 1191 1198 1199 1121 + 1198 1200 1201 1192 + 1199 1200 1202 1123 + 1194 1201 1202 1124 + 1196 1203 1204 1126 + 1203 1205 1206 1197 + 1204 1205 1207 1128 + 1199 1206 1207 1129 + 1206 1208 1209 1200 + 1207 1208 1210 1131 + 1202 1209 1210 1132 + 1204 1211 1212 1134 + 1211 1213 1214 1205 + 1212 1213 1215 1136 + 1207 1214 1215 1137 + 1214 1216 1217 1208 + 1215 1216 1218 1139 + 1210 1217 1218 1140 + 1212 1219 1220 1142 + 1219 1221 1222 1213 + 1220 1221 1223 1144 + 1215 1222 1223 1145 + 1222 1224 1225 1216 + 1223 1224 1226 1147 + 1218 1225 1226 1148 + 1220 1227 1228 1150 + 1227 1229 1230 1221 + 1228 1229 1231 1152 + 1223 1230 1231 1153 + 1230 1232 1233 1224 + 1231 1232 1234 1155 + 1226 1233 1234 1156 + 1228 1235 1236 1158 + 1235 1237 1238 1229 + 1236 1237 1239 1160 + 1231 1238 1239 1161 + 1238 1240 1241 1232 + 1239 1240 1242 1163 + 1234 1241 1242 1164 + 1236 1243 1244 1166 + 1243 1245 1246 1237 + 1244 1245 1247 1168 + 1239 1246 1247 1169 + 1246 1248 1249 1240 + 1247 1248 1250 1171 + 1242 1249 1250 1172 + 1251 1252 1253 1175 + 1251 1254 1256 1177 + 1252 1255 1257 1254 + 1253 1255 1258 1178 + 1256 1257 1258 1180 + 1256 1259 1261 1182 + 1257 1260 1262 1259 + 1258 1260 1263 1183 + 1261 1262 1263 1185 + 1253 1264 1265 1187 + 1264 1266 1267 1255 + 1265 1266 1268 1189 + 1258 1267 1268 1190 + 1267 1269 1270 1260 + 1268 1269 1271 1192 + 1263 1270 1271 1193 + 1265 1272 1273 1195 + 1272 1274 1275 1266 + 1273 1274 1276 1197 + 1268 1275 1276 1198 + 1275 1277 1278 1269 + 1276 1277 1279 1200 + 1271 1278 1279 1201 + 1273 1280 1281 1203 + 1280 1282 1283 1274 + 1281 1282 1284 1205 + 1276 1283 1284 1206 + 1283 1285 1286 1277 + 1284 1285 1287 1208 + 1279 1286 1287 1209 + 1281 1288 1289 1211 + 1288 1290 1291 1282 + 1289 1290 1292 1213 + 1284 1291 1292 1214 + 1291 1293 1294 1285 + 1292 1293 1295 1216 + 1287 1294 1295 1217 + 1289 1296 1297 1219 + 1296 1298 1299 1290 + 1297 1298 1300 1221 + 1292 1299 1300 1222 + 1299 1301 1302 1293 + 1300 1301 1303 1224 + 1295 1302 1303 1225 + 1297 1304 1305 1227 + 1304 1306 1307 1298 + 1305 1306 1308 1229 + 1300 1307 1308 1230 + 1307 1309 1310 1301 + 1308 1309 1311 1232 + 1303 1310 1311 1233 + 1305 1312 1313 1235 + 1312 1314 1315 1306 + 1313 1314 1316 1237 + 1308 1315 1316 1238 + 1315 1317 1318 1309 + 1316 1317 1319 1240 + 1311 1318 1319 1241 + 1313 1320 1321 1243 + 1320 1322 1323 1314 + 1321 1322 1324 1245 + 1316 1323 1324 1246 + 1323 1325 1326 1317 + 1324 1325 1327 1248 + 1319 1326 1327 1249 + 1328 1329 1330 1252 + 1328 1331 1333 1254 + 1329 1332 1334 1331 + 1330 1332 1335 1255 + 1333 1334 1335 1257 + 1333 1336 1338 1259 + 1334 1337 1339 1336 + 1335 1337 1340 1260 + 1338 1339 1340 1262 + 1330 1341 1342 1264 + 1341 1343 1344 1332 + 1342 1343 1345 1266 + 1335 1344 1345 1267 + 1344 1346 1347 1337 + 1345 1346 1348 1269 + 1340 1347 1348 1270 + 1342 1349 1350 1272 + 1349 1351 1352 1343 + 1350 1351 1353 1274 + 1345 1352 1353 1275 + 1352 1354 1355 1346 + 1353 1354 1356 1277 + 1348 1355 1356 1278 + 1350 1357 1358 1280 + 1357 1359 1360 1351 + 1358 1359 1361 1282 + 1353 1360 1361 1283 + 1360 1362 1363 1354 + 1361 1362 1364 1285 + 1356 1363 1364 1286 + 1358 1365 1366 1288 + 1365 1367 1368 1359 + 1366 1367 1369 1290 + 1361 1368 1369 1291 + 1368 1370 1371 1362 + 1369 1370 1372 1293 + 1364 1371 1372 1294 + 1366 1373 1374 1296 + 1373 1375 1376 1367 + 1374 1375 1377 1298 + 1369 1376 1377 1299 + 1376 1378 1379 1370 + 1377 1378 1380 1301 + 1372 1379 1380 1302 + 1374 1381 1382 1304 + 1381 1383 1384 1375 + 1382 1383 1385 1306 + 1377 1384 1385 1307 + 1384 1386 1387 1378 + 1385 1386 1388 1309 + 1380 1387 1388 1310 + 1382 1389 1390 1312 + 1389 1391 1392 1383 + 1390 1391 1393 1314 + 1385 1392 1393 1315 + 1392 1394 1395 1386 + 1393 1394 1396 1317 + 1388 1395 1396 1318 + 1390 1397 1398 1320 + 1397 1399 1400 1391 + 1398 1399 1401 1322 + 1393 1400 1401 1323 + 1400 1402 1403 1394 + 1401 1402 1404 1325 + 1396 1403 1404 1326 + 1405 1406 1407 1329 + 1405 1408 1410 1331 + 1406 1409 1411 1408 + 1407 1409 1412 1332 + 1410 1411 1412 1334 + 1410 1413 1415 1336 + 1411 1414 1416 1413 + 1412 1414 1417 1337 + 1415 1416 1417 1339 + 1407 1418 1419 1341 + 1418 1420 1421 1409 + 1419 1420 1422 1343 + 1412 1421 1422 1344 + 1421 1423 1424 1414 + 1422 1423 1425 1346 + 1417 1424 1425 1347 + 1419 1426 1427 1349 + 1426 1428 1429 1420 + 1427 1428 1430 1351 + 1422 1429 1430 1352 + 1429 1431 1432 1423 + 1430 1431 1433 1354 + 1425 1432 1433 1355 + 1427 1434 1435 1357 + 1434 1436 1437 1428 + 1435 1436 1438 1359 + 1430 1437 1438 1360 + 1437 1439 1440 1431 + 1438 1439 1441 1362 + 1433 1440 1441 1363 + 1435 1442 1443 1365 + 1442 1444 1445 1436 + 1443 1444 1446 1367 + 1438 1445 1446 1368 + 1445 1447 1448 1439 + 1446 1447 1449 1370 + 1441 1448 1449 1371 + 1443 1450 1451 1373 + 1450 1452 1453 1444 + 1451 1452 1454 1375 + 1446 1453 1454 1376 + 1453 1455 1456 1447 + 1454 1455 1457 1378 + 1449 1456 1457 1379 + 1451 1458 1459 1381 + 1458 1460 1461 1452 + 1459 1460 1462 1383 + 1454 1461 1462 1384 + 1461 1463 1464 1455 + 1462 1463 1465 1386 + 1457 1464 1465 1387 + 1459 1466 1467 1389 + 1466 1468 1469 1460 + 1467 1468 1470 1391 + 1462 1469 1470 1392 + 1469 1471 1472 1463 + 1470 1471 1473 1394 + 1465 1472 1473 1395 + 1467 1474 1475 1397 + 1474 1476 1477 1468 + 1475 1476 1478 1399 + 1470 1477 1478 1400 + 1477 1479 1480 1471 + 1478 1479 1481 1402 + 1473 1480 1481 1403 + 1482 1483 1484 1406 + 1482 1485 1487 1408 + 1483 1486 1488 1485 + 1484 1486 1489 1409 + 1487 1488 1489 1411 + 1487 1490 1492 1413 + 1488 1491 1493 1490 + 1489 1491 1494 1414 + 1492 1493 1494 1416 + 1484 1495 1496 1418 + 1495 1497 1498 1486 + 1496 1497 1499 1420 + 1489 1498 1499 1421 + 1498 1500 1501 1491 + 1499 1500 1502 1423 + 1494 1501 1502 1424 + 1496 1503 1504 1426 + 1503 1505 1506 1497 + 1504 1505 1507 1428 + 1499 1506 1507 1429 + 1506 1508 1509 1500 + 1507 1508 1510 1431 + 1502 1509 1510 1432 + 1504 1511 1512 1434 + 1511 1513 1514 1505 + 1512 1513 1515 1436 + 1507 1514 1515 1437 + 1514 1516 1517 1508 + 1515 1516 1518 1439 + 1510 1517 1518 1440 + 1512 1519 1520 1442 + 1519 1521 1522 1513 + 1520 1521 1523 1444 + 1515 1522 1523 1445 + 1522 1524 1525 1516 + 1523 1524 1526 1447 + 1518 1525 1526 1448 + 1520 1527 1528 1450 + 1527 1529 1530 1521 + 1528 1529 1531 1452 + 1523 1530 1531 1453 + 1530 1532 1533 1524 + 1531 1532 1534 1455 + 1526 1533 1534 1456 + 1528 1535 1536 1458 + 1535 1537 1538 1529 + 1536 1537 1539 1460 + 1531 1538 1539 1461 + 1538 1540 1541 1532 + 1539 1540 1542 1463 + 1534 1541 1542 1464 + 1536 1543 1544 1466 + 1543 1545 1546 1537 + 1544 1545 1547 1468 + 1539 1546 1547 1469 + 1546 1548 1549 1540 + 1547 1548 1550 1471 + 1542 1549 1550 1472 + 1544 1551 1552 1474 + 1551 1553 1554 1545 + 1552 1553 1555 1476 + 1547 1554 1555 1477 + 1554 1556 1557 1548 + 1555 1556 1558 1479 + 1550 1557 1558 1480 + 1559 1560 1561 1562 + 1559 1564 1567 1563 + 1560 1565 1568 1564 + 1561 1565 1569 1566 + 1562 1566 1570 1563 + 1567 1568 1569 1570 + 1567 1572 1575 1571 + 1568 1573 1576 1572 + 1569 1573 1577 1574 + 1570 1574 1578 1571 + 1575 1576 1577 1578 + 1575 1580 1583 1579 + 1576 1581 1584 1580 + 1577 1581 1585 1582 + 1578 1582 1586 1579 + 1583 1584 1585 1586 + 1561 1587 1588 1589 + 1587 1590 1592 1565 + 1588 1590 1593 1591 + 1589 1591 1594 1566 + 1569 1592 1593 1594 + 1592 1595 1597 1573 + 1593 1595 1598 1596 + 1594 1596 1599 1574 + 1577 1597 1598 1599 + 1597 1600 1602 1581 + 1598 1600 1603 1601 + 1599 1601 1604 1582 + 1585 1602 1603 1604 + 1588 1605 1606 1607 + 1605 1608 1610 1590 + 1606 1608 1611 1609 + 1607 1609 1612 1591 + 1593 1610 1611 1612 + 1610 1613 1615 1595 + 1611 1613 1616 1614 + 1612 1614 1617 1596 + 1598 1615 1616 1617 + 1615 1618 1620 1600 + 1616 1618 1621 1619 + 1617 1619 1622 1601 + 1603 1620 1621 1622 + 1606 1623 1624 1625 + 1623 1626 1628 1608 + 1624 1626 1629 1627 + 1625 1627 1630 1609 + 1611 1628 1629 1630 + 1628 1631 1633 1613 + 1629 1631 1634 1632 + 1630 1632 1635 1614 + 1616 1633 1634 1635 + 1633 1636 1638 1618 + 1634 1636 1639 1637 + 1635 1637 1640 1619 + 1621 1638 1639 1640 + 1624 1641 1642 1643 + 1641 1644 1646 1626 + 1642 1644 1647 1645 + 1643 1645 1648 1627 + 1629 1646 1647 1648 + 1646 1649 1651 1631 + 1647 1649 1652 1650 + 1648 1650 1653 1632 + 1634 1651 1652 1653 + 1651 1654 1656 1636 + 1652 1654 1657 1655 + 1653 1655 1658 1637 + 1639 1656 1657 1658 + 1642 1659 1660 1661 + 1659 1662 1664 1644 + 1660 1662 1665 1663 + 1661 1663 1666 1645 + 1647 1664 1665 1666 + 1664 1667 1669 1649 + 1665 1667 1670 1668 + 1666 1668 1671 1650 + 1652 1669 1670 1671 + 1669 1672 1674 1654 + 1670 1672 1675 1673 + 1671 1673 1676 1655 + 1657 1674 1675 1676 + 1660 1677 1678 1679 + 1677 1680 1682 1662 + 1678 1680 1683 1681 + 1679 1681 1684 1663 + 1665 1682 1683 1684 + 1682 1685 1687 1667 + 1683 1685 1688 1686 + 1684 1686 1689 1668 + 1670 1687 1688 1689 + 1687 1690 1692 1672 + 1688 1690 1693 1691 + 1689 1691 1694 1673 + 1675 1692 1693 1694 + 1678 1695 1696 1697 + 1695 1698 1700 1680 + 1696 1698 1701 1699 + 1697 1699 1702 1681 + 1683 1700 1701 1702 + 1700 1703 1705 1685 + 1701 1703 1706 1704 + 1702 1704 1707 1686 + 1688 1705 1706 1707 + 1705 1708 1710 1690 + 1706 1708 1711 1709 + 1707 1709 1712 1691 + 1693 1710 1711 1712 + 1713 1714 1715 1560 + 1713 1716 1718 1564 + 1714 1717 1719 1716 + 1715 1717 1720 1565 + 1718 1719 1720 1568 + 1718 1721 1723 1572 + 1719 1722 1724 1721 + 1720 1722 1725 1573 + 1723 1724 1725 1576 + 1723 1726 1728 1580 + 1724 1727 1729 1726 + 1725 1727 1730 1581 + 1728 1729 1730 1584 + 1715 1731 1732 1587 + 1731 1733 1734 1717 + 1732 1733 1735 1590 + 1720 1734 1735 1592 + 1734 1736 1737 1722 + 1735 1736 1738 1595 + 1725 1737 1738 1597 + 1737 1739 1740 1727 + 1738 1739 1741 1600 + 1730 1740 1741 1602 + 1732 1742 1743 1605 + 1742 1744 1745 1733 + 1743 1744 1746 1608 + 1735 1745 1746 1610 + 1745 1747 1748 1736 + 1746 1747 1749 1613 + 1738 1748 1749 1615 + 1748 1750 1751 1739 + 1749 1750 1752 1618 + 1741 1751 1752 1620 + 1743 1753 1754 1623 + 1753 1755 1756 1744 + 1754 1755 1757 1626 + 1746 1756 1757 1628 + 1756 1758 1759 1747 + 1757 1758 1760 1631 + 1749 1759 1760 1633 + 1759 1761 1762 1750 + 1760 1761 1763 1636 + 1752 1762 1763 1638 + 1754 1764 1765 1641 + 1764 1766 1767 1755 + 1765 1766 1768 1644 + 1757 1767 1768 1646 + 1767 1769 1770 1758 + 1768 1769 1771 1649 + 1760 1770 1771 1651 + 1770 1772 1773 1761 + 1771 1772 1774 1654 + 1763 1773 1774 1656 + 1765 1775 1776 1659 + 1775 1777 1778 1766 + 1776 1777 1779 1662 + 1768 1778 1779 1664 + 1778 1780 1781 1769 + 1779 1780 1782 1667 + 1771 1781 1782 1669 + 1781 1783 1784 1772 + 1782 1783 1785 1672 + 1774 1784 1785 1674 + 1776 1786 1787 1677 + 1786 1788 1789 1777 + 1787 1788 1790 1680 + 1779 1789 1790 1682 + 1789 1791 1792 1780 + 1790 1791 1793 1685 + 1782 1792 1793 1687 + 1792 1794 1795 1783 + 1793 1794 1796 1690 + 1785 1795 1796 1692 + 1787 1797 1798 1695 + 1797 1799 1800 1788 + 1798 1799 1801 1698 + 1790 1800 1801 1700 + 1800 1802 1803 1791 + 1801 1802 1804 1703 + 1793 1803 1804 1705 + 1803 1805 1806 1794 + 1804 1805 1807 1708 + 1796 1806 1807 1710 + 1808 1809 1810 1714 + 1808 1811 1813 1716 + 1809 1812 1814 1811 + 1810 1812 1815 1717 + 1813 1814 1815 1719 + 1813 1816 1818 1721 + 1814 1817 1819 1816 + 1815 1817 1820 1722 + 1818 1819 1820 1724 + 1818 1821 1823 1726 + 1819 1822 1824 1821 + 1820 1822 1825 1727 + 1823 1824 1825 1729 + 1810 1826 1827 1731 + 1826 1828 1829 1812 + 1827 1828 1830 1733 + 1815 1829 1830 1734 + 1829 1831 1832 1817 + 1830 1831 1833 1736 + 1820 1832 1833 1737 + 1832 1834 1835 1822 + 1833 1834 1836 1739 + 1825 1835 1836 1740 + 1827 1837 1838 1742 + 1837 1839 1840 1828 + 1838 1839 1841 1744 + 1830 1840 1841 1745 + 1840 1842 1843 1831 + 1841 1842 1844 1747 + 1833 1843 1844 1748 + 1843 1845 1846 1834 + 1844 1845 1847 1750 + 1836 1846 1847 1751 + 1838 1848 1849 1753 + 1848 1850 1851 1839 + 1849 1850 1852 1755 + 1841 1851 1852 1756 + 1851 1853 1854 1842 + 1852 1853 1855 1758 + 1844 1854 1855 1759 + 1854 1856 1857 1845 + 1855 1856 1858 1761 + 1847 1857 1858 1762 + 1849 1859 1860 1764 + 1859 1861 1862 1850 + 1860 1861 1863 1766 + 1852 1862 1863 1767 + 1862 1864 1865 1853 + 1863 1864 1866 1769 + 1855 1865 1866 1770 + 1865 1867 1868 1856 + 1866 1867 1869 1772 + 1858 1868 1869 1773 + 1860 1870 1871 1775 + 1870 1872 1873 1861 + 1871 1872 1874 1777 + 1863 1873 1874 1778 + 1873 1875 1876 1864 + 1874 1875 1877 1780 + 1866 1876 1877 1781 + 1876 1878 1879 1867 + 1877 1878 1880 1783 + 1869 1879 1880 1784 + 1871 1881 1882 1786 + 1881 1883 1884 1872 + 1882 1883 1885 1788 + 1874 1884 1885 1789 + 1884 1886 1887 1875 + 1885 1886 1888 1791 + 1877 1887 1888 1792 + 1887 1889 1890 1878 + 1888 1889 1891 1794 + 1880 1890 1891 1795 + 1882 1892 1893 1797 + 1892 1894 1895 1883 + 1893 1894 1896 1799 + 1885 1895 1896 1800 + 1895 1897 1898 1886 + 1896 1897 1899 1802 + 1888 1898 1899 1803 + 1898 1900 1901 1889 + 1899 1900 1902 1805 + 1891 1901 1902 1806 + 1903 1904 1905 1809 + 1903 1906 1908 1811 + 1904 1907 1909 1906 + 1905 1907 1910 1812 + 1908 1909 1910 1814 + 1908 1911 1913 1816 + 1909 1912 1914 1911 + 1910 1912 1915 1817 + 1913 1914 1915 1819 + 1913 1916 1918 1821 + 1914 1917 1919 1916 + 1915 1917 1920 1822 + 1918 1919 1920 1824 + 1905 1921 1922 1826 + 1921 1923 1924 1907 + 1922 1923 1925 1828 + 1910 1924 1925 1829 + 1924 1926 1927 1912 + 1925 1926 1928 1831 + 1915 1927 1928 1832 + 1927 1929 1930 1917 + 1928 1929 1931 1834 + 1920 1930 1931 1835 + 1922 1932 1933 1837 + 1932 1934 1935 1923 + 1933 1934 1936 1839 + 1925 1935 1936 1840 + 1935 1937 1938 1926 + 1936 1937 1939 1842 + 1928 1938 1939 1843 + 1938 1940 1941 1929 + 1939 1940 1942 1845 + 1931 1941 1942 1846 + 1933 1943 1944 1848 + 1943 1945 1946 1934 + 1944 1945 1947 1850 + 1936 1946 1947 1851 + 1946 1948 1949 1937 + 1947 1948 1950 1853 + 1939 1949 1950 1854 + 1949 1951 1952 1940 + 1950 1951 1953 1856 + 1942 1952 1953 1857 + 1944 1954 1955 1859 + 1954 1956 1957 1945 + 1955 1956 1958 1861 + 1947 1957 1958 1862 + 1957 1959 1960 1948 + 1958 1959 1961 1864 + 1950 1960 1961 1865 + 1960 1962 1963 1951 + 1961 1962 1964 1867 + 1953 1963 1964 1868 + 1955 1965 1966 1870 + 1965 1967 1968 1956 + 1966 1967 1969 1872 + 1958 1968 1969 1873 + 1968 1970 1971 1959 + 1969 1970 1972 1875 + 1961 1971 1972 1876 + 1971 1973 1974 1962 + 1972 1973 1975 1878 + 1964 1974 1975 1879 + 1966 1976 1977 1881 + 1976 1978 1979 1967 + 1977 1978 1980 1883 + 1969 1979 1980 1884 + 1979 1981 1982 1970 + 1980 1981 1983 1886 + 1972 1982 1983 1887 + 1982 1984 1985 1973 + 1983 1984 1986 1889 + 1975 1985 1986 1890 + 1977 1987 1988 1892 + 1987 1989 1990 1978 + 1988 1989 1991 1894 + 1980 1990 1991 1895 + 1990 1992 1993 1981 + 1991 1992 1994 1897 + 1983 1993 1994 1898 + 1993 1995 1996 1984 + 1994 1995 1997 1900 + 1986 1996 1997 1901 + 1998 1999 2000 1904 + 1998 2001 2003 1906 + 1999 2002 2004 2001 + 2000 2002 2005 1907 + 2003 2004 2005 1909 + 2003 2006 2008 1911 + 2004 2007 2009 2006 + 2005 2007 2010 1912 + 2008 2009 2010 1914 + 2008 2011 2013 1916 + 2009 2012 2014 2011 + 2010 2012 2015 1917 + 2013 2014 2015 1919 + 2000 2016 2017 1921 + 2016 2018 2019 2002 + 2017 2018 2020 1923 + 2005 2019 2020 1924 + 2019 2021 2022 2007 + 2020 2021 2023 1926 + 2010 2022 2023 1927 + 2022 2024 2025 2012 + 2023 2024 2026 1929 + 2015 2025 2026 1930 + 2017 2027 2028 1932 + 2027 2029 2030 2018 + 2028 2029 2031 1934 + 2020 2030 2031 1935 + 2030 2032 2033 2021 + 2031 2032 2034 1937 + 2023 2033 2034 1938 + 2033 2035 2036 2024 + 2034 2035 2037 1940 + 2026 2036 2037 1941 + 2028 2038 2039 1943 + 2038 2040 2041 2029 + 2039 2040 2042 1945 + 2031 2041 2042 1946 + 2041 2043 2044 2032 + 2042 2043 2045 1948 + 2034 2044 2045 1949 + 2044 2046 2047 2035 + 2045 2046 2048 1951 + 2037 2047 2048 1952 + 2039 2049 2050 1954 + 2049 2051 2052 2040 + 2050 2051 2053 1956 + 2042 2052 2053 1957 + 2052 2054 2055 2043 + 2053 2054 2056 1959 + 2045 2055 2056 1960 + 2055 2057 2058 2046 + 2056 2057 2059 1962 + 2048 2058 2059 1963 + 2050 2060 2061 1965 + 2060 2062 2063 2051 + 2061 2062 2064 1967 + 2053 2063 2064 1968 + 2063 2065 2066 2054 + 2064 2065 2067 1970 + 2056 2066 2067 1971 + 2066 2068 2069 2057 + 2067 2068 2070 1973 + 2059 2069 2070 1974 + 2061 2071 2072 1976 + 2071 2073 2074 2062 + 2072 2073 2075 1978 + 2064 2074 2075 1979 + 2074 2076 2077 2065 + 2075 2076 2078 1981 + 2067 2077 2078 1982 + 2077 2079 2080 2068 + 2078 2079 2081 1984 + 2070 2080 2081 1985 + 2072 2082 2083 1987 + 2082 2084 2085 2073 + 2083 2084 2086 1989 + 2075 2085 2086 1990 + 2085 2087 2088 2076 + 2086 2087 2089 1992 + 2078 2088 2089 1993 + 2088 2090 2091 2079 + 2089 2090 2092 1995 + 2081 2091 2092 1996 + 2093 2094 2095 1999 + 2093 2096 2098 2001 + 2094 2097 2099 2096 + 2095 2097 2100 2002 + 2098 2099 2100 2004 + 2098 2101 2103 2006 + 2099 2102 2104 2101 + 2100 2102 2105 2007 + 2103 2104 2105 2009 + 2103 2106 2108 2011 + 2104 2107 2109 2106 + 2105 2107 2110 2012 + 2108 2109 2110 2014 + 2095 2111 2112 2016 + 2111 2113 2114 2097 + 2112 2113 2115 2018 + 2100 2114 2115 2019 + 2114 2116 2117 2102 + 2115 2116 2118 2021 + 2105 2117 2118 2022 + 2117 2119 2120 2107 + 2118 2119 2121 2024 + 2110 2120 2121 2025 + 2112 2122 2123 2027 + 2122 2124 2125 2113 + 2123 2124 2126 2029 + 2115 2125 2126 2030 + 2125 2127 2128 2116 + 2126 2127 2129 2032 + 2118 2128 2129 2033 + 2128 2130 2131 2119 + 2129 2130 2132 2035 + 2121 2131 2132 2036 + 2123 2133 2134 2038 + 2133 2135 2136 2124 + 2134 2135 2137 2040 + 2126 2136 2137 2041 + 2136 2138 2139 2127 + 2137 2138 2140 2043 + 2129 2139 2140 2044 + 2139 2141 2142 2130 + 2140 2141 2143 2046 + 2132 2142 2143 2047 + 2134 2144 2145 2049 + 2144 2146 2147 2135 + 2145 2146 2148 2051 + 2137 2147 2148 2052 + 2147 2149 2150 2138 + 2148 2149 2151 2054 + 2140 2150 2151 2055 + 2150 2152 2153 2141 + 2151 2152 2154 2057 + 2143 2153 2154 2058 + 2145 2155 2156 2060 + 2155 2157 2158 2146 + 2156 2157 2159 2062 + 2148 2158 2159 2063 + 2158 2160 2161 2149 + 2159 2160 2162 2065 + 2151 2161 2162 2066 + 2161 2163 2164 2152 + 2162 2163 2165 2068 + 2154 2164 2165 2069 + 2156 2166 2167 2071 + 2166 2168 2169 2157 + 2167 2168 2170 2073 + 2159 2169 2170 2074 + 2169 2171 2172 2160 + 2170 2171 2173 2076 + 2162 2172 2173 2077 + 2172 2174 2175 2163 + 2173 2174 2176 2079 + 2165 2175 2176 2080 + 2167 2177 2178 2082 + 2177 2179 2180 2168 + 2178 2179 2181 2084 + 2170 2180 2181 2085 + 2180 2182 2183 2171 + 2181 2182 2184 2087 + 2173 2183 2184 2088 + 2183 2185 2186 2174 + 2184 2185 2187 2090 + 2176 2186 2187 2091 + 2188 2189 2190 2094 + 2188 2191 2193 2096 + 2189 2192 2194 2191 + 2190 2192 2195 2097 + 2193 2194 2195 2099 + 2193 2196 2198 2101 + 2194 2197 2199 2196 + 2195 2197 2200 2102 + 2198 2199 2200 2104 + 2198 2201 2203 2106 + 2199 2202 2204 2201 + 2200 2202 2205 2107 + 2203 2204 2205 2109 + 2190 2206 2207 2111 + 2206 2208 2209 2192 + 2207 2208 2210 2113 + 2195 2209 2210 2114 + 2209 2211 2212 2197 + 2210 2211 2213 2116 + 2200 2212 2213 2117 + 2212 2214 2215 2202 + 2213 2214 2216 2119 + 2205 2215 2216 2120 + 2207 2217 2218 2122 + 2217 2219 2220 2208 + 2218 2219 2221 2124 + 2210 2220 2221 2125 + 2220 2222 2223 2211 + 2221 2222 2224 2127 + 2213 2223 2224 2128 + 2223 2225 2226 2214 + 2224 2225 2227 2130 + 2216 2226 2227 2131 + 2218 2228 2229 2133 + 2228 2230 2231 2219 + 2229 2230 2232 2135 + 2221 2231 2232 2136 + 2231 2233 2234 2222 + 2232 2233 2235 2138 + 2224 2234 2235 2139 + 2234 2236 2237 2225 + 2235 2236 2238 2141 + 2227 2237 2238 2142 + 2229 2239 2240 2144 + 2239 2241 2242 2230 + 2240 2241 2243 2146 + 2232 2242 2243 2147 + 2242 2244 2245 2233 + 2243 2244 2246 2149 + 2235 2245 2246 2150 + 2245 2247 2248 2236 + 2246 2247 2249 2152 + 2238 2248 2249 2153 + 2240 2250 2251 2155 + 2250 2252 2253 2241 + 2251 2252 2254 2157 + 2243 2253 2254 2158 + 2253 2255 2256 2244 + 2254 2255 2257 2160 + 2246 2256 2257 2161 + 2256 2258 2259 2247 + 2257 2258 2260 2163 + 2249 2259 2260 2164 + 2251 2261 2262 2166 + 2261 2263 2264 2252 + 2262 2263 2265 2168 + 2254 2264 2265 2169 + 2264 2266 2267 2255 + 2265 2266 2268 2171 + 2257 2267 2268 2172 + 2267 2269 2270 2258 + 2268 2269 2271 2174 + 2260 2270 2271 2175 + 2262 2272 2273 2177 + 2272 2274 2275 2263 + 2273 2274 2276 2179 + 2265 2275 2276 2180 + 2275 2277 2278 2266 + 2276 2277 2279 2182 + 2268 2278 2279 2183 + 2278 2280 2281 2269 + 2279 2280 2282 2185 + 2271 2281 2282 2186 + 2283 2284 2285 2189 + 2283 2286 2288 2191 + 2284 2287 2289 2286 + 2285 2287 2290 2192 + 2288 2289 2290 2194 + 2288 2291 2293 2196 + 2289 2292 2294 2291 + 2290 2292 2295 2197 + 2293 2294 2295 2199 + 2293 2296 2298 2201 + 2294 2297 2299 2296 + 2295 2297 2300 2202 + 2298 2299 2300 2204 + 2285 2301 2302 2206 + 2301 2303 2304 2287 + 2302 2303 2305 2208 + 2290 2304 2305 2209 + 2304 2306 2307 2292 + 2305 2306 2308 2211 + 2295 2307 2308 2212 + 2307 2309 2310 2297 + 2308 2309 2311 2214 + 2300 2310 2311 2215 + 2302 2312 2313 2217 + 2312 2314 2315 2303 + 2313 2314 2316 2219 + 2305 2315 2316 2220 + 2315 2317 2318 2306 + 2316 2317 2319 2222 + 2308 2318 2319 2223 + 2318 2320 2321 2309 + 2319 2320 2322 2225 + 2311 2321 2322 2226 + 2313 2323 2324 2228 + 2323 2325 2326 2314 + 2324 2325 2327 2230 + 2316 2326 2327 2231 + 2326 2328 2329 2317 + 2327 2328 2330 2233 + 2319 2329 2330 2234 + 2329 2331 2332 2320 + 2330 2331 2333 2236 + 2322 2332 2333 2237 + 2324 2334 2335 2239 + 2334 2336 2337 2325 + 2335 2336 2338 2241 + 2327 2337 2338 2242 + 2337 2339 2340 2328 + 2338 2339 2341 2244 + 2330 2340 2341 2245 + 2340 2342 2343 2331 + 2341 2342 2344 2247 + 2333 2343 2344 2248 + 2335 2345 2346 2250 + 2345 2347 2348 2336 + 2346 2347 2349 2252 + 2338 2348 2349 2253 + 2348 2350 2351 2339 + 2349 2350 2352 2255 + 2341 2351 2352 2256 + 2351 2353 2354 2342 + 2352 2353 2355 2258 + 2344 2354 2355 2259 + 2346 2356 2357 2261 + 2356 2358 2359 2347 + 2357 2358 2360 2263 + 2349 2359 2360 2264 + 2359 2361 2362 2350 + 2360 2361 2363 2266 + 2352 2362 2363 2267 + 2362 2364 2365 2353 + 2363 2364 2366 2269 + 2355 2365 2366 2270 + 2357 2367 2368 2272 + 2367 2369 2370 2358 + 2368 2369 2371 2274 + 2360 2370 2371 2275 + 2370 2372 2373 2361 + 2371 2372 2374 2277 + 2363 2373 2374 2278 + 2373 2375 2376 2364 + 2374 2375 2377 2280 + 2366 2376 2377 2281 + + + 0 1 2 3 4 5 + 5 6 7 8 9 10 + 10 11 12 13 14 15 + 16 3 17 18 19 20 + 20 8 21 22 23 24 + 24 13 25 26 27 28 + 29 18 30 31 32 33 + 33 22 34 35 36 37 + 37 26 38 39 40 41 + 42 31 43 44 45 46 + 46 35 47 48 49 50 + 50 39 51 52 53 54 + 55 44 56 57 58 59 + 59 48 60 61 62 63 + 63 52 64 65 66 67 + 68 57 69 70 71 72 + 72 61 73 74 75 76 + 76 65 77 78 79 80 + 81 70 82 83 84 85 + 85 74 86 87 88 89 + 89 78 90 91 92 93 + 94 83 95 96 97 98 + 98 87 99 100 101 102 + 102 91 103 104 105 106 + 107 108 109 110 2 111 + 111 112 113 114 7 115 + 115 116 117 118 12 119 + 120 110 121 122 17 123 + 123 114 124 125 21 126 + 126 118 127 128 25 129 + 130 122 131 132 30 133 + 133 125 134 135 34 136 + 136 128 137 138 38 139 + 140 132 141 142 43 143 + 143 135 144 145 47 146 + 146 138 147 148 51 149 + 150 142 151 152 56 153 + 153 145 154 155 60 156 + 156 148 157 158 64 159 + 160 152 161 162 69 163 + 163 155 164 165 73 166 + 166 158 167 168 77 169 + 170 162 171 172 82 173 + 173 165 174 175 86 176 + 176 168 177 178 90 179 + 180 172 181 182 95 183 + 183 175 184 185 99 186 + 186 178 187 188 103 189 + 190 191 192 193 109 194 + 194 195 196 197 113 198 + 198 199 200 201 117 202 + 203 193 204 205 121 206 + 206 197 207 208 124 209 + 209 201 210 211 127 212 + 213 205 214 215 131 216 + 216 208 217 218 134 219 + 219 211 220 221 137 222 + 223 215 224 225 141 226 + 226 218 227 228 144 229 + 229 221 230 231 147 232 + 233 225 234 235 151 236 + 236 228 237 238 154 239 + 239 231 240 241 157 242 + 243 235 244 245 161 246 + 246 238 247 248 164 249 + 249 241 250 251 167 252 + 253 245 254 255 171 256 + 256 248 257 258 174 259 + 259 251 260 261 177 262 + 263 255 264 265 181 266 + 266 258 267 268 184 269 + 269 261 270 271 187 272 + 273 274 275 276 192 277 + 277 278 279 280 196 281 + 281 282 283 284 200 285 + 286 276 287 288 204 289 + 289 280 290 291 207 292 + 292 284 293 294 210 295 + 296 288 297 298 214 299 + 299 291 300 301 217 302 + 302 294 303 304 220 305 + 306 298 307 308 224 309 + 309 301 310 311 227 312 + 312 304 313 314 230 315 + 316 308 317 318 234 319 + 319 311 320 321 237 322 + 322 314 323 324 240 325 + 326 318 327 328 244 329 + 329 321 330 331 247 332 + 332 324 333 334 250 335 + 336 328 337 338 254 339 + 339 331 340 341 257 342 + 342 334 343 344 260 345 + 346 338 347 348 264 349 + 349 341 350 351 267 352 + 352 344 353 354 270 355 + 356 357 358 359 275 360 + 360 361 362 363 279 364 + 364 365 366 367 283 368 + 369 359 370 371 287 372 + 372 363 373 374 290 375 + 375 367 376 377 293 378 + 379 371 380 381 297 382 + 382 374 383 384 300 385 + 385 377 386 387 303 388 + 389 381 390 391 307 392 + 392 384 393 394 310 395 + 395 387 396 397 313 398 + 399 391 400 401 317 402 + 402 394 403 404 320 405 + 405 397 406 407 323 408 + 409 401 410 411 327 412 + 412 404 413 414 330 415 + 415 407 416 417 333 418 + 419 411 420 421 337 422 + 422 414 423 424 340 425 + 425 417 426 427 343 428 + 429 421 430 431 347 432 + 432 424 433 434 350 435 + 435 427 436 437 353 438 + 439 440 441 442 358 443 + 443 444 445 446 362 447 + 447 448 449 450 366 451 + 452 442 453 454 370 455 + 455 446 456 457 373 458 + 458 450 459 460 376 461 + 462 454 463 464 380 465 + 465 457 466 467 383 468 + 468 460 469 470 386 471 + 472 464 473 474 390 475 + 475 467 476 477 393 478 + 478 470 479 480 396 481 + 482 474 483 484 400 485 + 485 477 486 487 403 488 + 488 480 489 490 406 491 + 492 484 493 494 410 495 + 495 487 496 497 413 498 + 498 490 499 500 416 501 + 502 494 503 504 420 505 + 505 497 506 507 423 508 + 508 500 509 510 426 511 + 512 504 513 514 430 515 + 515 507 516 517 433 518 + 518 510 519 520 436 521 + 522 523 524 525 441 526 + 526 527 528 529 445 530 + 530 531 532 533 449 534 + 535 525 536 537 453 538 + 538 529 539 540 456 541 + 541 533 542 543 459 544 + 545 537 546 547 463 548 + 548 540 549 550 466 551 + 551 543 552 553 469 554 + 555 547 556 557 473 558 + 558 550 559 560 476 561 + 561 553 562 563 479 564 + 565 557 566 567 483 568 + 568 560 569 570 486 571 + 571 563 572 573 489 574 + 575 567 576 577 493 578 + 578 570 579 580 496 581 + 581 573 582 583 499 584 + 585 577 586 587 503 588 + 588 580 589 590 506 591 + 591 583 592 593 509 594 + 595 587 596 597 513 598 + 598 590 599 600 516 601 + 601 593 602 603 519 604 + 605 606 607 608 524 609 + 609 610 611 612 528 613 + 613 614 615 616 532 617 + 618 608 619 620 536 621 + 621 612 622 623 539 624 + 624 616 625 626 542 627 + 628 620 629 630 546 631 + 631 623 632 633 549 634 + 634 626 635 636 552 637 + 638 630 639 640 556 641 + 641 633 642 643 559 644 + 644 636 645 646 562 647 + 648 640 649 650 566 651 + 651 643 652 653 569 654 + 654 646 655 656 572 657 + 658 650 659 660 576 661 + 661 653 662 663 579 664 + 664 656 665 666 582 667 + 668 660 669 670 586 671 + 671 663 672 673 589 674 + 674 666 675 676 592 677 + 678 670 679 680 596 681 + 681 673 682 683 599 684 + 684 676 685 686 602 687 + 688 689 690 691 692 693 + 693 694 695 696 697 698 + 699 691 700 701 702 703 + 703 696 704 705 706 707 + 708 701 709 710 711 712 + 712 705 713 714 715 716 + 717 710 718 719 720 721 + 721 714 722 723 724 725 + 726 719 727 728 729 730 + 730 723 731 732 733 734 + 735 728 736 737 738 739 + 739 732 740 741 742 743 + 744 737 745 746 747 748 + 748 741 749 750 751 752 + 753 746 754 755 756 757 + 757 750 758 759 760 761 + 762 755 763 764 765 766 + 766 759 767 768 769 770 + 771 772 773 774 690 775 + 775 776 777 778 695 779 + 780 774 781 782 700 783 + 783 778 784 785 704 786 + 787 782 788 789 709 790 + 790 785 791 792 713 793 + 794 789 795 796 718 797 + 797 792 798 799 722 800 + 801 796 802 803 727 804 + 804 799 805 806 731 807 + 808 803 809 810 736 811 + 811 806 812 813 740 814 + 815 810 816 817 745 818 + 818 813 819 820 749 821 + 822 817 823 824 754 825 + 825 820 826 827 758 828 + 829 824 830 831 763 832 + 832 827 833 834 767 835 + 836 837 838 839 773 840 + 840 841 842 843 777 844 + 845 839 846 847 781 848 + 848 843 849 850 784 851 + 852 847 853 854 788 855 + 855 850 856 857 791 858 + 859 854 860 861 795 862 + 862 857 863 864 798 865 + 866 861 867 868 802 869 + 869 864 870 871 805 872 + 873 868 874 875 809 876 + 876 871 877 878 812 879 + 880 875 881 882 816 883 + 883 878 884 885 819 886 + 887 882 888 889 823 890 + 890 885 891 892 826 893 + 894 889 895 896 830 897 + 897 892 898 899 833 900 + 901 902 903 904 838 905 + 905 906 907 908 842 909 + 910 904 911 912 846 913 + 913 908 914 915 849 916 + 917 912 918 919 853 920 + 920 915 921 922 856 923 + 924 919 925 926 860 927 + 927 922 928 929 863 930 + 931 926 932 933 867 934 + 934 929 935 936 870 937 + 938 933 939 940 874 941 + 941 936 942 943 877 944 + 945 940 946 947 881 948 + 948 943 949 950 884 951 + 952 947 953 954 888 955 + 955 950 956 957 891 958 + 959 954 960 961 895 962 + 962 957 963 964 898 965 + 966 967 968 969 903 970 + 970 971 972 973 907 974 + 975 969 976 977 911 978 + 978 973 979 980 914 981 + 982 977 983 984 918 985 + 985 980 986 987 921 988 + 989 984 990 991 925 992 + 992 987 993 994 928 995 + 996 991 997 998 932 999 + 999 994 1000 1001 935 1002 + 1003 998 1004 1005 939 1006 + 1006 1001 1007 1008 942 1009 + 1010 1005 1011 1012 946 1013 + 1013 1008 1014 1015 949 1016 + 1017 1012 1018 1019 953 1020 + 1020 1015 1021 1022 956 1023 + 1024 1019 1025 1026 960 1027 + 1027 1022 1028 1029 963 1030 + 1031 1032 1033 1034 968 1035 + 1035 1036 1037 1038 972 1039 + 1040 1034 1041 1042 976 1043 + 1043 1038 1044 1045 979 1046 + 1047 1042 1048 1049 983 1050 + 1050 1045 1051 1052 986 1053 + 1054 1049 1055 1056 990 1057 + 1057 1052 1058 1059 993 1060 + 1061 1056 1062 1063 997 1064 + 1064 1059 1065 1066 1000 1067 + 1068 1063 1069 1070 1004 1071 + 1071 1066 1072 1073 1007 1074 + 1075 1070 1076 1077 1011 1078 + 1078 1073 1079 1080 1014 1081 + 1082 1077 1083 1084 1018 1085 + 1085 1080 1086 1087 1021 1088 + 1089 1084 1090 1091 1025 1092 + 1092 1087 1093 1094 1028 1095 + 1096 1097 1098 1099 1033 1100 + 1100 1101 1102 1103 1037 1104 + 1105 1099 1106 1107 1041 1108 + 1108 1103 1109 1110 1044 1111 + 1112 1107 1113 1114 1048 1115 + 1115 1110 1116 1117 1051 1118 + 1119 1114 1120 1121 1055 1122 + 1122 1117 1123 1124 1058 1125 + 1126 1121 1127 1128 1062 1129 + 1129 1124 1130 1131 1065 1132 + 1133 1128 1134 1135 1069 1136 + 1136 1131 1137 1138 1072 1139 + 1140 1135 1141 1142 1076 1143 + 1143 1138 1144 1145 1079 1146 + 1147 1142 1148 1149 1083 1150 + 1150 1145 1151 1152 1086 1153 + 1154 1149 1155 1156 1090 1157 + 1157 1152 1158 1159 1093 1160 + 1161 1162 1163 1164 1098 1165 + 1165 1166 1167 1168 1102 1169 + 1170 1164 1171 1172 1106 1173 + 1173 1168 1174 1175 1109 1176 + 1177 1172 1178 1179 1113 1180 + 1180 1175 1181 1182 1116 1183 + 1184 1179 1185 1186 1120 1187 + 1187 1182 1188 1189 1123 1190 + 1191 1186 1192 1193 1127 1194 + 1194 1189 1195 1196 1130 1197 + 1198 1193 1199 1200 1134 1201 + 1201 1196 1202 1203 1137 1204 + 1205 1200 1206 1207 1141 1208 + 1208 1203 1209 1210 1144 1211 + 1212 1207 1213 1214 1148 1215 + 1215 1210 1216 1217 1151 1218 + 1219 1214 1220 1221 1155 1222 + 1222 1217 1223 1224 1158 1225 + 1226 1227 1228 1229 1163 1230 + 1230 1231 1232 1233 1167 1234 + 1235 1229 1236 1237 1171 1238 + 1238 1233 1239 1240 1174 1241 + 1242 1237 1243 1244 1178 1245 + 1245 1240 1246 1247 1181 1248 + 1249 1244 1250 1251 1185 1252 + 1252 1247 1253 1254 1188 1255 + 1256 1251 1257 1258 1192 1259 + 1259 1254 1260 1261 1195 1262 + 1263 1258 1264 1265 1199 1266 + 1266 1261 1267 1268 1202 1269 + 1270 1265 1271 1272 1206 1273 + 1273 1268 1274 1275 1209 1276 + 1277 1272 1278 1279 1213 1280 + 1280 1275 1281 1282 1216 1283 + 1284 1279 1285 1286 1220 1287 + 1287 1282 1288 1289 1223 1290 + 1291 1292 1293 1294 1295 1296 + 1296 1297 1298 1299 1300 1301 + 1301 1302 1303 1304 1305 1306 + 1307 1294 1308 1309 1310 1311 + 1311 1299 1312 1313 1314 1315 + 1315 1304 1316 1317 1318 1319 + 1320 1309 1321 1322 1323 1324 + 1324 1313 1325 1326 1327 1328 + 1328 1317 1329 1330 1331 1332 + 1333 1322 1334 1335 1336 1337 + 1337 1326 1338 1339 1340 1341 + 1341 1330 1342 1343 1344 1345 + 1346 1335 1347 1348 1349 1350 + 1350 1339 1351 1352 1353 1354 + 1354 1343 1355 1356 1357 1358 + 1359 1348 1360 1361 1362 1363 + 1363 1352 1364 1365 1366 1367 + 1367 1356 1368 1369 1370 1371 + 1372 1361 1373 1374 1375 1376 + 1376 1365 1377 1378 1379 1380 + 1380 1369 1381 1382 1383 1384 + 1385 1374 1386 1387 1388 1389 + 1389 1378 1390 1391 1392 1393 + 1393 1382 1394 1395 1396 1397 + 1398 1399 1400 1401 1293 1402 + 1402 1403 1404 1405 1298 1406 + 1406 1407 1408 1409 1303 1410 + 1411 1401 1412 1413 1308 1414 + 1414 1405 1415 1416 1312 1417 + 1417 1409 1418 1419 1316 1420 + 1421 1413 1422 1423 1321 1424 + 1424 1416 1425 1426 1325 1427 + 1427 1419 1428 1429 1329 1430 + 1431 1423 1432 1433 1334 1434 + 1434 1426 1435 1436 1338 1437 + 1437 1429 1438 1439 1342 1440 + 1441 1433 1442 1443 1347 1444 + 1444 1436 1445 1446 1351 1447 + 1447 1439 1448 1449 1355 1450 + 1451 1443 1452 1453 1360 1454 + 1454 1446 1455 1456 1364 1457 + 1457 1449 1458 1459 1368 1460 + 1461 1453 1462 1463 1373 1464 + 1464 1456 1465 1466 1377 1467 + 1467 1459 1468 1469 1381 1470 + 1471 1463 1472 1473 1386 1474 + 1474 1466 1475 1476 1390 1477 + 1477 1469 1478 1479 1394 1480 + 1481 1482 1483 1484 1400 1485 + 1485 1486 1487 1488 1404 1489 + 1489 1490 1491 1492 1408 1493 + 1494 1484 1495 1496 1412 1497 + 1497 1488 1498 1499 1415 1500 + 1500 1492 1501 1502 1418 1503 + 1504 1496 1505 1506 1422 1507 + 1507 1499 1508 1509 1425 1510 + 1510 1502 1511 1512 1428 1513 + 1514 1506 1515 1516 1432 1517 + 1517 1509 1518 1519 1435 1520 + 1520 1512 1521 1522 1438 1523 + 1524 1516 1525 1526 1442 1527 + 1527 1519 1528 1529 1445 1530 + 1530 1522 1531 1532 1448 1533 + 1534 1526 1535 1536 1452 1537 + 1537 1529 1538 1539 1455 1540 + 1540 1532 1541 1542 1458 1543 + 1544 1536 1545 1546 1462 1547 + 1547 1539 1548 1549 1465 1550 + 1550 1542 1551 1552 1468 1553 + 1554 1546 1555 1556 1472 1557 + 1557 1549 1558 1559 1475 1560 + 1560 1552 1561 1562 1478 1563 + 1564 1565 1566 1567 1483 1568 + 1568 1569 1570 1571 1487 1572 + 1572 1573 1574 1575 1491 1576 + 1577 1567 1578 1579 1495 1580 + 1580 1571 1581 1582 1498 1583 + 1583 1575 1584 1585 1501 1586 + 1587 1579 1588 1589 1505 1590 + 1590 1582 1591 1592 1508 1593 + 1593 1585 1594 1595 1511 1596 + 1597 1589 1598 1599 1515 1600 + 1600 1592 1601 1602 1518 1603 + 1603 1595 1604 1605 1521 1606 + 1607 1599 1608 1609 1525 1610 + 1610 1602 1611 1612 1528 1613 + 1613 1605 1614 1615 1531 1616 + 1617 1609 1618 1619 1535 1620 + 1620 1612 1621 1622 1538 1623 + 1623 1615 1624 1625 1541 1626 + 1627 1619 1628 1629 1545 1630 + 1630 1622 1631 1632 1548 1633 + 1633 1625 1634 1635 1551 1636 + 1637 1629 1638 1639 1555 1640 + 1640 1632 1641 1642 1558 1643 + 1643 1635 1644 1645 1561 1646 + 1647 1648 1649 1650 1566 1651 + 1651 1652 1653 1654 1570 1655 + 1655 1656 1657 1658 1574 1659 + 1660 1650 1661 1662 1578 1663 + 1663 1654 1664 1665 1581 1666 + 1666 1658 1667 1668 1584 1669 + 1670 1662 1671 1672 1588 1673 + 1673 1665 1674 1675 1591 1676 + 1676 1668 1677 1678 1594 1679 + 1680 1672 1681 1682 1598 1683 + 1683 1675 1684 1685 1601 1686 + 1686 1678 1687 1688 1604 1689 + 1690 1682 1691 1692 1608 1693 + 1693 1685 1694 1695 1611 1696 + 1696 1688 1697 1698 1614 1699 + 1700 1692 1701 1702 1618 1703 + 1703 1695 1704 1705 1621 1706 + 1706 1698 1707 1708 1624 1709 + 1710 1702 1711 1712 1628 1713 + 1713 1705 1714 1715 1631 1716 + 1716 1708 1717 1718 1634 1719 + 1720 1712 1721 1722 1638 1723 + 1723 1715 1724 1725 1641 1726 + 1726 1718 1727 1728 1644 1729 + 1730 1731 1732 1733 1649 1734 + 1734 1735 1736 1737 1653 1738 + 1738 1739 1740 1741 1657 1742 + 1743 1733 1744 1745 1661 1746 + 1746 1737 1747 1748 1664 1749 + 1749 1741 1750 1751 1667 1752 + 1753 1745 1754 1755 1671 1756 + 1756 1748 1757 1758 1674 1759 + 1759 1751 1760 1761 1677 1762 + 1763 1755 1764 1765 1681 1766 + 1766 1758 1767 1768 1684 1769 + 1769 1761 1770 1771 1687 1772 + 1773 1765 1774 1775 1691 1776 + 1776 1768 1777 1778 1694 1779 + 1779 1771 1780 1781 1697 1782 + 1783 1775 1784 1785 1701 1786 + 1786 1778 1787 1788 1704 1789 + 1789 1781 1790 1791 1707 1792 + 1793 1785 1794 1795 1711 1796 + 1796 1788 1797 1798 1714 1799 + 1799 1791 1800 1801 1717 1802 + 1803 1795 1804 1805 1721 1806 + 1806 1798 1807 1808 1724 1809 + 1809 1801 1810 1811 1727 1812 + 1813 1814 1815 1816 1732 1817 + 1817 1818 1819 1820 1736 1821 + 1821 1822 1823 1824 1740 1825 + 1826 1816 1827 1828 1744 1829 + 1829 1820 1830 1831 1747 1832 + 1832 1824 1833 1834 1750 1835 + 1836 1828 1837 1838 1754 1839 + 1839 1831 1840 1841 1757 1842 + 1842 1834 1843 1844 1760 1845 + 1846 1838 1847 1848 1764 1849 + 1849 1841 1850 1851 1767 1852 + 1852 1844 1853 1854 1770 1855 + 1856 1848 1857 1858 1774 1859 + 1859 1851 1860 1861 1777 1862 + 1862 1854 1863 1864 1780 1865 + 1866 1858 1867 1868 1784 1869 + 1869 1861 1870 1871 1787 1872 + 1872 1864 1873 1874 1790 1875 + 1876 1868 1877 1878 1794 1879 + 1879 1871 1880 1881 1797 1882 + 1882 1874 1883 1884 1800 1885 + 1886 1878 1887 1888 1804 1889 + 1889 1881 1890 1891 1807 1892 + 1892 1884 1893 1894 1810 1895 + 1896 1897 1898 1899 1815 1900 + 1900 1901 1902 1903 1819 1904 + 1904 1905 1906 1907 1823 1908 + 1909 1899 1910 1911 1827 1912 + 1912 1903 1913 1914 1830 1915 + 1915 1907 1916 1917 1833 1918 + 1919 1911 1920 1921 1837 1922 + 1922 1914 1923 1924 1840 1925 + 1925 1917 1926 1927 1843 1928 + 1929 1921 1930 1931 1847 1932 + 1932 1924 1933 1934 1850 1935 + 1935 1927 1936 1937 1853 1938 + 1939 1931 1940 1941 1857 1942 + 1942 1934 1943 1944 1860 1945 + 1945 1937 1946 1947 1863 1948 + 1949 1941 1950 1951 1867 1952 + 1952 1944 1953 1954 1870 1955 + 1955 1947 1956 1957 1873 1958 + 1959 1951 1960 1961 1877 1962 + 1962 1954 1963 1964 1880 1965 + 1965 1957 1966 1967 1883 1968 + 1969 1961 1970 1971 1887 1972 + 1972 1964 1973 1974 1890 1975 + 1975 1967 1976 1977 1893 1978 + + + + H[0-191] + H[192-353] + H[354-545] + F[0,16,29,42,55,68,81,94,107,120,130,140,150,160,170,180,190,203,213,223,233,243,253,263,273,286,296,306,316,326,336,346,356,369,379,389,399,409,419,429,439,452,462,472,482,492,502,512,522,535,545,555,565,575,585,595,605,618,628,638,648,658,668,678] + F[1306,1319,1332,1345,1358,1371,1384,1397,1410,1420,1430,1440,1450,1460,1470,1480,1493,1503,1513,1523,1533,1543,1553,1563,1576,1586,1596,1606,1616,1626,1636,1646,1659,1669,1679,1689,169