MDStressLab++
StressTuple.h
Go to the documentation of this file.
1 /*
2  * StressTuple.h
3  *
4  * Created on: Dec 15, 2019
5  * Author: Nikhil
6  */
7 
8 #ifndef INCLUDE_STRESSTUPLE_H_
9 #define INCLUDE_STRESSTUPLE_H_
10 
11 // Recursively build stress of a type sType= Piola/Cauchy
12 template<std::size_t I=0, typename ...TStress>
13 inline typename std::enable_if<I == sizeof...(TStress), void>::type
14  recursiveBuildStress(const double& fij,
15  const Vector3d& ra,
16  const Vector3d& rA,
17  const Vector3d& rb,
18  const Vector3d& rB,
19  const Vector3d& rab,
20  const Vector3d& rAB,
21  const int& i_gridPoint,
22  const int& i_stress,
23  std::tuple<TStress&...> t)
24 {
25  if (sizeof...(TStress)!=0)
26  assert(0);
27 }
28 template<std::size_t I=0, StressType stressType, typename ...BF>
29 inline typename std::enable_if<I < sizeof...(BF), void>::type
30  recursiveBuildStress(const double& fij,
31  const Vector3d& ra,
32  const Vector3d& rA,
33  const Vector3d& rb,
34  const Vector3d& rB,
35  const Vector3d& rab,
36  const Vector3d& rAB,
37  const int& i_gridPoint,
38  const int& i_stress,
39  std::tuple<Stress<BF,stressType>&...> t)
40 {
41  if (I == i_stress && stressType == Cauchy)
42  {
43  assert(rab.squaredNorm()>epsilon);
44  std::get<I>(t).field[i_gridPoint]= std::get<I>(t).field[i_gridPoint] +
45  std::get<I>(t).method.bondFunction(ra,rb)*fij*rab.transpose()*rab/rab.norm();
46  }
47  else if (I == i_stress && stressType == Piola)
48  {
49  assert(rab.squaredNorm()>epsilon);
50  std::get<I>(t).field[i_gridPoint]= std::get<I>(t).field[i_gridPoint] +
51  std::get<I>(t).method.bondFunction(rA,rB)*fij*rAB.transpose()*rab/rab.norm();
52  }
53  else
54  recursiveBuildStress<I+1>(fij,ra,rA,rb,rB,rab,rAB,i_gridPoint,i_stress,t);
55 }
56 
57 // Recursively nullify stress of a type sType= Piola/Cauchy
58 template<std::size_t I=0, typename ...TStress>
59 inline typename std::enable_if<I == sizeof...(TStress), void>::type
60 recursiveNullifyStress(std::tuple<TStress&...> t)
61 {
62 }
63 template<std::size_t I=0, StressType stressType, typename ...BF>
64 inline typename std::enable_if<I < sizeof...(BF), void>::type
65 recursiveNullifyStress(std::tuple<Stress<BF,stressType>&...> t)
66 {
67  std::fill(std::get<I>(t).field.begin(), std::get<I>(t).field.end(),Matrix3d::Zero() );
68  recursiveNullifyStress<I+1>(t);
69 }
70 
72 double averagingDomainSize_max(const std::tuple<> t)
73 {
74  return 0;
75 }
76 template<std::size_t I=0, typename ...TStress>
77 inline typename std::enable_if<I == sizeof...(TStress)-1, double>::type
78  averagingDomainSize_max(const std::tuple<TStress&...> t)
79 {
80  return std::get<I>(t).method.getAveragingDomainSize();
81 }
82 template<std::size_t I=0, typename ...TStress>
83 inline typename std::enable_if<I < sizeof...(TStress)-1, double>::type
84  averagingDomainSize_max(const std::tuple<TStress&...> t)
85 {
86  return std::max(std::get<I>(t).method.getAveragingDomainSize(),averagingDomainSize_max<I+1>(t));
87 }
88 
91 std::map<Grid<Reference>*,double> recursiveGridMaxAveragingDomainSizeMap(const std::tuple<>& t)
92 {
93 std::map<Grid<Reference>*,double> map;
94 return map;
95 }
96 template<std::size_t I=0, StressType stressType,
97  typename TGrid= typename std::conditional<stressType == Piola,Grid<Reference>,Grid<Current>>::type,
98  typename ...BF>
99 inline typename std::enable_if<I == sizeof...(BF), std::map<TGrid*,double>>::type
100  recursiveGridMaxAveragingDomainSizeMap(const std::tuple<Stress<BF,stressType>&...> t)
101 {
102  std::map<TGrid*,double> map;
103  return map;
104 }
105 template<std::size_t I=0, StressType stressType,
106  typename TGrid= typename std::conditional<stressType == Piola,Grid<Reference>,Grid<Current>>::type,
107  typename ...BF>
108 inline typename std::enable_if<I < sizeof...(BF), std::map<TGrid*,double>>::type
109  recursiveGridMaxAveragingDomainSizeMap(const std::tuple<Stress<BF,stressType>&...> t)
110 {
111  std::map<TGrid*,double> map;
112  const std::map<TGrid*,double>& rmap= recursiveGridMaxAveragingDomainSizeMap<I+1>(t);
113  map[std::get<I>(t).pgrid]= std::get<I>(t).method.getAveragingDomainSize();
114 
115  // Loop over rmap
116  for (const auto& pair : rmap)
117  if (std::get<I>(t).pgrid == pair.first)
118  {
119  map[pair.first]= std::max(map.at(std::get<I>(t).pgrid),pair.second);
120  }
121  else
122  {
123  auto result= map.insert(pair);
124  assert(result.second==true);
125  }
126  return map;
127 }
128 
130 
131 inline std::vector<std::pair<Grid<Reference>*,double>> getTGridDomainSizePairs(const std::tuple<> emptyTuple)
132 {
133  std::vector<std::pair<Grid<Reference>*,double>> emptyVectorPair;
134  return emptyVectorPair;
135 }
136 template<std::size_t I=0, StressType stressType,
137  typename TGrid= typename std::conditional<stressType == Piola,Grid<Reference>,Grid<Current>>::type,
138  typename ...BF>
139 inline typename std::enable_if<I == sizeof...(BF)-1, std::vector<std::pair<TGrid*,double>>>::type
140  getTGridDomainSizePairs(const std::tuple<Stress<BF,stressType>&...> t)
141 {
142  std::vector<std::pair<TGrid*,double>> vectorPair;
143  vectorPair.push_back({std::get<I>(t).pgrid,std::get<I>(t).method.getAveragingDomainSize()});
144  return vectorPair;
145 }
146 template<std::size_t I=0, StressType stressType,
147  typename TGrid= typename std::conditional<stressType == Piola,Grid<Reference>,Grid<Current>>::type,
148  typename ...BF>
149 inline typename std::enable_if< I < sizeof...(BF)-1, std::vector<std::pair<TGrid*,double>> >::type
150  getTGridDomainSizePairs(const std::tuple<Stress<BF,stressType>&...> t)
151 {
152  std::vector<std::pair<TGrid*,double>> vectorPair;
153  vectorPair.push_back({std::get<I>(t).pgrid,std::get<I>(t).method.getAveragingDomainSize()});
154  std::vector<std::pair<TGrid*,double>> next= getTGridDomainSizePairs<I+1>(t);
155  vectorPair.insert(vectorPair.end(),next.begin(),next.end());
156  return vectorPair;
157 }
158 
160 std::vector<GridBase*> getBaseGridList(const std::tuple<> t)
161 {
162  std::vector<GridBase*> pgridBaseVector;
163  return pgridBaseVector;
164 }
165 template<std::size_t I=0, typename ...TStress>
166 inline typename std::enable_if<I == sizeof...(TStress)-1, std::vector<GridBase*>>::type
167  getBaseGridList(const std::tuple<TStress&...> t)
168 {
169  std::vector<GridBase*> pgridBaseVector;
170  pgridBaseVector.push_back(std::get<I>(t).pgrid);
171  return pgridBaseVector;
172 }
173 template<std::size_t I=0,typename ...TStress>
174 inline typename std::enable_if<I < sizeof...(TStress)-1, std::vector<GridBase*>>::type
175  getBaseGridList(const std::tuple<TStress&...> t)
176 {
177  std::vector<GridBase*> pgridBaseVector;
178 
179  pgridBaseVector.push_back(std::get<I>(t).pgrid);
180  std::vector<GridBase*> next= getBaseGridList<I+1>(t);
181  pgridBaseVector.insert(pgridBaseVector.end(),next.begin(),next.end());
182  return pgridBaseVector;
183 
184 }
185 
187 template<std::size_t I=0, typename ...TStress>
188 inline typename std::enable_if<I == sizeof...(TStress), void>::type
189  recursiveFold(const Vector3d& origin, const Vector3d& step, const Vector3i& pbc, const std::tuple<TStress&...> t)
190 { }
191 template<std::size_t I=0, typename ...TStress>
192 inline typename std::enable_if<I < sizeof...(TStress), void>::type
193  recursiveFold(const Vector3d& origin,
194  const Vector3d& step,
195  const Vector3i& pbc,
196  std::tuple<TStress&...> t)
197 {
198  BoxPoints boxPoints(origin,step, std::get<I>(t).pgrid->coordinates);
199  std::cout << "Folding grid points in grid: " << std::get<I>(t).pgrid << " if necessary...."<<"\n";
200  boxPoints.fold(pbc);
201  std::cout << std::endl;
202  recursiveFold<I+1>(origin,step,pbc,t);
203 }
204 
205 // Write grid data for each requested stress field
206 template<std::size_t I=0, typename ...TStress>
207 inline typename std::enable_if<I == sizeof...(TStress), void>::type
208  recursiveWriteStressAndGrid(std::tuple<TStress&...> t)
209 { }
210 
211 template<std::size_t I=0, typename ...TStress>
212 inline typename std::enable_if<I < sizeof...(TStress), void>::type
213  recursiveWriteStressAndGrid(std::tuple<TStress&...> t)
214 {
215  std::cout << "Writing stress and grid of " << std::get<I>(t).name << std::endl;
216  std::get<I>(t).write();
217  std::get<I>(t).pgrid->write(std::get<I>(t).name);
218  recursiveWriteStressAndGrid<I+1>(t);
219 }
220 
221 #endif
222 
const double epsilon
Definition: typedef.h:73
std::enable_if< I==sizeof...(TStress), void >::type recursiveBuildStress(const double &fij, const Vector3d &ra, const Vector3d &rA, const Vector3d &rb, const Vector3d &rB, const Vector3d &rab, const Vector3d &rAB, const int &i_gridPoint, const int &i_stress, std::tuple< TStress &... > t)
Definition: StressTuple.h:14
void fold(const Vector3i &pbc)
Definition: SpatialHash.h:176
StressType
Definition: typedef.h:63
Definition: Grid.h:31
Definition: Stress.h:23
Eigen::Matrix< double, 1, DIM, Eigen::RowMajor > Vector3d
Definition: typedef.h:60
Definition: typedef.h:64
Eigen::Matrix< int, 1, DIM, Eigen::RowMajor > Vector3i
Definition: typedef.h:61
Definition: typedef.h:65