Skip to content

Commit

Permalink
Fixes to ensure that you can calculate local Q6 parameters without us…
Browse files Browse the repository at this point in the history
…ing chains
  • Loading branch information
Gareth Aneurin Tribello authored and Gareth Aneurin Tribello committed Aug 18, 2024
1 parent 05389b7 commit b3bc765
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 28 deletions.
31 changes: 26 additions & 5 deletions src/adjmat/TorsionsMatrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class TorsionsMatrix : public ActionWithMatrix {
static void registerKeywords( Keywords& keys );
explicit TorsionsMatrix(const ActionOptions&);
unsigned getNumberOfDerivatives();
unsigned getNumberOfColumns() const override { return getConstPntrToComponent(0)->getShape()[1]; }
unsigned getNumberOfColumns() const override ;
void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const ;
void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override;
void runEndOfRowJobs( const unsigned& ival, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
Expand All @@ -55,6 +55,7 @@ void TorsionsMatrix::registerKeywords( Keywords& keys ) {
ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
keys.add("atoms","POSITIONS1","the positions to use for the molecules specified using the first argument");
keys.add("atoms","POSITIONS2","the positions to use for the molecules specified using the second argument");
keys.add("optional","MASK","the label for a sparse matrix that should be used to determine which elements of the matrix should be computed");
keys.setValueDescription("the matrix of torsions between the two vectors of input directors");
}

Expand Down Expand Up @@ -88,17 +89,37 @@ TorsionsMatrix::TorsionsMatrix(const ActionOptions&ao):
std::string headstr=getFirstActionInChain()->getLabel();
stored_matrix1 = getPntrToArgument(0)->ignoreStoredValue( headstr );
stored_matrix2 = getPntrToArgument(1)->ignoreStoredValue( headstr );

std::vector<Value*> mask; parseArgumentList("MASK",mask);
if( mask.size()==1 ) {
if( mask[0]->getRank()!=2 || getPntrToArgument(0)->hasDerivatives() ) error("argument passed to MASK keyword should be a matrix");
if( mask[0]->getShape()[0]!=shape[0] || mask[0]->getShape()[1]!=shape[1] ) error("argument passed to MASK keyword has the wrong shape");
log.printf(" only computing elements of matrix product that correspond to non-zero elements of matrix %s \n", mask[0]->getName().c_str() );
std::vector<Value*> allargs( getArguments() ); allargs.push_back( mask[0] ); requestArguments( allargs );
} else if( mask.size()!=0 ) error("MASK should only have one argument");
}

unsigned TorsionsMatrix::getNumberOfDerivatives() {
return nderivatives;
}

unsigned TorsionsMatrix::getNumberOfColumns() const {
if( getNumberOfArguments()>2 ) return getPntrToArgument(2)->getNumberOfColumns();
return getConstPntrToComponent(0)->getShape()[1];
}

void TorsionsMatrix::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(1)->getShape()[1];
if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
myvals.setSplitIndex( size_v + 1 );
if( getNumberOfArguments()>2 ) {
unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(2)->getRowLength(task_index);
if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + getPntrToArgument(2)->getRowIndex(task_index, i);
myvals.setSplitIndex( size_v + 1 );
} else {
unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(1)->getShape()[1];
if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
myvals.setSplitIndex( size_v + 1 );
}
}

void TorsionsMatrix::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
Expand Down
23 changes: 23 additions & 0 deletions src/core/ActionShortcut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,25 @@

namespace PLMD {

enum class Option { no, yes };

Option interpretEnv(const char* env,const char* str) {
if(!str) return Option::no;
if(!std::strcmp(str,"yes"))return Option::yes;
if(!std::strcmp(str,"no"))return Option::no;
plumed_error()<<"Cannot understand env var "<<env<<"\nPossible values: yes/no\nActual value: "<<str;
}

/// Switch on/off chains of actions using PLUMED environment variable
/// export PLUMED_FORBID_CHAINS=yes # forbid the use of chains in this run
/// export PLUMED_FORBID_CHAINS=no # allow chains to be used in the run
/// default: yes
Option getenvChainAllowed() {
static const char* name="PLUMED_FORBID_CHAINS";
static const auto opt = interpretEnv(name,std::getenv(name));
return opt;
}

void ActionShortcut::registerKeywords( Keywords& keys ) {
Action::registerKeywords( keys );
keys.add("hidden","IS_SHORTCUT","hidden keyword to tell if actions are shortcuts so that example generator can provide expansions of shortcuts");
Expand Down Expand Up @@ -65,6 +84,10 @@ ActionShortcut::ActionShortcut(const ActionOptions&ao):
} else label = ("@s" + s);
}

