LBIBCell
 All Classes Functions Variables Friends Pages
ForceSolver.cpp
1 /* Copyright (c) 2013 David Sichau <mail"at"sichau"dot"eu>
2  * 2013-2015 Simon Tanaka <tanakas"at"gmx"dot"ch>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 #include <LbmLib/include/Field.hpp>
23 #include <LbmLib/include/nodes/EulerianPoint.hpp>
24 #include <LbmLib/include/nodes/GeometryNode.hpp>
25 #include <LbmLib/include/solver/ForceSolver.hpp>
26 #include <LbmLib/include/solver/ForceStructs.hpp>
27 #include <UtilLib/include/Exception.hpp>
28 #include <omp.h>
29 #include <fstream>
30 #include <iostream>
31 #include <map>
32 #include <memory>
33 #include <sstream>
34 #include <string>
35 
36 namespace LbmLib {
37 namespace solver {
38 
40 {}
41 
42 void ForceSolver::calculateForce(const std::map<unsigned int,
43  std::shared_ptr<nodes::GeometryNode> >& nodes) {
44  std::vector< std::shared_ptr<AbstractForceStruct> > tempforcevector;
45 
46  const size_t nodes_length = nodes.size();
47  typedef std::map<unsigned int, std::shared_ptr<nodes::GeometryNode> >::const_iterator temp_map_it;
48  std::vector<temp_map_it> helper_nodes;
49 
50  // create the array of iterators sequentially:
51  auto nodes_it = nodes.begin();
52  for (size_t j=0;
53  j<nodes_length;
54  ++j)
55  {
56  helper_nodes.push_back(nodes_it++);
57  }
58 
59  // reset all forces on the GeometryNodes:
60 #pragma omp parallel for schedule(static)
61  for (size_t it=0; it<nodes_length; ++it) {
62  helper_nodes[it]->second->setForce(Field<double>(0.0, 0.0));
63  }
64 
65  auto forcemap_length = this->forcemap_.size();
66  std::vector<map_forcestruct::iterator> helper_forcemap;
67 
68  // create the array of iterators sequentially:
69  auto forcemap_it = this->forcemap_.begin();
70  for (size_t j=0;
71  j<forcemap_length;
72  ++j) {
73  helper_forcemap.push_back(forcemap_it++);
74  }
75 
76  // compute forces (parallelized):
77 # pragma omp parallel for schedule(static)
78  for (size_t it=0;
79  it<forcemap_length;
80  ++it) {
81  for (auto in : helper_forcemap[it]->second) {
82  in->calculateForce(nodes);
83  }
84  }
85 }
86 
88 
89 void ForceSolver::loadForceFile(const std::string& filename) {
90  std::ifstream fileStream;
91  fileStream.open(filename);
92  if (fileStream.is_open()) {
93  std::string line;
94  while (std::getline(fileStream, line)) {
95  std::stringstream lineStream(line);
96 
97  if (line.at(0) != '#') {
98  this->addForce(&lineStream);
99  }
100  }
101  } else {
102  lbm_fail("Cannot find the force solver file.");
103  }
104  fileStream.close();
105 }
106 
107 void ForceSolver::addForce(std::stringstream * const forcedescriptor)
108 {
109  unsigned int type, nodeid;
110  std::stringstream copyforcedescriptor(forcedescriptor->str()); // copy
111  copyforcedescriptor >> type >> nodeid;
112  if (type == 0) {
113 #pragma omp critical
114  this->forcemap_[nodeid].push_back(LbmLib::solver::ForceStructs::loadForceType0(forcedescriptor));
115  } else if (type == 1) {
116 #pragma omp critical
117  this->forcemap_[nodeid].push_back(LbmLib::solver::ForceStructs::loadForceType1(forcedescriptor));
118  } else if (type == 2) {
119 #pragma omp critical
120  this->forcemap_[nodeid].push_back(LbmLib::solver::ForceStructs::loadForceType2(forcedescriptor));
121  } else if (type == 3) {
122 #pragma omp critical
123  this->forcemap_[nodeid].push_back(LbmLib::solver::ForceStructs::loadForceType3(forcedescriptor));
124  } else if (type == 4) {
125 #pragma omp critical
126  this->forcemap_[nodeid].push_back(LbmLib::solver::ForceStructs::loadForceType4(forcedescriptor));
127  } else if (type == 5) {
128 #pragma omp critical
129  this->forcemap_[nodeid].push_back(LbmLib::solver::ForceStructs::loadForceType5(forcedescriptor));
130  } else if (type == 6) {
131 #pragma omp critical
132  this->forcemap_[nodeid].push_back(LbmLib::solver::ForceStructs::loadForceType6(forcedescriptor));
133  } else if (type == 7) {
134 #pragma omp critical
135  this->forcemap_[nodeid].push_back(LbmLib::solver::ForceStructs::loadForceType7(forcedescriptor));
136  } else {
137  lbm_fail("Invalid force solver type found.");
138  }
139 }
140 
141 void ForceSolver::writeForceSolver(const std::string& filename) const {
142  std::ofstream fileStream;
143  fileStream.open(filename);
144  if (fileStream.is_open()) {
145  for (auto it1=this->forcemap_.begin();
146  it1!=this->forcemap_.end();
147  ++it1) {
148  for (auto it2 : it1->second) {
149  it2->writeForceStruct(&fileStream);
150  }
151  }
152  } else {
153  throw UtilLib::Exception(
154  "Problem to open the output file for the force solver");
155  }
156 }
157 
159 {
160  for (auto it : this->forcemap_) {
161  it.second.clear();
162  assert(it.second.size()==0 && "ForceSolver::deleteAllForces: couldn't clear forcemap_");
163  }
164  this->forcemap_.clear();
165  assert(this->forcemap_.size()==0 && "ForceSolver::deleteAllForces: couldn't clear forcemap_");
166 }
167 
168 void ForceSolver::deleteForceType(const unsigned int forcetype)
169 {
170  // omp can't deal with non-random-access-iterators :(
171  const auto forcemap_length = this->forcemap_.size();
172 
173  std::vector<map_forcestruct::iterator> helper_map;
174  auto map_it = this->forcemap_.begin();
175 
176  // create array of iterators sequentally:
177  for (size_t j=0;
178  j<forcemap_length;
179  ++j) {
180  helper_map.push_back(map_it++);
181  }
182 
186 //#pragma omp parallel for schedule(static)
187  for (size_t j=0;
188  j<forcemap_length;
189  ++j) {
190  // erase-remove idiom:
191  helper_map[j]->second.erase( std::remove_if(helper_map[j]->second.begin(),
192  helper_map[j]->second.end(),
193  [forcetype](std::shared_ptr<AbstractForceStruct> force){
194  if (force->getType() == forcetype) {
195  return true;
196  }
197  else {
198  return false;
199  }
200  }),
201  helper_map[j]->second.end()
202  );
203  }
204 }
205 
206 std::vector<std::shared_ptr<AbstractForceStruct> > ForceSolver::getForcesOfNode(std::vector<std::shared_ptr<AbstractForceStruct> > &forcevector,
207  const unsigned int nodeid)
208 {
209  forcevector.clear();
210  assert(forcevector.size()==0 && "ForceSolver::getForcesOfNode: non-empty forcevector");
211 
212  if ( this->forcemap_.find(nodeid) == this->forcemap_.end() ) { // no forces
213  return forcevector;
214  } else {
215  forcevector.insert(forcevector.end(),
216  this->forcemap_[nodeid].begin(),
217  this->forcemap_[nodeid].end()
218  );
219  }
220  return forcevector;
221 }
222 
223 const map_forcestruct ForceSolver::getAllForces() const
224 {
225  return this->forcemap_;
226 }
227 
228 
229 }
230 } // end namespace
231 
void deleteForceType(const unsigned int forcetype)
reset all forces
~ForceSolver()
The destructor.
Definition: ForceSolver.cpp:87
vec_shptr_forcestruct getForcesOfNode(vec_shptr_forcestruct &forcevector, const unsigned int nodeid)
get all forces of nodeid
ForceSolver()
The constructor.
Definition: ForceSolver.cpp:39
void writeForceSolver(const std::string &filename) const
writes the forces to the file
void addForce(std::stringstream *const forcedescriptor)
add a force
const map_forcestruct getAllForces() const
getAllForces returns the entire map {nodeid, AbstractForceStruct}
void loadForceFile(const std::string &filename)
loading of the force solver
Definition: ForceSolver.cpp:89
void deleteAllForces()
reset all forces
void calculateForce(const std::map< unsigned int, std::shared_ptr< nodes::GeometryNode > > &nodes)
calculates the Force
Definition: ForceSolver.cpp:42