<?xml version="1.0" encoding="ISO-8859-1"?>

<!--
     Written by Laurent Lemaitre - r29173@users.sourceforge.net
     Documentation:
       http://sourceforge.net/docman/display_doc.php?docid=18993&group_id=84289
     Target Interface: ngspice
     Supported by adms-1.x.x
     This file is used by adms - http://sourceforge.net/projects/mot-adms.
     adms 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.
     adms 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 adms; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-->

<!DOCTYPE admst SYSTEM "admst.dtd">
<admst version="2.3.0" xmlns:admst="http://mot-adms.sourceforge.net/xml-files/admst">

<admst:template match="dectype">
  <admst:choose>
    <admst:when test="[type='real']">
      <admst:text format="  double "/>
    </admst:when>
    <admst:when test="[type='integer']">
      <admst:text format="  int "/>
    </admst:when>
    <admst:otherwise>
      <admst:text format="  char* "/>
    </admst:otherwise>
  </admst:choose>
</admst:template>

<admst:template match="code">
#define NGSPICE_DEBUG_OK

<admst:value-of select="attribute[name='ngspicename']/value"/>
<admst:variable name="module" select="%s"/>

#include &quot;ngspice/ngspice.h&quot;
#include &quot;ngspice/cktdefs.h&quot;
#include &quot;$(module)defs.h&quot;
#include &quot;ngspice/const.h&quot;
#include &quot;ngspice/trandefs.h&quot;
#include &quot;ngspice/sperror.h&quot;
#include &quot;ngspice/devdefs.h&quot;
#include &quot;ngspice/suffix.h&quot;

/*fixme: noise not implemented in ngspice*/
#define ngspice_flickernoise(p,n,mag,freq,info)\\
{\\
}
#define ngspice_whitenoise(p,n,mag,info)\\
{\\
}

#define NP(p) *(ckt-&gt;CKTrhsOld+here-&gt;p ## Node)
#define BP(p,n) (NP(p)-NP(n))
#define DBGNODE(p) printf(#p &quot;=%i - v=%e\\n&quot;,here-&gt;p ## Node,NP(p));

<admst:apply-templates select="." match="debug:strobe"/>

#define _STATIC
#define _DYNAMIC
#define _DERIVATE