bool ActionShortcut::chainsAreOff() const {
return getenvChainAllowed()==Option::yes;
}

void ActionShortcut::readInputLine( const std::string& input, bool saveline ) {
std::vector<std::string> words=Tools::getWords(input); Tools::interpretLabel(words);
// Check if this action name has been registered
Expand Down
1 change: 1 addition & 0 deletions src/core/ActionShortcut.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class ActionShortcut :
std::vector<std::string> savedOutputs;
void addToSavedInputLines( const std::string& line );
protected:
bool chainsAreOff() const ;
std::string getUpdateLimits() const ;
public:
const std::string & getShortcutLabel() const ;
Expand Down
42 changes: 28 additions & 14 deletions src/function/FunctionOfMatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,13 @@ class FunctionOfMatrix : public ActionWithMatrix {
void prepare() override ;
/// This gets the number of columns
unsigned getNumberOfColumns() const override ;
/// This checks for tasks in the parent class
// void buildTaskListFromArgumentRequests( const unsigned& ntasks, bool& reduce, std::set<AtomNumber>& otasks ) override ;
/// This ensures that we create some bookeeping stuff during the first step
void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol ) override ;
/// This sets up for the task
void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const ;
/// Calculate the full matrix
void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override ;
/// This updates the indices for the matrix
// void updateCentralMatrixIndex( const unsigned& ind, const std::vector<unsigned>& indices, MultiValue& myvals ) const override ;
void runEndOfRowJobs( const unsigned& ind, const std::vector<unsigned> & indices, MultiValue& myvals ) const override ;
};

Expand Down Expand Up @@ -232,21 +229,38 @@ unsigned FunctionOfMatrix<T>::getNumberOfColumns() const {

template <class T>
void FunctionOfMatrix<T>::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
for(unsigned i=0; i<getNumberOfArguments(); ++i) plumed_assert( getPntrToArgument(i)->getRank()==2 );
unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(0)->getRowLength(task_index);
int ncols = -1, basemat=-1; bool redo=false;
for(unsigned i=0; i<getNumberOfArguments(); ++i) {
if( ncols<0 && getPntrToArgument(i)->getRank()==2 ) { basemat=i; ncols = getPntrToArgument(i)->getNumberOfColumns(); }
else if( getPntrToArgument(i)->getRank()==2 && ncols!=getPntrToArgument(i)->getNumberOfColumns() ) redo=true;
}
redo = ncols>=getPntrToArgument(basemat)->getShape()[1];
unsigned start_n = getPntrToArgument(basemat)->getShape()[0];
if( !redo ) {
unsigned size_v = getPntrToArgument(basemat)->getRowLength(task_index);
for(unsigned j=basemat; j<getNumberOfArguments(); ++j) {
if( size_v!=getPntrToArgument(j)->getRowLength(task_index) ) { redo=true; break; }
}
if( !redo ) {
if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
for(unsigned i=0; i<size_v; ++i) {
unsigned colind = getPntrToArgument(basemat)->getRowIndex(task_index, i);
for(unsigned j=basemat; j<getNumberOfArguments(); ++j) {
if( colind!=getPntrToArgument(j)->getRowIndex(task_index, i) ) { redo=true; break; }
}
if( !redo ) break;
indices[i+1] = start_n + colind;
}
myvals.setSplitIndex( size_v + 1 );
}
}
if( !redo ) return;
unsigned size_v = getPntrToArgument(basemat)->getShape()[1];
if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + getPntrToArgument(0)->getRowIndex(task_index, i);
for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
myvals.setSplitIndex( size_v + 1 );
}

// template <class T>
// void FunctionOfMatrix<T>::buildTaskListFromArgumentRequests( const unsigned& ntasks, bool& reduce, std::set<AtomNumber>& otasks ) {
// // Check if this is the first element in a chain
// if( actionInChain() ) return;
// // If it is computed outside a chain get the tassks the daughter chain needs
// propegateTaskListsForValue( 0, ntasks, reduce, otasks );
// }

