|
691 | 691 | } |
692 | 692 | }; |
693 | 693 |
|
| 694 | +/// A decorator for fixing the state of the trajectory |
| 695 | +class fixedTrajectory: public AtomDistribution { |
| 696 | + std::unique_ptr<AtomDistribution> distribution; |
| 697 | + std::array<double,9> fixedBox= {0.0,0.0,0.0, |
| 698 | + 0.0,0.0,0.0, |
| 699 | + 0.0,0.0,0.0 |
| 700 | + }; |
| 701 | + std::vector<Vector> positions= {}; |
| 702 | + unsigned stride=0; |
| 703 | + bool generate=true; |
| 704 | +public: |
| 705 | + static constexpr auto id="fix"; |
| 706 | + static constexpr auto doc=R"=(Fixes the trajectory for stride steps, or forever if stride is 0 |
| 707 | +usage: |
| 708 | + "fix stride(optional)")="; |
| 709 | + |
| 710 | + static std::unique_ptr<AtomDistribution> decorate( |
| 711 | + std::unique_ptr<AtomDistribution>&& d, |
| 712 | + std::string_view cmd) { |
| 713 | + unpackedLine lines; |
| 714 | + Tools::getWordsSimple(lines,cmd); |
| 715 | + plumed_assert(lines.size() <= 2) << id << " supports only one optional parameter for the stride"; |
| 716 | + |
| 717 | + if (lines.size()==2) { |
| 718 | + unsigned newStride=0; |
| 719 | + Tools::convert(std::string(lines[1]), newStride); |
| 720 | + return std::make_unique<fixedTrajectory>(std::move(d),newStride); |
| 721 | + } |
| 722 | + //the default value is specified in the header |
| 723 | + return std::make_unique<fixedTrajectory>(std::move(d)); |
| 724 | + } |
| 725 | + fixedTrajectory(std::unique_ptr<AtomDistribution>&& d, |
| 726 | + unsigned newStride=0): |
| 727 | + distribution(std::move(d)), |
| 728 | + stride(newStride) |
| 729 | + {} |
| 730 | + |
| 731 | + void frame(View<Vector> posToUpdate, |
| 732 | + View<double,9> box, |
| 733 | + unsigned step, |
| 734 | + Random& rng) override { |
| 735 | + generate = (!generate && stride>0) ? |
| 736 | + step%stride==0 |
| 737 | + : generate; |
| 738 | + if (generate) { |
| 739 | + positions.resize(posToUpdate.size()); |
| 740 | + distribution->frame( |
| 741 | + make_view(positions), |
| 742 | + View<double,9>(fixedBox.data()), |
| 743 | + step,rng); |
| 744 | + generate=false; |
| 745 | + } |
| 746 | + plumed_assert(positions.size() == posToUpdate.size()) << "fixed atom distributions: the expected number of atoms changed"; |
| 747 | + std::copy(positions.begin(),positions.end(),posToUpdate.begin()); |
| 748 | + box[0] = fixedBox[0]; |
| 749 | + box[1] = fixedBox[1]; |
| 750 | + box[2] = fixedBox[2]; |
| 751 | + box[3] = fixedBox[3]; |
| 752 | + box[4] = fixedBox[4]; |
| 753 | + box[5] = fixedBox[5]; |
| 754 | + box[6] = fixedBox[6]; |
| 755 | + box[7] = fixedBox[7]; |
| 756 | + box[8] = fixedBox[8]; |
| 757 | + } |
| 758 | + |
| 759 | + bool overrideNat(unsigned& natoms) override { |
| 760 | + return distribution->overrideNat(natoms); |
| 761 | + } |
| 762 | +}; |
694 | 763 | //****************************Helpers and managements*************************** |
695 | 764 |
|
696 | 765 |
|
@@ -753,7 +822,8 @@ using decoratorDistribuitions = std::variant< |
753 | 822 | repliedTrajectory, |
754 | 823 | scaledTrajectory, |
755 | 824 | wiggleTrajectory, |
756 | | - forceBoxTrajectory>; |
| 825 | + forceBoxTrajectory, |
| 826 | + fixedTrajectory>; |
757 | 827 |
|
758 | 828 | template <size_t I=0> |
759 | 829 | std::optional<std::unique_ptr<AtomDistribution>> getAD(std::string_view atomicDistr) { |
|
0 commit comments