MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
surfacecoupling.h
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#ifndef SURFACECOUPLING_H_
8#define SURFACECOUPLING_H_
9
10#include <vector>
11#include "GRID/cartesiangrid.h"
13#include "INCLUDE/maiatypes.h"
14#include "UTIL/maiamath.h"
15
16namespace maia::coupling {
17
36template <MInt nDim, class S, class T, class M, class C>
37void setBoundaryForce(S& src, T& tgt, M& mapping, C conversion) {
38 tgt.resetForce();
39
40 for(MInt srcId = 0; srcId < src.size(); srcId++) {
41 std::array<MFloat, nDim> force{};
42 for(MInt n = 0; n < nDim; n++) {
43 force[n] = src.force(srcId, n) * conversion.force;
44 }
45
46 for(auto&& tgtId : mapping[srcId]) {
47 tgt.addForce(tgtId, force);
48 }
49 }
50}
51
70template <MInt nDim, class S, class T, class M, class C>
71void setBoundaryForceAndTorque(S& src, T& tgt, M& mapping, C conversion) {
72 static constexpr MInt nRot = (nDim == 3) ? 3 : 1;
73
74 tgt.resetForce();
75 tgt.resetTorque();
76
77 for(MInt srcId = 0; srcId < src.size(); srcId++) {
78 for(MInt j = 0; j < src.noForces(); j++) {
79 std::array<MFloat, nDim> force{};
80 for(MInt n = 0; n < nDim; n++) {
81 force[n] = src.force(srcId, j, n) * conversion.force;
82 }
83
84 for(auto&& tgtId : mapping[srcId]) {
85 tgt.addForce(tgtId, force);
86
87 std::array<MFloat, nDim> r{};
88 for(MInt n = 0; n < nDim; n++) {
89 r[n] = (src.surfaceCenter(srcId, j, n) - tgt.a_bodyCenter(tgtId, n)) * conversion.length;
90 }
91
92 std::array<MFloat, nRot> torque{};
93 if constexpr(nDim == 3) {
94 torque = maia::math::cross(force, r);
95 } else if constexpr(nDim == 2) {
96 torque[0] = force[0] * r[1] - force[1] * r[0];
97 }
98
99 tgt.addTorque(tgtId, torque);
100 }
101 }
102 }
103}
104
123template <MInt nDim, class S, class T, class M, class C>
124void setBoundaryVelocity(S& src, T& tgt, M& mapping, C conversion) {
125 static constexpr MInt nRot = (nDim == 3) ? 3 : 1;
126
127 if(mapping.size() == 0) {
128 return;
129 }
130
131 for(MInt srcId = 0; srcId < src.size(); srcId++) {
132 std::array<MFloat, nDim> velocity{};
133 src.getVelocity(srcId, velocity);
134 for(MInt n = 0; n < nDim; n++) {
135 velocity[n] *= conversion.velocity;
136 }
137
138 std::array<MFloat, nRot> angularVelocity{};
139 src.getAngularVelocity(srcId, angularVelocity);
140 for(MInt n = 0; n < nRot; n++) {
141 angularVelocity[n] *= conversion.angularVelocity;
142 }
143
144 for(auto&& tgtId : mapping[srcId]) {
145 std::array<MFloat, nDim> r{};
146 for(MInt n = 0; n < nDim; n++) {
147 r[n] = (tgt.cellCenter(tgtId, n) - src.a_bodyCenter(srcId, n)) * conversion.length;
148 }
149 std::array<MFloat, nDim> rotationalVelocity{};
150 IF_CONSTEXPR(nDim == 3) { rotationalVelocity = maia::math::cross(r, angularVelocity); }
151 else IF_CONSTEXPR(nDim == 2) {
152 rotationalVelocity[0] = angularVelocity[0] * r[0];
153 rotationalVelocity[1] = angularVelocity[0] * r[1];
154 }
155
156 tgt.setVelocity(tgtId, velocity);
157 tgt.addVelocity(tgtId, rotationalVelocity);
158 }
159 }
160}
161
167template <class Iter>
168class range {
169 Iter m_b;
170 Iter m_e;
171
172 public:
173 range(Iter b, Iter e) : m_b(b), m_e(e) {}
174
175 Iter begin() { return m_b; }
176 Iter end() { return m_e; }
177};
178
186struct Mapping {
187 std::vector<MUint> m_offsets;
188 std::vector<MInt> m_mapped;
189
191 MUint b = 0;
192 MUint e = 0;
193
194 if(i < m_offsets.size()) {
195 b = m_offsets[i];
196 e = (i == m_offsets.size() - 1) ? m_mapped.size() : m_offsets[i + 1];
197 }
198
199 std::vector<MInt>::const_iterator bb = m_mapped.begin() + b;
200 std::vector<MInt>::const_iterator ee = m_mapped.begin() + e;
201
202 return {bb, ee};
203 }
204
205 void clear() {
206 m_offsets.clear();
207 m_mapped.clear();
208 }
209
210 // Total count of mapped values
211 std::size_t size() const { return m_mapped.size(); }
212
213 // Insert value for key i, return value reference
214 MInt& insert(const MInt i) {
215 if(i < MInt(m_offsets.size() - 1)) {
216 // key already exists, but is not the last one
217
218 // if value is -1, set now!
219 if(m_mapped[m_offsets[i]] == -1) {
220 return m_mapped[m_offsets[i]];
221 }
222
223 for(MInt j = i + 1; j < MInt(m_offsets.size()); j++) {
224 m_offsets[j]++;
225 }
226
227 m_mapped.insert(m_mapped.begin() + m_offsets[i + 1] - 1, -1);
228
229 return m_mapped[m_offsets[i + 1] - 1];
230
231 } else if(i == MInt(m_offsets.size() - 1)) {
232 // key already exists and is the last
233
234 m_mapped.push_back(-1);
235
236 return m_mapped[m_mapped.size() - 1];
237
238 } else if(i >= MInt(m_offsets.size())) {
239 // key does not exist yet
240
241 // number of keys to be added
242 // none is mapping onto a value but the last one
243 const MUint noNewKeys = i + 1 - m_offsets.size();
244
245 for(MUint j = 0; j < noNewKeys; j++) {
246 m_offsets.push_back(m_mapped.size());
247 }
248
249 m_mapped.push_back(-1);
250
251 return m_mapped[m_mapped.size() - 1];
252 }
253
254 std::cerr << "Map insert shouldnt reach this case" << std::endl;
255 return m_mapped[m_mapped.size() - 1];
256 }
257
259};
260
261
262} // namespace maia::coupling
263#endif
Simple implementation of c++20 range.
range(Iter b, Iter e)
int32_t MInt
Definition: maiatypes.h:62
uint32_t MUint
Definition: maiatypes.h:63
void setBoundaryForceAndTorque(S &src, T &tgt, M &mapping, C conversion)
Setting the boundary force and torque from one surface collector to the other.
void setBoundaryForce(S &src, T &tgt, M &mapping, C conversion)
Setting the boundary force from one surface collector to the other.
void setBoundaryVelocity(S &src, T &tgt, M &mapping, C conversion)
Setting the boundary velocity from one surface collector to the other.
void cross(const T *const u, const T *const v, T *const c)
Definition: maiamath.h:101
Multi-to-multi mapping class.
std::vector< MUint > m_offsets
range< std::vector< MInt >::const_iterator > operator[](const MInt i) const
range< std::vector< MInt >::const_iterator > get(const MUint i) const
std::vector< MInt > m_mapped
MInt & insert(const MInt i)
std::size_t size() const