template <class T>
void FunctionOfMatrix<T>::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol ) {
if( firststep ) {
Expand Down
31 changes: 26 additions & 5 deletions src/matrixtools/MatrixTimesMatrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class MatrixTimesMatrix : public ActionWithMatrix {
explicit MatrixTimesMatrix(const ActionOptions&);
void prepare() override ;
unsigned getNumberOfDerivatives();
unsigned getNumberOfColumns() const override { return getConstPntrToComponent(0)->getShape()[1]; }
unsigned getNumberOfColumns() const override ;
void getAdditionalTasksRequired( ActionWithVector* action, std::vector<unsigned>& atasks ) override ;
void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const ;
void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const override;
Expand All @@ -65,6 +65,7 @@ PLUMED_REGISTER_ACTION(MatrixTimesMatrix,"DISSIMILARITIES")

void MatrixTimesMatrix::registerKeywords( Keywords& keys ) {
ActionWithMatrix::registerKeywords(keys); keys.use("ARG");
keys.add("optional","MASK","the label for a sparse matrix that should be used to determine which elements of the matrix should be computed");
keys.addFlag("SQUARED",false,"calculate the squares of the dissimilarities (this option cannot be used with MATRIX_PRODUCT)");
keys.setValueDescription("the product of the two input matrices");
}
Expand All @@ -86,12 +87,25 @@ MatrixTimesMatrix::MatrixTimesMatrix(const ActionOptions&ao):
parseFlag("SQUARED",squared);
if( squared ) log.printf(" calculating the squares of the dissimilarities \n");
} else squared=true;

std::vector<Value*> mask; parseArgumentList("MASK",mask);
if( mask.size()==1 ) {
if( mask[0]->getRank()!=2 || getPntrToArgument(0)->hasDerivatives() ) error("argument passed to MASK keyword should be a matrix");
if( mask[0]->getShape()[0]!=shape[0] || mask[0]->getShape()[1]!=shape[1] ) error("argument passed to MASK keyword has the wrong shape");
log.printf(" only computing elements of matrix product that correspond to non-zero elements of matrix %s \n", mask[0]->getName().c_str() );
std::vector<Value*> allargs( getArguments() ); allargs.push_back( mask[0] ); requestArguments( allargs );
} else if( mask.size()!=0 ) error("MASK should only have one argument");
}

unsigned MatrixTimesMatrix::getNumberOfDerivatives() {
return nderivatives;
}

unsigned MatrixTimesMatrix::getNumberOfColumns() const {
if( getNumberOfArguments()>2 ) return getPntrToArgument(2)->getNumberOfColumns();
return getConstPntrToComponent(0)->getShape()[1];
}

void MatrixTimesMatrix::prepare() {
Value* myval = getPntrToComponent(0);
if( myval->getShape()[0]==getPntrToArgument(0)->getShape()[0] && myval->getShape()[1]==getPntrToArgument(1)->getShape()[1] ) return;
Expand All @@ -107,10 +121,17 @@ void MatrixTimesMatrix::getAdditionalTasksRequired( ActionWithVector* action, st
}

void MatrixTimesMatrix::setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const {
unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(1)->getShape()[1];
if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
myvals.setSplitIndex( size_v + 1 );
if( getNumberOfArguments()>2 ) {
unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(2)->getRowLength(task_index);
if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + getPntrToArgument(2)->getRowIndex(task_index, i);
myvals.setSplitIndex( size_v + 1 );
} else {
unsigned start_n = getPntrToArgument(0)->getShape()[0], size_v = getPntrToArgument(1)->getShape()[1];
if( indices.size()!=size_v+1 ) indices.resize( size_v+1 );
for(unsigned i=0; i<size_v; ++i) indices[i+1] = start_n + i;
myvals.setSplitIndex( size_v + 1 );
}
}

void MatrixTimesMatrix::performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const {
Expand Down
6 changes: 4 additions & 2 deletions src/symfunc/LocalSteinhardt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,8 @@ LocalSteinhardt::LocalSteinhardt(const ActionOptions& ao):
readInputLine( getShortcutLabel() + "_vecsT: TRANSPOSE ARG=" + getShortcutLabel() + "_vecs" );
std::string sw_str; parse("SWITCH",sw_str); readInputLine( getShortcutLabel() + "_cmap: CONTACT_MATRIX GROUP=" + sp_str + " SWITCH={" + sw_str + "}");
// And the matrix of dot products
readInputLine( getShortcutLabel() + "_dpmat: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_vecs," + getShortcutLabel() + "_vecsT" );
if( chainsAreOff() ) readInputLine( getShortcutLabel() + "_dpmat: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_vecs," + getShortcutLabel() + "_vecsT MASK=" + getShortcutLabel() + "_cmap" );
else readInputLine( getShortcutLabel() + "_dpmat: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_vecs," + getShortcutLabel() + "_vecsT");
} else if( spa_str.length()>0 ) {
// Create a group with these atoms
readInputLine( getShortcutLabel() + "_grp: GROUP ATOMS=" + spa_str );
Expand Down Expand Up @@ -422,7 +423,8 @@ LocalSteinhardt::LocalSteinhardt(const ActionOptions& ao):
// Now normalise all the vectors by doing Hadammard "product" with normalising matrix
readInputLine( getShortcutLabel() + "_vecsB: CUSTOM ARG=" + getShortcutLabel() + "_uvecsB," + getShortcutLabel() + "_nmatB FUNC=x/y PERIODIC=NO");
std::string sw_str; parse("SWITCH",sw_str); readInputLine( getShortcutLabel() + "_cmap: CONTACT_MATRIX GROUPA=" + spa_str + " GROUPB=" + spb_str + " SWITCH={" + sw_str + "}");
readInputLine( getShortcutLabel() + "_dpmat: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_vecsA," + getShortcutLabel() + "_vecsB" );
if( chainsAreOff() ) readInputLine( getShortcutLabel() + "_dpmat: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_vecsA," + getShortcutLabel() + "_vecsB MASK=" + getShortcutLabel() + "_cmap");
else readInputLine( getShortcutLabel() + "_dpmat: MATRIX_PRODUCT ARG=" + getShortcutLabel() + "_vecsA," + getShortcutLabel() + "_vecsB");
}

// Now create the product matrix
Expand Down
6 changes: 4 additions & 2 deletions src/symfunc/SMAC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,16 @@ SMAC::SMAC(const ActionOptions& ao):
readInputLine( getShortcutLabel() + "_vecs: VSTACK ARG=" + sp_lab + ".x," + sp_lab + ".y," + sp_lab + ".z" );
readInputLine( getShortcutLabel() + "_vecsT: TRANSPOSE ARG=" + getShortcutLabel() + "_vecs" );
readInputLine( getShortcutLabel() + "_cmap: CONTACT_MATRIX GROUP=" + sp_lab + " SWITCH={" + sw_input + "}");
readInputLine( getShortcutLabel() + "_tpmat: TORSIONS_MATRIX ARG=" + getShortcutLabel() + "_vecs," + getShortcutLabel() + "_vecsT POSITIONS1=" + sp_lab + " POSITIONS2=" + sp_lab );
if( chainsAreOff() ) readInputLine( getShortcutLabel() + "_tpmat: TORSIONS_MATRIX ARG=" + getShortcutLabel() + "_vecs," + getShortcutLabel() + "_vecsT POSITIONS1=" + sp_lab + " POSITIONS2=" + sp_lab + " MASK=" + getShortcutLabel() + "_cmap");
else readInputLine( getShortcutLabel() + "_tpmat: TORSIONS_MATRIX ARG=" + getShortcutLabel() + "_vecs," + getShortcutLabel() + "_vecsT POSITIONS1=" + sp_lab + " POSITIONS2=" + sp_lab );
} else if( sp_laba.length()>0 ) {
std::string sp_labb; parse("SPECIESB",sp_labb);
readInputLine( getShortcutLabel() + "_vecsa: VSTACK ARG=" + sp_laba + ".x," + sp_laba + ".y," + sp_laba + ".z" );
readInputLine( getShortcutLabel() + "_vecsb: VSTACK ARG=" + sp_labb + ".x," + sp_labb + ".y," + sp_labb + ".z" );
readInputLine( getShortcutLabel() + "_vecsbT: TRANSPOSE ARG=" + getShortcutLabel() + "_vecsb" );
readInputLine( getShortcutLabel() + "_cmap: CONTACT_MATRIX GROUPA=" + sp_laba + " GROUPB=" + sp_labb + " SWITCH={" + sw_input + "}");
readInputLine( getShortcutLabel() + "_tpmat: TORSIONS_MATRIX ARG=" + getShortcutLabel() + "_vecsa," + getShortcutLabel() + "_vecsbT POSITIONS1=" + sp_laba + " POSITIONS2=" + sp_labb );
if( chainsAreOff() ) readInputLine( getShortcutLabel() + "_tpmat: TORSIONS_MATRIX ARG=" + getShortcutLabel() + "_vecsa," + getShortcutLabel() + "_vecsbT POSITIONS1=" + sp_laba + " POSITIONS2=" + sp_labb + " MASK=" + getShortcutLabel() + "_cmap");
else readInputLine( getShortcutLabel() + "_tpmat: TORSIONS_MATRIX ARG=" + getShortcutLabel() + "_vecsa," + getShortcutLabel() + "_vecsbT POSITIONS1=" + sp_laba + " POSITIONS2=" + sp_labb );
}
// Now need the Gaussians
std::string kmap_input= getShortcutLabel() + "_ksum: COMBINE PERIODIC=NO";
Expand Down

1 comment on commit b3bc765

@PlumedBot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found broken examples in automatic/ANGLES.tmp
Found broken examples in automatic/ANN.tmp
Found broken examples in automatic/CAVITY.tmp
Found broken examples in automatic/CLASSICAL_MDS.tmp
Found broken examples in automatic/CLUSTER_DIAMETER.tmp
Found broken examples in automatic/CLUSTER_DISTRIBUTION.tmp
Found broken examples in automatic/CLUSTER_PROPERTIES.tmp
Found broken examples in automatic/CONSTANT.tmp
Found broken examples in automatic/CONTACT_MATRIX.tmp
Found broken examples in automatic/CONTACT_MATRIX_PROPER.tmp
Found broken examples in automatic/COORDINATIONNUMBER.tmp
Found broken examples in automatic/DFSCLUSTERING.tmp
Found broken examples in automatic/DISTANCE_FROM_CONTOUR.tmp
Found broken examples in automatic/EDS.tmp
Found broken examples in automatic/EMMI.tmp
Found broken examples in automatic/ENVIRONMENTSIMILARITY.tmp
Found broken examples in automatic/FIND_CONTOUR.tmp
Found broken examples in automatic/FIND_CONTOUR_SURFACE.tmp
Found broken examples in automatic/FIND_SPHERICAL_CONTOUR.tmp
Found broken examples in automatic/FOURIER_TRANSFORM.tmp
Found broken examples in automatic/FUNCPATHGENERAL.tmp
Found broken examples in automatic/FUNCPATHMSD.tmp
Found broken examples in automatic/FUNNEL.tmp
Found broken examples in automatic/FUNNEL_PS.tmp
Found broken examples in automatic/GHBFIX.tmp
Found broken examples in automatic/GPROPERTYMAP.tmp
Found broken examples in automatic/HBOND_MATRIX.tmp
Found broken examples in automatic/INCLUDE.tmp
Found broken examples in automatic/INCYLINDER.tmp
Found broken examples in automatic/INENVELOPE.tmp
Found broken examples in automatic/INTERPOLATE_GRID.tmp
Found broken examples in automatic/LOCAL_AVERAGE.tmp
Found broken examples in automatic/MAZE_OPTIMIZER_BIAS.tmp
Found broken examples in automatic/MAZE_RANDOM_ACCELERATION_MD.tmp
Found broken examples in automatic/MAZE_SIMULATED_ANNEALING.tmp
Found broken examples in automatic/MAZE_STEERED_MD.tmp
Found broken examples in automatic/METATENSOR.tmp
Found broken examples in automatic/MULTICOLVARDENS.tmp
Found broken examples in automatic/OUTPUT_CLUSTER.tmp
Found broken examples in automatic/PAMM.tmp
Found broken examples in automatic/PCA.tmp
Found broken examples in automatic/PCAVARS.tmp
Found broken examples in automatic/PIV.tmp
Found broken examples in automatic/PLUMED.tmp
Found broken examples in automatic/PYCVINTERFACE.tmp
Found broken examples in automatic/PYTHONFUNCTION.tmp
Found broken examples in automatic/Q3.tmp
Found broken examples in automatic/Q4.tmp
Found broken examples in automatic/Q6.tmp
Found broken examples in automatic/QUATERNION.tmp
Found broken examples in automatic/SIZESHAPE_POSITION_LINEAR_PROJ.tmp
Found broken examples in automatic/SIZESHAPE_POSITION_MAHA_DIST.tmp
Found broken examples in automatic/SPRINT.tmp
Found broken examples in automatic/TETRAHEDRALPORE.tmp
Found broken examples in automatic/TORSIONS.tmp
Found broken examples in automatic/WHAM_WEIGHTS.tmp
Found broken examples in AnalysisPP.md
Found broken examples in CollectiveVariablesPP.md
Found broken examples in MiscelaneousPP.md

Please sign in to comment.