ug4
obstacle_constraint_interface_impl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2015: G-CSC, Goethe University Frankfurt
3  * Author: Raphael Prohl
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 __H__UG__LIB_ALGEBRA__OPERATOR__PRECONDITIONER__PROJECTED_GAUSS_SEIDEL__OBSTACLE_CONSTRAINT_INTERFACE_IMPL__
34 #define __H__UG__LIB_ALGEBRA__OPERATOR__PRECONDITIONER__PROJECTED_GAUSS_SEIDEL__OBSTACLE_CONSTRAINT_INTERFACE_IMPL__
35 
38 
39 #ifdef UG_FOR_LUA
41 #endif
42 
43 namespace ug{
44 
45 template <typename TDomain, typename TAlgebra>
47 init()
48 {
49  if(m_spDomain.invalid())
50  UG_THROW("No domain set in 'IObstacleConstraint::init' \n");
51 
52  if(m_spDD.invalid())
53  UG_THROW("DofDistribution not set in 'IObstacleConstraint'.");
54 
55  // build up a map of obstacle dofs and its corresponding obstacle values
56  init_obstacle_dofs_with_values(1.0);
57 
58  UG_LOG("In IObstacleConstraint::init: "<<m_mObstacleValues.size()<< " obstacleDoFs tagged \n");
59  UG_LOG("\n");
60 }
61 
62 template <typename TDomain, typename TAlgebra>
64 add(SmartPtr<UserData<number, dim, bool> > func, const char* function)
65 {
66  m_vCondNumberData.push_back(CondNumberData(func, function));
67 }
68 
69 template <typename TDomain, typename TAlgebra>
71 add(SmartPtr<UserData<number, dim, bool> > func, const char* function, const char* subsets)
72 {
73  m_vCondNumberData.push_back(CondNumberData(func, function, subsets));
74 }
75 
76 template <typename TDomain, typename TAlgebra>
78 add(SmartPtr<UserData<number, dim> > func, const char* function)
79 {
80  m_vNumberData.push_back(NumberData(func, function));
81 }
82 
83 template <typename TDomain, typename TAlgebra>
85 add(SmartPtr<UserData<number, dim> > func, const char* function, const char* subsets)
86 {
87  m_vNumberData.push_back(NumberData(func, function, subsets));
88 }
89 
90 template <typename TDomain, typename TAlgebra>
92 add(number value, const char* function)
93 {
94  m_vConstNumberData.push_back(ConstNumberData(value, function));
95 }
96 
97 template <typename TDomain, typename TAlgebra>
99 add(number value, const char* function, const char* subsets)
100 {
101  m_vConstNumberData.push_back(ConstNumberData(value, function, subsets));
102 }
103 
104 template <typename TDomain, typename TAlgebra>
106 add(SmartPtr<UserData<MathVector<dim>, dim> > func, const char* functions)
107 {
108  m_vVectorData.push_back(VectorData(func, functions));
109 }
110 
111 template <typename TDomain, typename TAlgebra>
113 add(SmartPtr<UserData<MathVector<dim>, dim> > func, const char* functions, const char* subsets)
114 {
115  m_vVectorData.push_back(VectorData(func, functions, subsets));
116 }
117 
118 #ifdef UG_FOR_LUA
119 template <typename TDomain, typename TAlgebra>
121 add(const char* name, const char* function)
122 {
126  add(sp, function);
127  return;
128  }
132  add(sp, function);
133  return;
134  }
135  if(LuaUserData<MathVector<dim>, dim>::check_callback_returns(name)){
137  LuaUserDataFactory<MathVector<dim>, dim>::create(name);
138  add(sp, function);
139  return;
140  }
141 
142 // no match found
144  UG_THROW("IObstacleConstraint::add: Lua-Callback with name '"<<name<<
145  "' does not exist.");
146 
147 // name exists but wrong signature
148  UG_THROW("IObstacleConstraint::add: Cannot find matching callback "
149  "signature. Use one of:\n"
150  "a) Number - Callback\n"
151  << (LuaUserData<number, dim>::signature()) << "\n" <<
152  "b) Conditional Number - Callback\n"
154  "c) "<<dim<<"d Vector - Callback\n"
155  << (LuaUserData<MathVector<dim>, dim>::signature()));
156 }
157 
158 template <typename TDomain, typename TAlgebra>
160 add(const char* name, const char* function, const char* subsets)
161 {
165  add(sp, function, subsets);
166  return;
167  }
171  add(sp, function, subsets);
172  return;
173  }
174  if(LuaUserData<MathVector<dim>, dim>::check_callback_returns(name)){
176  LuaUserDataFactory<MathVector<dim>, dim>::create(name);
177  add(sp, function, subsets);
178  return;
179  }
180 
181 // no match found
183  UG_THROW("IObstacleConstraint::add: Lua-Callback with name '"<<name<<
184  "' does not exist.");
185 
186 // name exists but wrong signature
187  UG_THROW("IObstacleConstraint::add: Cannot find matching callback "
188  "signature. Use one of:\n"
189  "a) Number - Callback\n"
190  << (LuaUserData<number, dim>::signature()) << "\n" <<
191  "b) Conditional Number - Callback\n"
193  "c) "<<dim<<"d Vector - Callback\n"
194  << (LuaUserData<MathVector<dim>, dim>::signature()));
195 }
196 #endif
197 
198 
199 template <typename TDomain, typename TAlgebra>
201 clear()
202 {
203  m_vCondNumberData.clear();
204  m_vNumberData.clear();
205  m_vConstNumberData.clear();
206  m_vVectorData.clear();
207 
208  m_mObstacleValues.clear();
209  m_vActiveDofs.clear();
210 }
211 
212 template <typename TDomain, typename TAlgebra>
214 check_functions_and_subsets(FunctionGroup& functionGroup, SubsetGroup& subsetGroup,
215  size_t numFct) const
216 {
217 // only number of functions allowed
218  if(functionGroup.size() != numFct)
219  UG_THROW("IObstacleConstraint:extract_data:"
220  " Only "<<numFct<<" function(s) allowed in specification of a"
221  " Obstacle Value, but the following functions given:"
222  <<functionGroup);
223 
224 // get subsethandler
225  ConstSmartPtr<ISubsetHandler> pSH = m_spDD->subset_handler();
226 
227 // loop subsets
228  for(size_t si = 0; si < subsetGroup.size(); ++si)
229  {
230  // get subset index
231  const int subsetIndex = subsetGroup[si];
232 
233  // check that subsetIndex is valid
234  if(subsetIndex < 0 || subsetIndex >= pSH->num_subsets())
235  UG_THROW("IObstacleConstraint:extract_data:"
236  " Invalid Subset Index " << subsetIndex << ". (Valid is"
237  " 0, .. , " << pSH->num_subsets() <<").");
238 
239  // check all functions
240  for(size_t i=0; i < functionGroup.size(); ++i)
241  {
242  const size_t fct = functionGroup[i];
243 
244  // check if function exist
245  if(fct >= m_spDD->num_fct())
246  UG_THROW("IObstacleConstraint:extract_data:"
247  " Function "<< fct << " does not exist in pattern.");
248 
249  // check that function is defined for segment
250  if(!m_spDD->is_def_in_subset(fct, subsetIndex))
251  UG_THROW("IObstacleConstraint:extract_data:"
252  " Function "<<fct<<" not defined on subset "<<subsetIndex);
253  }
254  }
255 
256 // everything ok
257 }
258 
259 template <typename TDomain, typename TAlgebra>
260 template <typename TUserData, typename TScheduledUserData>
262 extract_data(std::map<int, std::vector<TUserData*> >& mvUserDataObsSegment,
263  std::vector<TScheduledUserData>& vUserData)
264 {
265 // clear the extracted data
266  mvUserDataObsSegment.clear();
267 
268  for(size_t i = 0; i < vUserData.size(); ++i)
269  {
270  // create Function Group and Subset Group
271  if (vUserData[i].bWholeDomain == false){
272  try{
273  vUserData[i].ssGrp = m_spDD->subset_grp_by_name(vUserData[i].ssName.c_str());
274  }UG_CATCH_THROW(" Subsets '"<<vUserData[i].ssName<<"' not"
275  " all contained in DoFDistribution.");
276  }
277  else{
278  SubsetGroup ssGrp = SubsetGroup(m_spDD->subset_handler());
279  ssGrp.add_all();
280  vUserData[i].ssGrp = ssGrp;
281  }
282 
283  FunctionGroup fctGrp;
284  try{
285  fctGrp = m_spDD->fct_grp_by_name(vUserData[i].fctName.c_str());
286  }UG_CATCH_THROW(" Functions '"<<vUserData[i].fctName<<"' not"
287  " all contained in DoFDistribution.");
288 
289  // check functions and subsets
290  check_functions_and_subsets(fctGrp, vUserData[i].ssGrp, TUserData::numFct);
291 
292  // set functions
293  if(fctGrp.size() != TUserData::numFct)
294  UG_THROW("IObstacleConstraint: wrong number of fct");
295 
296  for(size_t fct = 0; fct < TUserData::numFct; ++fct)
297  {
298  vUserData[i].fct[fct] = fctGrp[fct];
299  }
300 
301  // loop subsets
302  for(size_t si = 0; si < vUserData[i].ssGrp.size(); ++si)
303  {
304  // get subset index and function
305  const int subsetIndex = vUserData[i].ssGrp[si];
306 
307  // remember functor and function
308  mvUserDataObsSegment[subsetIndex].push_back(&vUserData[i]);
309  }
310  }
311 }
312 
313 template <typename TDomain, typename TAlgebra>
315 extract_data()
316 {
317  extract_data(m_mNumberObsSegment, m_vNumberData);
318  extract_data(m_mCondNumberObsSegment, m_vCondNumberData);
319  extract_data(m_mConstNumberObsSegment, m_vConstNumberData);
320  extract_data(m_mVectorObsSegment, m_vVectorData);
321 }
322 
323 template <typename TDomain, typename TAlgebra>
326 {
327  extract_data();
328 
329  // reset map of obstacle values and vector of obstacle subset-indices
330  m_mObstacleValues.clear();
331  m_vObsSubsets.resize(0);
332 
333  init_obstacle_dofs_with_values<CondNumberData>(m_mCondNumberObsSegment, time);
334  init_obstacle_dofs_with_values<NumberData>(m_mNumberObsSegment, time);
335  init_obstacle_dofs_with_values<ConstNumberData>(m_mConstNumberObsSegment, time);
336  init_obstacle_dofs_with_values<VectorData>(m_mVectorObsSegment, time);
337 }
338 
339 template <typename TDomain, typename TAlgebra>
340 template <typename TUserData>
342 init_obstacle_dofs_with_values(const std::map<int, std::vector<TUserData*> >& mvUserData, number time)
343 {
344  typename std::map<int, std::vector<TUserData*> >::const_iterator iter;
345  for(iter = mvUserData.begin(); iter != mvUserData.end(); ++iter)
346  {
347  // get subset index
348  const int si = (*iter).first;
349 
350  // store obstacle subsets
351  m_vObsSubsets.push_back(si);
352 
353  // get vector of scheduled obstacle data on this subset
354  const std::vector<TUserData*>& vUserData = (*iter).second;
355 
356  // gets obstacle values in each base element type
357  try
358  {
359  if(m_spDD->max_dofs(VERTEX))
360  init_obstacle_dofs_with_values<RegularVertex, TUserData>(vUserData, si, time);
361  if(m_spDD->max_dofs(EDGE))
362  init_obstacle_dofs_with_values<Edge, TUserData>(vUserData, si, time);
363  if(m_spDD->max_dofs(FACE))
364  init_obstacle_dofs_with_values<Face, TUserData>(vUserData, si, time);
365  if(m_spDD->max_dofs(VOLUME))
366  init_obstacle_dofs_with_values<Volume, TUserData>(vUserData, si, time);
367  }
368  UG_CATCH_THROW("IObstacleConstraint::init_obstacle_dofs_with_values:"
369  " While calling 'obstacle_value' for TUserData, aborting.");
370  }
371 }
372 
373 template <typename TDomain, typename TAlgebra>
374 template <typename TBaseElem, typename TUserData>
376 init_obstacle_dofs_with_values(const std::vector<TUserData*>& vUserData, int si, number time)
377 {
378 // create Multiindex
379  std::vector<DoFIndex> multInd;
380 
381  // readin value
382  typename TUserData::value_type val;
383 
384 // position of dofs
385  std::vector<position_type> vPos;
386 
387 // iterators
388  typedef typename DoFDistribution::traits<TBaseElem>::const_iterator iter_type;
389  iter_type iter = m_spDD->begin<TBaseElem>(si);
390  iter_type iterEnd = m_spDD->end<TBaseElem>(si);
391 
392 // loop elements
393  for( ; iter != iterEnd; iter++)
394  {
395  // get baseElem
396  TBaseElem* elem = *iter;
397 
398  // loop obstacle functions on this segment
399  for(size_t i = 0; i < vUserData.size(); ++i)
400  {
401  for(size_t f = 0; f < TUserData::numFct; ++f)
402  {
403  // get function index
404  const size_t fct = vUserData[i]->fct[f];
405 
406  // get local finite element id
407  const LFEID& lfeID = m_spDD->local_finite_element_id(fct);
408 
409  // get dof position
410  InnerDoFPosition<TDomain>(vPos, elem, *m_spDomain, lfeID);
411 
412  // get multi indices
413  m_spDD->inner_dof_indices(elem, fct, multInd);
414 
415  UG_ASSERT(multInd.size() == vPos.size(),
416  "Mismatch: numInd="<<multInd.size()<<", numPos="
417  <<vPos.size()<<" on "<<elem->reference_object_id());
418 
419  // loop dofs on element
420  for(size_t j = 0; j < multInd.size(); ++j)
421  {
422  // check if function is an obstacle fct and read value
423  if(!(*vUserData[i])(val, vPos[j], time, si)) continue;
424 
425  // deposit obstacle values in a map
426  m_mObstacleValues[multInd[j]] = val[f];
427  }
428  }
429  }
430  }
431 }
432 
433 template <typename TDomain, typename TAlgebra>
434 bool
436 is_obs_dof(const DoFIndex& dof)
437 {
438  if (m_mObstacleValues.find(dof) == m_mObstacleValues.end()){return false;}
439  else {return true;}
440 }
441 
442 template <typename TDomain, typename TAlgebra>
443 void
446  ConstSmartPtr<DoFDistribution> ddFine, int type, number time)
447 {
448  UG_LOG("IObstacleConstraint<TDomain,TAlgebra>::adjust_restrictionR \n");
449 
450  R.print();
451 
452  typedef typename vector<DoFIndex>::iterator iter_type;
453  iter_type dofIter = m_vActiveDofs.begin();
454  iter_type dofIterEnd = m_vActiveDofs.end();
455  for( ; dofIter != dofIterEnd; dofIter++)
456  {
457  UG_LOG("IObstacleConstraint<TDomain,TAlgebra>::"
458  "adjust_restrictionR::activeDof : " <<*dofIter<< "\n");
459  SetCol(R, (*dofIter)[0], (*dofIter)[1]);
460  }
461 
462  if (m_vActiveDofs.size() > 0)
463  {
464  UG_LOG("#OfActiveDofs: " <<m_vActiveDofs.size()<< "\n");
465  R.print();
466  }
467  UG_LOG("IObstacleConstraint::adjust_restrictionR() \n");
468 };
469 
470 } // end namespace ug
471 
472 #endif /* __H__UG__LIB_ALGEBRA__OPERATOR__PRECONDITIONER__PROJECTED_GAUSS_SEIDEL__OBSTACLE_CONSTRAINT_INTERFACE_IMPL__ */
location name
Definition: checkpoint_util.lua:128
Definition: smart_pointer.h:296
Definition: smart_pointer.h:108
Definition: function_group.h:52
size_t size() const
number of functions in this group
Definition: function_group.h:116
void add(SmartPtr< UserData< number, dim, bool > > func, const char *function)
adds a lua callback (cond and non-cond)
Definition: obstacle_constraint_interface_impl.h:64
void check_functions_and_subsets(FunctionGroup &functionGroup, SubsetGroup &subsetGroup, size_t numFct) const
Definition: obstacle_constraint_interface_impl.h:214
void init_obstacle_dofs_with_values(number time)
store the obstacle value set by means of UserDatas
Definition: obstacle_constraint_interface_impl.h:325
void clear()
clear all UserData-member variables
Definition: obstacle_constraint_interface_impl.h:201
virtual void adjust_restriction(matrix_type &R, ConstSmartPtr< DoFDistribution > ddCoarse, ConstSmartPtr< DoFDistribution > ddFine, int type, number time=0.0)
sets constraints in restriction
Definition: obstacle_constraint_interface_impl.h:445
void init()
Definition: obstacle_constraint_interface_impl.h:47
void extract_data()
extract the UserDatas
Definition: obstacle_constraint_interface_impl.h:315
algebra_type::matrix_type matrix_type
Matrix type.
Definition: obstacle_constraint_interface.h:82
bool is_obs_dof(const DoFIndex &dof)
checks if a given dof is in an obstacle subset
Definition: obstacle_constraint_interface_impl.h:436
Identifier for Local Finite Elements.
Definition: local_finite_element_id.h:98
static SmartPtr< LuaUserData< TData, dim, TRet > > create(const std::string &name)
Definition: lua_user_data.h:223
provides data specified in the lua script
Definition: lua_user_data.h:96
static bool check_callback_returns(const char *callName, const bool bThrow=false)
returns true if callback has correct return values
Definition: lua_user_data_impl.h:247
static std::string signature()
returns string of required callback signature
Definition: lua_user_data_impl.h:65
Definition: multi_index.h:50
Group of subsets.
Definition: subset_group.h:51
size_t size() const
number of subsets in this group
Definition: subset_group.h:122
void add_all()
select all subsets of underlying subset handler
Definition: subset_group.cpp:133
Const iterator to traverse the surface of a multi-grid hierarchy.
Definition: surface_view.h:237
void SetCol(TSparseMatrix &A, size_t i, size_t alpha, number val=0.0)
Definition: sparsematrix_util.h:735
static const int dim
base_type::TBaseElem TBaseElem
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
#define UG_CATCH_THROW(msg)
Definition: error.h:64
#define UG_THROW(msg)
Definition: error.h:57
#define UG_LOG(msg)
Definition: log.h:367
double number
Definition: types.h:124
function util LuaCallbackHelper create(func)
the ug namespace
@ VOLUME
Definition: grid_base_objects.h:63
@ VERTEX
Definition: grid_base_objects.h:60
@ EDGE
Definition: grid_base_objects.h:61
@ FACE
Definition: grid_base_objects.h:62
bool CheckLuaCallbackName(const char *name)
returns true if callback exists
Definition: lua_user_data.cpp:50
function func(x, y, z, t, si)
T value_type
Definition: sparsematrix_interface.h:2
grouping for subset and conditional data
Definition: obstacle_constraint_interface.h:305
grouping for subset and conditional data
Definition: obstacle_constraint_interface.h:334
grouping for subset and non-conditional data
Definition: obstacle_constraint_interface.h:276
grouping for subset and non-conditional data
Definition: obstacle_constraint_interface.h:363