#define _load_static_residual2(p,n,v)\\
  *(ckt->CKTrhs+here->p ## Node)-=v;\\
  *(ckt->CKTrhs+here->n ## Node)+=v;
#define _load_static_residual1(p,v)\\
  *(ckt->CKTrhs+here->p ## Node)-=v;

#define _load_static_jacobian4(Sp,Sn,Pp,Pn,v)\\
  _load_static_residual2(Sp,Sn,-v*BP(Pp,Pn))\\
  *(here->PTR_J_ ## Sp ## _ ## Pp)+=v;\\
  *(here->PTR_J_ ## Sn ## _ ## Pn)+=v;\\
  *(here->PTR_J_ ## Sp ## _ ## Pn)-=v;\\
  *(here->PTR_J_ ## Sn ## _ ## Pp)-=v;\\
  (here->JSVAL_ ## Sp ## _ ## Pp)+=v;\\
  (here->JSVAL_ ## Sn ## _ ## Pn)+=v;\\
  (here->JSVAL_ ## Sp ## _ ## Pn)-=v;\\
  (here->JSVAL_ ## Sn ## _ ## Pp)-=v;
#define _load_static_jacobian2s(Sp,Sn,Pp,v)\\
  _load_static_residual2(Sp,Sn,-v*NP(Pp))\\
  *(here->PTR_J_ ## Sp ## _ ## Pp)+=v;\\
  *(here->PTR_J_ ## Sn ## _ ## Pp)-=v;\\
  (here->JSVAL_ ## Sp ## _ ## Pp)+=v;\\
  (here->JSVAL_ ## Sn ## _ ## Pp)-=v;
#define _load_static_jacobian2p(Sp,Pp,Pn,v)\\
  _load_static_residual1(Sp,-v*BP(Pp,Pn))\\
  *(here->PTR_J_ ## Sp ## _ ## Pp)+=v;\\
  *(here->PTR_J_ ## Sp ## _ ## Pn)-=v;\\
  (here->JSVAL_ ## Sp ## _ ## Pp)+=v;\\
  (here->JSVAL_ ## Sp ## _ ## Pn)-=v;
#define _load_static_jacobian1(Sp,Pp,v)\\
  _load_static_residual1(Sp,-v*NP(Pp))\\
  *(here->PTR_J_ ## Sp ## _ ## Pp)+=v;\\
  (here->JSVAL_ ## Sp ## _ ## Pp)+=v;

#define _load_dynamic_residual2(p,n,v)\\
if(ChargeComputationNeeded)\\
{\\
  int error;\\
  double unused;\\
  *(ckt-&gt;CKTstate0+here-&gt;state_##p##_##n)=v;\\
  if(ckt-&gt;CKTmode &amp; MODEINITTRAN)\\
    *(ckt-&gt;CKTstate1+here-&gt;state_##p##_##n)=*(ckt-&gt;CKTstate0+here-&gt;state_##p##_##n);\\
  error = NIintegrate(ckt,&amp;unused,&amp;unused,0.0,here-&gt;state_##p##_##n);\\
  if(error) return(error);\\
  if(ckt-&gt;CKTmode &amp; MODEINITTRAN)\\
    *(ckt-&gt;CKTstate1+here-&gt;state_##p##_##n+1) = *(ckt-&gt;CKTstate0+here-&gt;state_##p##_##n+1);\\
  *(ckt->CKTrhs+here->p##Node)-=*(ckt-&gt;CKTstate0+here-&gt;state_##p##_##n+1);\\
  *(ckt->CKTrhs+here->n##Node)+=*(ckt-&gt;CKTstate0+here-&gt;state_##p##_##n+1);\\
}
#define _load_dynamic_residual1(p,v)\\
if(ChargeComputationNeeded)\\
{\\
  int error;\\
  double unused;\\
  *(ckt-&gt;CKTstate0+here-&gt;state_##p##_GND)=v;\\
  if(ckt-&gt;CKTmode &amp; MODEINITTRAN)\\
    *(ckt-&gt;CKTstate1+here-&gt;state_##p##_GND)=*(ckt-&gt;CKTstate0+here-&gt;state_##p##_GND);\\
  error = NIintegrate(ckt,&amp;unused,&amp;unused,0.0,here-&gt;state_##p##_GND);\\
  if(error) return(error);\\
  if(ckt-&gt;CKTmode &amp; MODEINITTRAN)\\
    *(ckt-&gt;CKTstate1+here-&gt;state_##p##_GND+1) = *(ckt-&gt;CKTstate0+here-&gt;state_##p##_GND+1);\\
  *(ckt->CKTrhs+here->p##Node)-=*(ckt-&gt;CKTstate0+here-&gt;state_##p##_GND+1);\\
}

#define _load_dynamic_jacobian4(Sp,Sn,Pp,Pn,v)\\
if(ChargeComputationNeeded)\\
{\\
  double geq=(v)*ckt->CKTag[0];\\
  double ceq=geq*BP(Pp,Pn);\\
  *(ckt->CKTrhs+here->Sp##Node)+=ceq;\\
  *(ckt->CKTrhs+here->Sn##Node)-=ceq;\\
  *(here->PTR_J_ ## Sp ## _ ## Pp)+=geq;\\
  *(here->PTR_J_ ## Sn ## _ ## Pn)+=geq;\\
  *(here->PTR_J_ ## Sp ## _ ## Pn)-=geq;\\
  *(here->PTR_J_ ## Sn ## _ ## Pp)-=geq;\\
}\\
  (here->JDVAL_ ## Sp ## _ ## Pp)+=v;\\
  (here->JDVAL_ ## Sn ## _ ## Pn)+=v;\\
  (here->JDVAL_ ## Sp ## _ ## Pn)-=v;\\
  (here->JDVAL_ ## Sn ## _ ## Pp)-=v;
#define _load_dynamic_jacobian2s(Sp,Sn,Pp,v)\\
if(ChargeComputationNeeded)\\
{\\
  double geq=(v)*ckt->CKTag[0];\\
  double ceq=geq*NP(Pp);\\
  *(ckt->CKTrhs+here->Sp##Node)+=ceq;\\
  *(ckt->CKTrhs+here->Sn##Node)-=ceq;\\
  *(here->PTR_J_ ## Sp ## _ ## Pp)+=geq;\\
  *(here->PTR_J_ ## Sn ## _ ## Pp)-=geq;\\
}\\
  (here->JDVAL_ ## Sp ## _ ## Pp)+=v;\\
  (here->JDVAL_ ## Sn ## _ ## Pp)-=v;
#define _load_dynamic_jacobian2p(Sp,Pp,Pn,v)\\
if(ChargeComputationNeeded)\\
{\\
  double geq=(v)*ckt->CKTag[0];\\
  double ceq=geq*BP(Pp,Pn);\\
  *(ckt->CKTrhs+here->Sp##Node)+=ceq;\\
  *(here->PTR_J_ ## Sp ## _ ## Pp)+=geq;\\
  *(here->PTR_J_ ## Sp ## _ ## Pn)-=geq;\\
}\\
  (here->JDVAL_ ## Sp ## _ ## Pp)+=v;\\
  (here->JDVAL_ ## Sp ## _ ## Pn)-=v;
#define _load_dynamic_jacobian1(Sp,Pp,v)\\
if(ChargeComputationNeeded)\\
{\\
  double geq=(v)*ckt->CKTag[0];\\
  double ceq=geq*NP(Pp);\\
  *(ckt->CKTrhs+here->Sp##Node)+=ceq;\\
  *(here->PTR_J_ ## Sp ## _ ## Pp)+=geq;\\
}\\
(here->JDVAL_ ## Sp ## _ ## Pp)+=v;

int $(module)load(GENmodel *inModel, CKTcircuit *ckt)
     /* actually load the current value into the 
      * sparse matrix previously provided 
      */
{
  $(module)model *model = ($(module)model*)inModel;
  $(module)instance *here;
  int ChargeComputationNeeded =  
                 ((ckt->CKTmode &amp; (MODEAC | MODETRAN | MODEINITSMSIG)) ||
                 ((ckt->CKTmode &amp; MODETRANOP) &amp;&amp; (ckt->CKTmode &amp; MODEUIC)))
                 ? 1 : 0;

  for ( ; model != NULL; model = $(module)nextModel(model) )
  {
    /* loop through all the instances of the model */
    for (here = $(module)instances(model); here != NULL ; here = $(module)nextInstance(here))
    {
{
<admst:for-each select="jacobian[static='yes']">
  <admst:value-of select="column/name"/>
  <admst:value-of select="row/name"/>
  <admst:text format="  here->JSVAL_%s_%s=0.0;\n"/>
</admst:for-each>
<admst:for-each select="jacobian[dynamic='yes']">
  <admst:value-of select="column/name"/>
  <admst:value-of select="row/name"/>
  <admst:text format="  here->JDVAL_%s_%s=0.0;\n"/>
</admst:for-each>
}
{
#include &quot;$module.hxx&quot;
}
    } /* End of Instance */
  } /* End of Model */
  return(OK);
}

</admst:template>

<!-- analog/![initializeModel|initializeInstance|initial_model|initial_instance|initial_step|noise] -->
<admst:template match="debug:strobe">
<admst:value-of select="attribute[name='ngspicename']/value"/>
<admst:variable name="module" select="%s"/>

  <admst:text format="static void $(module)debug (CKTcircuit *ckt, $(module)model *model, $(module)instance *here)\n"/>
  <admst:text format="{\n"/>
  <admst:for-each select="node[grounded='no']">
    <admst:value-of select="name"/>
    <admst:value-of select="name"/>
    <admst:text format="  fprintf(stdout,&quot;voltage: %s=%%e\\n&quot;,NP(%s));\n"/>
  </admst:for-each>
  <admst:for-each select="variable[input='yes']">
    <admst:choose>
      <admst:when test="[type='integer']">
        <admst:apply-templates select="." match="variable"/>
        <admst:value-of select="/simulator/tmp"/>
        <admst:value-of select="name"/>
        <admst:value-of select="parametertype"/>
        <admst:text format="  fprintf(stdout,&quot;Parameter: %s: %s=%%i\\n&quot;,%s);\n"/>
      </admst:when>
      <admst:when test="[type='real']">
        <admst:apply-templates select="." match="variable"/>
        <admst:value-of select="/simulator/tmp"/>
        <admst:value-of select="name"/>
        <admst:value-of select="parametertype"/>
        <admst:text format="  fprintf(stdout,&quot;Parameter: %s: %s=%%e\\n&quot;,%s);\n"/>
      </admst:when>
    </admst:choose>
  </admst:for-each>
  <admst:for-each select="variable[input='no' and scope='global_model' and setinmodel='yes' and insource='yes']">
    <admst:choose>
      <admst:when test="[type='integer']">
        <admst:apply-templates select="." match="variable"/>
        <admst:value-of select="/simulator/tmp"/>
        <admst:value-of select="name"/>
        <admst:text format="  fprintf(stdout,&quot;model: %s=%%i\\n&quot;,%s);\n"/>
      </admst:when>
      <admst:when test="[type='real']">
        <admst:apply-templates select="." match="variable"/>
        <admst:value-of select="/simulator/tmp"/>
        <admst:value-of select="name"/>
        <admst:text format="  fprintf(stdout,&quot;model: %s=%%e\\n&quot;,%s);\n"/>
      </admst:when>
    </admst:choose>
  </admst:for-each>
  <admst:for-each select="variable[input='no' and scope='global_instance' and setininstance='yes' and insource='yes']">
    <admst:choose>
      <admst:when test="[type='integer']">
        <admst:apply-templates select="." match="variable"/>
        <admst:value-of select="/simulator/tmp"/>
        <admst:value-of select="name"/>
        <admst:text format="  fprintf(stdout,&quot;instance: %s=%%i\\n&quot;,%s);\n"/>
      </admst:when>
      <admst:when test="[type='real']">
        <admst:apply-templates select="." match="variable"/>
        <admst:value-of select="/simulator/tmp"/>
        <admst:value-of select="name"/>
        <admst:text format="  fprintf(stdout,&quot;instance: %s=%%e\\n&quot;,%s);\n"/>
      </admst:when>
    </admst:choose>
  </admst:for-each>
  <admst:text format="}\n"/>
</admst:template>

<admst:template match="analog:evaluate">
  <admst:if test="code">
    <admst:assert test="code/adms[datatypename='block']" format="expecting datatypename=block\n"/>
    <admst:for-each select="code/item">
      <admst:if test="adms[datatypename='block']">
        <admst:if test="[name!='initial_model' and name!='initial_instance' and name!='initializeModel' and name!='initializeInstance'
           and name!='initial_step']">
          <admst:apply-templates select="." match="block:local:declaration"/>
        </admst:if>
      </admst:if>
      <admst:if test="adms[datatypename!='block']">
        <admst:apply-templates select="." match="block:local:declaration"/>
      </admst:if>
    </admst:for-each>
    <admst:apply-templates select="code" match="variable:declaration"/>
    <admst:for-each select="code/item">
      <admst:choose>
        <admst:when test="adms[datatypename!='block']">
          <admst:value-of select="./adms/datatypename"/>
          <admst:apply-templates select="." match="%s"/>
        </admst:when>
        <admst:otherwise>
        <admst:if test="[name!='initial_model' and name!='initial_instance' and name!='initializeModel' and name!='initializeInstance'
             and name!='initial_step']">
            <admst:apply-templates select="." match="block"/>
          </admst:if>
        </admst:otherwise>
      </admst:choose>
    </admst:for-each>
  </admst:if>
</admst:template>

<admst:for-each select="/module">
  <admst:value-of select="attribute[name='ngspicename']/value"/>
  <admst:open file="%sload.c">
    <admst:text format="/***\n*** Interface: %(/simulator/package_string)\n"/>
    <admst:text format=" *** created by: %(/simulator/fullname) ***/\n"/>
    <admst:apply-templates select="." match="code"/>
  </admst:open>
  <admst:value-of select="attribute[name='ngspicename']/value"/>
  <admst:message format="%sload.c: file created\n"/>
</admst:for-each>

</admst>
