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;
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();
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) {
401 : in_(map.in_), out_(map.out_), maps_(
std::move(map.maps_)) {}
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 void setMass(const double &m) noexcept
virtual const Eigen::Vector3d & getPos() const
std::string getName() const
Gets the name of the bead.
virtual void setPos(const Eigen::Vector3d &bead_position)
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
void ClearParentBeads()
Clears out all parent beads.
void setU(const Eigen::Vector3d &u)
set first orientation (normal vector) vector of bead
bool HasF() const noexcept
void setF(const Eigen::Vector3d &bead_force)
bool HasVel() const noexcept
void setW(const Eigen::Vector3d &w)
set third orientation vector of bead
void setVel(const Eigen::Vector3d &r)
void AddParentBead(Index parent_bead_id)
Adds the id of a parent bead.
const Eigen::Vector3d & getVel() const
void setV(const Eigen::Vector3d &v)
set second orientation vector of bead
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