[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-gnucap] how to model sinusoidal dependence on charge?
From: |
address@hidden |
Subject: |
Re: [Help-gnucap] how to model sinusoidal dependence on charge? |
Date: |
Thu, 19 Nov 2009 13:30:32 +0100 |
User-agent: |
Thunderbird 2.0.0.23 (Windows/20090812) |
address@hidden a écrit :
Hi all,
I'm trying to model a device which has a voltage that depends periodically
on the charge which has passed through it: V=Vc*sin(q)
This seems almost possible with the controlled sources, but not quite,
since the SIN function always depends on time. Is it possible to implement
such a device with the model compiler, or could the trigonometric functions
be generalized to achieve this somehow?
Hello,
I have extended an old version of gnucap (2008-08-10 !) to enable the
use of such functions :
E1 (out 0 in 0) FUNC(3,5) exp=true means : out=e^(3*in+5)
E1 (out 0 in 0) FUNC(314,-78.5) cos=true means : out=cos(314*in -0,785)
= sin(314*in)
E1 (out 0 0 0) FUNC(4,5) xtime=true means : out=4*t+5 where t is the
time of the simulation
I hope it fit with a new version but I haven't time enough to test it.
So try it and if it doesn't fit
I'll write it again in a few day (I have started to upgrade to 2009-11-10)
Here what I did in a test purpose. It's not a good program, you are free
to enhance it.
Morever, I don't know how such an extension fit with the convergence
algorithm.
So I distribute it in the hope that it will be useful but WITHOUT ANY
WARRANTY ;-)
Good Luck.
diff src/Makefile.in
> am__objects_5 = bm_complex.$(OBJEXT) bm_exp.$(OBJEXT) bm_fit.$(OBJEXT) \
> bm_generator.$(OBJEXT) bm_poly.$(OBJEXT) bm_posy.$(OBJEXT) \
> bm_pulse.$(OBJEXT) bm_pwl.$(OBJEXT) bm_sffm.$(OBJEXT) \
> bm_sin.$(OBJEXT) bm_tanh.$(OBJEXT) bmm_table.$(OBJEXT) \
> bmm_semi.$(OBJEXT) bm_func.$(OBJEXT)
> # behavioral modeling functions
> BM_SRCS = \
> bm_complex.cc bm_exp.cc bm_fit.cc bm_generator.cc \
> bm_poly.cc bm_posy.cc bm_pulse.cc bm_pwl.cc bm_sffm.cc \
> bm_sin.cc bm_tanh.cc bmm_table.cc bmm_semi.cc bm_func.cc
and here bm_func.cc
// This file was built from bm_posy.cc written by Albert Davis
/* behavioral modeling - functions
* E1 (out 0 in 0) FUNC(3,5) exp=true means : out=e^(3*in+5)
* E1 (out 0 in 0) FUNC(314,-78.5) cos=true means : out=cos(314*in
-0,785) = sin(314*in)
* E1 (out 0 0 0) FUNC(4,5) xtime=true means : out=4*t+5 where t is the
time of the simultation
*/
#include "u_lang.h"
#include "globals.h"
#include "e_elemnt.h"
#include "bm.h"
/*--------------------------------------------------------------------------*/
namespace {
/*--------------------------------------------------------------------------*/
const bool _default_exp(false);
const bool _default_ln(false);
const bool _default_cos(false);
const bool _default_tan(false);
const bool _default_xtime(false);
/*--------------------------------------------------------------------------*/
class EVAL_BM_FUNC : public EVAL_BM_ACTION_BASE {
private:
PARAMETER<bool> _exp;
PARAMETER<bool> _ln;
PARAMETER<bool> _cos;
PARAMETER<bool> _tan;
PARAMETER<bool> _xtime;
std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > > _table;
explicit EVAL_BM_FUNC(const EVAL_BM_FUNC& p);
public:
explicit EVAL_BM_FUNC(int c=0);
~EVAL_BM_FUNC() {}
private: // override vitrual
bool operator==(const COMMON_COMPONENT&)const;
COMMON_COMPONENT* clone()const {return new EVAL_BM_FUNC(*this);}
void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const;
void elaborate(const COMPONENT*);
//COMMON_COMPONENT* deflate(); //COMPONENT_COMMON/nothing
void tr_eval(ELEMENT*)const;
//void ac_eval(ELEMENT*)const; //EVAL_BM_ACTION_BASE
//bool has_tr_eval()const; //EVAL_BM_BASE/true
//bool has_ac_eval()const; //EVAL_BM_BASE/true
std::string name()const {return "func";}
bool ac_too()const {untested();return false;}
bool parse_numlist(CS&);
bool parse_params_obsolete_callback(CS&);
};
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
EVAL_BM_FUNC::EVAL_BM_FUNC(int c)
:EVAL_BM_ACTION_BASE(c),
_exp(_default_exp),
_ln(_default_ln),
_cos(_default_cos),
_tan(_default_tan),
_xtime(_default_xtime),
_table()
{
}
/*--------------------------------------------------------------------------*/
EVAL_BM_FUNC::EVAL_BM_FUNC(const EVAL_BM_FUNC& p)
:EVAL_BM_ACTION_BASE(p),
_exp(p._exp),
_ln(p._ln),
_cos(p._cos),
_tan(p._tan),
_xtime(p._xtime),
_table(p._table)
{
}
/*--------------------------------------------------------------------------*/
bool EVAL_BM_FUNC::operator==(const COMMON_COMPONENT& x)const
{
const EVAL_BM_FUNC* p = dynamic_cast<const EVAL_BM_FUNC*>(&x);
bool rv = p
&& _exp == p->_exp
&& _ln == p->_ln
&& _cos == p->_cos
&& _tan == p->_tan
&& _xtime == p->_xtime
&& _table == p->_table
&& EVAL_BM_ACTION_BASE::operator==(x);
if (rv) {
untested();
}
return rv;
}
/*--------------------------------------------------------------------------*/
void EVAL_BM_FUNC::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE*
lang)const
{
assert(lang);
o << name() << '(';
for (std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > >::
const_iterator p = _table.begin(); p != _table.end(); ++p) {
o << p->second << ',' << p->first << ' ';
}
o << ')';
print_pair(o, lang, "exp", _exp, _exp.has_hard_value());
print_pair(o, lang, "ln", _ln, _ln.has_hard_value());
print_pair(o, lang, "cos", _cos, _cos.has_hard_value());
print_pair(o, lang, "tan", _tan, _tan.has_hard_value());
print_pair(o, lang, "xtime", _xtime, _xtime.has_hard_value());
EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang);
}
/*--------------------------------------------------------------------------*/
void EVAL_BM_FUNC::elaborate(const COMPONENT* c)
{
assert(c);
const CARD_LIST* par_scope = c->scope();
assert(par_scope);
EVAL_BM_ACTION_BASE::elaborate(c);
_exp.e_val(_default_exp, par_scope);
_ln.e_val(_default_ln, par_scope);
_cos.e_val(_default_cos, par_scope);
_tan.e_val(_default_tan, par_scope);
_xtime.e_val(_default_xtime, par_scope);
for (std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > >::
iterator p = _table.begin(); p != _table.end(); ++p) {
p->first.e_val(0, par_scope);
p->second.e_val(0, par_scope);
}
}
/*--------------------------------------------------------------------------*/
void EVAL_BM_FUNC::tr_eval(ELEMENT* d)const
{
double x_raw = (_xtime) ? ioffset(SIM::time0) : ioffset(d->_y[0].x);
double f0 = 0.; // value
double f1 = 0.; // derivative
// x = ax + b
std::vector<std::pair<PARAMETER<double>,PARAMETER<double> > >::
const_iterator p = _table.begin();
double x = p->second * x_raw + p->first;
f1 = p->second;
if(_exp) {
f0=exp(x);
f1*=f0;
} else if(_ln) { // use even
if(x>0) {
f0=log(x);
f1*=1/x;
} else if(x==0) {
f0=-BIGBIG;
f1=BIGBIG;
untested(); // why ?
} else {
f0=log(-x);
f1*=1/x;
}
} else if(_cos) {
f0=cos(x);
f1*=-sin(x);
} else if(_tan) {
f0=sin(x);
f1=cos(x);
if(f1==0.0) {
if(f0>0.0) f0=BIGBIG;
else f0=-BIGBIG;
f1=BIGBIG;
} else {
f0=f0/f1;
f1=1+f0*f0;
}
} else {
f0=x;
}
// end as in bm_posy
d->_y[0] = FPOLY1(ioffset(d->_y[0].x), f0, f1);
tr_final_adjust(&(d->_y[0]), d->f_is_value());
trace3("fa", d->_y[0].x, d->_y[0].f0, d->_y[0].f1);
}
/*--------------------------------------------------------------------------*/
bool EVAL_BM_FUNC::parse_numlist(CS& cmd)
{
unsigned start = cmd.cursor();
unsigned here = cmd.cursor();
for (;;) {
unsigned start_of_pair = here;
std::pair<PARAMETER<double>, PARAMETER<double> > p;
cmd >> p.second; // value
if (cmd.stuck(&here)) {
// no more, graceful finish
break;
}else{
cmd >> p.first; // key
if (cmd.stuck(&here)) {
// ran out, but already have half of the pair
// back up one, hoping somebody else knows what to do with it
cmd.reset(start_of_pair);
break;
}else{
_table.push_back(p);
}
}
}
if (cmd.gotit(start)) {
}else{
untested();
}
return cmd.gotit(start);
}
/*--------------------------------------------------------------------------*/
bool EVAL_BM_FUNC::parse_params_obsolete_callback(CS& cmd)
{
return ONE_OF
|| Get(cmd, "exp", &_exp)
|| Get(cmd, "ln", &_ln)
|| Get(cmd, "cos", &_cos)
|| Get(cmd, "tan", &_tan)
|| Get(cmd, "xtime", &_xtime)
|| EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd)
;
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
EVAL_BM_FUNC p1(CC_STATIC);
DISPATCHER<COMMON_COMPONENT>::INSTALL d1(&bm_dispatcher, "func", &p1);
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/