54 vector< Id > adjacent;
56 if ( adjacent.size() > 1 )
57 while ( !adjacent.empty() )
67 vector< vector< Id > > cstack;
71 cstack[ 0 ].push_back( seed );
72 while ( !cstack.empty() )
74 vector< Id >& top = cstack.back();
79 if ( !cstack.empty() )
80 cstack.back().pop_back();
84 if ( cstack.size() > 1 )
85 above = cstack[ cstack.size() - 2 ].back();
90 cstack.resize( cstack.size() + 1 );
104 double Vm, Cm, Em, Rm, inject;
105 double EmLeak, GmLeak;
106 double EmGmThev, GmThev;
108 vector< Id > leakage;
109 vector< Id >::iterator ileakage;
142 for ( ileakage = leakage.begin();
143 ileakage != leakage.end();
149 EmGmThev += EmLeak * GmLeak;
156 compartment.
EmByRm = EmGmThev;
161 inject_[ ic ].injectVarying = 0.0;
162 inject_[ ic ].injectBasal = inject;
169 double Ra, Rm, Cm, Em, initVm;
172 map< Id, unsigned int > hinesIndex;
173 for (
unsigned int ic = 0; ic <
nCompt_; ++ic )
176 vector< Id > childId;
177 vector< Id >::iterator child;
179 vector< Id >::iterator ic;
194 for ( child = childId.begin(); child != childId.end(); ++child )
195 node.
children.push_back( hinesIndex[ *child ] );
203 tree_.push_back( node );
217 if (
HJ_.size() != 0 )
218 memcpy( &
HJ_[ 0 ], &
HJCopy_[ 0 ],
sizeof(
double ) *
HJ_.size() );
220 vector< double >::iterator ihs =
HS_.begin();
221 vector< double >::iterator iv =
V_.begin();
223 vector< CompartmentStruct >::iterator ic;
227 *( 3 + ihs ) = *iv * ic->CmByDt + ic->EmByRm;
232 map< unsigned int, InjectStruct >::iterator inject;
233 for ( inject =
inject_.begin(); inject !=
inject_.end(); inject++ )
235 unsigned int ic = inject->first;
249 vector< double >::iterator ihs =
HS_.begin();
250 vector< vdIterator >::iterator iop =
operand_.begin();
251 vector< JunctionStruct >::iterator junction;
261 index = junction->index;
262 rank = junction->rank;
266 *( ihs + 4 ) -= *( ihs + 1 ) / *ihs **( ihs + 1 );
267 *( ihs + 7 ) -= *( ihs + 1 ) / *ihs **( ihs + 3 );
278 division = *( j + 1 ) / pivot;
279 *( s ) -= division **j;
280 *( s + 3 ) -= division **( ihs + 3 );
284 else if ( rank == 2 )
290 division = *( j + 1 ) / pivot;
291 *( s ) -= division **j;
292 *( j + 4 ) -= division **( j + 2 );
293 *( s + 3 ) -= division **( ihs + 3 );
296 division = *( j + 3 ) / pivot;
297 *( j + 5 ) -= division **j;
298 *( s ) -= division **( j + 2 );
299 *( s + 3 ) -= division **( ihs + 3 );
305 vector< vdIterator >::iterator
306 end = iop + 3 * rank * ( rank + 1 );
307 for ( ; iop < end; iop += 3 )
308 **iop -= **( iop + 2 ) / pivot ***( iop + 1 );
316 *( ihs + 4 ) -= *( ihs + 1 ) / *ihs **( ihs + 1 );
317 *( ihs + 7 ) -= *( ihs + 1 ) / *ihs **( ihs + 3 );
328 vector< double >::reverse_iterator ivmid =
VMid_.rbegin();
329 vector< double >::reverse_iterator iv =
V_.rbegin();
330 vector< double >::reverse_iterator ihs =
HS_.rbegin();
331 vector< vdIterator >::reverse_iterator iop =
operand_.rbegin();
332 vector< vdIterator >::reverse_iterator ibop =
backOperand_.rbegin();
333 vector< JunctionStruct >::reverse_iterator junction;
335 *ivmid = *ihs / *( ihs + 3 );
336 *iv = 2 * *ivmid - *iv;
337 --ic, ++ivmid, ++iv, ihs += 4;
345 index = junction->index;
346 rank = junction->rank;
350 *ivmid = ( *ihs - *( ihs + 2 ) **( ivmid - 1 ) ) / *( ihs + 3 );
351 *iv = 2 * *ivmid - *iv;
353 --ic, ++ivmid, ++iv, ihs += 4;
358 *ivmid = ( *ihs - **iop ***( iop + 2 ) ) / *( ihs + 3 );
362 else if ( rank == 2 )
378 for (
int i = 0; i < rank; ++i )
380 *ivmid -= **ibop ***( ibop + 1 );
383 *ivmid /= *( ihs + 3 );
385 iop += 3 * rank * ( rank + 1 );
388 *iv = 2 * *ivmid - *iv;
389 --ic, ++ivmid, ++iv, ihs += 4;
394 *ivmid = ( *ihs - *( ihs + 2 ) **( ivmid - 1 ) ) / *( ihs + 3 );
395 *iv = 2 * *ivmid - *iv;
397 --ic, ++ivmid, ++iv, ihs += 4;
431 bool isClose( T a, T b, T tolerance )
433 T epsilon = std::numeric_limits< T >::epsilon();
438 if ( a == 0 || b == 0 )
439 return ( fabs( a - b ) < tolerance * epsilon );
442 fabs( ( a - b ) / a ) < tolerance * epsilon
444 fabs( ( a - b ) / b ) < tolerance * epsilon
449 #include "../shell/Shell.h"
450 #include "../basecode/global.h"
452 void testHSolvePassive()
457 vector< int* > childArray;
458 vector< unsigned int > childArraySize;
480 int childArray_1[ ] =
504 childArray.push_back( childArray_1 );
505 childArraySize.push_back(
sizeof( childArray_1 ) /
sizeof(
int ) );
519 int childArray_2[ ] =
527 childArray.push_back( childArray_2 );
528 childArraySize.push_back(
sizeof( childArray_2 ) /
sizeof(
int ) );
542 int childArray_3[ ] =
550 childArray.push_back( childArray_3 );
551 childArraySize.push_back(
sizeof( childArray_3 ) /
sizeof(
int ) );
565 int childArray_4[ ] =
573 childArray.push_back( childArray_4 );
574 childArraySize.push_back(
sizeof( childArray_4 ) /
sizeof(
int ) );
589 int childArray_5[ ] =
599 childArray.push_back( childArray_5 );
600 childArraySize.push_back(
sizeof( childArray_5 ) /
sizeof(
int ) );
615 int childArray_6[ ] =
626 childArray.push_back( childArray_6 );
627 childArraySize.push_back(
sizeof( childArray_6 ) /
sizeof(
int ) );
633 int childArray_7[ ] =
638 childArray.push_back( childArray_7 );
639 childArraySize.push_back(
sizeof( childArray_7 ) /
sizeof(
int ) );
645 int childArray_8[ ] =
652 childArray.push_back( childArray_8 );
653 childArraySize.push_back(
sizeof( childArray_8 ) /
sizeof(
int ) );
659 int childArray_9[ ] =
666 childArray.push_back( childArray_9 );
667 childArraySize.push_back(
sizeof( childArray_9 ) /
sizeof(
int ) );
681 vector< vector< double > > matrix;
687 vector< TreeNodeStruct > tree;
691 vector< double > VMid;
701 unsigned int arraySize;
702 for (
unsigned int cell = 0; cell < childArray.size(); cell++ )
704 array = childArray[ cell ];
705 arraySize = childArraySize[ cell ];
706 nCompt = count( array, array + arraySize, -1 );
712 tree.resize( nCompt );
715 for ( i = 0; i < nCompt; i++ )
717 tree[ i ].Ra = 15.0 + 3.0 * i;
718 tree[ i ].Rm = 45.0 + 15.0 * i;
719 tree[ i ].Cm = 500.0 + 200.0 * i * i;
720 Em.push_back( -0.06 );
721 V.push_back( -0.06 + 0.01 * i );
725 for (
unsigned int a = 0; a < arraySize; a++ )
726 if ( array[ a ] == -1 )
729 tree[ count ].children.push_back( array[ a ] );
736 vector< Id > c( nCompt );
737 for ( i = 0; i < nCompt; i++ )
741 c[ i ] = shell->
doCreate(
"Compartment", n, name.str() , 1);
751 for ( i = 0; i < nCompt; i++ )
753 vector< unsigned int >& child = tree[ i ].children;
754 for ( j = 0; j < ( int )( child.size() ); j++ )
757 "Single", c[ i ],
"axial", c[ child[ j ] ],
"raxial" );
758 ASSERT( ! mid.
bad(),
"Creating test model" );
762 HP.
setup( c[ 0 ], dt );
770 ASSERT( (
int )( hc.size() ) == nCompt,
"Tree traversal" );
771 for ( i = 0; i < nCompt; i++ )
773 find( hc.begin(), hc.end(), c[ i ] ) != hc.end(),
"Tree traversal"
790 vector< unsigned int > permutation( nCompt );
791 for ( i = 0; i < nCompt; i++ )
793 unsigned int newIndex =
794 find( hc.begin(), hc.end(), c[ i ] ) - hc.begin();
795 permutation[ i ] = newIndex;
799 permute< TreeNodeStruct >( tree, permutation );
800 permute< double >( Em, permutation );
801 permute< double >( V, permutation );
804 for ( i = 0; i < nCompt; i++ )
806 vector< unsigned int >& child = tree[ i ].children;
807 for ( j = 0; j < ( int )( child.size() ); j++ )
808 child[ j ] = permutation[ child[ j ] ];
813 VMid.resize( nCompt );
816 vector< vector< double > > matrixCopy;
817 matrixCopy.assign( matrix.begin(), matrix.end() );
830 for ( i = 0; i < nCompt; ++i )
831 for ( j = 0; j < nCompt; ++j )
834 error <<
"Testing matrix construction:"
835 <<
" Cell# " << cell + 1
836 <<
" A(" << i <<
", " << j <<
")";
838 isClose< double >( HP.
getA( i, j ), matrix[ i ][ j ], tolerance ),
851 for (
int pass = 0; pass < 2; pass++ )
865 matrix.assign( matrixCopy.begin(), matrixCopy.end() );
867 for ( i = 0; i < nCompt; i++ )
869 V[ i ] * tree[ i ].Cm / ( dt / 2.0 ) +
870 Em[ i ] / tree[ i ].Rm;
873 for ( i = 0; i < nCompt; ++i )
876 error <<
"Updating right-hand side values:"
878 <<
" Cell# " << cell + 1
879 <<
" B(" << i <<
")";
881 isClose< double >( HP.
getB( i ), B[ i ], tolerance ),
895 for ( i = 0; i < nCompt - 1; i++ )
896 for ( j = i + 1; j < nCompt; j++ )
898 double div = matrix[ j ][ i ] / matrix[ i ][ i ];
899 for ( k = 0; k < nCompt; k++ )
900 matrix[ j ][ k ] -= div * matrix[ i ][ k ];
901 B[ j ] -= div * B[ i ];
905 for ( i = 0; i < nCompt; ++i )
906 for ( j = 0; j < nCompt; ++j )
909 error <<
"Forward elimination:"
911 <<
" Cell# " << cell + 1
912 <<
" A(" << i <<
", " << j <<
")";
914 isClose< double >( HP.
getA( i, j ), matrix[ i ][ j ], tolerance ),
920 for ( i = 0; i < nCompt; ++i )
923 error <<
"Forward elimination:"
925 <<
" Cell# " << cell + 1
926 <<
" B(" << i <<
")";
928 isClose< double >( HP.
getB( i ), B[ i ], tolerance ),
941 for ( i = nCompt - 1; i >= 0; i-- )
945 for ( j = nCompt - 1; j > i; j-- )
946 VMid[ i ] -= VMid[ j ] * matrix[ i ][ j ];
948 VMid[ i ] /= matrix[ i ][ i ];
950 V[ i ] = 2 * VMid[ i ] - V[ i ];
954 for ( i = nCompt - 1; i >= 0; i-- )
957 error <<
"Back substitution:"
959 <<
" Cell# " << cell + 1
960 <<
" VMid(" << i <<
")";
962 isClose< double >( HP.
getVMid( i ), VMid[ i ], tolerance ),
967 for ( i = nCompt - 1; i >= 0; i-- )
970 error <<
"Back substitution:"
972 <<
" Cell# " << cell + 1
973 <<
" V(" << i <<
")";
975 isClose< double >( HP.
getV( i ), V[ i ], tolerance ),
984 cout <<
"." << flush;
989 #endif // DO_UNIT_TESTS
double getVMid(unsigned int row) const
void makeFullMatrix(const vector< TreeNodeStruct > &tree, double dt, vector< vector< double > > &matrix)
#define ASSERT(unused, message)
static int children(Id compartment, vector< Id > &ret)
static int leakageChannels(Id compartment, vector< Id > &ret)
vector< double > VMid_
middle of a time step.
vector< unsigned int > children
Hines indices of child compts.
void setup(Id seed, double dt)
void setup(const vector< TreeNodeStruct > &tree, double dt)
double getB(unsigned int row) const
static int adjacent(Id compartment, vector< Id > &ret)
vector< Id > compartmentId_
static bool set(const ObjId &dest, const string &field, A arg)
Id doCreate(string type, ObjId parent, string name, unsigned int numData, NodePolicy nodePolicy=MooseBlockBalance, unsigned int preferredNode=1)
vector< vdIterator > backOperand_
void backwardSubstitute()
ostream & operator<<(ostream &s, const HinesMatrix &m)
vector< CompartmentStruct > compartment_
double getV(unsigned int row) const
int stage_
reached. Used in getA.
map< unsigned int, InjectStruct > inject_
vector< vdIterator > operand_
bool isClose(double x, double y, double tol)
vector< TreeNodeStruct > tree_
ObjId doAddMsg(const string &msgType, ObjId src, const string &srcField, ObjId dest, const string &destField)
static A get(const ObjId &dest, const string &field)
vector< JunctionStruct > junction_
vector< double >::iterator vdIterator
double getA(unsigned int row, unsigned int col) const