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.
206 lines
5.6 KiB
206 lines
5.6 KiB
/* ENO interpolation in 3-D */
|
|
/*
|
|
Copyright (C) 2004 University of Texas at Austin
|
|
|
|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "eno2.h"
|
|
#include "eno3.h"
|
|
|
|
#include "alloc.h"
|
|
#include "ngspice/cm.h"
|
|
|
|
|
|
struct Eno3 {
|
|
int order, ng, n1, n2, n3;
|
|
sf_eno **ent;
|
|
sf_eno2 jnt;
|
|
double **f, **f1;
|
|
};
|
|
/* concrete data type */
|
|
|
|
sf_eno3
|
|
sf_eno3_init(int order, /* interpolation order */
|
|
int n1, int n2, int n3 /* data dimensions */)
|
|
/*< Initialize interpolation object >*/
|
|
{
|
|
int xrc = 0;
|
|
sf_eno3 pnt = (sf_eno3) NULL;
|
|
|
|
/* Allocate base structrue */
|
|
if ((pnt = (sf_eno3) sf_alloc (1, sizeof *pnt)) == (sf_eno3) NULL) {
|
|
cm_message_printf("Unable to allocate sf_eno3 structure "
|
|
"in sf_eno3_init");
|
|
xrc = -1;
|
|
goto EXITPOINT;
|
|
}
|
|
|
|
pnt->order = order;
|
|
pnt->n1 = n1;
|
|
pnt->n2 = n2;
|
|
pnt->n3 = n3;
|
|
pnt->ng = 2 * order - 2;
|
|
|
|
if (pnt->ng > n2 || pnt->ng > n3) {
|
|
cm_message_printf("%s: ng=%d is too big", __FILE__, pnt->ng);
|
|
xrc = -1;
|
|
goto EXITPOINT;
|
|
}
|
|
|
|
if ((pnt->jnt = sf_eno2_init(
|
|
order, pnt->ng, pnt->ng)) == (sf_eno2) NULL) {
|
|
cm_message_printf("Unable to initialize field jnt "
|
|
"in sf_eno3_init");
|
|
xrc = -1;
|
|
goto EXITPOINT;
|
|
}
|
|
|
|
if ((pnt->f = sf_doublealloc2(pnt->ng, pnt->ng)) == (double **) NULL) {
|
|
cm_message_printf("Unable to allocate field f in sf_eno3_init()");
|
|
xrc = -1;
|
|
goto EXITPOINT;
|
|
}
|
|
|
|
if ((pnt->f1 = sf_doublealloc2(pnt->ng, pnt->ng)) == (double **) NULL) {
|
|
cm_message_printf("Unable to allocate field f1 in sf_eno3_init()");
|
|
xrc = -1;
|
|
goto EXITPOINT;
|
|
}
|
|
|
|
if ((pnt->ent = (sf_eno **) sf_alloc(
|
|
n3, sizeof(sf_eno*))) == (sf_eno **) NULL) {
|
|
cm_message_printf("Unable to allocate field ent in sf_eno3_init()");
|
|
xrc = -1;
|
|
goto EXITPOINT;
|
|
}
|
|
|
|
{
|
|
int i3;
|
|
for (i3 = 0; i3 < n3; i3++) {
|
|
if ((pnt->ent[i3] = (sf_eno*) sf_alloc(
|
|
n2, sizeof(sf_eno))) == (sf_eno *) NULL) {
|
|
cm_message_printf("Unable to allocate field ent[%d] "
|
|
"in sf_eno3_init()", i3);
|
|
xrc = -1;
|
|
goto EXITPOINT;
|
|
}
|
|
int i2;
|
|
for (i2 = 0; i2 < n2; i2++) {
|
|
if ((pnt->ent[i3][i2] = sf_eno_init(
|
|
order, n1)) == (sf_eno) NULL) {
|
|
cm_message_printf("Unable to initialize field "
|
|
"ent[%d][%d] in sf_eno3_init()",
|
|
i2, i3);
|
|
xrc = -1;
|
|
goto EXITPOINT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
EXITPOINT:
|
|
if (xrc != 0) {
|
|
if (pnt != (sf_eno3) NULL) {
|
|
sf_eno3_close(pnt);
|
|
free(pnt);
|
|
pnt = (sf_eno3) NULL;
|
|
}
|
|
}
|
|
return pnt;
|
|
}
|
|
|
|
void
|
|
sf_eno3_set(sf_eno3 pnt, double ***c /* data [n3][n2][n1] */)
|
|
/*< Set the interpolation table. c can be changed or freed afterwords. >*/
|
|
{
|
|
int i2, i3;
|
|
|
|
for (i3 = 0; i3 < pnt->n3; i3++)
|
|
for (i2 = 0; i2 < pnt->n2; i2++)
|
|
sf_eno_set (pnt->ent[i3][i2], c[i3][i2]);
|
|
}
|
|
|
|
void
|
|
sf_eno3_close(sf_eno3 pnt)
|
|
/*< Free internal storage. >*/
|
|
{
|
|
int i2, i3;
|
|
|
|
if (!pnt)
|
|
return;
|
|
|
|
sf_eno2_close (pnt->jnt);
|
|
for (i3 = 0; i3 < pnt->n3; i3++) {
|
|
for (i2 = 0; i2 < pnt->n2; i2++)
|
|
sf_eno_close (pnt->ent[i3][i2]);
|
|
free (pnt->ent[i3]);
|
|
}
|
|
free (pnt->ent);
|
|
free (pnt->f[0]);
|
|
free (pnt->f);
|
|
free (pnt->f1[0]);
|
|
free (pnt->f1);
|
|
free (pnt);
|
|
}
|
|
|
|
void
|
|
sf_eno3_apply(sf_eno3 pnt,
|
|
int i, int j, int k, /* grid location */
|
|
double x, double y, double z, /* offsets from grid */
|
|
double *f, /* output data */
|
|
double *f1, /* output derivative [3] */
|
|
der what /* to compute [FUNC|DER|BOTH] */)
|
|
/*< Apply interpolation. >*/
|
|
{
|
|
int i2, i3, b2, b3;
|
|
double g;
|
|
|
|
if (j - pnt->order + 2 < 0)
|
|
b2 = 0;
|
|
else if (j + pnt->order - 1 > pnt->n2 - 1)
|
|
b2 = pnt->n2 - pnt->ng;
|
|
else
|
|
b2 = j - pnt->order + 2;
|
|
|
|
j -= b2;
|
|
|
|
|
|
if (k - pnt->order + 2 < 0)
|
|
b3 = 0;
|
|
else if (k + pnt->order - 1 > pnt->n3 - 1)
|
|
b3 = pnt->n3 - pnt->ng;
|
|
else
|
|
b3 = k - pnt->order + 2;
|
|
|
|
k -= b3;
|
|
|
|
for (i3 = 0; i3 < pnt->ng; i3++)
|
|
for (i2 = 0; i2 < pnt->ng; i2++)
|
|
sf_eno_apply (pnt->ent[b3 + i3][b2 + i2], i, x,
|
|
&(pnt->f[i3][i2]),
|
|
&(pnt->f1[i3][i2]),
|
|
(what==FUNC ? FUNC : BOTH));
|
|
|
|
sf_eno2_set (pnt->jnt, pnt->f);
|
|
sf_eno2_apply (pnt->jnt, j, k, y, z, f, f1 + 1, what);
|
|
|
|
if (what != FUNC) {
|
|
sf_eno2_set (pnt->jnt, pnt->f1);
|
|
sf_eno2_apply (pnt->jnt, j, k, y, z, f1, &g, FUNC);
|
|
}
|
|
}
|
|
|
|
/* $Id: eno3.c 4148 2009-02-09 03:55:32Z sfomel $ */
|