Skip to content
Snippets Groups Projects
Commit 0f6f5d27 authored by Dilawar Singh's avatar Dilawar Singh
Browse files

Squashed 'moose-core/' changes from 6099142d6..ef066f704

ef066f704 Fixes to violation of mass-conservation when Dsolve and Gsolve run for very long time (#176)
46ea47260 Local Documentation (#177)
852819875 Added connectionList field to SparseMsg to allow direct control over connection matrix. Some sanity checks in SparseMatrix to go with this.

git-subtree-dir: moose-core
git-subtree-split: ef066f70493fe05fe05393af48449b264c8f4bc0
parent cc8759c2
No related branches found
No related tags found
No related merge requests found
......@@ -37,7 +37,7 @@ if(COMPILER_SUPPORTS_CXX11)
elseif(COMPILER_SUPPORTS_CXX0X)
message(STATUS "Your compiler supports c++0x features. Enabling it")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_definitions( -DENABLE_CXX11 )
add_definitions( -DENABLE_CPP11 )
add_definitions( -DBOOST_NO_CXX11_SCOPED_ENUMS -DBOOST_NO_SCOPED_ENUMS )
if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++" )
......
......@@ -582,7 +582,7 @@ public:
void tripletFill( const vector< unsigned int >& row,
const vector< unsigned int >& col,
const vector< T >& z )
const vector< T >& z, bool retainSize = false )
{
unsigned int len = row.size();
if ( len > col.size() ) len = col.size();
......@@ -591,16 +591,20 @@ public:
for ( unsigned int i = 0; i < len; ++i )
trip[i]= Triplet< T >(z[i], row[i], col[i] );
sort( trip.begin(), trip.end(), Triplet< T >::cmp );
unsigned int nr = trip.back().b_ + 1;
unsigned int nc = 0;
for ( typename vector< Triplet< T > >::iterator i =
trip.begin(); i != trip.end(); ++i )
{
if ( nc < i->c_ )
nc = i->c_;
}
nc++;
setSize( nr, nc );
unsigned int nr = nrows_;
unsigned int nc = ncolumns_;
if ( !retainSize ) {
nr = trip.back().b_ + 1;
nc = 0;
for ( typename vector< Triplet< T > >::iterator i =
trip.begin(); i != trip.end(); ++i )
{
if ( nc < i->c_ )
nc = i->c_;
}
nc++;
}
setSize( nr, nc );
vector< unsigned int > colIndex( nc );
vector< T > entry( nc );
......
This diff is collapsed.
......@@ -205,10 +205,10 @@ void GssaVoxelPools::advance( const ProcInfo* p, const GssaSystem* g )
numFire_[rindex]++;
double r = rng_.uniform();
while ( r <= 0.0 )
{
while ( r == 0.0 )
r = rng_.uniform();
}
t_ -= ( 1.0 / atot_ ) * log( r );
// g->stoich->updateFuncs( varS(), t_ ); // Handled next line.
updateDependentMathExpn( g, rindex, t_ );
......@@ -234,7 +234,7 @@ void GssaVoxelPools::reinit( const GssaSystem* g )
double base = floor( n[i] );
assert( base >= 0.0 );
double frac = n[i] - base;
if ( rng_.uniform() > frac )
if ( rng_.uniform() >= frac )
n[i] = base;
else
n[i] = base + 1.0;
......@@ -369,9 +369,9 @@ void GssaVoxelPools::xferIn( XferInfo& xf,
{
double& x = s[*k];
// cout << x << " i = " << *i << *j << " m = " << *m << endl;
double dx = *i++ - *j++;
double dx = *(i++) - *(j++);
double base = floor( dx );
if ( rng_.uniform() > dx - base )
if ( rng_.uniform() >= (dx - base) )
x += base;
else
x += base + 1.0;
......@@ -425,7 +425,7 @@ void GssaVoxelPools::xferInOnlyProxies(
if ( *k >= stoichPtr_->getNumVarPools() && *k < proxyEndIndex )
{
double base = floor( *i );
if ( rng_.uniform() > *i - base )
if ( rng_.uniform() >= (*i - base) )
varSinit()[*k] = (varS()[*k] += base );
else
varSinit()[*k] = (varS()[*k] += base + 1.0 );
......
......@@ -41,6 +41,17 @@ const Cinfo* SparseMsg::initCinfo()
"Number of Entries in matrix.",
&SparseMsg::getNumEntries
);
static ValueFinfo< SparseMsg, vector< unsigned int > > connectionList(
"connectionList",
"Pairwise specification of connection matrix where each x,y value "
"represents a connection from src[x] to dest[y]. "
"The (x,y) entries are ordered in a single vector as \n"
"(x0, x1,... x_n-1, y0, y1,... y_n-1)\n",
&SparseMsg::setEntryPairs,
&SparseMsg::getEntryPairs
);
/// Connection matrix entries to manipulate in Python.
static ReadOnlyValueFinfo< SparseMsg, vector< unsigned int > >
matrixEntry(
......@@ -124,6 +135,13 @@ const Cinfo* SparseMsg::initCinfo()
vector< unsigned int > >(
&SparseMsg::tripletFill ) );
static DestFinfo tripletFill1( "tripletFill1",
"Single contiguous array to fill entire connection matrix using "
"triplets of (x,y, fieldindex) ordered as \n"
"(x0, x1,... xn-1, y0, y1,... yn-1, fi0, fi1,... fi_n-1)\n",
new OpFunc1< SparseMsg, vector< unsigned int > >(
&SparseMsg::tripletFill1 ) );
////////////////////////////////////////////////////////////////////////
// Assemble it all.
////////////////////////////////////////////////////////////////////////
......@@ -132,6 +150,7 @@ const Cinfo* SparseMsg::initCinfo()
&numRows, // readonly value
&numColumns, // readonly value
&numEntries, // readonly value
&connectionList, // value
&matrixEntry, // ReadOnlyValue
&columnIndex, // ReadOnlyValue
&rowStart, // ReadOnlyValue
......@@ -144,6 +163,7 @@ const Cinfo* SparseMsg::initCinfo()
&transpose, //dest
&pairFill, //dest
&tripletFill, //dest
&tripletFill1, //dest
};
static Dinfo< short > dinfo;
......@@ -217,6 +237,28 @@ vector< unsigned int > SparseMsg::getRowStart() const
return matrix_.rowStart();
}
void SparseMsg::setEntryPairs( vector< unsigned int > v )
{
vector< unsigned int > src( v.begin(), v.begin() + v.size()/2 );
vector< unsigned int > dest( v.begin() + v.size()/2, v.end() );
pairFill( src, dest );
}
vector< unsigned int > SparseMsg::getEntryPairs() const
{
vector< unsigned int > cols = matrix_.colIndex();
vector< unsigned int > y;
for ( unsigned int row = 0; row < matrix_.nRows(); ++row ) {
unsigned int begin = matrix_.rowStart()[row];
unsigned int end = matrix_.rowStart()[row+1];
for ( unsigned int j = begin; j < end; ++j )
y.push_back( row );
}
assert( cols.size() == y.size() );
y.insert( y.end(), cols.begin(), cols.end() );
return y;
}
//////////////////////////////////////////////////////////////////
// DestFields
//////////////////////////////////////////////////////////////////
......@@ -256,21 +298,57 @@ void SparseMsg::updateAfterFill()
{
unsigned int startData = e2_->localDataStart();
unsigned int endData = startData + e2_->numLocalData();
for ( unsigned int i = 0; i < matrix_.nRows(); ++ i ) {
SparseMatrix< unsigned int > temp( matrix_);
temp.transpose();
for ( unsigned int i = 0; i < temp.nRows(); ++ i ) {
const unsigned int* colIndex;
const unsigned int* entry;
unsigned int num = matrix_.getRow( i, &entry, &colIndex );
unsigned int num = temp.getRow( i, &entry, &colIndex );
if ( i >= startData && i < endData ) {
e2_->resizeField( i - startData, num );
// Inefficient. Better to do it in one pass after getting
// the max num
e2_->resizeField( i - startData, num + 1 );
}
}
e1()->markRewired();
e2()->markRewired();
}
void SparseMsg::pairFill( vector< unsigned int > src,
vector< unsigned int> dest )
{
matrix_.pairFill( src, dest, 0 );
// Sanity check
vector< unsigned int >::const_iterator i;
for ( i = src.begin(); i != src.end(); ++i ) {
if (*i >= e1()->numData() ) {
cout << "Warning: SparseMsg::pairFill: Src index " << *i <<
" exceeds Src array size " << e1()->numData() <<
". Aborting\n";
return;
}
}
for ( i = dest.begin(); i != dest.end(); ++i ) {
if (*i >= e2()->numData() ) {
cout << "Warning: SparseMsg::pairFill: Dest index " << *i <<
" exceeds Dest array size " << e2()->numData() <<
". Aborting\n";
return;
}
}
vector< unsigned int > numAtDest( dest.size(), 0 );
vector< unsigned int > fieldIndex( dest.size(), 0 );
for ( unsigned int i = 0; i < dest.size(); ++i ) {
fieldIndex[i] = numAtDest[ dest[i] ];
// Could do on previous line, but clarity
++numAtDest[ dest[i] ];
}
/**
* We set retainSize flag to true since the # of src/dest objects
* doesn't change. We can explicitly assign it elsewhere if needed.
*/
matrix_.tripletFill( src, dest, fieldIndex, true );
updateAfterFill();
}
......@@ -278,10 +356,20 @@ void SparseMsg::tripletFill( vector< unsigned int > src,
vector< unsigned int> destDataIndex,
vector< unsigned int> destFieldIndex )
{
matrix_.tripletFill( src, destDataIndex, destFieldIndex );
// We set retainSize flag to true
matrix_.tripletFill( src, destDataIndex, destFieldIndex, true );
updateAfterFill();
}
void SparseMsg::tripletFill1( vector< unsigned int > v )
{
unsigned int s3 = v.size() / 3;
vector< unsigned int > src( v.begin(), v.begin() + s3 );
vector< unsigned int > dest( v.begin() + s3, v.begin() + 2 * s3 );
vector< unsigned int > fieldIndex( v.begin() + 2 * s3, v.end() );
tripletFill( src, dest, fieldIndex );
}
//////////////////////////////////////////////////////////////////
// Here are the actual class functions
//////////////////////////////////////////////////////////////////
......@@ -289,7 +377,10 @@ void SparseMsg::tripletFill( vector< unsigned int > src,
SparseMsg::SparseMsg( Element* e1, Element* e2, unsigned int msgIndex )
: Msg( ObjId( managerId_, (msgIndex != 0) ? msgIndex: msg_.size() ),
e1, e2 )
e1, e2 ),
numThreads_( 1 ),
nrows_( 0 ),
p_( 0.0 ), seed_( 0 )
{
unsigned int nrows = 0;
unsigned int ncolumns = 0;
......
......@@ -82,6 +82,9 @@ class SparseMsg: public Msg
long getSeed() const;
void setSeed( long value );
vector< unsigned int > getEntryPairs() const;
void setEntryPairs( vector< unsigned int > entries );
void setEntry( unsigned int row, unsigned int column,
unsigned int value );
......@@ -113,6 +116,14 @@ class SparseMsg: public Msg
void tripletFill( vector< unsigned int > src,
vector< unsigned int> dest,
vector< unsigned int > field );
/**
* Fills up the entire message based on triplets of
* src,destDataIndex,destFieldIndex, but catenates them all into
* a single long vector since PyMoose doesn't know how to handle
* multiple vectors.
*/
void tripletFill1( vector< unsigned int > entries );
/**
* Utility function to update all sorts of values after we've
......
......@@ -13,6 +13,7 @@ import pydoc
import os
from io import StringIO
from collections import defaultdict
import textwrap
import moose
from moose._moose import *
......@@ -308,6 +309,45 @@ def showmsg(el):
msg.e2.path,
msg.destFieldsOnE2)
def getfielddoc_(tokens, infoType=''):
indent=''
classname = tokens[0]
# print( classname )
while True:
try:
classelement = _moose.element('/classes/' + classname)
# print( classelement )
x = ''
for finfo in classelement.children:
# print (str(finfo)[33:-1])
# trial = 'path=/classes[0]/' + classname + '[0]/' + infoType
# print (trial)
# print (str(finfo)[33:-1] == trial)
for fieldelement in finfo:
fieldname = fieldelement.fieldName
if (str(fieldname).startswith('get')) or (str(fieldname).startswith('set')):
continue
baseinfo = ''
finfotype = fieldelement.name
if(infoType == 'destFinfo'):
say = 'Destination Message Field'
elif(infoType == 'valueFinfo'):
say = 'Value Field'
elif(infoType == 'srcFinfo'):
say = 'Source Message Field'
elif(infoType == 'lookupFinfo'):
say = 'Lookup Field'
elif(infoType == 'sharedFinfo'):
say = 'Shared Message Field'
# finfotype={finfotype}{baseinfo}
if (str(finfotype) == infoType):
x = x + '{indent}{classname}.{fieldname}: type= {type} finfotype= {say}{baseinfo}\n\t{docs}\n\n'.format(indent=indent, classname=tokens[0], fieldname = fieldname, type=fieldelement.type, say=say, baseinfo=baseinfo, docs=fieldelement.docs)
return x
# classname = classelement.baseClass
except ValueError:
raise NameError('`%s` has no field called `%s`'% (tokens[0], tokens[1]))
def getfielddoc(tokens, indent=''):
"""Return the documentation for field specified by `tokens`.
......@@ -340,6 +380,7 @@ def getfielddoc(tokens, indent=''):
try:
classelement = _moose.element('/classes/' + classname)
for finfo in classelement.children:
x = ''
for fieldelement in finfo:
baseinfo = ''
if classname != tokens[0]:
......@@ -348,18 +389,11 @@ def getfielddoc(tokens, indent=''):
# The field elements are
# /classes/{ParentClass}[0]/{fieldElementType}[N].
finfotype = fieldelement.name
return '{indent}{classname}.{fieldname}: type={type}, finfotype={finfotype}{baseinfo}\n\t{docs}\n'.format(
indent=indent, classname=tokens[0],
fieldname=fieldname,
type=fieldelement.type,
finfotype=finfotype,
baseinfo=baseinfo,
docs=fieldelement.docs)
x = x + '{indent}{classname}.{fieldname}: type={type}, finfotype={finfotype}{baseinfo}\n\t{docs}\n'.format(indent=indent, classname=tokens[0], fieldname=fieldname, type=fieldelement.type, finfotype=finfotype, baseinfo=baseinfo, docs=fieldelement.docs)
return x
classname = classelement.baseClass
except ValueError:
raise NameError('`%s` has no field called `%s`'
% (tokens[0], tokens[1]))
raise NameError('`%s` has no field called `%s`'% (tokens[0], tokens[1]))
def toUnicode(v, encoding='utf8'):
# if isinstance(v, str):
......@@ -407,20 +441,98 @@ def getmoosedoc(tokens, inherited=False):
if len(tokens) > 1:
docstring.write(toUnicode(getfielddoc(tokens)))
else:
docstring.write(toUnicode('%s\n' % (class_element.docs)))
append_finfodocs(tokens[0], docstring, indent)
doc_text = class_element.docs
textArray = textwrap.wrap(doc_text, width = 70, replace_whitespace = False, drop_whitespace = False)
text = "\n".join(textArray)
# print(text)
docstring.write(toUnicode('%s\n' % (text)))
info = '\t Functions and message destinations \n\t------------------------------------\n\t All \'destFinfo\' can be used as destination Field for moose.connect function.\n'
docstring.write(toUnicode('%s\n') % (info))
docstring.write(toUnicode(getfielddoc_(tokens, 'destFinfo')))
# append_finfodocs(tokens[0], docstring, indent)
if inherited:
mro = eval('_moose.%s' % (tokens[0])).mro()
for class_ in mro[1:]:
if class_ == _moose.melement:
break
docstring.write(toUnicode(
'\n\n#Inherited from %s#\n' % (class_.__name__)))
append_finfodocs(class_.__name__, docstring, indent)
docstring.write(toUnicode('\n#Inherited from %s#\n' % (class_.__name__)))
temp = []
temp.append(str(class_.__name__))
docstring.write(toUnicode(getfielddoc_(temp, 'destFinfo')))
# append_finfodocs(class_.__name__, docstring, indent)
if class_ == _moose.Neutral: # Neutral is the toplevel moose class
break
return docstring.getvalue()
info = '\t Class attributes \n\t -------------------- \n\t All \'valueFinfo\' are attributes of the class, and can be read and written using \n\t standard get and set Functions (unless explicitely mentioned otherwise). \n\t for example, getVm() and setVm() for access to Vm.\n\t All \'sharedFinfo\'...'
docstring.write(toUnicode('%s\n') % (info))
docstring.write(toUnicode(getfielddoc_(tokens, 'valueFinfo')))
# append_finfodocs(tokens[0], docstring, indent)
if inherited:
mro = eval('_moose.%s' % (tokens[0])).mro()
for class_ in mro[1:]:
if class_ == _moose.melement:
break
docstring.write(toUnicode('\n#Inherited from %s#\n' % (class_.__name__)))
temp = []
temp.append(str(class_.__name__))
docstring.write(toUnicode(getfielddoc_(temp, 'valueFinfo')))
# append_finfodocs(class_.__name__, docstring, indent)
if class_ == _moose.Neutral: # Neutral is the toplevel moose class
break
info = '\t Source Messages \n\t ----------------------- \n\t All \'srcFinfo\' can be used as sourceField for moose.connect function.'
docstring.write(toUnicode('%s\n') % (info))
docstring.write(toUnicode(getfielddoc_(tokens, 'srcFinfo')))
# append_finfodocs(tokens[0], docstring, indent)
if inherited:
mro = eval('_moose.%s' % (tokens[0])).mro()
for class_ in mro[1:]:
if class_ == _moose.melement:
break
docstring.write(toUnicode('\n#Inherited from %s#\n' % (class_.__name__)))
temp = []
temp.append(str(class_.__name__))
docstring.write(toUnicode(getfielddoc_(temp, 'srcFinfo')))
# append_finfodocs(class_.__name__, docstring, indent)
if class_ == _moose.Neutral: # Neutral is the toplevel moose class
break
info = '\t LookUp Fields \n\t ---------------- \n\t All \'lookupFinfo\' are ..................................\n'
docstring.write(toUnicode('%s\n') % (info))
docstring.write(toUnicode(getfielddoc_(tokens, 'lookupFinfo')))
# append_finfodocs(tokens[0], docstring, indent)
if inherited:
mro = eval('_moose.%s' % (tokens[0])).mro()
for class_ in mro[1:]:
if class_ == _moose.melement:
break
docstring.write(toUnicode('\n#Inherited from %s#\n' % (class_.__name__)))
temp = []
temp.append(str(class_.__name__))
docstring.write(toUnicode(getfielddoc_(temp, 'lookupFinfo')))
# append_finfodocs(class_.__name__, docstring, indent)
if class_ == _moose.Neutral: # Neutral is the toplevel moose class
break
info = '\t shared fields \n\t ---------------- \n\t All \'sharedFinfo\' are ..................................\n'
docstring.write(toUnicode('%s\n') % (info))
docstring.write(toUnicode(getfielddoc_(tokens, 'sharedFinfo')))
# append_finfodocs(tokens[0], docstring, indent)
if inherited:
mro = eval('_moose.%s' % (tokens[0])).mro()
for class_ in mro[1:]:
if class_ == _moose.melement:
break
docstring.write(toUnicode('\n#Inherited from %s#\n' % (class_.__name__)))
temp = []
temp.append(str(class_.__name__))
docstring.write(toUnicode(getfielddoc_(temp, 'sharedFinfo')))
# append_finfodocs(class_.__name__, docstring, indent)
if class_ == _moose.Neutral: # Neutral is the toplevel moose class
break
return docstring.getvalue()
def append_finfodocs(classname, docstring, indent):
"""Append list of finfos in class name to docstring"""
......@@ -438,7 +550,6 @@ def append_finfodocs(classname, docstring, indent):
except ValueError:
docstring.write(toUnicode('%sNone\n' % (indent)))
# the global pager is set from pydoc even if the user asks for paged
# help once. this is to strike a balance between GENESIS user's
# expectation of control returning to command line after printing the
......@@ -502,5 +613,4 @@ def doc(arg, inherited=True, paged=True):
if pager:
pager(text)
else:
print(text)
print(text, width=80)
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment