7#ifndef SBPINTERPOLATION_H_
8#define SBPINTERPOLATION_H_
30namespace interpolation {
45 ASSERT(noNodes > 0,
"Number of nodes must be greater than zero!");
48 const MFloat dx = F2 / (noNodes - 1);
49 std::fill_n(&nodes[0], noNodes, F0);
50 for(
MInt i = 0; i < noNodes; i++) {
51 nodes[i] = -F1 + i * dx;
68 ASSERT(noNodes > 0,
"Number of nodes must be greater than zero!");
71 const MFloat dx = F2 / (noNodes - 1);
74 std::fill_n(&wInt[0], noNodes, dx);
75 for(
MInt i = 0; i < lenP; i++) {
76 wInt[i] = sbpP(i) * dx;
77 wInt[noNodes - i - 1] = sbpP(i) * dx;
94 for(
MInt i = 0; i < noNodes; i++) {
95 for(
MInt j = 0; j < noNodes; j++) {
96 B(i, j) = Q(i, j) + Q(j, i);
100 MBool sbpProp =
true;
101 if(!
approx(B(0, 0), -F1, MFloatEps) || !
approx(B(noNodes - 1, noNodes - 1), F1, MFloatEps)) {
105 for(
MInt i = 0; i < noNodes; i++) {
106 for(
MInt j = 0; j < noNodes; j++) {
107 if(!
approx(B(i, j), 0.0, MFloatEps) && i != j) {
114 std::cout <<
"SBP Propery " << sbpProp << std::endl;
127inline void readCSV(std::string path, std::vector<std::vector<MFloat>>& data) {
128 std::ifstream stream(path);
131 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
139 if(!getline(stream, s))
break;
141 std::istringstream ss(s);
142 std::vector<MFloat> record;
145 if(!getline(ss, line,
','))
break;
146 record.push_back(std::stof(line));
148 data.push_back(record);
153 std::cerr <<
"Could not read file " << path <<
"\n";
154 std::__throw_invalid_argument(
"File not found.");
157 MInt dim0 = data.size();
158 MInt dim1 = data[0].size();
162 sendBuffer.
resize(dim0 * dim1);
164 for(
auto& line : data) {
165 for(
auto& coef : line) {
166 sendBuffer[it] = coef;
172 MPI_Bcast(&dim0, 1, MPI_INT, 0, MPI_COMM_WORLD, AT_,
"dim0");
173 MPI_Bcast(&dim1, 1, MPI_INT, 0, MPI_COMM_WORLD, AT_,
"dim1");
174 MPI_Bcast(&sendBuffer[0], dim0 * dim1, MPI_DOUBLE, 0, MPI_COMM_WORLD, AT_,
"sendBuffer");
180 MPI_Bcast(&dim0, 1, MPI_INT, 0, MPI_COMM_WORLD, AT_,
"dim0");
181 MPI_Bcast(&dim1, 1, MPI_INT, 0, MPI_COMM_WORLD, AT_,
"dim1");
184 recvBuffer.
resize(dim0 * dim1);
185 MPI_Bcast(&recvBuffer[0], dim0 * dim1, MPI_DOUBLE, 0, MPI_COMM_WORLD, AT_,
"recvBuffer");
187 for(
MInt i = 0; i < dim0; i++) {
188 std::vector<MFloat> line;
189 for(
MInt j = 0; j < dim1; j++) {
190 line.push_back(recvBuffer(dim1 * i + j));
192 data.push_back(line);
208 std::string path =
"./operatorsSBP/go4/DDRP307_N32/";
209 std::vector<std::vector<MFloat>> dData;
210 std::vector<std::vector<MFloat>> wData;
211 std::vector<std::vector<MFloat>> xData;
213 readCSV(path +
"diff_matrix.csv", dData);
214 readCSV(path +
"weights_int.csv", wData);
215 readCSV(path +
"nodes.csv", xData);
217 const MInt nNodes = xData.size();
225 for(
MInt i = 0; i < nNodes; i++) {
226 for(
MInt j = 0; j < nNodes; j++) {
227 Dhat(i, j) = dData[j][i] * wData[j][0] / wData[i][0];
229 wInt(i) = wData[i][0];
230 nodes(i) = xData[i][0];
256 MInt lenR = (1 + sqrt(1 + 8 * lenQ)) / 2;
265 for(
MInt i = 0; i < lenR; i++) {
266 for(
MInt j = i; j < lenR - 1; j++) {
267 Q(i, j + 1) = sbpQ(k);
268 Q(j + 1, i) = -sbpQ(k);
274 for(
MInt i = lenR; i < noNodes - lenR; i++) {
276 for(
MInt j = i - lenA; j < i; j++) {
281 for(
MInt j = i + 1; j < i + lenA + 1; j++) {
288 for(
MInt i = 0; i < lenA; i++) {
289 for(
MInt j = i; j < lenA; j++) {
290 Q(lenR - i - 1, lenR - i + j) = sbpA(j);
295 for(
MInt i = 0; i < lenR; i++) {
296 for(
MInt j = 0; j < lenR + lenA; j++) {
297 Q(noNodes - i - 1, noNodes - j - 1) = -Q(i, j);
307 for(
MInt i = 0; i < noNodes; i++) {
308 for(
MInt j = 0; j < noNodes; j++) {
309 Dhat(i, j) = -Q(i, j) / wInt[i];
328 MString path =
"./operatorsSBP/" + opName;
329 std::vector<std::vector<MFloat>> aData;
330 std::vector<std::vector<MFloat>> pData;
331 std::vector<std::vector<MFloat>> qData;
333 readCSV(path +
"/a.csv", aData);
334 readCSV(path +
"/p.csv", pData);
335 readCSV(path +
"/q.csv", qData);
337 MInt lenA = aData.size();
338 MInt lenP = pData.size();
340 MInt lenQ = lenP * (lenP - 1) / 2;
342 ASSERT(noNodes1D >= 2 * lenR,
343 "Not enough nodes for the " + opName +
" operator! " << noNodes1D <<
" set but " << 2 * lenR <<
" required.");
347 for(
auto&
a : aData) {
354 for(
auto& q : qData) {
361 for(
auto& p : pData) {
384 MBool exists =
false;
386 if(opName ==
"go4/s306") {
390 return exists =
false;
393 MInt lenA = op->
a.size();
394 MInt lenP = op->
p.size();
396 MInt lenQ = lenP * (lenP - 1) / 2;
398 ASSERT(noNodes1D >= 2 * lenR,
399 "Not enough nodes for the " + opName +
" operator!" << noNodes1D <<
" set but " << 2 * lenR <<
" required.");
403 for(
auto&
a : op->
a) {
410 for(
auto& q : op->
q) {
417 for(
auto& p : op->
p) {
441 for(
MInt i = 0; i < noNodes; i++) {
442 if(nodes[i] > point ||
approx(nodes[i], point, MFloatEps)) {
468 MFloat*
const polynomials) {
469 std::fill_n(&polynomials[0], noNodes, F0);
472 MInt idx[2] = {0, 0};
475 const MFloat dx = 2.0 / (noNodes - 1);
476 polynomials[idx[0]] = fabs(nodes[idx[1]] - x) / dx;
477 polynomials[idx[1]] = fabs(nodes[idx[0]] - x) / dx;
495template <
class T,
class U,
class V>
500 MFloatMatrix vdm(&vandermonde[0], noNodesOut, noNodesIn);
502 for(
MInt k = 0; k < noNodesOut; k++) {
503 MBool rowHasMatch =
false;
504 for(
MInt j = 0; j < noNodesIn; j++) {
506 if(
approx(nodesOut[k], nodesIn[j], MFloatEps)) {
512 if(rowHasMatch ==
false) {
536 MInt idx[2][2] = {{0, 0}, {0, 0}};
541 const MFloat dx = 2.0 / (noNodes - 1);
542 const MFloat dx2 = pow(dx, 2);
544 std::fill_n(out, noVars, 0.0);
549 for(
MInt i = 0; i < 2; i++) {
550 for(
MInt j = 0; j < 2; j++) {
551 const MFloat a = fabs((nodes[idx[0][1 - i]] - point[0]) * (nodes[idx[1][1 - j]] - point[1])) / dx2;
552 for(
MInt v = 0; v < noVars; v++) {
553 out[v] +=
a * U(idx[0][i], idx[1][j], 0, v);
576 MInt idx[3][2] = {{0, 0}, {0, 0}, {0, 0}};
582 const MFloat dx = 2.0 / (noNodes - 1);
583 const MFloat dx3 = pow(dx, 3);
585 std::fill_n(out, noVars, 0.0);
590 for(
MInt i = 0; i < 2; i++) {
591 for(
MInt j = 0; j < 2; j++) {
592 for(
MInt k = 0; k < 2; k++) {
593 const MFloat a = fabs((nodes[idx[0][1 - i]] - point[0]) * (nodes[idx[1][1 - j]] - point[1])
594 * (nodes[idx[2][1 - k]] - point[2]))
597 for(
MInt v = 0; v < noVars; v++) {
598 out[v] +=
a * U(idx[0][i], idx[1][j], idx[2][k], v);
void transpose()
Transposes the first two dimensions (i.e. acting as if the tensor is a matrix).
size_type dim0() const
Return the size of dimension 0.
void set(const T &value)
Initializes tensor to constant value.
size_type dim(size_type d) const
Return the size of dimension d.
size_type resize(size_type n0, size_type n1=1, size_type n2=1, size_type n3=1, size_type n4=1)
Deletes the old data structure and creates a new one with the requested dimensions.
MBool approx(const T &, const U &, const T)
std::basic_string< char > MString
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Bcast
void readCSV(std::string path, std::vector< std::vector< MFloat > > &data)
Reads .csv-file on rank 0 and broadcasts it to all ranks.
void findNodeIndicesAtPoint(const MFloat point, const MFloat *nodes, const MInt noNodes, MInt &idx1, MInt &idx2)
Finds the neighboring indices to point in one dimension.
void readSbpOperator(MInt noNodes1D, MString opName, MFloatVector &sbpA, MFloatVector &sbpP, MFloatVector &sbpQ)
Reads all coefficient files to contruct SBP operator.
void calcTrilinearInterpolation(MFloat *point, const MFloat *nodes, const MInt noNodes, const MInt noVars, const MFloat *u, MFloat *const out)
Calculates trilinear interpolation at given point (3D)
MBool checkSBPProp(const MFloatMatrix &Q)
Helper function for checking the SBP property of a given operator.
void calcLinearInterpolationBase(const MFloat x, const MInt noNodes, const MFloat *nodes, MFloat *const polynomials)
Calculates linear interpolation base for point (1D).
void calcSBPNodes(const MInt noNodes, MFloat *nodes)
Generates an equidistant node distribution.
void readDDRP(MFloat *nodesVector, MFloat *wIntVector, MFloat *dhatMatrix)
Reads DDRP operator and nodal distribution from file.
void calcLinearInterpolationMatrix(const MInt noNodesIn, const T nodesIn, const MInt noNodesOut, const U nodesOut, V vandermonde)
Calculates the linear interpolation matrix (Vandermonde) to interpolate from one set of nodes to anot...
void calcDhatSBP(const MInt noNodes, MFloatVector sbpA, MFloatVector sbpQ, const MFloat *wInt, MFloat *dhatMatrix)
Calculates SBP operator from coefficients.
void calcSBPWeights(const MInt noNodes, MFloatVector sbpP, MFloat *wInt)
Calulates the diagonal weight matrix (H) entries.
void calcBilinearInterpolation(MFloat *point, const MFloat *nodes, const MInt noNodes, const MInt noVars, const MFloat *u, MFloat *const out)
Calculates bilinear interpolation at given point (2D)
MBool getSBPOperator(const MInt noNodes1D, const MString opName, MFloatVector &sbpA, MFloatVector &sbpP, MFloatVector &sbpQ)
Gets SBP Coefficients from corresponding header if existent.
Namespace for auxiliary functions/classes.
maia::tensor::Tensor< MFloat > MFloatMatrix
maia::tensor::Tensor< MFloat > MFloatVector