58 void AddElem(
const Bead *in,
double weight,
double force_weight);
86 for (
auto &map_ :
maps_) {
99 vector<double> fweights;
107 vector<double> weights = tok_weights.
ToVector<
double>();
110 if (beads.size() != weights.size()) {
112 string(
"number of subbeads in " + opts_bead->
get(
"name").
as<
string>() +
113 " and number of weights in map " +
114 opts_map->
get(
"name").
as<
string>() +
" do not match"));
118 double norm = 1. / std::accumulate(weights.begin(), weights.end(), 0.);
120 transform(weights.begin(), weights.end(), weights.begin(),
121 [&norm](
double w) { return w * norm; });
126 d = tok_weights2.
ToVector<
double>();
128 norm = 1. / std::accumulate(d.begin(), d.end(), 0.);
129 transform(d.begin(), d.end(), d.begin(),
130 [&norm](
double w) { return w * norm; });
133 d.resize(weights.size());
134 copy(weights.begin(), weights.end(), d.begin());
138 if (beads.size() != d.size()) {
140 string(
"number of subbeads in " + opts_bead->
get(
"name").
as<
string>() +
141 " and number of d-coefficients in map " +
142 opts_map->
get(
"name").
as<
string>() +
" do not match"));
145 fweights.resize(weights.size());
147 for (
size_t i = 0; i < weights.size(); ++i) {
148 if (weights[i] == 0 && d[i] != 0) {
150 "A d coefficient is nonzero while weights is zero in mapping " +
151 opts_map->
get(
"name").
as<
string>());
153 if (weights[i] != 0) {
154 fweights[i] = d[i] / weights[i];
160 for (
size_t i = 0; i < beads.size(); ++i) {
163 throw std::runtime_error(
164 string(
"mapping error: molecule " + beads[i] +
" does not exist"));
172 assert(
matrix_.size() > 0 &&
"Cannot map to sphere there are no beads");
175 bPos = bVel = bF =
false;
176 out_->ClearParentBeads();
179 Eigen::Vector3d r0 = Eigen::Vector3d::Zero();
183 if (
matrix_.front().in_->HasPos()) {
184 r0 =
matrix_.front().in_->getPos();
185 name0 =
matrix_.front().in_->getName();
186 id0 =
matrix_.front().in_->getId();
191 Eigen::Vector3d cg = Eigen::Vector3d::Zero();
192 Eigen::Vector3d f = Eigen::Vector3d::Zero();
193 Eigen::Vector3d vel = Eigen::Vector3d::Zero();
196 double max_bead_dist = 0;
197 if (bead_max_dist->
HasPos()) {
201 for (
const auto &iter :
matrix_) {
202 const Bead *bead = iter.in_;
207 if (r.norm() > max_bead_dist) {
208 max_bead_dist = r.norm();
209 bead_max_dist = bead;
211 cg += iter.weight_ * (r + r0);
220 if (max_bead_dist > max_dist) {
221 cout << r0 <<
" " << bead_max_dist->
getPos() << endl;
222 throw std::runtime_error(
223 "coarse-grained bead is bigger than half the box \n "
225 name0 +
" (id " + boost::lexical_cast<string>(id0 + 1) +
")" +
", " +
226 bead_max_dist->
getName() +
" (id " +
227 boost::lexical_cast<string>(bead_max_dist->
getId() + 1) +
")" +
229 boost::lexical_cast<string>(bead_max_dist->
getMoleculeId() + 1) +
234 for (
const auto &iter :
matrix_) {
235 const Bead *bead = iter.in_;
237 vel += iter.weight_ * bead->
getVel();
241 f += iter.force_weight_ * bead->
getF();
260 assert(
matrix_.size() > 0 &&
"Cannot map to ellipsoid there are no beads");
263 bPos = bVel = bF =
false;
266 Eigen::Vector3d r0 = Eigen::Vector3d::Zero();
270 if (
matrix_.front().in_->HasPos()) {
271 r0 =
matrix_.front().in_->getPos();
272 name0 =
matrix_.front().in_->getName();
273 id0 =
matrix_.front().in_->getId();
276 Eigen::Vector3d cg = Eigen::Vector3d::Zero();
277 Eigen::Vector3d c = Eigen::Vector3d::Zero();
278 Eigen::Vector3d f = Eigen::Vector3d::Zero();
279 Eigen::Vector3d vel = Eigen::Vector3d::Zero();
283 out_->ClearParentBeads();
286 double max_bead_dist = 0;
287 if (bead_max_dist->
HasPos()) {
291 for (
const auto &iter :
matrix_) {
292 const Bead *bead = iter.in_;
296 if (r.norm() > max_bead_dist) {
297 max_bead_dist = r.norm();
298 bead_max_dist = bead;
300 cg += iter.weight_ * (r + r0);
309 if (max_bead_dist > max_dist) {
310 cout << r0 <<
" " << bead_max_dist->
getPos() << endl;
311 throw std::runtime_error(
312 "coarse-grained bead is bigger than half the box \n "
314 name0 +
" (id " + boost::lexical_cast<string>(id0 + 1) +
")" +
", " +
315 bead_max_dist->
getName() +
" (id " +
316 boost::lexical_cast<string>(bead_max_dist->
getId() + 1) +
")" +
318 boost::lexical_cast<string>(bead_max_dist->
getMoleculeId() + 1) +
323 for (
const auto &iter :
matrix_) {
324 const Bead *bead = iter.in_;
325 if (bead->
HasVel() ==
true) {
326 vel += iter.weight_ * bead->
getVel();
333 f += iter.force_weight_ * bead->
getF();
337 if (iter.weight_ > 0 && bead->
HasPos()) {
354 out_->setU(Eigen::Vector3d::UnitX());
355 out_->setV(Eigen::Vector3d::UnitY());
356 out_->setW(Eigen::Vector3d::UnitZ());
360 Eigen::Matrix3d m = Eigen::Matrix3d::Zero();
364 if (iter.weight_ == 0) {
367 const Bead *bead = iter.in_;
368 Eigen::Vector3d v = bead->
getPos() - c;
374 m += v * v.transpose() / (double)
matrix_.size();
377 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eig;
378 eig.computeDirect(m);
380 Eigen::Vector3d u = eig.eigenvectors().col(0);
381 Eigen::Vector3d v =
matrix_[1].in_->getPos() -
matrix_[0].in_->getPos();
386 Eigen::Vector3d w =
matrix_[2].in_->getPos() -
matrix_[0].in_->getPos();
389 if (v.cross(w).dot(u) < 0) {
406 maps_ = std::move(map.maps_);
412 maps_.push_back(std::make_unique<Map_Sphere>());
414 maps_.push_back(std::make_unique<Map_Ellipsoid>());
416 return maps_.back().get();
virtual const Eigen::Vector3d & getPos() const
std::string getName() const
Gets the name of the bead.
Index getMoleculeId() const noexcept
Get the id of the molecule the bead is a part of, if the molecule id has not been set return topology...
virtual const double & getMass() const noexcept
bool HasPos() const noexcept
Index getId() const noexcept
Gets the id of the bead.
tools::Property * opts_map_
tools::Property * opts_bead_
const Eigen::Vector3d & getF() const
get the force acting on the bead
bool HasF() const noexcept
bool HasVel() const noexcept
const Eigen::Vector3d & getVel() const
Class keeps track of how the boundaries of the system are handled.
double getShortestBoxDimension() const
Self explanatory gets the shortest dimension of the boundary conditions.
virtual Eigen::Vector3d BCShortestConnection(const Eigen::Vector3d &r_i, const Eigen::Vector3d &r_j) const =0
virtual eBoxtype getBoxType() const noexcept=0
void Apply(const BoundaryCondition &) final
void AddElem(const Bead *in, double weight, double force_weight)
void Apply(const BoundaryCondition &) override
std::vector< element_t > matrix_
virtual void Initialize(const Molecule *in, Bead *out, tools::Property *opts_bead, tools::Property *opts_map) override
void Apply(const BoundaryCondition &bc)
BeadMap * CreateBeadMap(const BeadMapType type)
Map & operator=(Map &&map)
Map(const Molecule &in, Molecule &out)
std::vector< std::unique_ptr< BeadMap > > maps_
information about molecules
Bead * getBead(Index bead)
get the id of a bead in the molecule
Index getBeadByName(const std::string &name) const
find a bead by it's name
base class for all analysis tools