13 #include "../utility/Vec.h"
26 #include "../utility/numutil.h"
58 "x coord of other end",
64 "y coord of other end",
70 "z coord of other end",
76 "Radius of other end",
82 "All the coords as a single vector: x0 y0 z0 x1 y1 z1 r0 r1 diffLength",
89 "Length constant to use for subdivisions"
90 "The system will attempt to subdivide using compartments of"
91 "length diffLength on average. If the cylinder has different end"
92 "diameters r0 and r1, it will scale to smaller lengths"
93 "for the smaller diameter end and vice versa."
94 "Once the value is set it will recompute diffLength as "
95 "totLength/numEntries",
102 "Number of diffusive compartments in model",
108 "Total length of cylinder",
120 static Finfo* cylMeshFinfos[] = {
135 static string doc[] =
138 "Author",
"Upi Bhalla",
139 "Description",
"Chemical compartment with cylindrical geometry. "
140 "Defaults to a uniform cylinder of radius 1 micron, "
141 "length 100 microns, and voxel length 1 micron so there "
142 "are 100 voxels in the cylinder. "
143 "The cylinder can be given a linear taper, by assigning "
144 "different radii r0 and r1 to the two ends. ",
151 sizeof( cylMeshFinfos ) /
sizeof (
Finfo* ),
154 sizeof(doc)/
sizeof(
string)
182 diffLength_( 1.0e-6 ),
183 surfaceGranularity_( 0.1 ),
214 cout <<
"Error: CylMesh::updateCoords:\n"
215 "total length of compartment = 0 with these parameters\n";
226 numEntries_ =
static_cast< unsigned int >( round ( temp ) );
240 vector< double > childConcs;
253 vector< double > childConcs;
266 vector< double > childConcs;
279 vector< double > childConcs;
293 vector< double > childConcs;
306 vector< double > childConcs;
319 vector< double > childConcs;
332 vector< double > childConcs;
345 vector< double > childConcs;
365 if ( v.size() < 9 ) {
366 cout <<
"CylMesh::setCoords: Warning: size of argument vec should be >= 9, was " << v.size() << endl;
374 vector< double > ret( 9 );
394 vector< double > childConcs;
482 double leni = len0 + ( fid + 0.5 ) *
lenSlope_;
484 return leni * ri * ri *
PI;
491 vector< double > ret(10, 0.0);
494 double lenStart = len0 +
lenSlope_ * 0.5;
496 double axialStart = fid * lenStart + ( ( fid * (fid - 1 ) )/2 ) *
lenSlope_;
499 (fid + 1) * lenStart + ( ( fid * (fid + 1 ) )/2 ) *
lenSlope_;
523 return vector< double >( 0 );
530 vector < double > ret( 2 );
531 ret[0] = rlow * rlow *
PI;
532 ret[1] = rhigh * rhigh *
PI;
535 return vector < double >( 1, rhigh * rhigh *
PI );
541 vector < double > ret( 2 );
542 ret[0] = rlow * rlow *
PI;
546 return vector < double >( 1, rlow * rlow *
PI );
549 vector< double > ret( 2 );
550 ret[0] = rlow * rlow *
PI;
551 ret[1] = rhigh * rhigh *
PI;
559 return vector< double >( 0 );
562 return vector< double >( 1, 1.0 );
564 return vector< double >( 2, 1.0 );
584 const SrcFinfo2<
unsigned int, vector< double > >* meshStatsFinfo
588 meshStatsFinfo->send( e, 1, ret );
593 unsigned int numNodes,
unsigned int numThreads )
625 static const unsigned int WayTooLarge = 1000000;
626 if ( n == 0 || n > WayTooLarge ) {
627 cout <<
"Warning: CylMesh::innerSetNumEntries( " << n <<
628 " ): out of range\n";
647 double r = pow( ( volume / (
PI * 2 ) ), 1.0 / 3 );
648 vector< double > coords( 9, 0 );
660 ret[0] =
static_cast< unsigned int >( -1 );
669 static vector< double > vol;
678 static vector< double > midpoint(
numEntries_ * 3, 0.0 );
683 vector< double >::iterator j = midpoint.begin();
696 static vector< double > area;
699 double frac = ( 0.5 +
static_cast< double >( i ) ) /
701 double r =
r0_ * ( 1.0 - frac ) +
r1_ * frac;
702 area[i] = r * r *
PI;
709 static vector< double > length;
725 double linScale = pow( volume/oldVol, 1.0 / 3.0 );
791 double aLow = rLow * rLow *
PI;
792 double aHigh = rHigh * rHigh *
PI;
793 vector< double > entry;
794 vector< unsigned int > colIndex;
796 colIndex.push_back( 1 );
799 colIndex.push_back( numEntries_ - 1 );
802 }
else if ( i == numEntries_ - 1 ) {
804 colIndex.push_back( 0 );
810 colIndex.push_back( numEntries_ - 2 );
813 colIndex.push_back( i - 1 );
815 colIndex.push_back( i + 1 );
818 addRow( i, entry, colIndex );
828 vector< VoxelJunction >& ret )
const
854 cout <<
"Warning:CylMesh::matchMeshEntries: " <<
855 " unknown mesh type\n";
862 vector< VoxelJunction >& ret )
const
879 if ( dr1 <= dr2 && dr1 <= dr3 && dr1 <= dr4 ) {
880 if ( ( dr1/totLen_ < EPSILON && dr1/other->
totLen_ < EPSILON ) ) {
882 if ( r0_ < other->
r0_ )
885 xda = 2 * other->
r0_ * other->
r0_ *
PI /
888 ret.back().first = 0;
889 ret.back().second = 0;
893 }
else if ( dr2 <= dr3 && dr2 <= dr4 ) {
894 if ( ( dr2/totLen_ < EPSILON && dr2/other->
totLen_ < EPSILON ) ) {
896 if ( r1_ < other->
r1_ )
899 xda = 2 * other->
r1_ * other->
r1_ *
PI /
908 }
else if ( dr3 <= dr4 ) {
909 if ( ( dr3/totLen_ < EPSILON && dr3/other->
totLen_ < EPSILON ) ) {
911 if ( r1_ < other->
r0_ )
914 xda = 2 * other->
r0_ * other->
r0_ *
PI /
918 ret.back().second = 0;
923 if ( ( dr4/totLen_ < EPSILON && dr4/other->
totLen_ < EPSILON ) ) {
925 if ( r0_ < other->
r1_ )
928 xda = 2 * other->
r1_ * other->
r1_ *
PI /
931 ret.back().first = 0;
956 const Vec& u,
const Vec& v,
const Vec& q,
957 double h,
double r, vector< double >& area,
965 unsigned int numAngle = floor( 2.0 *
PI * r / h + 0.5 );
966 assert( numAngle > 0 );
967 double dtheta = 2.0 *
PI / numAngle;
968 double dArea = h * dtheta * r;
970 for (
unsigned int j = 0; j < numAngle; ++j ) {
971 double theta = j * dtheta;
972 double c = cos( theta );
973 double s = sin( theta );
974 double p0 = q.
a0() + r * ( u.
a0() * c + v.
a0() * s );
975 double p1 = q.
a1() + r * ( u.
a1() * c + v.
a1() * s );
976 double p2 = q.
a2() + r * ( u.
a2() * c + v.
a2() * s );
979 area[index] += dArea;
984 vector< VoxelJunction >& ret )
const
999 for (
unsigned int j = 0; j < num; ++j ) {
1000 unsigned int m = i * num + j;
1001 double frac = ( m * h + h/2.0 ) /
totLen_;
1002 double q0 =
x0_ + a.
a0() * frac;
1003 double q1 =
y0_ + a.
a1() * frac;
1004 double q2 =
z0_ + a.
a2() * frac;
1006 double r =
r0_ + ( m * h + h / 2.0 ) *
rSlope_;
1008 h, r, area, other );
1013 for (
unsigned int k = 0; k < area.size(); ++k ) {
1014 if ( area[k] > EPSILON ) {
1022 vector< VoxelJunction >& ret )
const
1027 double& x,
double& y,
double& z )
const
1030 double k = ( index + 0.5 ) / static_cast< double >(
numEntries_ );
1037 static double dotprd (
double x0,
double y0,
double z0,
1038 double x1,
double y1,
double z1 )
1040 return x0 * x1 + y0 * y1 + z0 * z1;
1046 double& linePos,
double& r )
const
1061 x -
x0_, y -
y0_, z -
z0_ ) / ( dist * dist );
1068 double ret =
distance( x - x2, y - y2, z - z2 );
1076 unsigned int& index )
const
1080 double ret =
nearest( x, y, z, k, r );
1084 }
else if ( k > 1.0 ) {
static const Cinfo * initCinfo()
double surfaceGranularity_
Length constant for diffusion. Equal to dx.
vector< double > getDiffusionArea(unsigned int fid) const
Virtual function to return diffusion X-section area.
void updateCoords(const Eref &e, const vector< double > &childConcs)
double nearest(double x, double y, double z, unsigned int &index) const
void innerResetStencil()
virtual func implemented here.
double getY0(const Eref &e) const
static const Cinfo * initCinfo()
vector< double > getCoordinates(unsigned int fid) const
Virtual function to return coords of mesh Entry.
unsigned int getMeshType(unsigned int fid) const
Virtual function to return MeshType of specified entry.
unsigned int spaceToIndex(double x, double y, double z) const
Converts the 3-D coords to an index. EMPTY if out of range.
void addRow(unsigned int index, const vector< double > &entry, const vector< unsigned int > &colIndex)
void innerHandleNodeInfo(const Eref &e, unsigned int numNodes, unsigned int numThreads)
double extendedMeshEntryVolume(unsigned int fid) const
Virtual function to return volume of mesh Entry, including.
void setDiffLength(const Eref &e, double v)
void transmitChange(const Eref &e)
static const Cinfo * cylMeshCinfo
void indexToSpace(unsigned int index, double &x, double &y, double &z) const
void setY1(const Eref &e, double v)
vector< double > getCoords(const Eref &e) const
double r1_
Radius at one end.
static double dotprd(double x0, double y0, double z0, double x1, double y1, double z1)
unsigned int getNumEntries() const
double getTotLength() const
unsigned int innerGetNumEntries() const
void innerHandleRequestMeshStats(const Eref &e, const SrcFinfo2< unsigned int, vector< double > > *meshStatsFinfo)
More inherited virtual funcs: request comes in for mesh stats.
double getX1(const Eref &e) const
unsigned int getMeshDimensions(unsigned int fid) const
Virtual function to return dimensions of specified entry.
bool doubleEq(double x, double y)
double lenSlope_
Utility value: dr/dx.
void setZ0(const Eref &e, double v)
double getMeshEntryVolume(unsigned int fid) const
Virtual function to return volume of mesh Entry.
void matchNeuroMeshEntries(const NeuroMesh *other, vector< VoxelJunction > &ret) const
static double distance(double x, double y, double z)
void setX0(const Eref &e, double v)
void innerSetNumEntries(unsigned int n)
Inherited virtual func.
void matchMeshEntries(const ChemCompt *other, vector< VoxelJunction > &ret) const
void setX1(const Eref &e, double v)
void getChildConcs(const Eref &e, vector< double > &childConcs) const
double getR1(const Eref &e) const
const vector< double > & getVoxelArea() const
void setR0(const Eref &e, double v)
double extendedMeshEntryVolume(unsigned int fid) const
Volume of mesh Entry including abutting diff-coupled voxels.
double getR0(const Eref &e) const
vector< double > getDiffusionScaling(unsigned int fid) const
Virtual function to return scale factor for diffusion. 1 here.
double rSlope_
Utility value: Total length of cylinder.
double getZ0(const Eref &e) const
bool vSetVolumeNotRates(double volume)
Inherited virtual. Resizes len and dia of each voxel.
unsigned int setChildConcs(const Eref &e, const vector< double > &childConcs, unsigned int start) const
vector< unsigned int > getParentVoxel() const
Inherited virtual, do nothing for now.
double getY1(const Eref &e) const
static unsigned int numNodes
const vector< double > & vGetVoxelMidpoint() const
Virtual func so that derived classes can return voxel midpoint.
void fillPointsOnCircle(const Vec &u, const Vec &v, const Vec &q, double h, double r, vector< double > &area, const CubeMesh *other)
double diffLength_
Radius at other end.
void setR1(const Eref &e, double v)
void matchCubeMeshEntries(const CubeMesh *other, vector< VoxelJunction > &ret) const
double getX0(const Eref &e) const
static const unsigned int EMPTY
const vector< double > & getVoxelLength() const
void orthogonalAxes(Vec &u, Vec &v) const
Generates vectors u and v to form a mutually orthogonal system.
const vector< double > & vGetVoxelVolume() const
Virtual func so that derived classes can pass voxel volume back.
void setY0(const Eref &e, double v)
void setZ1(const Eref &e, double v)
double getDiffLength(const Eref &e) const
void setStencilSize(unsigned int numRows, unsigned int numCols)
double vGetEntireVolume() const
Inherited virtual. Returns entire volume of compartment.
void matchCylMeshEntries(const CylMesh *other, vector< VoxelJunction > &ret) const
void innerBuildDefaultMesh(const Eref &e, double volume, unsigned int numEntries)
Virtual func to make a mesh with specified Volume and numEntries.
unsigned int innerGetDimensions() const
void flipRet(vector< VoxelJunction > &ret) const
Utility function for swapping first and second in VoxelJunctions.
void matchMeshEntries(const ChemCompt *other, vector< VoxelJunction > &ret) const
void setCoords(const Eref &e, vector< double > v)
double getZ1(const Eref &e) const
double selectGridVolume(double h) const
void innerSetCoords(const Eref &e, const vector< double > &v)