Plugins
aniso_ref.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2020: G-CSC, Goethe University Frankfurt
3  * Author: Lukas Larisch
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 #ifndef ANISO_REF_
34 #define ANISO_REF_
35 
37 #ifdef UG_PARALLEL
40 #endif
41 
43 
44 namespace ug{
45 namespace SmallStrainMechanics{
46 
47 #ifdef UG_DIM_3
48 
49 template <class TDomain>
50 number MaxEdgeLength(TDomain& dom, MathVector<TDomain::dim>& ndir)
51 {
52 
53  UG_ASSERT(TDomain::dim == 3, "dimension must be 3!");
54 
55  typedef typename domain_traits<TDomain::dim>::element_type elem_t;
56  typedef typename MultiGrid::traits<elem_t>::iterator iter_t;
57 
58  typename TDomain::position_accessor_type aaPos = dom.position_accessor();
59  MultiGrid& mg = *dom.grid();
61 
62  typedef MathVector<TDomain::dim> vector_t;
63 
64  number maxSq = 0;
65 
66  for(iter_t e_iter = mg.begin<elem_t>(); e_iter != mg.end<elem_t>(); ++e_iter){
67  elem_t* elem = *e_iter;
68  if(mg.has_children(elem))
69  continue;
70 
71  mg.associated_elements(edges, elem);
72 
73  for(size_t i = 0; i < edges.size(); ++i){
74  vector_t edgeDir;
75  VecSubtract(edgeDir, aaPos[edges[i]->vertex(0)], aaPos[edges[i]->vertex(1)]);
76  VecNormalize(edgeDir, edgeDir);
77  number dot = VecDot(edgeDir, ndir);
78 
79  if((dot + SMALL >= 1) || (dot - SMALL <= -1)){
80  maxSq = max(maxSq, EdgeLengthSq(edges[i], aaPos));
81  }
82  }
83  }
84 
85  return sqrt(maxSq);
86 }
87 
88 
89 
90 template <class TDomain>
91 void MarkAnisotropic_Along_Normal(TDomain& dom, IRefiner& refiner, MathVector<TDomain::dim>& ndir)
92 {
93  UG_ASSERT(dom.grid().get() == refiner.get_associated_grid(),
94  "Grids in domain and in refiner have to match!");
95 
96  UG_ASSERT(TDomain::dim == 3, "dimension must be 3!");
97 
98  typedef typename domain_traits<TDomain::dim>::element_type elem_t;
99  typedef typename MultiGrid::traits<elem_t>::iterator iter_t;
100 
101  typename TDomain::position_accessor_type aaPos = dom.position_accessor();
102  MultiGrid& mg = *dom.grid();
104 
105  typedef MathVector<TDomain::dim> vector_t;
106 
107  for(iter_t e_iter = mg.begin<elem_t>(); e_iter != mg.end<elem_t>(); ++e_iter){
108  elem_t* elem = *e_iter;
109  if(mg.has_children(elem))
110  continue;
111 
112  // we'll mark all volumes as anisotropic, since we currently have to use
113  // copy elements during anisotropic refinement.
114  refiner.mark(elem, RM_ANISOTROPIC);
115 
116  mg.associated_elements(edges, elem);
117 
118  for(size_t i = 0; i < edges.size(); ++i){
119  vector_t edgeDir;
120  VecSubtract(edgeDir, aaPos[edges[i]->vertex(0)], aaPos[edges[i]->vertex(1)]);
121  VecNormalize(edgeDir, edgeDir);
122  number dot = VecDot(edgeDir, ndir);
123 
124  if((dot + SMALL >= 1) || (dot - SMALL <= -1)){
125  refiner.mark(edges[i]);
126  }
127  }
128  }
129 }
130 
131 
132 template <class TDomain>
133 void MarkAnisotropic_Longest_Scaled_Normal(TDomain& dom, IRefiner& refiner, number Ex, number Ey, number Ez)
134 {
135  UG_ASSERT(dom.grid().get() == refiner.get_associated_grid(),
136  "Grids in domain and in refiner have to match!");
137 
138  UG_ASSERT(TDomain::dim == 3, "dimension must be 3!");
139 
140  typedef MathVector<TDomain::dim> vector_t;
141 
142  vector_t ndirX; //x tang
143  vector_t ndirY; //y long
144  vector_t ndirZ; //z radi
145 
146  ndirX[0] = 1; ndirX[1] = 0; ndirX[2] = 0;
147  ndirY[0] = 0; ndirY[1] = 1; ndirY[2] = 0;
148  ndirZ[0] = 0; ndirZ[1] = 0; ndirZ[2] = 1;
149 
150  //length of edges in directions x, y, z
151  number maxX = MaxEdgeLength(dom, ndirX);
152  number maxY = MaxEdgeLength(dom, ndirY);
153  number maxZ = MaxEdgeLength(dom, ndirZ);
154 
155  number scaleXsqrt = sqrt(maxX/Ex);
156  number scaleYsqrt = sqrt(maxY/Ey);
157  number scaleZsqrt = sqrt(maxZ/Ez);
158 
159  number scaleXYZmin = min(scaleXsqrt, min(scaleYsqrt, scaleZsqrt));
160 
161  scaleXsqrt /= scaleXYZmin;
162  scaleYsqrt /= scaleXYZmin;
163  scaleZsqrt /= scaleXYZmin;
164 
165  std::cout << "scale normed x: " << scaleXsqrt << std::endl;
166  std::cout << "scale normed y: " << scaleYsqrt << std::endl;
167  std::cout << "scale normed z: " << scaleZsqrt << std::endl;
168 
169  if(scaleXsqrt > scaleYsqrt){
170  if(scaleXsqrt > scaleZsqrt){
171  UG_LOG("[MarkAnisotropic_Longest_Scaled_Normal] refine in X direction");
172  MarkAnisotropic_Along_Normal(dom, refiner, ndirX);
173  }
174  else{
175  UG_LOG("[MarkAnisotropic_Longest_Scaled_Normal] refine in Z direction");
176  MarkAnisotropic_Along_Normal(dom, refiner, ndirZ);
177  }
178 
179  }
180  else{
181  if(scaleZsqrt > scaleYsqrt){
182  UG_LOG("[MarkAnisotropic_Longest_Scaled_Normal] refine in Z direction");
183  MarkAnisotropic_Along_Normal(dom, refiner, ndirZ);
184  }
185  else{
186  UG_LOG("[MarkAnisotropic_Longest_Scaled_Normal] refine in Y direction");
187  MarkAnisotropic_Along_Normal(dom, refiner, ndirY);
188  }
189  }
190 }
191 
192 #endif
193 
194 
195 }// end of namespace SmallStrainMechanics
196 }// end of namespace ug
197 
198 #endif /* ANISO_REF_ */
Grid::VertexAttachmentAccessor< position_attachment_type > position_accessor_type
int element_type() const
static const int dim
UG_API number EdgeLengthSq(const EdgeVertices *e, TAAPosVRT &aaPos)
RM_ANISOTROPIC
#define UG_ASSERT(expr, msg)
#define UG_LOG(msg)
double number
void VecNormalize(vector_t &vOut, const vector_t &v)
void VecSubtract(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
const number SMALL
geometry_traits< TElem >::iterator iterator
PointerConstArray< TElem * > secure_container