You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
3.4 KiB
131 lines
3.4 KiB
2 years ago
|
// Copyright(C) 1999-2021 National Technology & Engineering Solutions
|
||
|
// of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
|
||
|
// NTESS, the U.S. Government retains certain rights in this software.
|
||
|
//
|
||
|
// See packages/seacas/LICENSE for details
|
||
|
|
||
|
#include "apr_symrec.h"
|
||
|
#include "aprepro.h" // for array, Aprepro, etc
|
||
|
|
||
|
#include <vector> // for vector
|
||
|
|
||
|
namespace SEAMS {
|
||
|
extern SEAMS::Aprepro *aprepro;
|
||
|
|
||
|
double array_interpolate(const array *arr, double row, double col)
|
||
|
{
|
||
|
/*
|
||
|
* Bilinear interpolation.
|
||
|
* Assumes equal grid spacing over the range
|
||
|
* (0.0 -> rows-1) (0.0 -> cols-1)
|
||
|
*/
|
||
|
|
||
|
int cols = arr->cols;
|
||
|
int rows = arr->rows;
|
||
|
|
||
|
int irl = row;
|
||
|
int irh = rows > 1 ? irl + 1 : irl;
|
||
|
int icl = col;
|
||
|
int ich = cols > 1 ? icl + 1 : icl;
|
||
|
|
||
|
double value = 0.0;
|
||
|
|
||
|
if (irh < rows && ich < cols) {
|
||
|
double v11 = arr->data[irl * cols + icl];
|
||
|
double v21 = arr->data[irh * cols + icl];
|
||
|
double v12 = arr->data[irl * cols + ich];
|
||
|
double v22 = arr->data[irh * cols + ich];
|
||
|
if (rows > 1 && cols > 1) {
|
||
|
value = (v11 * (irh - row) + v21 * (row - irl)) * (ich - col) +
|
||
|
(v12 * (irh - row) * v22 * (row - irl)) * (col - icl);
|
||
|
}
|
||
|
else if (rows > 1 && cols == 1) {
|
||
|
value = v11 * (irh - row) + v21 * (row - irl);
|
||
|
}
|
||
|
else if (cols > 1 && rows == 1) {
|
||
|
value = v11 * (ich - col) + v12 * (col - icl);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
aprepro->error("Row or Column index out of range");
|
||
|
}
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
double array_value(array *arr, double row, double col)
|
||
|
{
|
||
|
if (aprepro->ap_options.one_based_index) {
|
||
|
row--;
|
||
|
col--;
|
||
|
}
|
||
|
|
||
|
double value = 0.0;
|
||
|
int cols = arr->cols;
|
||
|
int rows = arr->rows;
|
||
|
if (row >= 0 && row < rows && col >= 0 && col < cols) {
|
||
|
if (row != static_cast<int>(row) || col != static_cast<int>(col)) {
|
||
|
value = array_interpolate(arr, row, col);
|
||
|
}
|
||
|
else {
|
||
|
int irow = row;
|
||
|
int icol = col;
|
||
|
int offset = irow * cols + icol;
|
||
|
value = arr->data[offset];
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
aprepro->error("Row or Column index out of range");
|
||
|
}
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
array *array_add(const array *a, const array *b)
|
||
|
{
|
||
|
auto array_data = aprepro->make_array(a->rows, a->cols);
|
||
|
for (int i = 0; i < a->rows * a->cols; i++) {
|
||
|
array_data->data[i] = a->data[i] + b->data[i];
|
||
|
}
|
||
|
return array_data;
|
||
|
}
|
||
|
|
||
|
array *array_sub(const array *a, const array *b)
|
||
|
{
|
||
|
auto array_data = aprepro->make_array(a->rows, a->cols);
|
||
|
|
||
|
for (int i = 0; i < a->rows * a->cols; i++) {
|
||
|
array_data->data[i] = a->data[i] - b->data[i];
|
||
|
}
|
||
|
return array_data;
|
||
|
}
|
||
|
|
||
|
array *array_scale(const array *a, double s)
|
||
|
{
|
||
|
auto array_data = aprepro->make_array(a->rows, a->cols);
|
||
|
|
||
|
for (int i = 0; i < a->rows * a->cols; i++) {
|
||
|
array_data->data[i] = a->data[i] * s;
|
||
|
}
|
||
|
|
||
|
return array_data;
|
||
|
}
|
||
|
|
||
|
array *array_mult(const array *a, const array *b)
|
||
|
{
|
||
|
int ac = a->cols;
|
||
|
int bc = b->cols;
|
||
|
|
||
|
auto array_data = aprepro->make_array(a->rows, b->cols);
|
||
|
|
||
|
for (int i = 0; i < b->cols; i++) {
|
||
|
for (int j = 0; j < a->rows; j++) {
|
||
|
double sum = 0.0;
|
||
|
for (int k = 0; k < a->cols; k++) {
|
||
|
sum += a->data[j * ac + k] * b->data[k * bc + i];
|
||
|
}
|
||
|
array_data->data[j * bc + i] = sum;
|
||
|
}
|
||
|
}
|
||
|
return array_data;
|
||
|
}
|
||
|
} // namespace SEAMS
|