MDStressLab++
Loading...
Searching...
No Matches
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
12template<std::size_t I=0, typename ...TStress>
13inline 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}
28template<std::size_t I=0, StressType stressType, typename ...BF>
29inline 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
58template<std::size_t I=0, typename ...TStress>
59inline typename std::enable_if<I == sizeof...(TStress), void>::type
60recursiveNullifyStress(std::tuple<TStress&...> t)
61{
62}
63template<std::size_t I=0, StressType stressType, typename ...BF>
64inline typename std::enable_if<I < sizeof...(BF), void>::type
65recursiveNullifyStress(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
72double averagingDomainSize_max(const std::tuple<> t)
73{
74 return 0;
75}
76template<std::size_t I=0, typename ...TStress>
77inline 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}
82template<std::size_t I=0, typename ...TStress>
83inline 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
91std::map<Grid<Reference>*,double> recursiveGridMaxAveragingDomainSizeMap(const std::tuple<>& t)
92{
93std::map<Grid<Reference>*,double> map;
94return map;
95}
96template<std::size_t I=0, StressType stressType,
97 typename TGrid= typename std::conditional<stressType == Piola,Grid<Reference>,Grid<Current>>::type,
98 typename ...BF>
99inline typename std::enable_if<I == sizeof...(BF), std::map<TGrid*,double>>::type
101{
102 std::map<TGrid*,double> map;
103 return map;
104}
105template<std::size_t I=0, StressType stressType,
106 typename TGrid= typename std::conditional<stressType == Piola,Grid<Reference>,Grid<Current>>::type,
107 typename ...BF>
108inline typename std::enable_if<I < sizeof...(BF), std::map<TGrid*,double>>::type
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
131inline std::vector<std::pair<Grid<Current>*,double>> getTGridDomainSizePairs(const std::tuple<>& emptyTuple)
132{
133 std::vector<std::pair<Grid<Current>*,double>> emptyVectorPair;
134 return emptyVectorPair;
135}
136inline std::vector<std::pair<Grid<Reference>*,double>> getTGridDomainSizePairs(std::tuple<>&& emptyTuple)
137{
138 std::vector<std::pair<Grid<Reference>*,double>> emptyVectorPair;
139 return emptyVectorPair;
140}
141template<std::size_t I=0, StressType stressType,
142 typename TGrid= typename std::conditional<stressType == Piola,Grid<Reference>,Grid<Current>>::type,
143 typename ...BF>
144inline typename std::enable_if<I == sizeof...(BF)-1, std::vector<std::pair<TGrid*,double>>>::type
146{
147 std::vector<std::pair<TGrid*,double>> vectorPair;
148 vectorPair.push_back({std::get<I>(t).pgrid,std::get<I>(t).method.getAveragingDomainSize()});
149 return vectorPair;
150}
151template<std::size_t I=0, StressType stressType,
152 typename TGrid= typename std::conditional<stressType == Piola,Grid<Reference>,Grid<Current>>::type,
153 typename ...BF>
154inline typename std::enable_if< I < sizeof...(BF)-1, std::vector<std::pair<TGrid*,double>> >::type
155 getTGridDomainSizePairs(const std::tuple<Stress<BF,stressType>&...> t)
156{
157 std::vector<std::pair<TGrid*,double>> vectorPair;
158 vectorPair.push_back({std::get<I>(t).pgrid,std::get<I>(t).method.getAveragingDomainSize()});
159 std::vector<std::pair<TGrid*,double>> next= getTGridDomainSizePairs<I+1>(t);
160 vectorPair.insert(vectorPair.end(),next.begin(),next.end());
162}
163
165std::vector<GridBase*> getBaseGridList(const std::tuple<> t)
166{
167 std::vector<GridBase*> pgridBaseVector;
168 return pgridBaseVector;
169}
170template<std::size_t I=0, typename ...TStress>
171inline typename std::enable_if<I == sizeof...(TStress)-1, std::vector<GridBase*>>::type
172 getBaseGridList(const std::tuple<TStress&...> t)
173{
174 std::vector<GridBase*> pgridBaseVector;
175 pgridBaseVector.push_back(std::get<I>(t).pgrid);
176 return pgridBaseVector;
177}
178template<std::size_t I=0,typename ...TStress>
179inline typename std::enable_if<I < sizeof...(TStress)-1, std::vector<GridBase*>>::type
180 getBaseGridList(const std::tuple<TStress&...> t)
181{
182 std::vector<GridBase*> pgridBaseVector;
183
184 pgridBaseVector.push_back(std::get<I>(t).pgrid);
185 std::vector<GridBase*> next= getBaseGridList<I+1>(t);
186 pgridBaseVector.insert(pgridBaseVector.end(),next.begin(),next.end());
188
189}
190
192template<std::size_t I=0, typename ...TStress>
193inline typename std::enable_if<I == sizeof...(TStress), void>::type
194 recursiveFold(const Vector3d& origin, const Vector3d& step, const Vector3i& pbc, const std::tuple<TStress&...> t)
195{ }
196template<std::size_t I=0, typename ...TStress>
197inline typename std::enable_if<I < sizeof...(TStress), void>::type
198 recursiveFold(const Vector3d& origin,
199 const Vector3d& step,
200 const Vector3i& pbc,
201 std::tuple<TStress&...> t)
202{
203 BoxPoints boxPoints(origin,step, std::get<I>(t).pgrid->coordinates);
204 std::cout << "Folding grid points in grid: " << std::get<I>(t).pgrid << " if necessary...."<<"\n";
205 boxPoints.fold(pbc);
206 std::cout << std::endl;
207 recursiveFold<I+1>(origin,step,pbc,t);
208}
209
210// Write grid data for each requested stress field
211template<std::size_t I=0, typename ...TStress>
212inline typename std::enable_if<I == sizeof...(TStress), void>::type
213 recursiveWriteStressAndGrid(std::tuple<TStress&...> t)
214{ }
215
216template<std::size_t I=0, typename ...TStress>
217inline typename std::enable_if<I < sizeof...(TStress), void>::type
218 recursiveWriteStressAndGrid(std::tuple<TStress&...> t)
219{
220 std::cout << "Writing stress and grid of " << std::get<I>(t).name << std::endl;
221 std::get<I>(t).write();
222 std::get<I>(t).pgrid->write(std::get<I>(t).name);
224}
225
226#endif
227
double averagingDomainSize_max(const std::tuple<> t)
Definition StressTuple.h:72
std::enable_if< I< sizeof...(BF) -1, std::vector< std::pair< TGrid *, double > > >::type getTGridDomainSizePairs(const std::tuple< Stress< BF, stressType > &... > t){ std::vector< std::pair< TGrid *, double > > vectorPair;vectorPair.push_back({std::get< I >(t).pgrid, std::get< I >(t).method.getAveragingDomainSize()});std::vector< std::pair< TGrid *, double > next
std::enable_if< I==sizeof...(TStress), void >::type recursiveFold(const Vector3d &origin, const Vector3d &step, const Vector3i &pbc, const std::tuple< TStress &... > t)
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
std::enable_if< I< sizeof...(BF), std::map< TGrid *, double > >::type recursiveGridMaxAveragingDomainSizeMap(const std::tuple< Stress< BF, stressType > &... > t){ std::map< TGrid *, double > map;const std::map< TGrid *, double > &rmap=recursiveGridMaxAveragingDomainSizeMap< I+1 >(t);map[std::get< I >(t).pgrid]=std::get< I >(t).method.getAveragingDomainSize();for(const auto &pair :rmap) if(std::get< I >(t).pgrid==pair.first) { map[pair.first]=std::max(map.at(std::get< I >(t).pgrid), pair.second);} else { auto result=map.insert(pair);assert(result.second==true);} return map;}inline std::vector< std::pair< Grid< Current > *, double > getTGridDomainSizePairs(const std::tuple<> &emptyTuple)
return pgridBaseVector
std::vector< GridBase * > getBaseGridList(const std::tuple<> t)
return vectorPair
recursiveWriteStressAndGrid< I+1 >(t)
std::enable_if< I==sizeof...(TStress), void >::type recursiveWriteStressAndGrid(std::tuple< TStress &... > t)
std::enable_if< I< sizeof...(TStress) -1, double >::type averagingDomainSize_max(const std::tuple< TStress &... > t){ return std::max(std::get< I >(t).method.getAveragingDomainSize(), averagingDomainSize_max< I+1 >(t));}std::map< Grid< Reference > double recursiveGridMaxAveragingDomainSizeMap(const std::tuple<> &t)
Definition StressTuple.h:91
Definition Grid.h:31
Eigen::Matrix< double, 1, DIM, Eigen::RowMajor > Vector3d
Definition typedef.h:60
Eigen::Matrix< int, 1, DIM, Eigen::RowMajor > Vector3i
Definition typedef.h:61
StressType
Definition typedef.h:63
@ Cauchy
Definition typedef.h:64
@ Piola
Definition typedef.h:65
const double epsilon
Definition typedef.h:73