In my memristor model, I'm including a window function like this:
template <typename ScalarT>
void X_var_F( const ScalarT & V1, const ScalarT & V2, const ScalarT & X, const ScalarT & UV, const ScalarT & RON, const ScalarT & ROFF, const ScalarT & D, const ScalarT & PCOEFF, ScalarT & fval ){
fval = UV*RON/D/D/(RON * X + ROFF * (1 - X))*(V1-V2)*(1.0 - pow( (2.0*X - 1.0), 2.0*PCOEFF.val() ));
}
,where the last major term is the window. If I don't use `PCOEFF.val()`, but instead `PCOEFF.val()`, then `fval` =
fval = 0 [ nan nan nan ]
, which stops the sim in it's tracks. Otherwise, with .val(), I get:
fval = 0 [ 2.5e-11 -2.5e-11 0 ]
, which is correct. In the TEAM model, the window functions all use the non- .val(). Those TEAM memristor simulations are also not working for me, failing at the DCOP step, and I suspect this is why.
Any idea what's going on?
P = 2 [ 0 0 0 ]
X = 0.001 [ 0 0 1 ]
fval = 0.00797603 [ nan nan nan ]
ri.xVarFContribution = 0
ri.dxFEqdVpos = nan
ri.dxFEqdVneg = nan
ri.dxFEqdx = nan
template <typename ScalarT>
void JogelkarWindowFunction( const ScalarT & X, const ScalarT & P, ScalarT & fval )
{
fval = 1.0 - pow( (2.0*X - 1.0), (2*P) );
if (DEBUG_DEVICE){
Xyce::dout() << " P = " << P << std::endl;
Xyce::dout() << " X = " << X << std::endl;
Xyce::dout() << " fval = " << fval << std::endl;
}
}
// linear current voltage model, Reff
template <typename ScalarT>
void Reff( const ScalarT & X, const ScalarT & RON, const ScalarT & ROFF, ScalarT & fval )
{
fval = RON * X + ROFF * (1 - X);
}
template <typename ScalarT>
void X_var_F( const ScalarT & V1, const ScalarT & V2, const ScalarT & X, const ScalarT & UV, const ScalarT & RON, const ScalarT & ROFF, const ScalarT & D, const ScalarT & P, ScalarT & fval ){
ScalarT Rval;
Reff( X, RON, ROFF, Rval );
ScalarT Windowval;
JogelkarWindowFunction(X, P, Windowval );
fval = UV*RON/D/D/Rval*(V1-V2)*Windowval;
}
Master:updateState
{
// evaluate the state variable equation
//Sacado::Fad::SFad<double,2> varDeltaV( 2, 0, (v_pos-v_neg) );
Sacado::Fad::SFad<double,3> varV1( 3, 0, v_pos );
Sacado::Fad::SFad<double,3> varV2( 3, 1, v_neg );
Sacado::Fad::SFad<double,3> varX( 3, 2, x );
Sacado::Fad::SFad<double,3> paramUV( ri.model_.uv_ );
Sacado::Fad::SFad<double,3> paramD( ri.model_.D_ );
Sacado::Fad::SFad<double,3> paramRON( ri.model_.Ron_ );
Sacado::Fad::SFad<double,3> paramROFF( ri.model_.Roff_ );
Sacado::Fad::SFad<double,3> paramP( ri.model_.p_ );
Sacado::Fad::SFad<double,3> resultFad;
X_var_F( varV1, varV2, varX, paramUV, paramRON, paramROFF, paramD, paramP, resultFad );
ri.xVarFContribution = resultFad.val();
ri.dxFEqdVpos = resultFad.dx(0);
ri.dxFEqdVneg = resultFad.dx(1);
ri.dxFEqdx = resultFad.dx(2);
if (DEBUG_DEVICE){
Xyce::dout() << " ri.xVarFContribution = " << ri.xVarFContribution << std::endl;
Xyce::dout() << " ri.dxFEqdVpos = " << ri.dxFEqdVpos << std::endl;
Xyce::dout() << " ri.dxFEqdVneg = " << ri.dxFEqdVneg << std::endl;
Xyce::dout() << " ri.dxFEqdx = " << ri.dxFEqdx << std::endl;
}
}
P = 2 [ 0 0 0 ]
X = 0.001 [ 0 0 1 ]
fval = 0.00797603 [ nan nan nan ]
ri.xVarFContribution = 0
ri.dxFEqdVpos = nan
ri.dxFEqdVneg = nan
ri.dxFEqdx = nan
template <typename ScalarT>
void JogelkarWindowFunction( const ScalarT & X, const ScalarT & P, ScalarT & fval )
{
fval = 1.0 - pow( (2.0*X - 1.0), (2*P) );
if (DEBUG_DEVICE){
Xyce::dout() << " P = " << P << std::endl;
Xyce::dout() << " X = " << X << std::endl;
Xyce::dout() << " fval = " << fval << std::endl;
}
}
// linear current voltage model, Reff
template <typename ScalarT>
void Reff( const ScalarT & X, const ScalarT & RON, const ScalarT & ROFF, ScalarT & fval )
{
fval = RON * X + ROFF * (1 - X);
}
template <typename ScalarT>
void X_var_F( const ScalarT & V1, const ScalarT & V2, const ScalarT & X, const ScalarT & UV, const ScalarT & RON, const ScalarT & ROFF, const ScalarT & D, const ScalarT & P, ScalarT & fval ){
ScalarT Rval;
Reff( X, RON, ROFF, Rval );
ScalarT Windowval;
JogelkarWindowFunction(X, P, Windowval );
fval = UV*RON/D/D/Rval*(V1-V2)*Windowval;
}
{
// evaluate the state variable equation
template <typename ScalarT>
ScalarT JogelkarWindowFunction( const ScalarT & X, double P)
{
ScalarT fval;
fval = 1.0 - pow( (2.0*X - 1.0), (2*P) );
if (DEBUG_DEVICE){
Xyce::dout() << " P = " << P << std::endl;
Xyce::dout() << " X = " << X << std::endl;
Xyce::dout() << " fval = " << fval << std::endl;
}
return fval;
}
// linear current voltage model, Reff
template <typename ScalarT>
ScalarT Reff( const ScalarT & X, double RON, double ROFF)
{
return(RON * X + ROFF * (1 - X));
}
template <typename ScalarT>
ScalarT X_var_F( const ScalarT & V1, const ScalarT & V2, const ScalarT & X,
double UV, double RON, double ROFF, double D, double P){
ScalarT Rval=Reff( X, RON, ROFF );
ScalarT Windowval=JogelkarWindowFunction(X, P);
return(UV*RON/D/D/Rval*(V1-V2)*Windowval);
}
// evaluate the state variable equation
Sacado::Fad::SFad<double,3> varV1( 3, 0, v_pos );
Sacado::Fad::SFad<double,3> varV2( 3, 1, v_neg );
Sacado::Fad::SFad<double,3> varX( 3, 2, x );
Sacado::Fad::SFad<double,3> resultFad;
resultFad = X_var_F( varV1, varV2, varX, ri.model_.uv_, ri.model_.Ron_, ri.model_.Roff_, ri.model_.D_, ri.model_.p_);