Browse Source
xspice/icm/table, introduce table2d/table3d
xspice/icm/table, introduce table2d/table3d
which allows to model devices based upon linear interpolationpre-master-46
committed by
rlar
30 changed files with 2802 additions and 2 deletions
-
1src/spinit.in
-
2src/xspice/Makefile.am
-
2src/xspice/icm/GNUmakefile.in
-
71src/xspice/icm/table/mada/alloc.c
-
23src/xspice/icm/table/mada/alloc.h
-
133src/xspice/icm/table/mada/eno.c
-
36src/xspice/icm/table/mada/eno.h
-
120src/xspice/icm/table/mada/eno2.c
-
35src/xspice/icm/table/mada/eno2.h
-
142src/xspice/icm/table/mada/eno3.c
-
35src/xspice/icm/table/mada/eno3.h
-
2src/xspice/icm/table/modpath.lst
-
135src/xspice/icm/table/support/gettokens.c
-
183src/xspice/icm/table/support/interp.c
-
705src/xspice/icm/table/table2D/cfunc.mod
-
78src/xspice/icm/table/table2D/ifspec.ifs
-
768src/xspice/icm/table/table3D/cfunc.mod
-
87src/xspice/icm/table/table3D/ifspec.ifs
-
0src/xspice/icm/table/udnpath.lst
-
1visualc/how-to-ngspice-vstudio.txt
-
2visualc/make-install-vngspice.bat
-
2visualc/make-install-vngspiced.bat
-
1visualc/spinit
-
1visualc/spinit64
-
1visualc/spinitd
-
1visualc/spinitd64
-
5visualc/vngspice-fftw.sln
-
5visualc/vngspice.sln
-
225visualc/xspice/table.vcxproj
-
2visualc/xspice/xspice-local.sln
@ -0,0 +1,71 @@ |
|||||
|
/* Convenience allocation programs. */ |
||||
|
/* |
||||
|
Copyright (C) 2004 University of Texas at Austin |
||||
|
Copyright (C) 2007 Colorado School of Mines |
||||
|
|
||||
|
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 <stdlib.h> |
||||
|
#include <sys/types.h> |
||||
|
|
||||
|
#include "alloc.h" |
||||
|
#include "ngspice/cm.h" |
||||
|
|
||||
|
|
||||
|
/*------------------------------------------------------------*/ |
||||
|
void * |
||||
|
sf_alloc(int n /* number of elements */, |
||||
|
size_t size /* size of one element */) |
||||
|
/*< output-checking allocation >*/ |
||||
|
{ |
||||
|
void *ptr; |
||||
|
|
||||
|
size *= (size_t) n; |
||||
|
|
||||
|
if (0 >= size) |
||||
|
cm_message_printf("%s: illegal allocation(%d bytes)", __FILE__, (int) size); |
||||
|
|
||||
|
ptr = malloc(size); |
||||
|
|
||||
|
if (NULL == ptr) |
||||
|
cm_message_printf("%s: cannot allocate %d bytes : ", __FILE__, (int) size); |
||||
|
|
||||
|
return ptr; |
||||
|
} |
||||
|
|
||||
|
/*------------------------------------------------------------*/ |
||||
|
double * |
||||
|
sf_doublealloc(int n /* number of elements */) |
||||
|
/*< float allocation >*/ |
||||
|
{ |
||||
|
return (double*) sf_alloc(n, sizeof(double)); |
||||
|
} |
||||
|
|
||||
|
/*------------------------------------------------------------*/ |
||||
|
double ** |
||||
|
sf_doublealloc2(int n1 /* fast dimension */, |
||||
|
int n2 /* slow dimension */) |
||||
|
/*< float 2-D allocation, out[0] points to a contiguous array >*/ |
||||
|
{ |
||||
|
int i2; |
||||
|
double **ptr = (double**) sf_alloc(n2, sizeof(double*)); |
||||
|
|
||||
|
ptr[0] = sf_doublealloc(n1 * n2); |
||||
|
for (i2 = 1; i2 < n2; i2++) |
||||
|
ptr[i2] = ptr[0] + i2 * n1; |
||||
|
|
||||
|
return ptr; |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
#ifndef _sf_alloc_h |
||||
|
#define _sf_alloc_h |
||||
|
|
||||
|
|
||||
|
#include <stdio.h> |
||||
|
#include <stdlib.h> |
||||
|
|
||||
|
|
||||
|
/*------------------------------------------------------------*/ |
||||
|
void *sf_alloc (int n, /* number of elements */ |
||||
|
size_t size /* size of one element */); |
||||
|
/*< output-checking allocation >*/ |
||||
|
|
||||
|
/*------------------------------------------------------------*/ |
||||
|
double *sf_doublealloc (int n /* number of elements */); |
||||
|
/*< double allocation >*/ |
||||
|
|
||||
|
/*------------------------------------------------------------*/ |
||||
|
double **sf_doublealloc2(int n1, /* fast dimension */ |
||||
|
int n2 /* slow dimension */); |
||||
|
/*< float 2-D allocation, out[0] points to a contiguous array >*/ |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,133 @@ |
|||||
|
/* 1-D ENO interpolation */ |
||||
|
/* |
||||
|
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 <math.h> |
||||
|
#include <float.h> |
||||
|
#include <stdlib.h> |
||||
|
|
||||
|
#include "eno.h" |
||||
|
#include "alloc.h" |
||||
|
|
||||
|
#define SF_MAX(a,b) ((a) < (b) ? (b) : (a)) |
||||
|
#define SF_MIN(a,b) ((a) < (b) ? (a) : (b)) |
||||
|
|
||||
|
|
||||
|
struct Eno { |
||||
|
int order, n; |
||||
|
double **diff; |
||||
|
}; |
||||
|
/* concrete data type */ |
||||
|
|
||||
|
sf_eno |
||||
|
sf_eno_init (int order, /* interpolation order */ |
||||
|
int n /* data size */) |
||||
|
/*< Initialize interpolation object. >*/ |
||||
|
{ |
||||
|
sf_eno ent; |
||||
|
int i; |
||||
|
|
||||
|
ent = (sf_eno) sf_alloc(1, sizeof(*ent)); |
||||
|
ent->order = order; |
||||
|
ent->n = n; |
||||
|
ent->diff = (double**) sf_alloc(order, sizeof(double*)); |
||||
|
for (i = 0; i < order; i++) |
||||
|
ent->diff[i] = sf_doublealloc(n - i); |
||||
|
|
||||
|
return ent; |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
sf_eno_close (sf_eno ent) |
||||
|
/*< Free internal storage >*/ |
||||
|
{ |
||||
|
int i; |
||||
|
|
||||
|
for (i = 0; i < ent->order; i++) |
||||
|
free (ent->diff[i]); |
||||
|
free (ent->diff); |
||||
|
free (ent); |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
sf_eno_set (sf_eno ent, double *c /* data [n] */) |
||||
|
/*< Set the interpolation table. c can be changed or freed afterwords >*/ |
||||
|
{ |
||||
|
int i, j; |
||||
|
|
||||
|
for (i = 0; i < ent->n; i++) { |
||||
|
/* copy the initial data */ |
||||
|
ent->diff[0][i] = c[i]; |
||||
|
} |
||||
|
|
||||
|
for (j = 1; j < ent->order; j++) { |
||||
|
for (i = 0; i < ent->n - j; i++) { |
||||
|
/* compute difference tables */ |
||||
|
ent->diff[j][i] = ent->diff[j - 1][i + 1] - ent->diff[j - 1][i]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void sf_eno_apply (sf_eno ent, |
||||
|
int i, /* grid location */ |
||||
|
double x, /* offset from grid */ |
||||
|
double *f, /* output data value */ |
||||
|
double *f1, /* output derivative */ |
||||
|
der what /* flag of what to compute */) |
||||
|
/*< Apply interpolation >*/ |
||||
|
{ |
||||
|
int j, k, i1, i2, n; |
||||
|
double s, s1, y, w, g, g1; |
||||
|
|
||||
|
i2 = SF_MAX (0, SF_MIN(i, ent->n - ent->order)); |
||||
|
i1 = SF_MIN (i2, SF_MAX(0, i - ent->order + 2)); |
||||
|
|
||||
|
w = fabs(ent->diff[ent->order - 1][i1]); |
||||
|
for (j = i1 + 1; j <= i2; j++) { |
||||
|
g = fabs(ent->diff[ent->order - 1][j]); |
||||
|
if (w > g) |
||||
|
w = g; |
||||
|
} |
||||
|
|
||||
|
/* loop over starting points */ |
||||
|
for (g = 0., g1 = 0., n = 0, j = i1; j <= i2; j++) { |
||||
|
if (fabs(ent->diff[ent->order - 1][j]) > w) |
||||
|
continue; |
||||
|
n++; |
||||
|
|
||||
|
y = x + i - j; |
||||
|
|
||||
|
/* loop to compute the polynomial */ |
||||
|
for (s = 1., s1 = 0., k = 0; k < ent->order; k++) { |
||||
|
if (what != FUNC) { |
||||
|
g1 += s1 * ent->diff[k][j]; |
||||
|
s1 = (s + s1 * (y - k)) / (k + 1.); |
||||
|
} |
||||
|
if (what != DER) |
||||
|
g += s * ent->diff[k][j]; |
||||
|
s *= (y - k) / (k + 1.); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (what != DER) |
||||
|
*f = g / n; |
||||
|
if (what != FUNC) |
||||
|
*f1 = g1 / n; |
||||
|
} |
||||
|
|
||||
|
/* $Id: eno.c 8699 2012-07-03 22:10:38Z vovizmus $ */ |
||||
@ -0,0 +1,36 @@ |
|||||
|
/* This file is automatically generated. DO NOT EDIT! */ |
||||
|
|
||||
|
#ifndef _sf_eno_h |
||||
|
#define _sf_eno_h |
||||
|
|
||||
|
|
||||
|
typedef struct Eno *sf_eno; |
||||
|
/* abstract data type */ |
||||
|
|
||||
|
|
||||
|
typedef enum {FUNC, DER, BOTH} der; |
||||
|
/* flag values */ |
||||
|
|
||||
|
|
||||
|
sf_eno sf_eno_init (int order, /* interpolation order */ |
||||
|
int n /* data size */); |
||||
|
/*< Initialize interpolation object. >*/ |
||||
|
|
||||
|
|
||||
|
void sf_eno_close (sf_eno ent); |
||||
|
/*< Free internal storage >*/ |
||||
|
|
||||
|
|
||||
|
void sf_eno_set (sf_eno ent, double* c /* data [n] */); |
||||
|
/*< Set the interpolation table. c can be changed or freed afterwords >*/ |
||||
|
|
||||
|
|
||||
|
void sf_eno_apply (sf_eno ent, |
||||
|
int i, /* grid location */ |
||||
|
double x, /* offset from grid */ |
||||
|
double *f, /* output data value */ |
||||
|
double *f1, /* output derivative */ |
||||
|
der what /* flag of what to compute */); |
||||
|
/*< Apply interpolation >*/ |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,120 @@ |
|||||
|
/* ENO interpolation in 2-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 "eno.h" |
||||
|
#include "eno2.h" |
||||
|
|
||||
|
#include "alloc.h" |
||||
|
#include "ngspice/cm.h" |
||||
|
|
||||
|
|
||||
|
struct Eno2 { |
||||
|
int order, ng, n1, n2; |
||||
|
sf_eno jnt, *ent; |
||||
|
double *f, *f1; |
||||
|
}; |
||||
|
/* concrete data type */ |
||||
|
|
||||
|
sf_eno2 |
||||
|
sf_eno2_init (int order, /* interpolation order */ |
||||
|
int n1, int n2 /* data dimensions */) |
||||
|
/*< Initialize interpolation object >*/ |
||||
|
{ |
||||
|
sf_eno2 pnt; |
||||
|
int i2; |
||||
|
|
||||
|
pnt = (sf_eno2) sf_alloc(1, sizeof(*pnt)); |
||||
|
pnt->order = order; |
||||
|
pnt->n1 = n1; |
||||
|
pnt->n2 = n2; |
||||
|
pnt->ng = 2 * order - 2; |
||||
|
if (pnt->ng > pnt->n2) |
||||
|
cm_message_printf("%s: ng=%d is too big", __FILE__, pnt->ng); |
||||
|
pnt->jnt = sf_eno_init (order, pnt->ng); |
||||
|
pnt->f = sf_doublealloc (pnt->ng); |
||||
|
pnt->f1 = sf_doublealloc (pnt->ng); |
||||
|
pnt->ent = (sf_eno*) sf_alloc(n2, sizeof(sf_eno)); |
||||
|
for (i2 = 0; i2 < n2; i2++) |
||||
|
pnt->ent[i2] = sf_eno_init (order, n1); |
||||
|
|
||||
|
return pnt; |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
sf_eno2_set (sf_eno2 pnt, double **c /* data [n2][n1] */) |
||||
|
/*< Set the interpolation table. c can be changed or freed afterwords. >*/ |
||||
|
{ |
||||
|
int i2; |
||||
|
|
||||
|
for (i2 = 0; i2 < pnt->n2; i2++) |
||||
|
sf_eno_set (pnt->ent[i2], c[i2]); |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
sf_eno2_close (sf_eno2 pnt) |
||||
|
/*< Free internal storage >*/ |
||||
|
{ |
||||
|
int i2; |
||||
|
|
||||
|
sf_eno_close (pnt->jnt); |
||||
|
for (i2 = 0; i2 < pnt->n2; i2++) |
||||
|
sf_eno_close (pnt->ent[i2]); |
||||
|
free (pnt->f); |
||||
|
free (pnt->f1); |
||||
|
free (pnt->ent); |
||||
|
free (pnt); |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
sf_eno2_apply (sf_eno2 pnt, |
||||
|
int i, int j, /* grid location */ |
||||
|
double x, double y, /* offset from grid */ |
||||
|
double *f, /* output data value */ |
||||
|
double *f1, /* output derivative [2] */ |
||||
|
der what /* what to compute [FUNC,DER,BOTH] */) |
||||
|
/*< Apply interpolation. >*/ |
||||
|
{ |
||||
|
int k, b2; |
||||
|
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; |
||||
|
|
||||
|
for (k = 0; k < pnt->ng; k++) |
||||
|
if (what != FUNC) |
||||
|
sf_eno_apply (pnt->ent[b2 + k], i, x, pnt->f + k, pnt->f1 + k, BOTH); |
||||
|
else |
||||
|
sf_eno_apply (pnt->ent[b2 + k], i, x, pnt->f + k, pnt->f1 + k, FUNC); |
||||
|
|
||||
|
sf_eno_set (pnt->jnt, pnt->f); |
||||
|
sf_eno_apply (pnt->jnt, j, y, f, f1 + 1, what); |
||||
|
|
||||
|
if (what != FUNC) { |
||||
|
sf_eno_set (pnt->jnt, pnt->f1); |
||||
|
sf_eno_apply (pnt->jnt, j, y, f1, &g, FUNC); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* $Id: eno2.c 9044 2012-08-13 19:35:59Z vovizmus $ */ |
||||
@ -0,0 +1,35 @@ |
|||||
|
/* This file is automatically generated. DO NOT EDIT! */ |
||||
|
|
||||
|
#ifndef _sf_eno2_h |
||||
|
#define _sf_eno2_h |
||||
|
|
||||
|
|
||||
|
#include "eno.h" |
||||
|
|
||||
|
|
||||
|
typedef struct Eno2 *sf_eno2; |
||||
|
/* abstract data type */ |
||||
|
|
||||
|
|
||||
|
sf_eno2 sf_eno2_init (int order, /* interpolation order */ |
||||
|
int n1, int n2 /* data dimensions */); |
||||
|
/*< Initialize interpolation object >*/ |
||||
|
|
||||
|
|
||||
|
void sf_eno2_set (sf_eno2 pnt, double **c /* data [n2][n1] */); |
||||
|
/*< Set the interpolation table. c can be changed or freed afterwords. >*/ |
||||
|
|
||||
|
|
||||
|
void sf_eno2_close (sf_eno2 pnt); |
||||
|
/*< Free internal storage >*/ |
||||
|
|
||||
|
|
||||
|
void sf_eno2_apply (sf_eno2 pnt, |
||||
|
int i, int j, /* grid location */ |
||||
|
double x, double y, /* offset from grid */ |
||||
|
double *f, /* output data value */ |
||||
|
double *f1, /* output derivative [2] */ |
||||
|
der what /* what to compute [FUNC,DER,BOTH] */); |
||||
|
/*< Apply interpolation. >*/ |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,142 @@ |
|||||
|
/* 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 >*/ |
||||
|
{ |
||||
|
sf_eno3 pnt; |
||||
|
int i2, i3; |
||||
|
|
||||
|
pnt = (sf_eno3) sf_alloc (1, sizeof(*pnt)); |
||||
|
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); |
||||
|
pnt->jnt = sf_eno2_init (order, pnt->ng, pnt->ng); |
||||
|
pnt->f = sf_doublealloc2 (pnt->ng, pnt->ng); |
||||
|
pnt->f1 = sf_doublealloc2 (pnt->ng, pnt->ng); |
||||
|
pnt->ent = (sf_eno**) sf_alloc (n3, sizeof(sf_eno*)); |
||||
|
for (i3 = 0; i3 < n3; i3++) { |
||||
|
pnt->ent[i3] = (sf_eno*) sf_alloc (n2, sizeof(sf_eno)); |
||||
|
for (i2 = 0; i2 < n2; i2++) |
||||
|
pnt->ent[i3][i2] = sf_eno_init (order, n1); |
||||
|
} |
||||
|
|
||||
|
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; |
||||
|
|
||||
|
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 $ */ |
||||
@ -0,0 +1,35 @@ |
|||||
|
/* This file is automatically generated. DO NOT EDIT! */ |
||||
|
|
||||
|
#ifndef _sf_eno3_h |
||||
|
#define _sf_eno3_h |
||||
|
|
||||
|
|
||||
|
#include "eno2.h" |
||||
|
|
||||
|
|
||||
|
typedef struct Eno3 *sf_eno3; |
||||
|
/* abstract data type */ |
||||
|
|
||||
|
|
||||
|
sf_eno3 sf_eno3_init (int order, /* interpolation order */ |
||||
|
int n1, int n2, int n3 /* data dimensions */); |
||||
|
/*< Initialize interpolation object >*/ |
||||
|
|
||||
|
|
||||
|
void sf_eno3_set (sf_eno3 pnt, double ***c /* data [n3][n2][n1] */); |
||||
|
/*< Set the interpolation table. c can be changed or freed afterwords. >*/ |
||||
|
|
||||
|
|
||||
|
void sf_eno3_close (sf_eno3 pnt); |
||||
|
/*< Free internal storage. >*/ |
||||
|
|
||||
|
|
||||
|
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. >*/ |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,2 @@ |
|||||
|
table2D |
||||
|
table3D |
||||
@ -0,0 +1,135 @@ |
|||||
|
/*=== Static CNVgettok ROUTINE ================*/ |
||||
|
/* |
||||
|
Get the next token from the input string. The input string pointer |
||||
|
is advanced to the following token and the token from the input |
||||
|
string is copied to malloced storage and a pointer to that storage |
||||
|
is returned. The original input string is undisturbed. |
||||
|
*/ |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
#include <ctype.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <string.h> |
||||
|
#include <math.h> |
||||
|
|
||||
|
/*=== CONSTANTS ========================*/ |
||||
|
|
||||
|
#define OK 0 |
||||
|
#define FAIL 1 |
||||
|
|
||||
|
/* Type definition for each possible token returned. */ |
||||
|
typedef enum token_type_s { CNV_NO_TOK, CNV_STRING_TOK } Cnv_Token_Type_t; |
||||
|
|
||||
|
extern char *CNVget_token(char **s, Cnv_Token_Type_t *type); |
||||
|
|
||||
|
/*=== MACROS ===========================*/ |
||||
|
|
||||
|
#if defined(__MINGW32__) || defined(_MSC_VER) |
||||
|
#define DIR_PATHSEP "\\" |
||||
|
#else |
||||
|
#define DIR_PATHSEP "/" |
||||
|
#endif |
||||
|
|
||||
|
#if defined(_MSC_VER) |
||||
|
#define strdup _strdup |
||||
|
#define snprintf _snprintf |
||||
|
#endif |
||||
|
|
||||
|
|
||||
|
|
||||
|
char * |
||||
|
CNVgettok(char **s) |
||||
|
{ |
||||
|
char *buf; /* temporary storage to copy token into */ |
||||
|
/*char *temp;*/ /* temporary storage to copy token into */ |
||||
|
char *ret_str; /* storage for returned string */ |
||||
|
|
||||
|
int i; |
||||
|
|
||||
|
/* allocate space big enough for the whole string */ |
||||
|
|
||||
|
buf = (char *) malloc(strlen(*s) + 1); |
||||
|
|
||||
|
/* skip over any white space */ |
||||
|
|
||||
|
while (isspace_c(**s) || (**s == '=') || |
||||
|
(**s == '(') || (**s == ')') || (**s == ',')) |
||||
|
(*s)++; |
||||
|
|
||||
|
/* isolate the next token */ |
||||
|
|
||||
|
switch (**s) { |
||||
|
|
||||
|
case '\0': /* End of string found */ |
||||
|
if (buf) |
||||
|
free(buf); |
||||
|
return NULL; |
||||
|
|
||||
|
|
||||
|
default: /* Otherwise, we are dealing with a */ |
||||
|
/* string representation of a number */ |
||||
|
/* or a mess o' characters. */ |
||||
|
i = 0; |
||||
|
while ( (**s != '\0') && |
||||
|
(! ( isspace_c(**s) || (**s == '=') || |
||||
|
(**s == '(') || (**s == ')') || |
||||
|
(**s == ',') |
||||
|
) ) ) { |
||||
|
buf[i] = **s; |
||||
|
i++; |
||||
|
(*s)++; |
||||
|
} |
||||
|
buf[i] = '\0'; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
/* skip over white space up to next token */ |
||||
|
|
||||
|
while (isspace_c(**s) || (**s == '=') || |
||||
|
(**s == '(') || (**s == ')') || (**s == ',')) |
||||
|
(*s)++; |
||||
|
|
||||
|
/* make a copy using only the space needed by the string length */ |
||||
|
|
||||
|
|
||||
|
ret_str = (char *) malloc(strlen(buf) + 1); |
||||
|
ret_str = strcpy(ret_str,buf); |
||||
|
|
||||
|
if (buf) free(buf); |
||||
|
|
||||
|
return ret_str; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/*=== Static CNVget_token ROUTINE =============*/ |
||||
|
/* |
||||
|
Get the next token from the input string together with its type. |
||||
|
The input string pointer |
||||
|
is advanced to the following token and the token from the input |
||||
|
string is copied to malloced storage and a pointer to that storage |
||||
|
is returned. The original input string is undisturbed. |
||||
|
*/ |
||||
|
|
||||
|
char * |
||||
|
CNVget_token(char **s, Cnv_Token_Type_t *type) |
||||
|
{ |
||||
|
char *ret_str; /* storage for returned string */ |
||||
|
|
||||
|
/* get the token from the input line */ |
||||
|
ret_str = CNVgettok(s); |
||||
|
|
||||
|
/* if no next token, return */ |
||||
|
if (ret_str == NULL) { |
||||
|
*type = CNV_NO_TOK; |
||||
|
return NULL; |
||||
|
} |
||||
|
|
||||
|
/* else, determine and return token type */ |
||||
|
switch (*ret_str) { |
||||
|
default: |
||||
|
*type = CNV_STRING_TOK; |
||||
|
break; |
||||
|
} |
||||
|
return ret_str; |
||||
|
} |
||||
@ -0,0 +1,183 @@ |
|||||
|
#include <stdio.h> |
||||
|
#include <ctype.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <string.h> |
||||
|
#include <math.h> |
||||
|
|
||||
|
/*********************/ |
||||
|
/* 3d geometry types */ |
||||
|
/*********************/ |
||||
|
|
||||
|
typedef struct Point3Struct { /* 3d point */ |
||||
|
double x, y, z; |
||||
|
} Point3; |
||||
|
typedef Point3 Vector3; |
||||
|
|
||||
|
//FIXME |
||||
|
double BilinearInterpolation(double q11, double q12, double q21, double q22, double x1, double x2, double y1, double y2, double x, double y); |
||||
|
|
||||
|
|
||||
|
/* Function to find the cross over point (the point before |
||||
|
which elements are smaller than or equal to x and after |
||||
|
which greater than x) |
||||
|
http://www.geeksforgeeks.org/find-k-closest-elements-given-value/ */ |
||||
|
int |
||||
|
findCrossOver(double arr[], int low, int high, double x) |
||||
|
{ |
||||
|
int mid; |
||||
|
// Base cases |
||||
|
if (arr[high] <= x) // x is greater than all |
||||
|
return high; |
||||
|
if (arr[low] > x) // x is smaller than all |
||||
|
return low; |
||||
|
|
||||
|
// Find the middle point |
||||
|
mid = (low + high)/2; /* low + (high - low)/2 */ |
||||
|
|
||||
|
/* If x is same as middle element, then return mid */ |
||||
|
if (arr[mid] <= x && arr[mid+1] > x) |
||||
|
return mid; |
||||
|
|
||||
|
/* If x is greater than arr[mid], then either arr[mid + 1] |
||||
|
is ceiling of x or ceiling lies in arr[mid+1...high] */ |
||||
|
if (arr[mid] < x) |
||||
|
return findCrossOver(arr, mid+1, high, x); |
||||
|
|
||||
|
return findCrossOver(arr, low, mid - 1, x); |
||||
|
} |
||||
|
|
||||
|
/* https://helloacm.com/cc-function-to-compute-the-bilinear-interpolation/ */ |
||||
|
double |
||||
|
BilinearInterpolation(double q11, double q12, double q21, double q22, double x1, double x2, double y1, double y2, double x, double y) |
||||
|
{ |
||||
|
double x2x1, y2y1, x2x, y2y, yy1, xx1; |
||||
|
x2x1 = x2 - x1; |
||||
|
y2y1 = y2 - y1; |
||||
|
x2x = x2 - x; |
||||
|
y2y = y2 - y; |
||||
|
yy1 = y - y1; |
||||
|
xx1 = x - x1; |
||||
|
return 1.0 / (x2x1 * y2y1) * ( |
||||
|
q11 * x2x * y2y + |
||||
|
q21 * xx1 * y2y + |
||||
|
q12 * x2x * yy1 + |
||||
|
q22 * xx1 * yy1 |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* |
||||
|
* C code from the article |
||||
|
* "Tri-linear Interpolation" |
||||
|
* by Steve Hill, sah@ukc.ac.uk |
||||
|
* in "Graphics Gems IV", Academic Press, 1994 |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
#if 0 |
||||
|
|
||||
|
double |
||||
|
trilinear(Point3 *p, double *d, int xsize, int ysize, int zsize, double def) |
||||
|
{ |
||||
|
# define DENS(X, Y, Z) d[(X)+xsize*((Y)+ysize*(Z))] |
||||
|
|
||||
|
int x0, y0, z0, |
||||
|
x1, y1, z1; |
||||
|
double *dp, |
||||
|
fx, fy, fz, |
||||
|
d000, d001, d010, d011, |
||||
|
d100, d101, d110, d111, |
||||
|
dx00, dx01, dx10, dx11, |
||||
|
dxy0, dxy1, dxyz; |
||||
|
|
||||
|
x0 = floor(p->x); |
||||
|
fx = p->x - x0; |
||||
|
y0 = floor(p->y); |
||||
|
fy = p->y - y0; |
||||
|
z0 = floor(p->z); |
||||
|
fz = p->z - z0; |
||||
|
|
||||
|
x1 = x0 + 1; |
||||
|
y1 = y0 + 1; |
||||
|
z1 = z0 + 1; |
||||
|
|
||||
|
if (x0 >= 0 && x1 < xsize && |
||||
|
y0 >= 0 && y1 < ysize && |
||||
|
z0 >= 0 && z1 < zsize) { |
||||
|
dp = &DENS(x0, y0, z0); |
||||
|
d000 = dp[0]; |
||||
|
d100 = dp[1]; |
||||
|
dp += xsize; |
||||
|
d010 = dp[0]; |
||||
|
d110 = dp[1]; |
||||
|
dp += xsize*ysize; |
||||
|
d011 = dp[0]; |
||||
|
d111 = dp[1]; |
||||
|
dp -= xsize; |
||||
|
d001 = dp[0]; |
||||
|
d101 = dp[1]; |
||||
|
} else { |
||||
|
# define INRANGE(X, Y, Z) \ |
||||
|
((X) >= 0 && (X) < xsize && \ |
||||
|
(Y) >= 0 && (Y) < ysize && \ |
||||
|
(Z) >= 0 && (Z) < zsize) |
||||
|
|
||||
|
d000 = INRANGE(x0, y0, z0) ? DENS(x0, y0, z0) : def; |
||||
|
d001 = INRANGE(x0, y0, z1) ? DENS(x0, y0, z1) : def; |
||||
|
d010 = INRANGE(x0, y1, z0) ? DENS(x0, y1, z0) : def; |
||||
|
d011 = INRANGE(x0, y1, z1) ? DENS(x0, y1, z1) : def; |
||||
|
|
||||
|
d100 = INRANGE(x1, y0, z0) ? DENS(x1, y0, z0) : def; |
||||
|
d101 = INRANGE(x1, y0, z1) ? DENS(x1, y0, z1) : def; |
||||
|
d110 = INRANGE(x1, y1, z0) ? DENS(x1, y1, z0) : def; |
||||
|
d111 = INRANGE(x1, y1, z1) ? DENS(x1, y1, z1) : def; |
||||
|
} |
||||
|
/* linear interpolation from l (when a=0) to h (when a=1)*/ |
||||
|
/* (equal to (a*h)+((1-a)*l) */ |
||||
|
#define LERP(a,l,h) ((l)+(((h)-(l))*(a))) |
||||
|
|
||||
|
dx00 = LERP(fx, d000, d100); |
||||
|
dx01 = LERP(fx, d001, d101); |
||||
|
dx10 = LERP(fx, d010, d110); |
||||
|
dx11 = LERP(fx, d011, d111); |
||||
|
|
||||
|
dxy0 = LERP(fy, dx00, dx10); |
||||
|
dxy1 = LERP(fy, dx01, dx11); |
||||
|
|
||||
|
dxyz = LERP(fz, dxy0, dxy1); |
||||
|
|
||||
|
return dxyz; |
||||
|
} |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
|
||||
|
/* trilinear interpolation |
||||
|
Paul Bourke |
||||
|
July 1997 |
||||
|
http://paulbourke.net/miscellaneous/interpolation/ */ |
||||
|
|
||||
|
double |
||||
|
TrilinearInterpolation(double x, double y, double z, int xind, int yind, int zind, double ***td) |
||||
|
{ |
||||
|
double V000, V100, V010, V001, V101, V011, V110, V111, Vxyz; |
||||
|
|
||||
|
V000 = td[zind][yind][xind]; |
||||
|
V100 = td[zind][yind][xind+1]; |
||||
|
V010 = td[zind][yind+1][xind]; |
||||
|
V001 = td[zind+1][yind][xind]; |
||||
|
V101 = td[zind+1][yind][xind+1]; |
||||
|
V011 = td[zind+1][yind+1][xind]; |
||||
|
V110 = td[zind][yind+1][xind+1]; |
||||
|
V111 = td[zind+1][yind+1][xind+1]; |
||||
|
|
||||
|
Vxyz = V000 * (1 - x) * (1 - y) * (1 - z) + |
||||
|
V100 * x * (1 - y) * (1 - z) + |
||||
|
V010 * (1 - x) * y * (1 - z) + |
||||
|
V001 * (1 - x) * (1 - y) * z + |
||||
|
V101 * x * (1 - y) * z + |
||||
|
V011 * (1 - x) * y * z + |
||||
|
V110 * x * y * (1 - z) + |
||||
|
V111 * x * y * z; |
||||
|
return Vxyz; |
||||
|
} |
||||
@ -0,0 +1,705 @@ |
|||||
|
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
||||
|
================================================================================ |
||||
|
|
||||
|
FILE table2D/cfunc.mod |
||||
|
|
||||
|
Copyright 2015 |
||||
|
Holger Vogt |
||||
|
|
||||
|
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 |
||||
|
|
||||
|
|
||||
|
|
||||
|
AUTHORS |
||||
|
|
||||
|
03 Nov 2015 Holger Vogt |
||||
|
|
||||
|
|
||||
|
MODIFICATIONS |
||||
|
|
||||
|
|
||||
|
SUMMARY |
||||
|
|
||||
|
This file contains the model-specific routines used to |
||||
|
functionally describe the 2D table code model used |
||||
|
to read and interpolate a value from a 2D table from a file. |
||||
|
|
||||
|
The essentially non-oscillatory (ENO) interpolation in 2-D (eno2.c) is taken from the |
||||
|
Madagascar Project at http://www.ahay.org/wiki/Main_Page |
||||
|
Currently ENO is used only to obtain the derivatives, |
||||
|
the data values are obtained by bilinear interpolation. |
||||
|
This combination allows op convergence for some data tables (no guarantee though). |
||||
|
|
||||
|
INTERFACES |
||||
|
|
||||
|
FILE ROUTINE CALLED |
||||
|
|
||||
|
N/A N/A |
||||
|
|
||||
|
|
||||
|
REFERENCED FILES |
||||
|
|
||||
|
Inputs from and outputs to ARGS structure. |
||||
|
|
||||
|
|
||||
|
NON-STANDARD FEATURES |
||||
|
|
||||
|
NONE |
||||
|
|
||||
|
===============================================================================*/ |
||||
|
|
||||
|
/*=== INCLUDE FILES ====================*/ |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
#include <ctype.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <string.h> |
||||
|
#include <math.h> |
||||
|
|
||||
|
#include <sys/types.h> |
||||
|
#include <sys/stat.h> |
||||
|
|
||||
|
#include "mada/eno2.h" |
||||
|
|
||||
|
/*=== CONSTANTS ========================*/ |
||||
|
|
||||
|
#define OK 0 |
||||
|
#define FAIL 1 |
||||
|
|
||||
|
/*=== MACROS ===========================*/ |
||||
|
|
||||
|
#if defined(__MINGW32__) || defined(_MSC_VER) |
||||
|
#define DIR_PATHSEP "\\" |
||||
|
#else |
||||
|
#define DIR_PATHSEP "/" |
||||
|
#endif |
||||
|
|
||||
|
#if defined(_MSC_VER) |
||||
|
#define strdup _strdup |
||||
|
#define snprintf _snprintf |
||||
|
#endif |
||||
|
|
||||
|
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
||||
|
|
||||
|
struct filesource_state { |
||||
|
FILE *fp; |
||||
|
long pos; |
||||
|
unsigned char atend; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
typedef struct { |
||||
|
|
||||
|
int ix; /* size of array in x */ |
||||
|
int iy; /* size of array in y */ |
||||
|
|
||||
|
struct filesource_state *state; /* the storage array for the |
||||
|
filesource status. */ |
||||
|
int init_err; |
||||
|
|
||||
|
sf_eno2 newtable; /* the table, code borrowed from madagascar project */ |
||||
|
|
||||
|
double *xcol; /* array of floats in x */ |
||||
|
double *ycol; /* array of floats in y */ |
||||
|
|
||||
|
double **table; |
||||
|
|
||||
|
} Local_Data_t; |
||||
|
|
||||
|
/* Type definition for each possible token returned. */ |
||||
|
typedef enum token_type_s {CNV_NO_TOK, CNV_STRING_TOK} Cnv_Token_Type_t; |
||||
|
|
||||
|
typedef char line_t[82]; /* A SPICE size line. <= 80 characters plus '\n\0' */ |
||||
|
|
||||
|
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
||||
|
|
||||
|
extern int findCrossOver(double arr[], int low, int high, double x); |
||||
|
extern double BilinearInterpolation(double q11, double q12, double q21, double q22, double x1, double x2, double y1, double y2, double x, double y); |
||||
|
|
||||
|
extern char *CNVgettok(char **s); |
||||
|
|
||||
|
/*============================================================================== |
||||
|
|
||||
|
FUNCTION cnv_get_spice_value() |
||||
|
|
||||
|
AUTHORS |
||||
|
|
||||
|
??? Bill Kuhn |
||||
|
|
||||
|
MODIFICATIONS |
||||
|
|
||||
|
30 Sep 1991 Jeffrey P. Murray |
||||
|
|
||||
|
SUMMARY |
||||
|
|
||||
|
This function takes as input a string token from a SPICE |
||||
|
deck and returns a floating point equivalent value. |
||||
|
|
||||
|
INTERFACES |
||||
|
|
||||
|
FILE ROUTINE CALLED |
||||
|
|
||||
|
N/A N/A |
||||
|
|
||||
|
RETURNED VALUE |
||||
|
|
||||
|
Returns the floating point value in pointer *p_value. Also |
||||
|
returns an integer representing successful completion. |
||||
|
|
||||
|
GLOBAL VARIABLES |
||||
|
|
||||
|
NONE |
||||
|
|
||||
|
NON-STANDARD FEATURES |
||||
|
|
||||
|
NONE |
||||
|
|
||||
|
==============================================================================*/ |
||||
|
|
||||
|
/*=== Static CNV_get_spice_value ROUTINE =============*/ |
||||
|
|
||||
|
/* |
||||
|
Function takes as input a string token from a SPICE |
||||
|
deck and returns a floating point equivalent value. |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
static int |
||||
|
cnv_get_spice_value(char *str, /* IN - The value text e.g. 1.2K */ |
||||
|
double *p_value) /* OUT - The numerical value */ |
||||
|
{ |
||||
|
/* the following were "int4" devices - jpm */ |
||||
|
size_t len; |
||||
|
size_t i; |
||||
|
int n_matched; |
||||
|
|
||||
|
line_t val_str; |
||||
|
|
||||
|
char c = ' '; |
||||
|
char c1; |
||||
|
|
||||
|
double scale_factor; |
||||
|
double value; |
||||
|
|
||||
|
/* Scan the input string looking for an alpha character that is not */ |
||||
|
/* 'e' or 'E'. Such a character is assumed to be an engineering */ |
||||
|
/* suffix as defined in the Spice 2G.6 user's manual. */ |
||||
|
|
||||
|
len = strlen(str); |
||||
|
if (len > sizeof(val_str) - 1) |
||||
|
len = sizeof(val_str) - 1; |
||||
|
|
||||
|
for (i = 0; i < len; i++) { |
||||
|
c = str[i]; |
||||
|
if (isalpha_c(c) && (c != 'E') && (c != 'e')) |
||||
|
break; |
||||
|
else if (isspace_c(c)) |
||||
|
break; |
||||
|
else |
||||
|
val_str[i] = c; |
||||
|
} |
||||
|
val_str[i] = '\0'; |
||||
|
|
||||
|
/* Determine the scale factor */ |
||||
|
|
||||
|
if ((i >= len) || !isalpha_c(c)) |
||||
|
scale_factor = 1.0; |
||||
|
else { |
||||
|
|
||||
|
if (isupper_c(c)) |
||||
|
c = tolower_c(c); |
||||
|
|
||||
|
switch (c) { |
||||
|
|
||||
|
case 't': |
||||
|
scale_factor = 1.0e12; |
||||
|
break; |
||||
|
|
||||
|
case 'g': |
||||
|
scale_factor = 1.0e9; |
||||
|
break; |
||||
|
|
||||
|
case 'k': |
||||
|
scale_factor = 1.0e3; |
||||
|
break; |
||||
|
|
||||
|
case 'u': |
||||
|
scale_factor = 1.0e-6; |
||||
|
break; |
||||
|
|
||||
|
case 'n': |
||||
|
scale_factor = 1.0e-9; |
||||
|
break; |
||||
|
|
||||
|
case 'p': |
||||
|
scale_factor = 1.0e-12; |
||||
|
break; |
||||
|
|
||||
|
case 'f': |
||||
|
scale_factor = 1.0e-15; |
||||
|
break; |
||||
|
|
||||
|
case 'm': |
||||
|
i++; |
||||
|
if (i >= len) { |
||||
|
scale_factor = 1.0e-3; |
||||
|
break; |
||||
|
} |
||||
|
c1 = str[i]; |
||||
|
if (!isalpha_c(c1)) { |
||||
|
scale_factor = 1.0e-3; |
||||
|
break; |
||||
|
} |
||||
|
if (islower_c(c1)) |
||||
|
c1 = toupper_c(c1); |
||||
|
if (c1 == 'E') |
||||
|
scale_factor = 1.0e6; |
||||
|
else if (c1 == 'I') |
||||
|
scale_factor = 25.4e-6; |
||||
|
else |
||||
|
scale_factor = 1.0e-3; |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
scale_factor = 1.0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* Convert the numeric portion to a float and multiply by the */ |
||||
|
/* scale factor. */ |
||||
|
|
||||
|
n_matched = sscanf(val_str, "%le", &value); |
||||
|
|
||||
|
if (n_matched < 1) { |
||||
|
*p_value = 0.0; |
||||
|
return FAIL; |
||||
|
} |
||||
|
|
||||
|
*p_value = value * scale_factor; |
||||
|
return OK; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/*============================================================================== |
||||
|
|
||||
|
FUNCTION void cm_table2D() |
||||
|
|
||||
|
AUTHORS |
||||
|
|
||||
|
08 Nov 2015 Holger Vogt |
||||
|
|
||||
|
MODIFICATIONS |
||||
|
|
||||
|
|
||||
|
|
||||
|
SUMMARY |
||||
|
|
||||
|
This function implements 2D table code model. |
||||
|
|
||||
|
INTERFACES |
||||
|
|
||||
|
FILE ROUTINE CALLED |
||||
|
|
||||
|
N/A N/A |
||||
|
|
||||
|
|
||||
|
RETURNED VALUE |
||||
|
|
||||
|
Returns inputs and outputs via ARGS structure. |
||||
|
|
||||
|
GLOBAL VARIABLES |
||||
|
|
||||
|
NONE |
||||
|
|
||||
|
NON-STANDARD FEATURES |
||||
|
|
||||
|
NONE |
||||
|
|
||||
|
INPUT FILE SPEC |
||||
|
|
||||
|
* Title (comments preceded by * ignored) |
||||
|
* table size |
||||
|
ix |
||||
|
iy |
||||
|
* x row independent variables |
||||
|
x0 x1 x2 x3 ... xix-1 |
||||
|
y column independent variables |
||||
|
y0 y1 y2 y3 ... yiy-1 |
||||
|
* table |
||||
|
x0y0 x1y0 x2y0 ... xix-1y0 |
||||
|
... |
||||
|
x0yiy-1 x1yiy-1 x2yiy-1 ... xix-1yiy-1 |
||||
|
|
||||
|
|
||||
|
|
||||
|
==============================================================================*/ |
||||
|
|
||||
|
|
||||
|
/*=== CM_table2D ROUTINE ===*/ |
||||
|
|
||||
|
|
||||
|
void |
||||
|
cm_table2D(ARGS) /* structure holding parms, inputs, outputs, etc. */ |
||||
|
{ |
||||
|
int size, xind, yind; |
||||
|
double xval, yval, xoff, yoff, xdiff, ydiff; |
||||
|
double derivval[2], outval; |
||||
|
double q11, q12, q21, q22, x1, x2, y1, y2; |
||||
|
|
||||
|
Local_Data_t *loc; /* Pointer to local static data, not to be included |
||||
|
in the state vector */ |
||||
|
Mif_Complex_t ac_gain; |
||||
|
|
||||
|
size = PORT_SIZE(out); |
||||
|
if (INIT == 1) { |
||||
|
|
||||
|
int i; |
||||
|
int ix = 0, /* elements in a row */ |
||||
|
iy = 0; /* number of rows */ |
||||
|
double **table_data; |
||||
|
double tmp; |
||||
|
char *cFile, *cThisPtr, *cThisLine, *cThisLinePtr; |
||||
|
int isNewline; /* Boolean indicating we've read a CR or LF */ |
||||
|
size_t lFileLen; /* Length of file */ |
||||
|
size_t lFileRead; /* Length of file read in */ |
||||
|
long lIndex; /* Index into cThisLine array */ |
||||
|
int lLineCount; /* Current line number */ |
||||
|
size_t lStartPos; /* Offset of start of current line */ |
||||
|
size_t lTotalChars; /* Total characters read */ |
||||
|
int interporder; /* order of interpolation for eno */ |
||||
|
|
||||
|
/* allocate static storage for *loc */ |
||||
|
STATIC_VAR (locdata) = calloc(1, sizeof(Local_Data_t)); |
||||
|
loc = STATIC_VAR (locdata); |
||||
|
|
||||
|
/* Allocate storage for internal state */ |
||||
|
loc->state = (struct filesource_state*) malloc(sizeof(struct filesource_state)); |
||||
|
loc->ix = loc->iy = 0; |
||||
|
|
||||
|
/* open file */ |
||||
|
loc->state->fp = fopen_with_path(PARAM(file), "r"); |
||||
|
loc->state->pos = 0; |
||||
|
loc->state->atend = 0; |
||||
|
if (!loc->state->fp) { |
||||
|
char *lbuffer, *p; |
||||
|
lbuffer = getenv("NGSPICE_INPUT_DIR"); |
||||
|
if (lbuffer && *lbuffer) { |
||||
|
p = (char*) malloc(strlen(lbuffer) + strlen(DIR_PATHSEP) + strlen(PARAM(file)) + 1); |
||||
|
sprintf(p, "%s%s%s", lbuffer, DIR_PATHSEP, PARAM(file)); |
||||
|
loc->state->fp = fopen(p, "r"); |
||||
|
free(p); |
||||
|
} |
||||
|
} |
||||
|
struct stat st; |
||||
|
if (!loc->state->fp || fstat(fileno(loc->state->fp), &st)) { |
||||
|
cm_message_printf("cannot open file %s", PARAM(file)); |
||||
|
loc->state->atend = 1; |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
/* get file length */ |
||||
|
lFileLen = (size_t) st.st_size; |
||||
|
|
||||
|
/* create string to hold the whole file */ |
||||
|
cFile = calloc(lFileLen + 1, sizeof(char)); |
||||
|
/* create another string long enough for file manipulation */ |
||||
|
cThisLine = calloc(lFileLen + 1, sizeof(char)); |
||||
|
if (cFile == NULL || cThisLine == NULL) { |
||||
|
cm_message_printf("Insufficient memory to read file %s", PARAM(file)); |
||||
|
loc->state->atend = 1; |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
/* read whole file into cFile */ |
||||
|
lFileRead = fread(cFile, sizeof(char), lFileLen, loc->state->fp); |
||||
|
fclose(loc->state->fp); |
||||
|
/* Number of chars read may be less than lFileLen, because /r are skipt by 'fread' */ |
||||
|
cFile[lFileRead] = '\0'; |
||||
|
|
||||
|
cThisPtr = cFile; |
||||
|
cThisLinePtr = cThisLine; |
||||
|
lLineCount = 0L; |
||||
|
lTotalChars = 0L; |
||||
|
|
||||
|
while (*cThisPtr) { /* Read until reaching null char */ |
||||
|
|
||||
|
lIndex = 0L; /* Reset counters and flags */ |
||||
|
isNewline = 0; |
||||
|
lStartPos = lTotalChars; |
||||
|
|
||||
|
while (*cThisPtr) { |
||||
|
if (!isNewline) { /* Haven't read a LF yet */ |
||||
|
if (*cThisPtr == '\n') /* This char is LF */ |
||||
|
isNewline = 1; /* Set flag */ |
||||
|
} |
||||
|
else if (*cThisPtr != '\n') /* Already found LF */ |
||||
|
break; /* Done with line */ |
||||
|
|
||||
|
cThisLinePtr[lIndex++] = *cThisPtr++; /* Add char to output and increment */ |
||||
|
lTotalChars++; |
||||
|
} |
||||
|
|
||||
|
cThisLinePtr[lIndex] = '\0'; /* Terminate the string */ |
||||
|
lLineCount++; /* Increment the line counter */ |
||||
|
/* continue if comment or empty */ |
||||
|
if (cThisLinePtr[0] == '*' || cThisLinePtr[0] == '\n') { |
||||
|
lLineCount--; /* we count only real lines */ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (lLineCount == 1) { |
||||
|
cnv_get_spice_value(cThisLinePtr, &tmp); |
||||
|
loc->ix = ix = (int) tmp; |
||||
|
/* generate row data structure (x) */ |
||||
|
loc->xcol = (double*) calloc((size_t) ix, sizeof(double)); |
||||
|
} |
||||
|
else if (lLineCount == 2) { |
||||
|
cnv_get_spice_value(cThisLinePtr, &tmp); |
||||
|
loc->iy = iy = (int) tmp; |
||||
|
/* generate column data structure (y) */ |
||||
|
loc->ycol = (double*) calloc((size_t) iy, sizeof(double)); |
||||
|
} |
||||
|
else if (lLineCount == 3) { |
||||
|
char *token = CNVgettok(&cThisLinePtr); |
||||
|
i = 0; |
||||
|
while (token) { |
||||
|
if (i == ix) { |
||||
|
cm_message_printf("Too many numbers in x row."); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
cnv_get_spice_value(token, &loc->xcol[i++]); |
||||
|
free(token); |
||||
|
token = CNVgettok(&cThisLinePtr); |
||||
|
} |
||||
|
if (i < ix) { |
||||
|
cm_message_printf("Not enough numbers in x row."); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
else if (lLineCount == 4) { |
||||
|
char *token = CNVgettok(&cThisLinePtr); |
||||
|
i = 0; |
||||
|
while (token) { |
||||
|
if (i == iy) { |
||||
|
cm_message_printf("Too many numbers in y row."); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
cnv_get_spice_value(token, &loc->ycol[i++]); |
||||
|
free(token); |
||||
|
token = CNVgettok(&cThisLinePtr); |
||||
|
} |
||||
|
if (i < iy) { |
||||
|
cm_message_printf("Not enough numbers in y row."); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
/* jump out of while loop to read in the table */ |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* generate table core */ |
||||
|
interporder = PARAM(order); |
||||
|
/* boundary limits set to param 'order' aren't recognized, |
||||
|
so limit them here */ |
||||
|
if (interporder < 2) { |
||||
|
cm_message_printf("Parameter Order=%d not possible, set to minimum value 2", interporder); |
||||
|
interporder = 2; |
||||
|
} |
||||
|
/* int order : interpolation order, |
||||
|
int n1, int n2 : data dimensions */ |
||||
|
loc->newtable = sf_eno2_init(interporder, ix, iy); |
||||
|
|
||||
|
/* create table_data in memory */ |
||||
|
/* data [n2][n1] */ |
||||
|
table_data = calloc((size_t) iy, sizeof(double *)); |
||||
|
for (i = 0; i < iy; i++) |
||||
|
table_data[i] = calloc((size_t) ix, sizeof(double)); |
||||
|
|
||||
|
loc->table = table_data; |
||||
|
|
||||
|
/* continue reading from cFile */ |
||||
|
lLineCount = 0; |
||||
|
while (*cThisPtr) { /* Read until reaching null char */ |
||||
|
char *token; |
||||
|
|
||||
|
lIndex = 0L; /* Reset counters and flags */ |
||||
|
isNewline = 0; |
||||
|
lStartPos = lTotalChars; |
||||
|
|
||||
|
while (*cThisPtr) { /* Read until reaching null char */ |
||||
|
|
||||
|
if (!isNewline) { /* Haven't read a LF yet */ |
||||
|
if (*cThisPtr == '\n') /* This char is a LF */ |
||||
|
isNewline = 1; /* Set flag */ |
||||
|
} |
||||
|
|
||||
|
else if (*cThisPtr != '\n') /* Already found LF */ |
||||
|
break; /* Done with line */ |
||||
|
|
||||
|
cThisLinePtr[lIndex++] = *cThisPtr++; /* Add char to output and increment */ |
||||
|
lTotalChars++; |
||||
|
} |
||||
|
|
||||
|
cThisLinePtr[lIndex] = '\0'; /* Terminate the string */ |
||||
|
lLineCount++; /* Increment the line counter */ |
||||
|
/* continue if comment or empty */ |
||||
|
if (cThisLinePtr[0] == '*' || cThisLinePtr[0] == '\0') { |
||||
|
if (lTotalChars >= lFileLen) { |
||||
|
cm_message_printf("Not enough data in file %s", PARAM(file)); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
lLineCount--; /* we count only real lines */ |
||||
|
continue; |
||||
|
} |
||||
|
token = CNVgettok(&cThisLinePtr); |
||||
|
i = 0; |
||||
|
while (token) { |
||||
|
double tmpval; |
||||
|
if (i == ix) { |
||||
|
cm_message_printf("Too many numbers in y row no. %d.", lLineCount); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
/* read table core from cFile, fill local static table structure table_data */ |
||||
|
cnv_get_spice_value(token, &tmpval); |
||||
|
table_data[lLineCount - 1][i++] = tmpval; |
||||
|
free(token); |
||||
|
token = CNVgettok(&cThisLinePtr); |
||||
|
} |
||||
|
if (i < ix) { |
||||
|
cm_message_printf("Not enough numbers in y row no. %d.", lLineCount); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* fill table data into eno2 structure */ |
||||
|
sf_eno2_set (loc->newtable, table_data /* data [n2][n1] */); |
||||
|
|
||||
|
/* free all the emory allocated */ |
||||
|
// for (i = 0; i < iy; i++) |
||||
|
// free(table_data[i]); |
||||
|
// free(table_data); |
||||
|
free(cFile); |
||||
|
free(cThisLine); |
||||
|
} /* end of initialization "if (INIT == 1)" */ |
||||
|
|
||||
|
loc = STATIC_VAR (locdata); |
||||
|
|
||||
|
/* return immediately if there was an initialization error */ |
||||
|
if (loc->init_err == 1) |
||||
|
return; |
||||
|
|
||||
|
/* get input x, y, |
||||
|
find corresponding indices, |
||||
|
get x and y offsets, |
||||
|
call interpolation function with value and derivative */ |
||||
|
xval = INPUT(inx); |
||||
|
yval = INPUT(iny); |
||||
|
|
||||
|
/* find index */ |
||||
|
if (xval < loc->xcol[0] || xval > loc->xcol[loc->ix - 1]) { |
||||
|
if (PARAM(verbose) > 0) |
||||
|
cm_message_printf("x value %g exceeds table limits,\n" |
||||
|
" please enlarge range of your table", |
||||
|
xval); |
||||
|
return; |
||||
|
} |
||||
|
if (yval < loc->ycol[0] || yval > loc->ycol[loc->iy - 1]) { |
||||
|
if (PARAM(verbose) > 0) |
||||
|
cm_message_printf("y value %g exceeds table limits,\n" |
||||
|
" please enlarge range of your table", |
||||
|
yval); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
/* something like binary search to get the index */ |
||||
|
xind = findCrossOver(loc->xcol, 0, loc->ix - 1, xval); |
||||
|
/* find index with minimum distance between xval and row value */ |
||||
|
if (fabs(loc->xcol[xind + 1] - xval) < fabs(xval - loc->xcol[xind])) |
||||
|
xind++; |
||||
|
xoff = xval - loc->xcol[xind]; |
||||
|
yind = findCrossOver(loc->ycol, 0, loc->iy - 1, yval); |
||||
|
/* find index with minimum distance between yval and column value */ |
||||
|
if (fabs(loc->ycol[yind + 1] - yval) < fabs(yval - loc->ycol[yind])) |
||||
|
yind++; |
||||
|
yoff = yval - loc->ycol[yind]; |
||||
|
|
||||
|
/* find local difference around index of independent row and column values */ |
||||
|
if (xind == loc->ix - 1) |
||||
|
xdiff = loc->xcol[xind] - loc->xcol[xind - 1]; |
||||
|
else if (xind == 0) |
||||
|
xdiff = loc->xcol[xind + 1] - loc->xcol[xind]; |
||||
|
else |
||||
|
xdiff = 0.5 * (loc->xcol[xind + 1] - loc->xcol[xind - 1]); |
||||
|
|
||||
|
if (yind == loc->iy - 1) |
||||
|
ydiff = loc->ycol[yind] - loc->ycol[yind - 1]; |
||||
|
else if (yind == 0) |
||||
|
ydiff = loc->ycol[yind + 1] - loc->ycol[yind]; |
||||
|
else |
||||
|
ydiff = 0.5 * (loc->ycol[yind + 1] - loc->ycol[yind - 1]); |
||||
|
|
||||
|
/* Essentially non-oscillatory (ENO) interpolation to obtain the derivatives only. |
||||
|
Using outval for now yields ngspice op non-convergence */ |
||||
|
sf_eno2_apply (loc->newtable, |
||||
|
xind, yind, /* grid location */ |
||||
|
xoff, yoff, /* offset from grid */ |
||||
|
&outval, /* output data value */ |
||||
|
derivval, /* output derivatives [2] */ |
||||
|
DER /* what to compute [FUNC, DER, BOTH] */ |
||||
|
); |
||||
|
|
||||
|
/* bilinear interpolation to obtain the output value */ |
||||
|
xind = findCrossOver(loc->xcol, 0, loc->ix - 1, xval); |
||||
|
yind = findCrossOver(loc->ycol, 0, loc->iy - 1, yval); |
||||
|
x1 = loc->xcol[xind]; |
||||
|
x2 = loc->xcol[xind + 1]; |
||||
|
y1 = loc->ycol[yind]; |
||||
|
y2 = loc->ycol[yind + 1]; |
||||
|
q11 = loc->table[yind][xind]; |
||||
|
q12 = loc->table[yind + 1][xind]; |
||||
|
q21 = loc->table[yind][xind + 1]; |
||||
|
q22 = loc->table[yind + 1][xind + 1]; |
||||
|
outval = BilinearInterpolation(q11, q12, q21, q22, x1, x2, y1, y2, xval, yval); |
||||
|
|
||||
|
if (ANALYSIS != MIF_AC) { |
||||
|
double xderiv, yderiv, outv; |
||||
|
outv = PARAM(offset) + PARAM(gain) * outval; |
||||
|
OUTPUT(out) = outv; |
||||
|
xderiv = PARAM(gain) * derivval[0] / xdiff; |
||||
|
PARTIAL(out, inx) = xderiv; |
||||
|
yderiv = PARAM(gain) * derivval[1] / ydiff; |
||||
|
PARTIAL(out, iny) = yderiv; |
||||
|
|
||||
|
if (PARAM(verbose) > 1) |
||||
|
cm_message_printf("\nI: %g, xval: %g, yval: %g, xderiv: %g, yderiv: %g", outv, xval, yval, xderiv, yderiv); |
||||
|
} |
||||
|
else { |
||||
|
ac_gain.real = PARAM(gain) * derivval[0] / xdiff; |
||||
|
ac_gain.imag= 0.0; |
||||
|
AC_GAIN(out, inx) = ac_gain; |
||||
|
ac_gain.real = PARAM(gain) * derivval[1] / ydiff; |
||||
|
ac_gain.imag= 0.0; |
||||
|
AC_GAIN(out, iny) = ac_gain; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,78 @@ |
|||||
|
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
||||
|
================================================================================ |
||||
|
Copyright 2015 |
||||
|
Holger Vogt |
||||
|
|
||||
|
AUTHORS |
||||
|
|
||||
|
06 Nov 2015 Holger Vogt |
||||
|
|
||||
|
|
||||
|
SUMMARY |
||||
|
|
||||
|
This file contains the interface specification file for the |
||||
|
2D table code model. |
||||
|
|
||||
|
===============================================================================*/ |
||||
|
|
||||
|
NAME_TABLE: |
||||
|
|
||||
|
C_Function_Name: cm_table2D |
||||
|
Spice_Model_Name: table2d |
||||
|
Description: "2D table model" |
||||
|
|
||||
|
|
||||
|
PORT_TABLE: |
||||
|
|
||||
|
Port_Name: inx iny out |
||||
|
Description: "inputx" "inputy" "output" |
||||
|
Direction: in in out |
||||
|
Default_Type: v v i |
||||
|
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id,vnam] [v,vd,i,id] |
||||
|
Vector: no no no |
||||
|
Vector_Bounds: - - - |
||||
|
Null_Allowed: no no no |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: order verbose |
||||
|
Description: "order" "verbose" |
||||
|
Data_Type: int int |
||||
|
Default_Value: 3 0 |
||||
|
Limits: [2 -] [0 2] |
||||
|
Vector: no no |
||||
|
Vector_Bounds: - - |
||||
|
Null_Allowed: yes yes |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: offset gain |
||||
|
Description: "offset" "gain" |
||||
|
Data_Type: real real |
||||
|
Default_Value: 0.0 1.0 |
||||
|
Limits: - - |
||||
|
Vector: no no |
||||
|
Vector_Bounds: - - |
||||
|
Null_Allowed: yes yes |
||||
|
|
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: file |
||||
|
Description: "file name" |
||||
|
Data_Type: string |
||||
|
Default_Value: "2D-table-model.txt" |
||||
|
Limits: - |
||||
|
Vector: no |
||||
|
Vector_Bounds: - |
||||
|
Null_Allowed: yes |
||||
|
|
||||
|
|
||||
|
STATIC_VAR_TABLE: |
||||
|
|
||||
|
Static_Var_Name: locdata |
||||
|
Description: "local static data" |
||||
|
Data_Type: pointer |
||||
@ -0,0 +1,768 @@ |
|||||
|
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
||||
|
================================================================================ |
||||
|
|
||||
|
FILE table3D/cfunc.mod |
||||
|
|
||||
|
Copyright 2015 |
||||
|
Holger Vogt |
||||
|
|
||||
|
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 |
||||
|
|
||||
|
|
||||
|
|
||||
|
AUTHORS |
||||
|
|
||||
|
03 Nov 2015 Holger Vogt |
||||
|
|
||||
|
|
||||
|
MODIFICATIONS |
||||
|
|
||||
|
|
||||
|
SUMMARY |
||||
|
|
||||
|
This file contains the model-specific routines used to |
||||
|
functionally describe the 3D table code model used |
||||
|
to read and interpolate a value from a 3D table from a file. |
||||
|
|
||||
|
The essentially non-oscillatory (ENO) interpolation in 3-D (eno3.c) is taken from the |
||||
|
Madagascar Project at http://www.ahay.org/wiki/Main_Page |
||||
|
Currently ENO is used only to obtain the derivatives, |
||||
|
the data values are obtained by trilinear interpolation. |
||||
|
This combination allows op convergence for some data tables (no guarantee though). |
||||
|
|
||||
|
INTERFACES |
||||
|
|
||||
|
FILE ROUTINE CALLED |
||||
|
|
||||
|
N/A N/A |
||||
|
|
||||
|
|
||||
|
REFERENCED FILES |
||||
|
|
||||
|
Inputs from and outputs to ARGS structure. |
||||
|
|
||||
|
|
||||
|
NON-STANDARD FEATURES |
||||
|
|
||||
|
NONE |
||||
|
|
||||
|
===============================================================================*/ |
||||
|
|
||||
|
/*=== INCLUDE FILES ====================*/ |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
#include <ctype.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <string.h> |
||||
|
#include <math.h> |
||||
|
|
||||
|
#include <sys/types.h> |
||||
|
#include <sys/stat.h> |
||||
|
|
||||
|
#include "mada/eno2.h" |
||||
|
#include "mada/eno3.h" |
||||
|
|
||||
|
/*=== CONSTANTS ========================*/ |
||||
|
|
||||
|
#define OK 0 |
||||
|
#define FAIL 1 |
||||
|
|
||||
|
/*=== MACROS ===========================*/ |
||||
|
|
||||
|
#if defined(__MINGW32__) || defined(_MSC_VER) |
||||
|
#define DIR_PATHSEP "\\" |
||||
|
#else |
||||
|
#define DIR_PATHSEP "/" |
||||
|
#endif |
||||
|
|
||||
|
#if defined(_MSC_VER) |
||||
|
#define strdup _strdup |
||||
|
#define snprintf _snprintf |
||||
|
#endif |
||||
|
|
||||
|
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
||||
|
|
||||
|
struct filesource_state { |
||||
|
FILE *fp; |
||||
|
long pos; |
||||
|
unsigned char atend; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
typedef struct { |
||||
|
|
||||
|
int ix; /* size of array in x */ |
||||
|
int iy; /* size of array in y */ |
||||
|
int iz; /* size of array in z */ |
||||
|
|
||||
|
struct filesource_state *state; /* the storage array for the |
||||
|
filesource status. */ |
||||
|
|
||||
|
int init_err; |
||||
|
|
||||
|
sf_eno3 newtable; /* the table, code borrowed from madagascar project */ |
||||
|
|
||||
|
double *xcol; /* array of doubles in x */ |
||||
|
double *ycol; /* array of doubles in y */ |
||||
|
double *zcol; /* array of doubles in z */ |
||||
|
|
||||
|
double ***table; |
||||
|
|
||||
|
} Local_Data_t; |
||||
|
|
||||
|
/*********************/ |
||||
|
/* 3d geometry types */ |
||||
|
/*********************/ |
||||
|
|
||||
|
typedef char line_t[82]; /* A SPICE size line. <= 80 characters plus '\n\0' */ |
||||
|
|
||||
|
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
||||
|
|
||||
|
extern int findCrossOver(double arr[], int low, int high, double x); |
||||
|
|
||||
|
extern double TrilinearInterpolation(double x, double y, double z, int xind, int yind, int zind, double ***td); |
||||
|
|
||||
|
extern char *CNVgettok(char **s); |
||||
|
|
||||
|
/*============================================================================== |
||||
|
|
||||
|
FUNCTION cnv_get_spice_value() |
||||
|
|
||||
|
AUTHORS |
||||
|
|
||||
|
??? Bill Kuhn |
||||
|
|
||||
|
MODIFICATIONS |
||||
|
|
||||
|
30 Sep 1991 Jeffrey P. Murray |
||||
|
|
||||
|
SUMMARY |
||||
|
|
||||
|
This function takes as input a string token from a SPICE |
||||
|
deck and returns a floating point equivalent value. |
||||
|
|
||||
|
INTERFACES |
||||
|
|
||||
|
FILE ROUTINE CALLED |
||||
|
|
||||
|
N/A N/A |
||||
|
|
||||
|
RETURNED VALUE |
||||
|
|
||||
|
Returns the floating point value in pointer *p_value. Also |
||||
|
returns an integer representing successful completion. |
||||
|
|
||||
|
GLOBAL VARIABLES |
||||
|
|
||||
|
NONE |
||||
|
|
||||
|
NON-STANDARD FEATURES |
||||
|
|
||||
|
NONE |
||||
|
|
||||
|
==============================================================================*/ |
||||
|
|
||||
|
/*=== Static CNV_get_spice_value ROUTINE =============*/ |
||||
|
|
||||
|
/* |
||||
|
Function takes as input a string token from a SPICE |
||||
|
deck and returns a floating point equivalent value. |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
static int |
||||
|
cnv_get_spice_value(char *str, /* IN - The value text e.g. 1.2K */ |
||||
|
double *p_value) /* OUT - The numerical value */ |
||||
|
{ |
||||
|
/* the following were "int4" devices - jpm */ |
||||
|
size_t len; |
||||
|
size_t i; |
||||
|
int n_matched; |
||||
|
|
||||
|
line_t val_str; |
||||
|
|
||||
|
char c = ' '; |
||||
|
char c1; |
||||
|
|
||||
|
double scale_factor; |
||||
|
double value; |
||||
|
|
||||
|
/* Scan the input string looking for an alpha character that is not */ |
||||
|
/* 'e' or 'E'. Such a character is assumed to be an engineering */ |
||||
|
/* suffix as defined in the Spice 2G.6 user's manual. */ |
||||
|
|
||||
|
len = strlen(str); |
||||
|
if (len > sizeof(val_str) - 1) |
||||
|
len = sizeof(val_str) - 1; |
||||
|
|
||||
|
for (i = 0; i < len; i++) { |
||||
|
c = str[i]; |
||||
|
if (isalpha_c(c) && (c != 'E') && (c != 'e')) |
||||
|
break; |
||||
|
else if (isspace_c(c)) |
||||
|
break; |
||||
|
else |
||||
|
val_str[i] = c; |
||||
|
} |
||||
|
val_str[i] = '\0'; |
||||
|
|
||||
|
/* Determine the scale factor */ |
||||
|
|
||||
|
if ((i >= len) || (! isalpha_c(c))) |
||||
|
scale_factor = 1.0; |
||||
|
else { |
||||
|
|
||||
|
if (isupper_c(c)) |
||||
|
c = tolower_c(c); |
||||
|
|
||||
|
switch (c) { |
||||
|
|
||||
|
case 't': |
||||
|
scale_factor = 1.0e12; |
||||
|
break; |
||||
|
|
||||
|
case 'g': |
||||
|
scale_factor = 1.0e9; |
||||
|
break; |
||||
|
|
||||
|
case 'k': |
||||
|
scale_factor = 1.0e3; |
||||
|
break; |
||||
|
|
||||
|
case 'u': |
||||
|
scale_factor = 1.0e-6; |
||||
|
break; |
||||
|
|
||||
|
case 'n': |
||||
|
scale_factor = 1.0e-9; |
||||
|
break; |
||||
|
|
||||
|
case 'p': |
||||
|
scale_factor = 1.0e-12; |
||||
|
break; |
||||
|
|
||||
|
case 'f': |
||||
|
scale_factor = 1.0e-15; |
||||
|
break; |
||||
|
|
||||
|
case 'm': |
||||
|
i++; |
||||
|
if (i >= len) { |
||||
|
scale_factor = 1.0e-3; |
||||
|
break; |
||||
|
} |
||||
|
c1 = str[i]; |
||||
|
if (!isalpha_c(c1)) { |
||||
|
scale_factor = 1.0e-3; |
||||
|
break; |
||||
|
} |
||||
|
if (islower_c(c1)) |
||||
|
c1 = toupper_c(c1); |
||||
|
if (c1 == 'E') |
||||
|
scale_factor = 1.0e6; |
||||
|
else if (c1 == 'I') |
||||
|
scale_factor = 25.4e-6; |
||||
|
else |
||||
|
scale_factor = 1.0e-3; |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
scale_factor = 1.0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* Convert the numeric portion to a float and multiply by the */ |
||||
|
/* scale factor. */ |
||||
|
|
||||
|
n_matched = sscanf(val_str, "%le", &value); |
||||
|
|
||||
|
if (n_matched < 1) { |
||||
|
*p_value = 0.0; |
||||
|
return FAIL; |
||||
|
} |
||||
|
|
||||
|
*p_value = value * scale_factor; |
||||
|
return OK; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/*============================================================================== |
||||
|
|
||||
|
FUNCTION void cm_table3D() |
||||
|
|
||||
|
AUTHORS |
||||
|
|
||||
|
08 Nov 2015 Holger Vogt |
||||
|
|
||||
|
MODIFICATIONS |
||||
|
|
||||
|
|
||||
|
|
||||
|
SUMMARY |
||||
|
|
||||
|
This function implements 2D table code model. |
||||
|
|
||||
|
INTERFACES |
||||
|
|
||||
|
FILE ROUTINE CALLED |
||||
|
|
||||
|
N/A N/A |
||||
|
|
||||
|
|
||||
|
RETURNED VALUE |
||||
|
|
||||
|
Returns inputs and outputs via ARGS structure. |
||||
|
|
||||
|
GLOBAL VARIABLES |
||||
|
|
||||
|
NONE |
||||
|
|
||||
|
NON-STANDARD FEATURES |
||||
|
|
||||
|
NONE |
||||
|
|
||||
|
INPUT FILE SPEC |
||||
|
|
||||
|
* Title (comments preceded by * ignored) |
||||
|
* table size |
||||
|
ix |
||||
|
iy |
||||
|
* x row independent variables |
||||
|
x0 x1 x2 x3 ... xix-1 |
||||
|
y column independent variables |
||||
|
y0 y1 y2 y3 ... yiy-1 |
||||
|
* table |
||||
|
x0y0 x1y0 x2y0 ... xix-1y0 |
||||
|
... |
||||
|
x0yiy-1 x1yiy-1 x2yiy-1 ... xix-1yiy-1 |
||||
|
|
||||
|
|
||||
|
|
||||
|
==============================================================================*/ |
||||
|
|
||||
|
|
||||
|
/*=== CM_table3D ROUTINE ===*/ |
||||
|
|
||||
|
|
||||
|
void |
||||
|
cm_table3D(ARGS) /* structure holding parms, inputs, outputs, etc. */ |
||||
|
{ |
||||
|
int size, xind, yind, zind; |
||||
|
double xval, yval, zval, xoff, yoff, zoff, xdiff, ydiff, zdiff; |
||||
|
double derivval[3], outval; |
||||
|
|
||||
|
Local_Data_t *loc; /* Pointer to local static data, not to be included |
||||
|
in the state vector */ |
||||
|
Mif_Complex_t ac_gain; |
||||
|
|
||||
|
size = PORT_SIZE(out); |
||||
|
if (INIT == 1) { |
||||
|
|
||||
|
int i, j; |
||||
|
int ix = 0, /* elements in a row */ |
||||
|
iy = 0, /* number of rows */ |
||||
|
iz = 0; /* number of 2D tables */ |
||||
|
|
||||
|
double ***table_data; |
||||
|
|
||||
|
double tmp; |
||||
|
char *cFile, *cThisPtr, *cThisLine, *cThisLinePtr; |
||||
|
int isNewline; /* Boolean indicating we've read a CR or LF */ |
||||
|
size_t lFileLen; /* Length of file */ |
||||
|
size_t lFileRead; /* Length of file read in */ |
||||
|
long lIndex; /* Index into cThisLine array */ |
||||
|
int lLineCount; /* Current line number */ |
||||
|
size_t lStartPos; /* Offset of start of current line */ |
||||
|
size_t lTotalChars; /* Total characters read */ |
||||
|
int lTableCount; /* Number of tables */ |
||||
|
int interporder; /* order of interpolation for eno */ |
||||
|
|
||||
|
/* allocate static storage for *loc */ |
||||
|
STATIC_VAR (locdata) = calloc (1, sizeof(Local_Data_t)); |
||||
|
loc = STATIC_VAR (locdata); |
||||
|
|
||||
|
/* Allocate storage for internal state */ |
||||
|
loc->state = (struct filesource_state*) malloc(sizeof(struct filesource_state)); |
||||
|
loc->ix = loc->iy = loc->iz = 0; |
||||
|
loc->init_err = 0; |
||||
|
|
||||
|
/* open file */ |
||||
|
loc->state->fp = fopen_with_path(PARAM(file), "r"); |
||||
|
loc->state->pos = 0; |
||||
|
loc->state->atend = 0; |
||||
|
if (!loc->state->fp) { |
||||
|
char *lbuffer, *pp; |
||||
|
lbuffer = getenv("NGSPICE_INPUT_DIR"); |
||||
|
if (lbuffer && *lbuffer) { |
||||
|
pp = (char*) malloc(strlen(lbuffer) + strlen(DIR_PATHSEP) + strlen(PARAM(file)) + 1); |
||||
|
sprintf(pp, "%s%s%s", lbuffer, DIR_PATHSEP, PARAM(file)); |
||||
|
loc->state->fp = fopen(pp, "r"); |
||||
|
free(pp); |
||||
|
} |
||||
|
} |
||||
|
struct stat st; |
||||
|
if (!loc->state->fp || fstat(fileno(loc->state->fp), &st)) { |
||||
|
cm_message_printf("cannot open file %s", PARAM(file)); |
||||
|
loc->state->atend = 1; |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
/* get file length */ |
||||
|
lFileLen = (size_t) st.st_size; |
||||
|
|
||||
|
/* create string to hold the whole file */ |
||||
|
cFile = calloc(lFileLen + 1, sizeof(char)); |
||||
|
/* create another string long enough for file manipulation */ |
||||
|
cThisLine = calloc(lFileLen + 1, sizeof(char)); |
||||
|
if (cFile == NULL || cThisLine == NULL) { |
||||
|
cm_message_printf("Insufficient memory to read file %s", PARAM(file)); |
||||
|
loc->state->atend = 1; |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
/* read whole file into cFile */ |
||||
|
lFileRead = fread(cFile, sizeof(char), lFileLen, loc->state->fp); |
||||
|
fclose(loc->state->fp); |
||||
|
/* Number of chars read may be less than lFileLen, because /r are skipt by 'fread' */ |
||||
|
cFile[lFileRead] = '\0'; |
||||
|
|
||||
|
cThisPtr = cFile; |
||||
|
cThisLinePtr = cThisLine; |
||||
|
lLineCount = 0L; |
||||
|
lTotalChars = 0L; |
||||
|
|
||||
|
while (*cThisPtr) { /* Read until reaching null char */ |
||||
|
lIndex = 0L; /* Reset counters and flags */ |
||||
|
isNewline = 0; |
||||
|
lStartPos = lTotalChars; |
||||
|
|
||||
|
while (*cThisPtr) { /* Read until reaching null char */ |
||||
|
if (!isNewline) { /* Haven't read a LF yet */ |
||||
|
if (*cThisPtr == '\n') /* This char is a LF */ |
||||
|
isNewline = 1; /* Set flag */ |
||||
|
} |
||||
|
|
||||
|
else if (*cThisPtr != '\n') /* Already found LF */ |
||||
|
break; /* Done with line */ |
||||
|
|
||||
|
cThisLinePtr[lIndex++] = *cThisPtr++; /* Add char to output and increment */ |
||||
|
lTotalChars++; |
||||
|
} |
||||
|
|
||||
|
cThisLinePtr[lIndex] = '\0'; /* Terminate the string */ |
||||
|
lLineCount++; /* Increment the line counter */ |
||||
|
/* continue if comment or empty */ |
||||
|
if (cThisLinePtr[0] == '*' || cThisLinePtr[0] == '\n') { |
||||
|
lLineCount--; /* we count only real lines */ |
||||
|
continue; |
||||
|
} |
||||
|
if (lLineCount == 1) { |
||||
|
cnv_get_spice_value(cThisLinePtr, &tmp); |
||||
|
loc->ix = ix = (int) tmp; |
||||
|
/* generate row data structure (x) */ |
||||
|
loc->xcol = (double*) calloc((size_t) ix, sizeof(double)); |
||||
|
} else if (lLineCount == 2) { |
||||
|
cnv_get_spice_value(cThisLinePtr, &tmp); |
||||
|
loc->iy = iy = (int) tmp; |
||||
|
/* generate column data structure (y) */ |
||||
|
loc->ycol = (double*) calloc((size_t) iy, sizeof(double)); |
||||
|
} else if (lLineCount == 3) { |
||||
|
cnv_get_spice_value(cThisLinePtr, &tmp); |
||||
|
loc->iz = iz = (int) tmp; |
||||
|
/* generate column data structure (y) */ |
||||
|
loc->zcol = (double*) calloc((size_t) iz, sizeof(double)); |
||||
|
} else if (lLineCount == 4) { |
||||
|
char *token = CNVgettok(&cThisLinePtr); |
||||
|
i = 0; |
||||
|
while (token) { |
||||
|
if (i == ix) { |
||||
|
cm_message_printf("Too many numbers in x row."); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
cnv_get_spice_value(token, &loc->xcol[i++]); |
||||
|
free(token); |
||||
|
token = CNVgettok(&cThisLinePtr); |
||||
|
} |
||||
|
if (i < ix) { |
||||
|
cm_message_printf("Not enough numbers in x row."); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
} else if (lLineCount == 5) { |
||||
|
char *token = CNVgettok(&cThisLinePtr); |
||||
|
i = 0; |
||||
|
while (token) { |
||||
|
if (i == iy) { |
||||
|
cm_message_printf("Too many numbers in y row."); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
cnv_get_spice_value(token, &loc->ycol[i++]); |
||||
|
free(token); |
||||
|
token = CNVgettok(&cThisLinePtr); |
||||
|
} |
||||
|
if (i < iy) { |
||||
|
cm_message_printf("Not enough numbers in y row."); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
} else if (lLineCount == 6) { |
||||
|
char *token = CNVgettok(&cThisLinePtr); |
||||
|
i = 0; |
||||
|
while (token) { |
||||
|
if (i == iz) { |
||||
|
cm_message_printf("Too many numbers in z row."); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
cnv_get_spice_value(token, &loc->zcol[i++]); |
||||
|
free(token); |
||||
|
token = CNVgettok(&cThisLinePtr); |
||||
|
} |
||||
|
if (i < iz) { |
||||
|
cm_message_printf("Not enough numbers in z row."); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
/* jump out of while loop to read in the table */ |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* generate table core */ |
||||
|
interporder = PARAM(order); |
||||
|
/* boundary limits set to param 'order' aren't recognized, |
||||
|
so limit them here */ |
||||
|
if (interporder < 2) { |
||||
|
cm_message_printf("Parameter Order=%d not possible, set to minimum value 2", interporder); |
||||
|
interporder = 2; |
||||
|
} |
||||
|
/* int order : interpolation order, |
||||
|
int n1, int n2, int n3 : data dimensions */ |
||||
|
loc->newtable = sf_eno3_init(interporder, ix, iy, iz); |
||||
|
|
||||
|
/* create table_data in memory */ |
||||
|
/* data [n3][n2][n1] */ |
||||
|
table_data = calloc((size_t) iy, sizeof(double *)); |
||||
|
for (i = 0; i < iz; i++) { |
||||
|
table_data[i] = calloc((size_t) iy, sizeof(double *)); |
||||
|
for (j = 0; j < iy; j++) |
||||
|
table_data[i][j] = calloc((size_t) ix, sizeof(double)); |
||||
|
} |
||||
|
|
||||
|
loc->table = table_data; |
||||
|
|
||||
|
/* continue reading from cFile */ |
||||
|
for (lTableCount = 0; lTableCount < iz; lTableCount++) { |
||||
|
lLineCount = 0; |
||||
|
while (lLineCount < iy) { |
||||
|
char *token; |
||||
|
|
||||
|
lIndex = 0L; /* Reset counters and flags */ |
||||
|
isNewline = 0; |
||||
|
lStartPos = lTotalChars; |
||||
|
|
||||
|
/* read a line */ |
||||
|
while (*cThisPtr) { /* Read until reaching null char */ |
||||
|
if (!isNewline) { /* Haven't read a CR or LF yet */ |
||||
|
if (*cThisPtr == '\n') /* This char is LF */ |
||||
|
isNewline = 1; /* Set flag */ |
||||
|
} |
||||
|
|
||||
|
else if (*cThisPtr != '\n') /* Already found LF */ |
||||
|
break; /* Done with line */ |
||||
|
|
||||
|
cThisLinePtr[lIndex++] = *cThisPtr++; /* Add char to output and increment */ |
||||
|
lTotalChars++; |
||||
|
} |
||||
|
|
||||
|
cThisLinePtr[lIndex] = '\0'; /* Terminate the string */ |
||||
|
/* continue if comment or empty */ |
||||
|
if (cThisLinePtr[0] == '*' || cThisLinePtr[0] == '\0') { |
||||
|
if (lTotalChars >= lFileLen) { |
||||
|
cm_message_printf("Not enough data in file %s", PARAM(file)); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
continue; |
||||
|
} |
||||
|
token = CNVgettok(&cThisLinePtr); |
||||
|
i = 0; |
||||
|
while (token) { |
||||
|
double tmpval; |
||||
|
|
||||
|
if (i == ix) { |
||||
|
cm_message_printf("Too many numbers in y row no. %d of table %d.", lLineCount, lTableCount); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
/* read table core from cFile, fill local static table structure table_data */ |
||||
|
cnv_get_spice_value(token, &tmpval); |
||||
|
|
||||
|
table_data[lTableCount][lLineCount][i++] = tmpval; |
||||
|
|
||||
|
free(token); |
||||
|
token = CNVgettok(&cThisLinePtr); |
||||
|
} |
||||
|
if (i < ix) { |
||||
|
cm_message_printf("Not enough numbers in y row no. %d of table %d.", lLineCount, lTableCount); |
||||
|
loc->init_err = 1; |
||||
|
return; |
||||
|
} |
||||
|
lLineCount++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* fill table data into eno3 structure */ |
||||
|
|
||||
|
sf_eno3_set(loc->newtable, table_data /* data [n3][n2][n1] */); |
||||
|
|
||||
|
/* free all the emory allocated */ |
||||
|
// for (i = 0; i < iy; i++) |
||||
|
// free(table_data[i]); |
||||
|
// free(table_data); |
||||
|
free(cFile); |
||||
|
free(cThisLine); |
||||
|
} /* end of initialization "if (INIT == 1)" */ |
||||
|
|
||||
|
loc = STATIC_VAR (locdata); |
||||
|
|
||||
|
/* return immediately if there was an initialization error */ |
||||
|
if (loc->init_err == 1) |
||||
|
return; |
||||
|
|
||||
|
/* get input x, y, z; |
||||
|
find corresponding indices; |
||||
|
get x and y offsets; |
||||
|
call interpolation functions with value and derivative */ |
||||
|
|
||||
|
xval = INPUT(inx); |
||||
|
yval = INPUT(iny); |
||||
|
zval = INPUT(inz); |
||||
|
|
||||
|
/* check table ranges */ |
||||
|
if (xval < loc->xcol[0] || xval > loc->xcol[loc->ix - 1]) { |
||||
|
if (PARAM(verbose) > 0) |
||||
|
cm_message_printf("x value %g exceeds table limits, \nplease enlarge range of your table", xval); |
||||
|
return; |
||||
|
} |
||||
|
if (yval < loc->ycol[0] || yval > loc->ycol[loc->iy - 1]) { |
||||
|
if (PARAM(verbose) > 0) |
||||
|
cm_message_printf("y value %g exceeds table limits, \nplease enlarge range of your table", yval); |
||||
|
return; |
||||
|
} |
||||
|
if (zval < loc->zcol[0] || zval > loc->zcol[loc->iz - 1]) { |
||||
|
if (PARAM(verbose) > 0) |
||||
|
cm_message_printf("z value %g exceeds table limits, \nplease enlarge range of your table", zval); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
/* find index */ |
||||
|
/* something like binary search to get the index */ |
||||
|
xind = findCrossOver(loc->xcol, 0, loc->ix - 1, xval); |
||||
|
|
||||
|
/* find index with minimum distance between xval and row value |
||||
|
if (fabs(loc->xcol[xind + 1] - xval) < fabs(xval - loc->xcol[xind])) |
||||
|
xind++; |
||||
|
*/ |
||||
|
xoff = xval - loc->xcol[xind]; |
||||
|
yind = findCrossOver(loc->ycol, 0, loc->iy - 1, yval); |
||||
|
/* find index with minimum distance between yval and column value |
||||
|
if (fabs(loc->ycol[yind + 1] - yval) < fabs(yval - loc->ycol[yind])) |
||||
|
yind++; |
||||
|
*/ |
||||
|
yoff = yval - loc->ycol[yind]; |
||||
|
zind = findCrossOver(loc->zcol, 0, loc->iz - 1, zval); |
||||
|
/* find index with minimum distance between zval and table value |
||||
|
if (fabs(loc->zcol[zind + 1] - zval) < fabs(zval - loc->zcol[zind])) |
||||
|
zind++; |
||||
|
*/ |
||||
|
zoff = zval - loc->zcol[zind]; |
||||
|
|
||||
|
/* find local difference around index of independent row and column values */ |
||||
|
if (xind == loc->ix - 1) |
||||
|
xdiff = loc->xcol[xind] - loc->xcol[xind - 1]; |
||||
|
else if (xind == 0) |
||||
|
xdiff = loc->xcol[xind + 1] - loc->xcol[xind]; |
||||
|
else |
||||
|
xdiff = 0.5 * (loc->xcol[xind + 1] - loc->xcol[xind - 1]); |
||||
|
|
||||
|
if (yind == loc->iy - 1) |
||||
|
ydiff = loc->ycol[yind] - loc->ycol[yind - 1]; |
||||
|
else if (yind == 0) |
||||
|
ydiff = loc->ycol[yind + 1] - loc->ycol[yind]; |
||||
|
else |
||||
|
ydiff = 0.5 * (loc->ycol[yind + 1] - loc->ycol[yind - 1]); |
||||
|
|
||||
|
if (zind == loc->iz - 1) |
||||
|
zdiff = loc->zcol[zind] - loc->zcol[zind - 1]; |
||||
|
else if (zind == 0) |
||||
|
zdiff = loc->zcol[zind + 1] - loc->zcol[zind]; |
||||
|
else |
||||
|
zdiff = 0.5 * (loc->zcol[zind + 1] - loc->zcol[zind - 1]); |
||||
|
|
||||
|
/* Essentially non-oscillatory (ENO) interpolation to obtain the derivatives only. |
||||
|
Using outval for now yields ngspice op non-convergence */ |
||||
|
sf_eno3_apply (loc->newtable, |
||||
|
xind, yind, zind, /* grid location */ |
||||
|
xoff, yoff, zoff, /* offset from grid */ |
||||
|
&outval, /* output data value */ |
||||
|
derivval, /* output derivatives [3] */ |
||||
|
DER /* what to compute [FUNC, DER, BOTH] */ |
||||
|
); |
||||
|
|
||||
|
|
||||
|
outval = TrilinearInterpolation(xoff / (loc->xcol[xind + 1] - loc->xcol[xind]), |
||||
|
yoff / (loc->ycol[yind + 1] - loc->ycol[yind]), |
||||
|
zoff / (loc->zcol[zind + 1] - loc->zcol[zind]), |
||||
|
xind, yind, zind, loc->table); |
||||
|
|
||||
|
if (ANALYSIS != MIF_AC) { |
||||
|
double xderiv, yderiv, zderiv, outv; |
||||
|
outv = PARAM(offset) + PARAM(gain) * outval; |
||||
|
OUTPUT(out) = outv; |
||||
|
xderiv = PARAM(gain) * derivval[0] / xdiff; |
||||
|
PARTIAL(out, inx) = xderiv; |
||||
|
yderiv = PARAM(gain) * derivval[1] / ydiff; |
||||
|
PARTIAL(out, iny) = yderiv; |
||||
|
zderiv = PARAM(gain) * derivval[2] / zdiff; |
||||
|
PARTIAL(out, inz) = zderiv; |
||||
|
|
||||
|
if (PARAM(verbose) > 1) |
||||
|
cm_message_printf("\nI: %g, xval: %g, yval: %g, zval: %g, xderiv: %g, yderiv: %g, zderiv: %g", outv, xval, yval, zval, xderiv, yderiv, zderiv); |
||||
|
} else { |
||||
|
ac_gain.real = PARAM(gain) * derivval[0] / xdiff; |
||||
|
ac_gain.imag= 0.0; |
||||
|
AC_GAIN(out, inx) = ac_gain; |
||||
|
ac_gain.real = PARAM(gain) * derivval[1] / ydiff; |
||||
|
ac_gain.imag= 0.0; |
||||
|
AC_GAIN(out, iny) = ac_gain; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* These includes add functions from extra source code files, |
||||
|
* still using the standard XSPICE procedure of cmpp-ing cfunc.mod |
||||
|
* and then only compiling the resulting *.c file. |
||||
|
*/ |
||||
|
|
||||
|
#include "../support/gettokens.c" /* reading tokens */ |
||||
|
#include "../support/interp.c" /* 2D and 3D linear interpolation */ |
||||
|
#include "../mada/alloc.c" /* eno interpolation from madagascar project */ |
||||
|
#include "../mada/eno.c" /* eno interpolation from madagascar project */ |
||||
|
#include "../mada/eno2.c" /* eno interpolation from madagascar project */ |
||||
|
#include "../mada/eno3.c" /* eno interpolation from madagascar project */ |
||||
@ -0,0 +1,87 @@ |
|||||
|
/*.......1.........2.........3.........4.........5.........6.........7.........8 |
||||
|
================================================================================ |
||||
|
Copyright 2015 |
||||
|
Holger Vogt |
||||
|
|
||||
|
AUTHORS |
||||
|
|
||||
|
06 Nov 2015 Holger Vogt |
||||
|
|
||||
|
|
||||
|
SUMMARY |
||||
|
|
||||
|
This file contains the interface specification file for the |
||||
|
3D table code model. |
||||
|
|
||||
|
===============================================================================*/ |
||||
|
|
||||
|
NAME_TABLE: |
||||
|
|
||||
|
C_Function_Name: cm_table3D |
||||
|
Spice_Model_Name: table3d |
||||
|
Description: "3D table model" |
||||
|
|
||||
|
|
||||
|
PORT_TABLE: |
||||
|
|
||||
|
Port_Name: inx iny inz |
||||
|
Description: "inputx" "inputy" "inputz" |
||||
|
Direction: in in in |
||||
|
Default_Type: v v v |
||||
|
Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id,vnam] [v,vd,i,id,vnam] |
||||
|
Vector: no no no |
||||
|
Vector_Bounds: - - - |
||||
|
Null_Allowed: no no no |
||||
|
|
||||
|
PORT_TABLE: |
||||
|
|
||||
|
Port_Name: out |
||||
|
Description: "output" |
||||
|
Direction: out |
||||
|
Default_Type: i |
||||
|
Allowed_Types: [v,vd,i,id] |
||||
|
Vector: no |
||||
|
Vector_Bounds: - |
||||
|
Null_Allowed: no |
||||
|
|
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: order verbose |
||||
|
Description: "order" "verbose" |
||||
|
Data_Type: int int |
||||
|
Default_Value: 3 0 |
||||
|
Limits: [2 -] [0 2] |
||||
|
Vector: no no |
||||
|
Vector_Bounds: - - |
||||
|
Null_Allowed: yes yes |
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: offset gain |
||||
|
Description: "offset" "gain" |
||||
|
Data_Type: real real |
||||
|
Default_Value: 0.0 1.0 |
||||
|
Limits: - - |
||||
|
Vector: no no |
||||
|
Vector_Bounds: - - |
||||
|
Null_Allowed: yes yes |
||||
|
|
||||
|
|
||||
|
PARAMETER_TABLE: |
||||
|
|
||||
|
Parameter_Name: file |
||||
|
Description: "file name" |
||||
|
Data_Type: string |
||||
|
Default_Value: "3D-table-model.txt" |
||||
|
Limits: - |
||||
|
Vector: no |
||||
|
Vector_Bounds: - |
||||
|
Null_Allowed: yes |
||||
|
|
||||
|
|
||||
|
STATIC_VAR_TABLE: |
||||
|
|
||||
|
Static_Var_Name: locdata |
||||
|
Description: "local static data" |
||||
|
Data_Type: pointer |
||||
@ -0,0 +1,225 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<ItemGroup Label="ProjectConfigurations"> |
||||
|
<ProjectConfiguration Include="Debug|Win32"> |
||||
|
<Configuration>Debug</Configuration> |
||||
|
<Platform>Win32</Platform> |
||||
|
</ProjectConfiguration> |
||||
|
<ProjectConfiguration Include="Release|Win32"> |
||||
|
<Configuration>Release</Configuration> |
||||
|
<Platform>Win32</Platform> |
||||
|
</ProjectConfiguration> |
||||
|
<ProjectConfiguration Include="Debug|x64"> |
||||
|
<Configuration>Debug</Configuration> |
||||
|
<Platform>x64</Platform> |
||||
|
</ProjectConfiguration> |
||||
|
<ProjectConfiguration Include="Release|x64"> |
||||
|
<Configuration>Release</Configuration> |
||||
|
<Platform>x64</Platform> |
||||
|
</ProjectConfiguration> |
||||
|
</ItemGroup> |
||||
|
<PropertyGroup Label="Globals"> |
||||
|
<ProjectName>table</ProjectName> |
||||
|
<ProjectGuid>{7A6473F5-AFED-4910-88D2-6204DA829832}</ProjectGuid> |
||||
|
<RootNamespace>icmanalog</RootNamespace> |
||||
|
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> |
||||
|
</PropertyGroup> |
||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> |
||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType> |
||||
|
<CharacterSet>NotSet</CharacterSet> |
||||
|
<PlatformToolset>v140</PlatformToolset> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> |
||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType> |
||||
|
<CharacterSet>NotSet</CharacterSet> |
||||
|
<WholeProgramOptimization>true</WholeProgramOptimization> |
||||
|
<PlatformToolset>v140</PlatformToolset> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> |
||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType> |
||||
|
<CharacterSet>NotSet</CharacterSet> |
||||
|
<PlatformToolset>v140</PlatformToolset> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> |
||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType> |
||||
|
<CharacterSet>MultiByte</CharacterSet> |
||||
|
<WholeProgramOptimization>true</WholeProgramOptimization> |
||||
|
<PlatformToolset>v140</PlatformToolset> |
||||
|
</PropertyGroup> |
||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> |
||||
|
<ImportGroup Label="ExtensionSettings"> |
||||
|
</ImportGroup> |
||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> |
||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
|
</ImportGroup> |
||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> |
||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
|
</ImportGroup> |
||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> |
||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
|
</ImportGroup> |
||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> |
||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
|
</ImportGroup> |
||||
|
<PropertyGroup Label="UserMacros" /> |
||||
|
<PropertyGroup> |
||||
|
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> |
||||
|
<TargetExt>.cm</TargetExt> |
||||
|
<OutDir>$(SolutionDir)codemodels\$(Platform)\$(Configuration)\</OutDir> |
||||
|
<IntDir>$(SolutionDir)xspice\intermediate\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
|
<GenerateManifest>true</GenerateManifest> |
||||
|
<LinkIncremental>false</LinkIncremental> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
|
<GenerateManifest>false</GenerateManifest> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |
||||
|
<TargetName>$(ProjectName)64</TargetName> |
||||
|
<GenerateManifest>true</GenerateManifest> |
||||
|
<LinkIncremental>false</LinkIncremental> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> |
||||
|
<TargetName>$(ProjectName)64</TargetName> |
||||
|
<GenerateManifest>false</GenerateManifest> |
||||
|
</PropertyGroup> |
||||
|
<ItemDefinitionGroup> |
||||
|
<PreBuildEvent> |
||||
|
<Message>generate cfunc.c and ifspec.c files</Message> |
||||
|
<Command>call .\aux-cfunc.bat $(ProjectName)</Command> |
||||
|
</PreBuildEvent> |
||||
|
</ItemDefinitionGroup> |
||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
|
<ClCompile> |
||||
|
<Optimization>Disabled</Optimization> |
||||
|
<AdditionalIncludeDirectories>icm\$(ProjectName);..\src\include;..\..\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;CIDER;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
|
<MinimalRebuild>false</MinimalRebuild> |
||||
|
<ExceptionHandling> |
||||
|
</ExceptionHandling> |
||||
|
<BasicRuntimeChecks>Default</BasicRuntimeChecks> |
||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> |
||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo> |
||||
|
<WarningLevel>Level4</WarningLevel> |
||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> |
||||
|
<CompileAs>CompileAsC</CompileAs> |
||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation> |
||||
|
</ClCompile> |
||||
|
<Link> |
||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
|
<AssemblyDebug> |
||||
|
</AssemblyDebug> |
||||
|
<SubSystem>Windows</SubSystem> |
||||
|
<NoEntryPoint>false</NoEntryPoint> |
||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress> |
||||
|
<DataExecutionPrevention> |
||||
|
</DataExecutionPrevention> |
||||
|
<ImportLibrary>$(TargetDir)$(TargetName).lib</ImportLibrary> |
||||
|
<TargetMachine>MachineX86</TargetMachine> |
||||
|
</Link> |
||||
|
</ItemDefinitionGroup> |
||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
|
<ClCompile> |
||||
|
<Optimization>MaxSpeed</Optimization> |
||||
|
<IntrinsicFunctions>true</IntrinsicFunctions> |
||||
|
<AdditionalIncludeDirectories>icm\$(ProjectName);..\src\include;..\..\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
|
<ExceptionHandling> |
||||
|
</ExceptionHandling> |
||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> |
||||
|
<FunctionLevelLinking>true</FunctionLevelLinking> |
||||
|
<WarningLevel>Level4</WarningLevel> |
||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> |
||||
|
<CompileAs>CompileAsC</CompileAs> |
||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation> |
||||
|
</ClCompile> |
||||
|
<Link> |
||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
|
<OptimizeReferences>true</OptimizeReferences> |
||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding> |
||||
|
<NoEntryPoint>false</NoEntryPoint> |
||||
|
<ImportLibrary>$(TargetDir)$(TargetName).lib</ImportLibrary> |
||||
|
<TargetMachine>MachineX86</TargetMachine> |
||||
|
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> |
||||
|
</Link> |
||||
|
</ItemDefinitionGroup> |
||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |
||||
|
<Midl> |
||||
|
<TargetEnvironment>X64</TargetEnvironment> |
||||
|
</Midl> |
||||
|
<ClCompile> |
||||
|
<Optimization>Disabled</Optimization> |
||||
|
<AdditionalIncludeDirectories>icm\$(ProjectName);..\src\include;..\..\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;CIDER;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
|
<MinimalRebuild>false</MinimalRebuild> |
||||
|
<ExceptionHandling> |
||||
|
</ExceptionHandling> |
||||
|
<BasicRuntimeChecks>Default</BasicRuntimeChecks> |
||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> |
||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo> |
||||
|
<WarningLevel>Level4</WarningLevel> |
||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> |
||||
|
<CompileAs>CompileAsC</CompileAs> |
||||
|
</ClCompile> |
||||
|
<Link> |
||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
|
<AssemblyDebug> |
||||
|
</AssemblyDebug> |
||||
|
<SubSystem>Windows</SubSystem> |
||||
|
<NoEntryPoint>false</NoEntryPoint> |
||||
|
<RandomizedBaseAddress>false</RandomizedBaseAddress> |
||||
|
<DataExecutionPrevention> |
||||
|
</DataExecutionPrevention> |
||||
|
<ImportLibrary>$(TargetDir)$(TargetName).lib</ImportLibrary> |
||||
|
<TargetMachine>MachineX64</TargetMachine> |
||||
|
</Link> |
||||
|
</ItemDefinitionGroup> |
||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> |
||||
|
<Midl> |
||||
|
<TargetEnvironment>X64</TargetEnvironment> |
||||
|
</Midl> |
||||
|
<ClCompile> |
||||
|
<Optimization>MaxSpeed</Optimization> |
||||
|
<IntrinsicFunctions>true</IntrinsicFunctions> |
||||
|
<AdditionalIncludeDirectories>icm\$(ProjectName);..\src\include;..\..\src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
||||
|
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
|
<ExceptionHandling> |
||||
|
</ExceptionHandling> |
||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> |
||||
|
<FunctionLevelLinking>true</FunctionLevelLinking> |
||||
|
<WarningLevel>Level4</WarningLevel> |
||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> |
||||
|
<CompileAs>CompileAsC</CompileAs> |
||||
|
</ClCompile> |
||||
|
<Link> |
||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
|
<OptimizeReferences>true</OptimizeReferences> |
||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding> |
||||
|
<NoEntryPoint>false</NoEntryPoint> |
||||
|
<ImportLibrary>$(TargetDir)$(TargetName).lib</ImportLibrary> |
||||
|
<TargetMachine>MachineX64</TargetMachine> |
||||
|
</Link> |
||||
|
</ItemDefinitionGroup> |
||||
|
<ItemGroup> |
||||
|
<ClCompile Include="icm\table\table2D\table2D-cfunc.c"> |
||||
|
<AdditionalIncludeDirectories>..\..\src\xspice\icm\$(ProjectName);..\..\src\xspice\%(RelativeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
||||
|
</ClCompile> |
||||
|
<ClCompile Include="icm\table\table2D\table2D-ifspec.c" /> |
||||
|
<ClCompile Include="icm\table\table3D\table3D-cfunc.c"> |
||||
|
<AdditionalIncludeDirectories>..\..\src\xspice\icm\$(ProjectName);..\..\src\xspice\%(RelativeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
||||
|
</ClCompile> |
||||
|
<ClCompile Include="icm\table\table3D\table3D-ifspec.c" /> |
||||
|
<ClCompile Include="..\..\src\xspice\icm\dlmain.c" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<None Include="..\..\src\xspice\icm\table\table2D\cfunc.mod" /> |
||||
|
<None Include="..\..\src\xspice\icm\table\table2D\ifspec.ifs" /> |
||||
|
<None Include="..\..\src\xspice\icm\table\table3D\cfunc.mod" /> |
||||
|
<None Include="..\..\src\xspice\icm\table\table3D\ifspec.ifs" /> |
||||
|
</ItemGroup> |
||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
||||
|
<ImportGroup Label="ExtensionTargets"> |
||||
|
</ImportGroup> |
||||
|
</Project> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue