26#include <boost/lexical_cast.hpp>
50 cout <<
"begin to calculate inverse monte carlo parameters\n";
52 throw runtime_error(
"error, can not have --do-imc and --include-intra");
55 cout <<
"begin to calculate distribution functions\n";
57 cout <<
"# of bonded interactions: " <<
bonded_.size() << endl;
58 cout <<
"# of non-bonded interactions: " <<
nonbonded_.size() << endl;
61 throw std::runtime_error(
62 "No interactions defined in options xml-file - nothing to be done");
91 string name = prop->get(
"name").value();
101 beads1.
Generate(*top, prop->get(
"type1").value());
102 beads2.
Generate(*top, prop->get(
"type2").value());
103 beads3.
Generate(*top, prop->get(
"type3").value());
105 if (beads1.
size() == 0) {
106 throw std::runtime_error(
107 "Topology does not have beads of type \"" +
108 prop->get(
"type1").value() +
110 "This was specified in type1 of interaction \"" +
113 if (beads2.
size() == 0) {
114 throw std::runtime_error(
115 "Topology does not have beads of type \"" +
116 prop->get(
"type2").value() +
118 "This was specified in type2 of interaction \"" +
121 if (beads3.
size() == 0) {
122 throw std::runtime_error(
123 "Topology does not have beads of type \"" +
124 prop->get(
"type3").value() +
126 "This was specified in type3 of interaction \"" +
135 if (max > max_dist) {
136 throw std::runtime_error(
"The max of interaction \"" + name +
137 "\" bigger is than half the box.");
143 beads1.
Generate(*top, prop->get(
"type1").value());
144 beads2.
Generate(*top, prop->get(
"type2").value());
146 if (beads1.
size() == 0) {
147 throw std::runtime_error(
148 "Topology does not have beads of type \"" +
149 prop->get(
"type1").value() +
151 "This was specified in type1 of interaction \"" +
154 if (beads2.
size() == 0) {
155 throw std::runtime_error(
156 "Topology does not have beads of type \"" +
157 prop->get(
"type2").value() +
159 "This was specified in type2 of interaction \"" +
164 if (prop->get(
"type1").value() == prop->get(
"type2").value()) {
173 string name = prop->get(
"name").value();
176 throw std::runtime_error(
177 "Bonded interaction '" + name +
178 "' defined in options xml-file, but not in topology - check name "
179 "definition in the mapping file again");
186 string name = p->
get(
"name").
value();
189 group = p->
get(
"inverse.imc.group").
value();
196 std::make_pair(name, std::make_unique<interaction_t>()));
199 if (group !=
"none") {
208 i->
max_ = p->
get(
"max_intra").
as<
double>();
252 throw std::runtime_error(
253 "no frames were processed. Please check your input");
278 inter.second->average_.Clear();
279 if (inter.second->force_) {
280 inter.second->average_force_.Clear();
284 group.second->corr_.setZero();
303 string name = prop->
get(
"name").
value();
311 bool gridsearch =
true;
313 if (
imc_->options_.exists(
"cg.nbsearch")) {
314 if (
imc_->options_.get(
"cg.nbsearch").as<
string>() ==
"grid") {
316 }
else if (
imc_->options_.get(
"cg.nbsearch").as<
string>() ==
"simple") {
319 throw std::runtime_error(
"cg.nbsearch invalid, can be grid or simple");
334 std::unique_ptr<NBList_3Body> nb;
339 nb = std::make_unique<NBList_3Body>();
342 nb->setCutoff(i.
cut_);
352 nb->Generate(beads1,
true);
357 nb->Generate(beads1, beads2,
true);
365 nb->Generate(beads1, beads2, beads3,
true);
368 for (
auto &triple : *nb) {
369 Eigen::Vector3d rij = triple->r12();
370 Eigen::Vector3d rik = triple->r13();
371 double var = std::acos(rij.dot(rik) /
372 sqrt(rij.squaredNorm() * rik.squaredNorm()));
387 std::unique_ptr<NBList> nb;
389 nb = std::unique_ptr<NBList>(
new NBListGrid());
391 nb = std::unique_ptr<NBList>(
new NBListGrid());
402 nb->Generate(beads1, !(
imc_->include_intra_));
404 nb->Generate(beads1, beads2, !(
imc_->include_intra_));
410 std::unique_ptr<NBList> nb_force;
412 nb_force = std::unique_ptr<NBList>(
new NBListGrid());
414 nb_force = std::unique_ptr<NBList>(
new NBListGrid());
421 nb_force->Generate(beads1);
423 nb_force->Generate(beads1, beads2);
428 for (
auto &pair : *nb_force) {
429 Eigen::Vector3d F2 = pair->second()->getF();
430 Eigen::Vector3d F1 = pair->first()->getF();
431 Eigen::Vector3d r12 = pair->r();
433 double var = pair->dist();
434 double scale = 0.5 * (F2 - F1).dot(r12);
445 string name = prop->
get(
"name").
value();
454 double v = ic->EvaluateVar(*top);
462 map<string, std::unique_ptr<group_t> >::iterator iter;
466 groups_.insert(std::make_pair(name, std::make_unique<group_t>()));
467 return success.first->second.get();
469 return (*iter).second.get();
477 map<string, group_t *>::iterator group_iter;
483 auto &grp = group.second;
486 auto &interactions = grp->interactions_;
488 votca::Index n = std::accumulate(interactions.begin(), interactions.end(),
490 return j + i->average_.getNBins();
497 M = Eigen::MatrixXd::Zero(n, n);
509 pair_matrix corr = M.block(offset_i, offset_j, n1, n2);
511 grp->pairs_.push_back(
512 pair_t(interactions[i], interactions[j], offset_i, offset_j, corr));
527 auto &grp = group.second;
529 for (
auto &pair : grp->pairs_) {
530 Eigen::VectorXd &a = worker->
current_hists_[pair.i1_->index_].data().y();
531 Eigen::VectorXd &b = worker->
current_hists_[pair.i2_->index_].data().y();
534 M = ((((double)
nframes_ - 1.0) * M) + a * b.transpose()) /
542 map<string, interaction_t *>::iterator iter;
549 auto &interaction = pair.second;
555 if (interaction->force_) {
556 force = interaction->average_force_.data();
560 if (!interaction->is_bonded_) {
562 if (interaction->threebody_) {
564 double norm = dist.
y().cwiseAbs().sum();
567 interaction->norm_ * dist.
y() / (norm * interaction->step_);
572 if (!interaction->threebody_) {
578 if (dist.
y()[i] != 0) {
579 force.
y()[i] /= dist.
y()[i];
590 double x1 = dist.
x()[i] - 0.5 * interaction->step_;
591 double x2 = x1 + interaction->step_;
595 dist.
y()[i] =
avg_vol_.getAvg() * interaction->norm_ * dist.
y()[i] /
596 (4. / 3. * M_PI * (x2 * x2 * x2 - x1 * x1 * x1));
603 double norm = dist.
y().cwiseAbs().sum();
605 dist.
y() = interaction->norm_ * dist.
y() / (norm * interaction->step_);
609 dist.
Save((pair.first) + suffix);
610 cout <<
"written " << (pair.first) + suffix <<
"\n";
613 if (interaction->force_) {
614 force.
Save((pair.first) +
".force.new");
615 cout <<
"written " << (pair.first) +
".force.new" <<
"\n";
631 map<string, group_t *>::iterator group_iter;
635 auto &grp = group.second;
636 string grp_name = group.first;
648 vector<std::pair<std::string, votca::tools::RangeParser> >
658 Eigen::VectorBlock<Eigen::VectorXd> sub_dS =
662 Eigen::VectorBlock<Eigen::VectorXd> sub_r =
675 ranges.push_back(std::pair<std::string, votca::tools::RangeParser>(
676 ic->
p_->
get(
"name").
as<
string>(), rp));
686 for (
pair_t &pair : grp->pairs_) {
701 M = -(M - a * b.transpose());
703 gmc.block(j, i, n2, n1) = M.transpose().eval();
714 Eigen::VectorBlock<Eigen::VectorXd> &dS) {
715 const string &name = interaction->
p_->
get(
"name").
as<
string>();
718 target.
Load(name +
".dist.tgt");
722 double x1 = target.x()[i] - 0.5 * interaction->
step_;
723 double x2 = x1 + interaction->
step_;
727 target.y()[i] = 1. / (
avg_vol_.getAvg() * interaction->
norm_) *
729 (4. / 3. * M_PI * (x2 * x2 * x2 - x1 * x1 * x1));
732 target.y() = (1.0 / interaction->
norm_) * target.y();
734 if (target.y().size() != interaction->
average_.
data().
y().size()) {
735 throw std::runtime_error(
736 "number of grid points in target does not match the grid");
750 auto &grp = group.second;
751 string grp_name = group.first;
752 list<interaction_t *>::iterator iter;
759 Eigen::VectorXd dS(n);
760 Eigen::VectorXd r(n);
763 vector<votca::Index> sizes;
764 vector<string> names;
770 Eigen::VectorBlock<Eigen::VectorXd> sub_dS =
774 Eigen::VectorBlock<Eigen::VectorXd> sub_r =
784 names.push_back(ic->
p_->
get(
"name").
as<
string>());
792 string name_dS = grp_name + suffix +
".S";
793 out_dS.open(name_dS);
794 out_dS << setprecision(8);
796 throw runtime_error(
string(
"error, cannot open file ") + name_dS);
800 out_dS << r[i] <<
" " << dS[i] << endl;
804 cout <<
"written " << name_dS << endl;
808 string name_cor = grp_name + suffix +
".cor";
809 out_cor.open(name_cor);
810 out_cor << setprecision(8);
813 throw runtime_error(
string(
"error, cannot open file ") + name_cor);
818 out_cor << grp->corr_(i, j) <<
" ";
823 cout <<
"written " << name_cor << endl;
829 auto worker = std::make_unique<Imc::Worker>();
835 auto &i = interaction.second;
836 worker->current_hists_[i->index_].Initialize(
837 i->average_.getMin(), i->average_.getMax(), i->average_.getNBins());
839 if (interaction.second->force_) {
840 worker->current_hists_force_[i->index_].Initialize(
841 i->average_force_.getMin(), i->average_force_.getMax(),
842 i->average_force_.getNBins());
852 map<string, interaction_t *>::iterator ic_iter;
858 auto &i = interaction.second;
859 i->average_.data().y() =
860 (((double)
nframes_ - 1.0) * i->average_.data().y() +
865 i->average_force_.data().y() =
866 (((double)
nframes_ - 1.0) * i->average_force_.data().y() +
880 string suffix = string(
"_") + boost::lexical_cast<string>(
nblock_) +
Index Generate(Topology &top, const std::string &select)
Select all beads of type "select".
Worker, derived from Thread, does the work.
bool FoundPair(Bead *, Bead *, const Eigen::Vector3d &, const double dist)
bool FoundPair(Bead *b1, Bead *, const Eigen::Vector3d &, const double dist)
IMCNBSearchHandler(votca::tools::Histogram *hist)
std::vector< tools::Histogram > current_hists_force_
void EvalConfiguration(Topology *top, Topology *top_atom) override
evaluate current conformation
void DoNonbonded(Topology *top)
process non-bonded interactions for given frame
std::vector< tools::Histogram > current_hists_
void DoBonded(Topology *top)
process bonded interactions for given frame
Eigen::MatrixXd group_matrix
interaction_t * AddInteraction(tools::Property *p, bool is_bonded)
create a new interaction entry based on given options
votca::Index block_length_
std::unique_ptr< CsgApplication::Worker > ForkWorker()
void WriteIMCData(const std::string &suffix="")
void EndEvaluate()
end coarse graining a trajectory
tools::Average< double > avg_vol_
tools::Property options_
the options parsed from cg definition file
void InitializeGroups()
initializes the group structs after interactions were added
std::map< std::string, std::unique_ptr< group_t > > groups_
map group-name to group
std::vector< tools::Property * > nonbonded_
list of non-bonded interactions
std::map< std::string, std::unique_ptr< interaction_t > > interactions_
map interaction-name to interaction
void MergeWorker(CsgApplication::Worker *worker_)
void DoCorrelations(Imc::Worker *worker)
update the correlations after interations were processed
bool processed_some_frames_
std::vector< tools::Property * > bonded_
list of bonded interactions
void WriteDist(const std::string &suffix="")
void BeginEvaluate(Topology *top, Topology *top_atom)
begin coarse graining a trajectory
void CalcDeltaS(interaction_t *interaction, Eigen::VectorBlock< Eigen::VectorXd > &dS)
void WriteIMCBlock(const std::string &suffix)
void LoadOptions(const std::string &file)
load cg definitions file
Eigen::Block< group_matrix > pair_matrix
group_t * getGroup(const std::string &name)
get group by name, creates one if it doesn't exist
base class for all interactions
topology of the whole system
std::vector< Interaction * > InteractionsInGroup(const std::string &group)
double ShortestBoxSize() const
return the shortest box size
void imcio_write_dS(const std::string &file, const tools::Table &dS, const std::list< Index > *list=nullptr)
void imcio_write_index(const std::string &file, const std::vector< std::pair< std::string, tools::RangeParser > > &ranges)
void imcio_write_matrix(const std::string &file, const Eigen::MatrixXd &gmc, const std::list< Index > *list=nullptr)
Provides a means for comparing floating point numbers.
struct to store collected information for groups (e.g. crosscorrelations)
std::vector< interaction_t * > interactions_
struct to store collected information for interactions
tools::Histogram average_
tools::Histogram average_force_