NeoFOAM
WIP Prototype of a modern OpenFOAM core
Loading...
Searching...
No Matches
fieldFreeFunctions.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: 2023 NeoFOAM authors
3#pragma once
4
5#include <tuple>
6#include <span>
7
8#include <Kokkos_Core.hpp>
12
13namespace NeoFOAM
14{
15
16// Forward declaration
17template<typename ValueType>
18class Field;
19
20
28template<typename T, typename Inner>
29void map(Field<T>& a, const Inner inner, std::pair<size_t, size_t> range = {0, 0})
30{
31 auto [start, end] = range;
32 if (end == 0)
33 {
34 end = a.size();
35 }
36 auto spanA = a.span();
38 a.exec(), {start, end}, KOKKOS_LAMBDA(const size_t i) { spanA[i] = inner(i); }
39 );
40}
41
49template<typename ValueType>
50void fill(
52 const std::type_identity_t<ValueType> value,
53 std::pair<size_t, size_t> range = {0, 0}
54)
55{
56 auto [start, end] = range;
57 if (end == 0)
58 {
59 end = a.size();
60 }
61 auto spanA = a.span();
63 a.exec(), {start, end}, KOKKOS_LAMBDA(const size_t i) { spanA[i] = value; }
64 );
65}
66
67
75template<typename ValueType>
78 const std::span<const std::type_identity_t<ValueType>> b,
79 std::pair<size_t, size_t> range = {0, 0}
80)
81{
82 auto [start, end] = range;
83 if (end == 0)
84 {
85 end = a.size();
86 }
87 auto spanA = a.span();
89 a.exec(), {start, end}, KOKKOS_LAMBDA(const size_t i) { spanA[i] = b[i]; }
90 );
91}
92
93template<typename ValueType>
94void scalarMul(Field<ValueType>& a, const std::type_identity_t<ValueType> value)
95{
96 auto spanA = a.span();
98 a, KOKKOS_LAMBDA(const size_t i) { return spanA[i] * value; }
99 );
100}
101
102namespace detail
103{
104template<typename ValueType, typename BinaryOp>
106 Field<ValueType>& a, const Field<std::type_identity_t<ValueType>>& b, BinaryOp op
107)
108{
110 auto spanA = a.span();
111 auto spanB = b.span();
113 a, KOKKOS_LAMBDA(const size_t i) { return op(spanA[i], spanB[i]); }
114 );
115}
116}
117
118template<typename ValueType>
119void add(Field<ValueType>& a, const Field<std::type_identity_t<ValueType>>& b)
120{
122 a, b, KOKKOS_LAMBDA(ValueType va, ValueType vb) { return va + vb; }
123 );
124}
125
126
127template<typename ValueType>
128void sub(Field<ValueType>& a, const Field<std::type_identity_t<ValueType>>& b)
129{
131 a, b, KOKKOS_LAMBDA(ValueType va, ValueType vb) { return va - vb; }
132 );
133}
134
135template<typename ValueType>
136void mul(Field<ValueType>& a, const Field<std::type_identity_t<ValueType>>& b)
137{
139 a, b, KOKKOS_LAMBDA(ValueType va, ValueType vb) { return va * vb; }
140 );
141}
142
143template<typename... Args>
144auto spans(Args&... fields)
145{
146 return std::make_tuple(fields.span()...);
147}
148
149template<typename... Args>
150auto copyToHosts(Args&... fields)
151{
152 return std::make_tuple(fields.copyToHost()...);
153}
154
155template<typename T>
156bool equal(Field<T>& field, T value)
157{
158 auto hostField = field.copyToHost();
159 auto hostSpan = hostField.span();
160 for (size_t i = 0; i < hostSpan.size(); i++)
161 {
162 if (hostSpan[i] != value)
163 {
164 return false;
165 }
166 }
167 return true;
168};
169
170template<typename T>
171bool equal(const Field<T>& field, const Field<T>& field2)
172{
173 auto [hostField, hostField2] = copyToHosts(field, field2);
174 auto [hostSpan, hostSpan2] = spans(hostField, hostField2);
175
176 if (hostSpan.size() != hostSpan2.size())
177 {
178 return false;
179 }
180
181 for (size_t i = 0; i < hostSpan.size(); i++)
182 {
183 if (hostSpan[i] != hostSpan2[i])
184 {
185 return false;
186 }
187 }
188
189 return true;
190};
191
192template<typename T>
193bool equal(const Field<T>& field, std::span<T> span2)
194{
195 auto hostSpan = field.copyToHost().span();
196
197 if (hostSpan.size() != span2.size())
198 {
199 return false;
200 }
201
202 for (size_t i = 0; i < hostSpan.size(); i++)
203 {
204 if (hostSpan[i] != span2[i])
205 {
206 return false;
207 }
208 }
209
210 return true;
211}
212
213} // namespace NeoFOAM
A class to contain the data and executors for a field and define some basic operations.
Definition field.hpp:49
size_t size() const
Gets the size of the field.
Definition field.hpp:355
const Executor & exec() const
Gets the executor associated with the field.
Definition field.hpp:349
Field< ValueType > copyToHost() const
Returns a copy of the field back to the host.
Definition field.hpp:183
std::span< ValueType > span() &&=delete
#define NeoFOAM_ASSERT_EQUAL_LENGTH(_op1, _op2)
void fieldBinaryOp(Field< ValueType > &a, const Field< std::type_identity_t< ValueType > > &b, BinaryOp op)
void mul(Field< ValueType > &a, const Field< std::type_identity_t< ValueType > > &b)
auto copyToHosts(Args &... fields)
void setField(Field< ValueType > &a, const std::span< const std::type_identity_t< ValueType > > b, std::pair< size_t, size_t > range={0, 0})
Set the field with a span of values using a specific executor.
void add(Field< ValueType > &a, const Field< std::type_identity_t< ValueType > > &b)
void map(Field< T > &a, const Inner inner, std::pair< size_t, size_t > range={0, 0})
Map a field using a specific executor.
bool equal(Field< T > &field, T value)
void sub(Field< ValueType > &a, const Field< std::type_identity_t< ValueType > > &b)
void parallelFor(const Executor &exec, std::pair< size_t, size_t > range, Kernel kernel, std::string name="parallelFor")
auto spans(Args &... fields)
void scalarMul(Field< ValueType > &a, const std::type_identity_t< ValueType > value)
void fill(Field< ValueType > &a, const std::type_identity_t< ValueType > value, std::pair< size_t, size_t > range={0, 0})
Fill the field with a scalar value using a specific executor.