46 #include <Xyce_config.h>
53 #include <N_UTL_Misc.h>
57 #include <N_LAS_Vector.h>
58 #include <N_LAS_Matrix.h>
73 std::vector<std::string> & currentEqus, std::vector<std::string> & indepVars, std::vector<std::string> & fEqs,
74 std::vector<std::string> & qEqs, std::vector<std::string> & extraFunctions, std::vector<std::string> & extraParameters) :
79 currentEqus_(currentEqus),
80 indepVars_(indepVars),
83 extraFunctions_(extraFunctions),
84 extraParameters_(extraParameters)
112 std::vector< std::vector< int > > & segmentJacStamp )
133 std::map<std::string,int>::iterator currVarOffset =
indepVarOffset_.begin();
134 std::map<std::string,int>::iterator endVarOffset =
indepVarOffset_.end();
136 while( currVarOffset != endVarOffset )
138 std::set<std::string> depVarNames;
140 if( currVarOffset->first ==
"V" )
171 std::set<std::string>::iterator depVarNamesEnd = depVarNames.end();
173 std::map< std::string, int > tmpIndVarMap;
175 for(
int i=0; i<numEnteries; i++)
181 Xyce::dout() <<
"Assigned tmpIndVarMap[ " << offsetToIndepVar_[i] <<
" ]= " << (numFound-1) << std::endl;
186 Xyce::dout() <<
"tmpIndVarMap assigned to variable " << currVarOffset->first << std::endl;
194 if( currVarOffset->first !=
"V" )
196 segmentJacStamp[offset + currVarOffset->second ].resize( numvars );
200 std::set<std::string>::iterator depVarNamesCurr = depVarNames.begin();
201 while( depVarNamesCurr != depVarNamesEnd )
203 if( currVarOffset->first ==
"V" )
205 segmentJacStamp[offset + currVarOffset->second ][ vOffset+
systemJacOffset_[currVarOffset->second ][*depVarNamesCurr ]] = offset +
indepVarOffset_[*depVarNamesCurr];
209 segmentJacStamp[offset + currVarOffset->second ][
systemJacOffset_[currVarOffset->second ][*depVarNamesCurr ]] = offset +
indepVarOffset_[*depVarNamesCurr];
218 Xyce::dout() <<
"MembraneUserDefined::setJacStamp() jacStamp = " << std::endl;
219 for(
int i = 0; i<segmentJacStamp.size(); ++i )
221 Xyce::dout() <<
"jacStamp[ " << i <<
" ] = { ";
222 for(
int j=0; j<segmentJacStamp[i].size(); ++j)
224 Xyce::dout() << segmentJacStamp[i][j];
225 if( j != ( segmentJacStamp[i].size() -1 ) )
227 Xyce::dout() <<
", ";
230 Xyce::dout() <<
" }" << std::endl;
232 Xyce::dout() << Xyce::section_divider << std::endl;
234 Xyce::dout() <<
"MembraneUserDefined::setJacStamp() systemJacOffset_ = " << std::endl;
237 Xyce::dout() <<
"systemJacOffset[ " << i <<
" ] = { ";
238 std::map<std::string,int>::iterator currVarOffset =
systemJacOffset_[i].begin();
239 std::map<std::string,int>::iterator endVarOffset =
systemJacOffset_[i].end();
240 while( currVarOffset != endVarOffset )
242 Xyce::dout() << currVarOffset->first <<
", " << currVarOffset->second << std::endl;
245 Xyce::dout() <<
" }" << std::endl;
247 Xyce::dout() << Xyce::section_divider << std::endl;
262 std::vector< int > & lidIndexVector,
263 N_LAS_Vector * solnVecPtr,
264 N_LAS_Vector * daeQVecPtr,
270 (*daeQVecPtr)[lidIndexVector[index]] +=
cMem_ * segArea * (*solnVecPtr)[lidIndexVector[index]];
272 Xyce::dout() <<
"loadDAEQVector: entry for index " << index <<
" : " <<
cMem_ * segArea * (*solnVecPtr)[lidIndexVector[index]] << std::endl;
276 for(
int i=0; i<numExp; i++)
280 for(
int j=0; j<numvars; j++)
285 double resultValue=0.0;
292 int lidIndexVectorIndex = index + i + 1;
293 (*daeQVecPtr)[lidIndexVector[lidIndexVectorIndex]] += resultValue;
294 Xyce::dout() <<
"loadDAEQVector: entry for LID index " << lidIndexVectorIndex
295 <<
", varname " <<
offsetToIndepVar_[lidIndexVectorIndex-index] <<
" : " << resultValue << std::endl;
310 std::vector< int > & lidIndexVector,
311 N_LAS_Vector * solnVecPtr,
312 N_LAS_Vector * daeFVecPtr,
315 Xyce::dout() <<
"loadDAEFVector" << std::endl;
320 (*daeFVecPtr)[lidIndexVector[index]] +=
gMem_ * segArea * ((*solnVecPtr)[lidIndexVector[index]] -
vRest_ );
327 for(
int i=0; i<numCurrentExp; i++)
329 Xyce::dout() <<
"membrane V equation contribution from current equation # " << i << std::endl;
332 for(
int j=0; j<numvars; j++)
335 Xyce::dout() <<
"Segment " << segmentNumber <<
" current load variable = " << currentEqusVarNames_[i][j] <<
" value = " <<
currentEqusVarValues_[i][j] << std::endl;
338 double resultValue=0.0;
340 Xyce::dout() <<
"Segment " << segmentNumber <<
" current equ F = " << resultValue << std::endl;
344 (*daeFVecPtr)[lidIndexVector[index]] += segArea*resultValue;
349 for(
int i=0; i<numExp; i++)
351 Xyce::dout() <<
"F terms from f equation # " << i << std::endl;
354 for(
int j=0; j<numvars; j++)
357 Xyce::dout() <<
"Segment " << segmentNumber <<
" extra var load variable = " << fEqsEqusVarNames_[i][j] <<
" value = " <<
fEqsEqusVarValues_[i][j] << std::endl;
360 double resultValue=0.0;
365 int lidIndexVectorIndex = index + i + 1;
366 (*daeFVecPtr)[lidIndexVector[lidIndexVectorIndex]] += resultValue;
367 Xyce::dout() <<
"Segment " << segmentNumber <<
" LID index " << lidIndexVectorIndex
368 <<
", extra vars equ F = " << resultValue << std::endl;
382 std::vector< int > & lidIndexVector,
383 std::vector< std::vector< int > > & jacobianOffsets,
384 N_LAS_Vector * solnVecPtr,
385 N_LAS_Matrix * dQdxMatPtr,
388 Xyce::dout() <<
"loadDAEdQdx" << std::endl;
402 (*dQdxMatPtr)[lidIndexVector[index]][jacobianOffsets[row][vOffset]] +=
cMem_ * segArea;
409 for(
int i=0; i<numExp; i++)
412 Xyce::dout() <<
"Q terms for q equation " << i <<
"; assumed to be for variable " << targetVarName << std::endl;
415 for(
int j=0; j<numvars; j++)
418 Xyce::dout() <<
"contribution from " << qEqsEqusVarNames_[i][j] <<
": " <<
qEqsEqusVarValues_[i][j] << std::endl;
421 double resultValue=0.0;
422 std::vector<double> derivValues;
423 derivValues.resize( numvars );
425 Xyce::dout() <<
"expression result: " << resultValue << std::endl;
428 for(
int j=0; j<numvars; j++)
431 Xyce::dout() <<
"contribution of variable " << j <<
"(" << varName <<
")" << std::endl;
433 int targetVarIndex = index + targetVarOffset;
434 int targetVarRow = row + targetVarOffset;
436 Xyce::dout() <<
"targerVarOffset: " << targetVarOffset <<
", targetVarIndex: " << targetVarIndex
437 <<
", jacobianRow: " << targetVarRow <<
", jacobianCol: " << jacOffsetsCol << std::endl;
438 (*dQdxMatPtr)[lidIndexVector[targetVarIndex]][jacobianOffsets[targetVarRow][jacOffsetsCol]] += derivValues[j];
439 Xyce::dout() <<
"adding (*dQdxMatPtr)[ " << lidIndexVector[targetVarIndex] <<
" ][ " << jacobianOffsets[targetVarRow][jacOffsetsCol] <<
" ] = " << derivValues[j] << std::endl;
453 std::vector< int > & lidIndexVector,
454 std::vector< std::vector< int > > & jacobianOffsets,
455 N_LAS_Vector * solnVecPtr,
456 N_LAS_Matrix * dFdxMatPtr,
459 Xyce::dout() <<
"loadDAEdFdx" << std::endl;
473 (*dFdxMatPtr)[lidIndexVector[index]][jacobianOffsets[row][vOffset]] +=
gMem_ * segArea;
474 Xyce::dout() <<
"leak current dFdx: " <<
"vOffset = " << vOffset <<
" row = " << row << std::endl;
475 Xyce::dout() <<
"adding (*dFdxMatPtr)[ " << lidIndexVector[index] <<
" ][ " << jacobianOffsets[row][vOffset ] <<
" ] = " <<
gMem_ * segArea << std::endl;
479 for(
int i=0; i<numCurrentEq; i++)
483 for(
int j=0; j<numvars; j++)
488 double resultValue=0.0;
489 std::vector<double> derivValues;
490 derivValues.resize( numvars );
495 for(
int j=0; j<numvars; j++)
498 Xyce::dout() <<
"contribution of variable " << j <<
"(" << varName <<
") to V" << std::endl;
502 Xyce::dout() <<
" jacOffsetsRow: " << row <<
" jacOffsetsCol: " << jacOffsetsCol << std::endl;
504 (*dFdxMatPtr)[lidIndexVector[index]][ jacobianOffsets[row][jacOffsetsCol] ] += segArea*derivValues[j];
505 Xyce::dout() <<
"adding (*dFdxMatPtr)[ " << lidIndexVector[index] <<
" ][ " << jacobianOffsets[row][jacOffsetsCol] <<
" ] = " << segArea*derivValues[j] << std::endl;
511 for(
int i=0; i<numExp; i++)
514 Xyce::dout() <<
"F terms for f equation " << i <<
"; assumed to be for variable " << targetVarName << std::endl;
517 for(
int j=0; j<numvars; j++)
522 double resultValue=0.0;
523 std::vector<double> derivValues;
524 derivValues.resize( numvars );
528 for(
int j=0; j<numvars; j++)
531 Xyce::dout() <<
"contribution of variable " << j <<
"(" << varName <<
")" << std::endl;
533 int targetVarIndex = index + targetVarOffset;
534 int targetVarRow = row + targetVarOffset;
536 Xyce::dout() <<
"targetVarOffset: " << targetVarOffset <<
" targetVarIndex: " << targetVarIndex
537 <<
", jacOffsetsRow: " << targetVarRow <<
" jacOffsetsCol: " << jacOffsetsCol << std::endl;
538 (*dFdxMatPtr)[lidIndexVector[targetVarIndex]][ jacobianOffsets[targetVarRow][jacOffsetsCol] ] += derivValues[j];
539 Xyce::dout() <<
"Adding (*dFdxMatPtr)[ " << lidIndexVector[targetVarIndex] <<
" ][ " << jacobianOffsets[targetVarRow][jacOffsetsCol] <<
" ] = " << derivValues[j] << std::endl;
554 int numStrings = stringInput.size();
555 for(
int i=0; i<numStrings; i++ )
558 expRCPOut.push_back( rcp(
new Util::Expression( stringInput.at(i) ) ) );
588 for(
int i=0; i<numParams; i+=2)
590 std::vector<std::string> names;
593 if( names.size() > 1 )
595 Xyce::dout() <<
"Warning MembraneUserDefined::consolidateExpressions() parameter name vec longer than expected." << names.size() << std::endl;
605 for(
int i=0; i<numFuncs; i+=2 )
607 std::vector<std::string> names;
646 Xyce::dout() <<
"Currentequ = " <<
currentEqusExpRCP_.at(i)->get_expression() << std::endl;
651 Xyce::dout() <<
"F: " <<
fEqsExpRCP_.at(i)->get_expression() <<
" Q: " <<
qEqsExpRCP_.at(i)->get_expression() << std::endl;
652 double fval=0, qval=0;
653 std::vector<double> fargs, qargs;
654 fargs.push_back(0.2); fargs.push_back(-0.015); qargs.push_back(0.2);
657 Xyce::dout() <<
"F(V=-0.015,n/m/h=0.2) = " << fval <<
" Q(V=-0.015,n/m/h=0.2) = " << qval << std::endl;
677 for(
int i=0; i<numParams; i++)
679 int numExp = expRCP_.size();
680 for(
int j=0; j<numExp; j++ )
699 for(
int i=0; i<numFuncs; i++)
701 int numExp = expRCP_.size();
702 for(
int j=0; j<numExp; j++ )
728 for(
int i=0; i<numIndependentVars; i++ )
730 std::vector<std::string> expNames;
732 int numExpNames=expNames.size();
733 for(
int j=0; j<numExpNames; j++ )
735 Xyce::dout() <<
"makeSymbolSet, i=" <<i <<
", j="<<j <<
": adding " << expNames.at(j) <<
" to userDefinedNames" << std::endl;
752 while( currName != endName )
766 Xyce::dout() <<
"MembraneUserDefined::makeSymbolSet() Independent var offset map : " << std::endl;
767 std::map<std::string,int>::iterator currVarOffset =
indepVarOffset_.begin();
768 std::map<std::string,int>::iterator endVarOffset =
indepVarOffset_.end();
769 while( currVarOffset != endVarOffset )
771 Xyce::dout() <<
"map[ " << currVarOffset->first <<
" ] = " << currVarOffset->second << std::endl;
776 while( currOffset != endOffset )
778 Xyce::dout() <<
"inv-map[ " << currOffset->first <<
" ] = " << currOffset->second << std::endl;
799 int numExp = expRCP.size();
802 expNamesVec.resize( numExp );
803 expValsVec.resize( numExp );
805 for(
int i=0; i<numExp; i++ )
808 std::vector<std::string> expNamesTmp;
809 expRCP.at(i)->get_names( type, expNamesTmp );
810 int numExpNames=expNamesTmp.size();
811 for(
int j=0; j<numExpNames; j++ )
817 if( findResult != endName )
820 expRCP.at(i)->make_var( expNamesTmp.at(j) );
822 expNamesVec[i].push_back( expNamesTmp.at(j) );
826 Xyce::dout() <<
"Warning symbol \"" << expNamesTmp.at(j) <<
"\" not listed in independent variables. Ignoring for now." << std::endl;
830 expValsVec[i].resize( expNamesVec[i].size() );
832 Xyce::dout() <<
"MembraneUserDefined::convertSymbolsToVars: expression " << expRCP.at(i)->get_expression() <<
" Has vars: ";
833 std::vector<std::string>::iterator cni = expNamesVec[i].begin();
834 std::vector<std::string>::iterator eni = expNamesVec[i].end();
837 Xyce::dout() << *cni <<
", ";
840 Xyce::dout() << std::endl;