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

/* 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 $ */