/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2020-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . Class Foam::DMDModels::STDMD Description Streaming Total Dynamic Mode Decomposition (i.e. \c STDMD) is a variant of dynamic mode decomposition. Among other Dynamic Mode Decomposition (DMD) variants, \c STDMD is presumed to provide the general DMD method capabilities alongside economised and feasible memory and CPU usage. The code implementation corresponds to Figs. 15-16 of the first citation below, more broadly to Section 2.4. References: \verbatim DMD and mode-sorting algorithms (tags:K, HRDC, KZ, HWR): Kiewat, M. (2019). Streaming modal decomposition approaches for vehicle aerodynamics. PhD thesis. Munich: Technical University of Munich. URL:mediatum.ub.tum.de/doc/1482652/1482652.pdf Hemati, M. S., Rowley, C. W., Deem, E. A., & Cattafesta, L. N. (2017). De-biasing the dynamic mode decomposition for applied Koopman spectral analysis of noisy datasets. Theoretical and Computational Fluid Dynamics, 31(4), 349-368. DOI:10.1007/s00162-017-0432-2 Kou, J., & Zhang, W. (2017). An improved criterion to select dominant modes from dynamic mode decomposition. European Journal of Mechanics-B/Fluids, 62, 109-129. DOI:10.1016/j.euromechflu.2016.11.015 Hemati, M. S., Williams, M. O., & Rowley, C. W. (2014). Dynamic mode decomposition for large and streaming datasets. Physics of Fluids, 26(11), 111701. DOI:10.1063/1.4901016 Parallel classical Gram-Schmidt process (tag:Ka): Katagiri, T. (2003). Performance evaluation of parallel Gram-Schmidt re-orthogonalization methods. In: Palma J. M. L. M., Sousa A. A., Dongarra J., Hernández V. (eds) High Performance Computing for Computational Science — VECPAR 2002. Lecture Notes in Computer Science, vol 2565, p. 302-314. Berlin, Heidelberg: Springer. DOI:10.1007/3-540-36569-9_19 Parallel direct tall-skinny QR decomposition (tags:BGD, DGHL): Benson, A. R., Gleich, D. F., & Demmel, J. (2013). Direct QR factorizations for tall-and-skinny matrices in MapReduce architectures. 2013 IEEE International Conference on Big Data. DOI:10.1109/bigdata.2013.6691583 Demmel, J., Grigori, L., Hoemmen, M., & Langou, J. (2012). Communication-optimal parallel and sequential QR and LU factorizations. SIAM Journal on Scientific Computing, 34(1), A206-A239. DOI:10.1137/080731992 \endverbatim Usage Minimal example by using \c system/controlDict.functions: \verbatim DMD1 { // Mandatory entries DMDModel STDMD; // Conditional mandatory entries // Option-1 interval 5.5; // Option-2 executeInterval 10; // Optional entries modeSorter kiewat; nGramSchmidt 5; maxRank 50; nModes 50; fMin 0; fMax 1000000000; nAgglomerationProcs 20; // Optional entries (not recommended to change) minBasis 0.00000001; minEVal 0.00000001; sortLimiter 500.0; // Inherited entries ... } \endverbatim where the entries mean: \table Property | Description | Type | Reqd | Deflt DMDModel | Type: STDMD | word | yes | - interval | STDMD time-step size [s] | scalar | cndtnl | executeInterval*(current time-step of the simulation) modeSorter | Mode-sorting algorithm model | word | no | firstSnapshot nModes | Number of output modes in input frequency range | label | no | GREAT maxRank | Max columns in accumulated matrices | label | no | GREAT nGramSchmidt | Number of Gram-Schmidt iterations | label | no | 5 fMin | Min (non-negative) output frequency | label | no | 0 fMax | Max output frequency | label | no | GREAT nAgglomerationProcs | Number of processors at each agglomeration unit during the computation of reduced Koopman operator | label | no | 20 minBasis | Orthogonal basis expansion threshold | scalar| no | 1e-8 minEVal | Min eigenvalue for below eigenvalues are omitted | scalar| no | 1e-8 sortLimiter | Max allowable magnitude for mag(eigenvalue)*(number of DMD steps) to be used in modeSorter={kiewat,kouZhang} to avoid overflow errors | scalar | no | 500.0 \endtable Options for the \c modeSorter entry: \verbatim kiewat | Modified weighted-amplitude scaling method kouZhang | Weighted-amplitude scaling method firstSnapshot | First-snapshot amplitude magnitude method \endverbatim Note - To specify the STDMD time-step size (not necessarily equal to the time step of the simulation), entries of either \c interval or \c executeInterval must be available (highest to lowest precedence). While \c interval allows users to directly specify the STDMD time-step size in seconds, in absence of \c interval, for convenience, \c executeInterval allows users to compute the STDMD time-step internally by multiplying itself with the current time-step size of the simulation. - Limitation: Restart is currently not available since intermediate writing of STDMD matrices are not supported. - Limitation: Non-physical input (e.g. full-zero fields) can upset STDMD. - Warning: In \c modeSorter algorithms of \c kiewat and \c kouZhang, a function of \f$power(x,y)\f$ exists where \c x is the magnitude of an eigenvalue, and \c y is the number of STDMD snapshots. This function poses a risk of overflow errors since, for example, if \c x ends up above 1.5 with 500 snapshots or more, this function automatically throws the floating point error meaning overflow. Therefore, the domain-range of this function is heuristically constrained by the optional entry \c sortLimiter which skips the evaluation of this function for a given mag(eigenvalue)*(no. of STDMD steps), i.e. x*y, whose magnitude is larger than \c sortLimiter. See also - Foam::functionObjects::DMD - Foam::DMDModel SourceFiles STDMD.C STDMDTemplates.C \*---------------------------------------------------------------------------*/ #ifndef Foam_DMDModels_STDMD_H #define Foam_DMDModels_STDMD_H #include "DMDModel.H" #include "SquareMatrix.H" #include "RectangularMatrix.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { namespace DMDModels { /*---------------------------------------------------------------------------*\ Class STDMD Declaration \*---------------------------------------------------------------------------*/ class STDMD : public DMDModel { typedef SquareMatrix SMatrix; typedef RectangularMatrix RMatrix; typedef RectangularMatrix RCMatrix; // Private Enumerations //- Options for the mode-sorting algorithm enum modeSorterType : char { FIRST_SNAPSHOT = 0, //!< "First-snapshot amplitude magnitude method" KIEWAT, //!< "Modified weighted-amplitude scaling method" KOU_ZHANG //!< "Weighted-amplitude scaling method" }; //- Names for modeSorterType static const Enum modeSorterTypeNames; // Private Data //- Mode-sorting algorithm enum modeSorterType modeSorter_; //- Accumulated-in-time unitary similarity matrix produced by the //- orthonormal decomposition of the augmented snapshot matrix 'z' // (K:Eq. 60) RMatrix Q_; //- Accumulated-in-time (squared) upper triangular matrix produced by //- the orthonormal decomposition of the augmented snapshot matrix 'z' // (K:Eq. 64) SMatrix G_; //- Upper half of 'Q' RMatrix Qupper_; //- Lower half of 'Q' RMatrix Qlower_; //- Moore-Penrose pseudo-inverse of 'R' produced by //- the QR decomposition of the last time-step 'Q' RMatrix RxInv_; //- Eigenvalues of modes List evals_; //- Eigenvectors of modes RCMatrix evecs_; //- (Non-negative) frequencies of modes List freqs_; //- Indices of 'freqs' where frequencies are //- non-negative and within ['fMin', 'fMax'] DynamicList