Skip to content

Commit

Permalink
Fix Colvars#569 and allow mixing scalar and vector CVCs
Browse files Browse the repository at this point in the history
  • Loading branch information
HanatoK committed Aug 28, 2023
1 parent 110b08f commit 80bc185
Showing 1 changed file with 2 additions and 15 deletions.
17 changes: 2 additions & 15 deletions src/colvarcomp_combination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,8 @@ colvar::linearCombination::linearCombination(std::string const &conf): cvc(conf)
" expects one or more nesting components.\n");
return;
} else {
// TODO: Maybe we can add an option to allow mixing scalar and vector types,
// but that's a bit complicated so we just require a consistent type
// of nesting CVs.
x.type(cv[0]->value());
x.reset();
for (size_t i_cv = 1; i_cv < cv.size(); ++i_cv) {
const auto type_i = cv[i_cv]->value().type();
if (type_i != x.type()) {
cvm::error("Error: the type of sub-CVC " + cv[i_cv]->name +
" is " + colvarvalue::type_desc(type_i) + ", which is "
"different to the type of the first sub-CVC. Currently "
"only sub-CVCs of the same type are supported to be "
"nested.\n");
return;
}
}
}
use_explicit_gradients = true;
for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
Expand Down Expand Up @@ -317,7 +303,8 @@ void colvar::customColvar::apply_force(colvarvalue const &force) {
}
} else {
const colvarvalue& current_cv_value = cv[i_cv]->value();
colvarvalue cv_force(current_cv_value.type());
colvarvalue cv_force(current_cv_value);
cv_force.reset();
const cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
for (size_t j_elem = 0; j_elem < current_cv_value.size(); ++j_elem) {
for (size_t c = 0; c < x.size(); ++c) {
Expand Down

1 comment on commit 80bc185

@HanatoK
Copy link
Owner Author

Choose a reason for hiding this comment

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

I am not very sure about the exact requirement on the sub-cvcs of linearcombination (and its subclasses). But it seems that the function colvar::linearCombination::calc_value() actually requires sub-cvcs are either all scalars or all vectors of the same length, since it contains the following lines:

    if (current_cv_value.type() == colvarvalue::type_scalar) {
        x += cv[i_cv]->sup_coeff * (cvm::pow(current_cv_value.real_value, cv[i_cv]->sup_np));
    } else {
        x += cv[i_cv]->sup_coeff * current_cv_value;
    }

Yes. In the linearCombination class if the types are different then there will be an error raised in calc_value(). I remove that requirement in the constructor, so that the derived classes such as torchann and customColvar can use something like

colvar {
    name nn_0
    width 0.05
    extendedLagrangian on
    extendedFluctuation 0.1
    extendedTimeConstant 200
    customColvar {
        name z
        customFunction x+y2
        dihedral {
            group1 {atomNumbers {25}}
            group2 {atomNumbers {27}}
            group3 {atomNumbers {29}}
            group4 {atomNumbers {35}}
        }
        cartesian {
            name y
            atoms {
                atomNumbers {35}
            }
        }
    }
}

which is not possible before this commit.

Please sign in to comment.