summaryrefslogtreecommitdiff
path: root/src/dynamics/descriptorField.h
blob: d9f955a137b2bc5abac35027ab7f1a0ba9ac1a7f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/*  This file is part of the OpenLB library
 *
 *  Copyright (C) 2019 Adrian Kummerlaender
 *  E-mail contact: info@openlb.net
 *  The most recent release of OpenLB can be downloaded at
 *  <http://www.openlb.net/>
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public
 *  License along with this program; if not, write to the Free
 *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA  02110-1301, USA.
*/

#ifndef DESCRIPTOR_FIELD_H
#define DESCRIPTOR_FIELD_H

#include <type_traits>
#include <stdexcept>

namespace olb {

namespace descriptors {

/// \defgroup descriptor
//@{

/// Base of a descriptor field whose size is defined by A*D + B*Q + C
template <unsigned C, unsigned A=0, unsigned B=0>
struct DESCRIPTOR_FIELD_BASE {

  /// Deleted constructor to enforce pure usage as type and prevent implicit narrowing conversions
  DESCRIPTOR_FIELD_BASE() = delete;

  /// Evaluates the size function
  /**
   * To be called by DESCRIPTOR_BASE
   **/
  template <unsigned D, unsigned Q>
  static constexpr unsigned size()
  {
    return A * D + B * Q + C;
  }

  /// Returns global index from local index and provides out_of_range safety
  template <unsigned D, unsigned Q>
  static constexpr unsigned getLocalIndex(const unsigned localIndex)
  {
    return localIndex < (A*D+B*Q+C) ? localIndex : throw std::out_of_range("Index exceeds data field");
  }

};

/// \defgroup descriptor_fields Set of common descriptor fields
/// \ingroup descriptor
//@{

// Field types need to be distinct (i.e. not aliases) in order for `getDescriptorFieldBeginsAt` to work
// (Field size parametrized by: Cs + Ds*D + Qs*Q)          Cs Ds Qs
struct POPULATION           : public DESCRIPTOR_FIELD_BASE<0,  0, 1> { };
struct VELOCITY             : public DESCRIPTOR_FIELD_BASE<0,  1, 0> { };
struct VELOCITY2            : public DESCRIPTOR_FIELD_BASE<0,  1, 0> { };
struct SOURCE               : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct FORCE                : public DESCRIPTOR_FIELD_BASE<0,  1, 0> { };
struct EXTERNAL_FORCE       : public DESCRIPTOR_FIELD_BASE<0,  1, 0> { };
struct TAU_EFF              : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct CUTOFF_KIN_ENERGY    : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct CUTOFF_HEAT_FLUX     : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct CHEM_POTENTIAL       : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct V6                   : public DESCRIPTOR_FIELD_BASE<6,  0, 0> { };
struct V12                  : public DESCRIPTOR_FIELD_BASE<12, 0, 0> { };
struct OMEGA                : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct G                    : public DESCRIPTOR_FIELD_BASE<0,  1, 0> { };
struct EPSILON              : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct BODY_FORCE           : public DESCRIPTOR_FIELD_BASE<0,  1, 0> { };
struct K                    : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct NU                   : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct POROSITY             : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct VELOCITY_NUMERATOR   : public DESCRIPTOR_FIELD_BASE<0,  1, 0> { };
struct VELOCITY_DENOMINATOR : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct LOCAL_DRAG           : public DESCRIPTOR_FIELD_BASE<0,  1, 0> { };
struct VELOCITY_SOLID       : public DESCRIPTOR_FIELD_BASE<0,  1, 0> { };
struct COORDINATE           : public DESCRIPTOR_FIELD_BASE<0,  1, 0> { };
struct F                    : public DESCRIPTOR_FIELD_BASE<0,  0, 1> { };
struct DJDF                 : public DESCRIPTOR_FIELD_BASE<0,  0, 1> { };
struct DJDALPHA             : public DESCRIPTOR_FIELD_BASE<0,  1, 0> { };
struct AV_SHEAR             : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct TAU_W                : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct SCALAR               : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct SMAGO_CONST          : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct EFFECTIVE_OMEGA      : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct VELO_GRAD            : public DESCRIPTOR_FIELD_BASE<0,  3, 0> { };
struct FIL_RHO              : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct LOCAL_FIL_VEL_X      : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct LOCAL_FIL_VEL_Y      : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct LOCAL_FIL_VEL_Z      : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct LOCAL_AV_DISS        : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct LOCAL_AV_TKE         : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct LOCAL_SIGMA_ADM      : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct LOCAL_NU_EDDY        : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct FILTERED_VEL_GRAD    : public DESCRIPTOR_FIELD_BASE<0,  3, 0> { };
struct ERROR_COVARIANCE     : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct VARIANCE             : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct TAU_SGS              : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct FILTERED_POPULATION  : public DESCRIPTOR_FIELD_BASE<0,  0, 1> { };
struct INDICATE             : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct BIOGAS_INSTANT       : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct BIOGAS_CUMULATIVE    : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct METHANE_INSTANT      : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct METHANE_CUMULATIVE   : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct CO2_INSTANT          : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };
struct CO2_CUMULATIVE       : public DESCRIPTOR_FIELD_BASE<1,  0, 0> { };

struct TENSOR {
  TENSOR() = delete;

  template <unsigned D, unsigned Q>
  static constexpr unsigned size()
  {
    return (D * (D+1)) / 2; // see `TensorVal` in `core/util.h`
  }

  template <unsigned D, unsigned Q>
  static constexpr unsigned getLocalIndex(const unsigned localIndex)
  {
    return localIndex < size<D,Q>() ? localIndex : throw (std::out_of_range("Index exceeds data field"));
  }
};

//@}

/// \defgroup descriptor_details Descriptor field handling
/// \ingroup descriptor
//@{

template <
  unsigned D,
  unsigned Q,
  typename WANTED_FIELD,
  typename CURRENT_FIELD,
  typename... FIELDS,
  // WANTED_FIELD equals the head of our field list, terminate recursion
  utilities::meta::enable_if_t<std::is_same<WANTED_FIELD,CURRENT_FIELD>::value, int> = 0
>
constexpr unsigned getIndexFromFieldList()
{
  return 0;
}

template <
  unsigned D,
  unsigned Q,
  typename WANTED_FIELD,
  typename CURRENT_FIELD,
  typename... FIELDS,
  // WANTED_FIELD doesn't equal the head of our field list
  utilities::meta::enable_if_t<!std::is_same<WANTED_FIELD,CURRENT_FIELD>::value, int> = 0
>
constexpr unsigned getIndexFromFieldList()
{
  // Break compilation when WANTED_FIELD is not provided by list of fields
  static_assert(sizeof...(FIELDS) > 0, "Field not found.");

  // Add size of current field to implicit offset and continue search
  // for WANTED_FIELD in the tail of our field list
  return CURRENT_FIELD::template size<D,Q>() + getIndexFromFieldList<D,Q,WANTED_FIELD,FIELDS...>();
}


template <unsigned D, unsigned Q>
constexpr unsigned getFieldListSize()
{
  // Field-less descriptor base case
  return 0;
}

template <unsigned D, unsigned Q, typename CURRENT_FIELD, typename... FIELDS>
constexpr unsigned getFieldListSize()
{
  // Calculate size of CURRENT_FIELD and add it to the sum of all remaining field sizes
  return CURRENT_FIELD::template size<D,Q>() + getFieldListSize<D,Q,FIELDS...>();
}

//@}

//@}

}

}

#endif