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