help-gnucap
[Top][All Lists]
Advanced

[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);
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/









reply via email to

[Prev in Thread] Current Thread [Next in Thread]