Line data Source code
1 : /*
2 : * Copyright (c) 2011-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Andreas Vogel
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_DISC__ORDERING_STRATEGIES_ALGORITHMS__LEXORDER__
34 : #define __H__UG__LIB_DISC__ORDERING_STRATEGIES_ALGORITHMS__LEXORDER__
35 :
36 : #include <vector>
37 : #include <utility> // for pair
38 : #include <cstring> //strlen
39 :
40 : #include "lib_disc/domain.h"
41 : #include "lib_disc/function_spaces/grid_function.h"
42 :
43 : #include "lib_algebra/ordering_strategies/algorithms/IOrderingAlgorithm.h"
44 : #include "lib_algebra/ordering_strategies/algorithms/util.h"
45 : #include "lib_disc/function_spaces/dof_position_util.h"
46 :
47 : #include "common/error.h"
48 :
49 : namespace ug{
50 :
51 : template<int dim>
52 : void ComputeLexicographicOrder(std::vector<size_t>& vNewIndex,
53 : std::vector<std::pair<MathVector<dim>, size_t> >& vPos,
54 : size_t orderDim = 0, bool increasing = true);
55 :
56 : /// orders the dof distribution using lexicographic order
57 : template <typename TDomain>
58 : void OrderLexForDofDist(SmartPtr<DoFDistribution> dd, ConstSmartPtr<TDomain> domain,
59 : size_t orderDim = 0, bool increasing = true);
60 :
61 : /// orders the all DofDistributions of the ApproximationSpace using lexicographic order
62 : template <typename TDomain>
63 : void OrderLex(ApproximationSpace<TDomain>& approxSpace, const char *order);
64 :
65 :
66 : template <typename TAlgebra, typename TDomain, typename O_t>
67 : class LexOrdering : public IOrderingAlgorithm<TAlgebra, O_t>
68 : {
69 : public:
70 : typedef typename TAlgebra::matrix_type M_t;
71 : typedef typename TAlgebra::vector_type V_t;
72 : typedef IOrderingAlgorithm<TAlgebra, O_t> baseclass;
73 :
74 : /// Grid function type for the solution
75 : typedef GridFunction<TDomain, TAlgebra> GridFunc_t;
76 :
77 : /// Position attachment type
78 : typedef typename std::pair<MathVector<TDomain::dim>, size_t> Position_t;
79 :
80 0 : LexOrdering(){}
81 :
82 : /// clone constructor
83 0 : LexOrdering( const LexOrdering<TAlgebra, TDomain, O_t> &parent )
84 0 : : baseclass(){}
85 :
86 0 : SmartPtr<IOrderingAlgorithm<TAlgebra, O_t> > clone()
87 : {
88 0 : return make_sp(new LexOrdering<TAlgebra, TDomain, O_t>(*this));
89 : }
90 :
91 : void parse(){
92 : if(sizeof(m_dir) == 0){
93 : UG_THROW(name() << "::parse: empty string\n");
94 : }
95 :
96 : std::cout << name() << "::parse()" << std::endl;
97 : std::cout << "length: " << strlen(m_dir) << std::endl;
98 : }
99 :
100 0 : void compute(){
101 0 : size_t len = strlen(m_dir);
102 :
103 0 : if(len == 0){
104 0 : UG_THROW(name() << "::compute: Empty direction!");
105 : }
106 :
107 : size_t pos = 0;
108 : bool increasing = true;
109 : char sign;
110 0 : while(pos < len){
111 0 : if(increasing){
112 : sign = '+';
113 : }
114 : else{
115 : sign = '-';
116 : }
117 :
118 0 : switch(m_dir[pos]){
119 0 : case '+':
120 : //UG_LOG(name() << "::compute: LexOrdering in + direction.\n")
121 0 : ++pos;
122 : increasing = true;
123 0 : break;
124 0 : case '-':
125 : //UG_LOG(name() << "::compute: LexOrdering in - direction.\n")
126 0 : ++pos;
127 : increasing = false;
128 0 : break;
129 : case 'x':
130 0 : UG_LOG(name() << "::compute: LexOrdering in " << sign << "x direction.\n")
131 0 : ComputeLexicographicOrder<TDomain::dim>(o, m_vPositions, 0, increasing);
132 0 : ++pos;
133 : increasing = true;
134 0 : break;
135 : case 'y':
136 0 : UG_LOG(name() << "::compute: LexOrdering in " << sign << "y direction.\n")
137 0 : ComputeLexicographicOrder<TDomain::dim>(o, m_vPositions, 1, increasing);
138 0 : ++pos;
139 : increasing = true;
140 0 : break;
141 : case 'z':
142 0 : UG_LOG(name() << "::compute: LexOrdering in " << sign << "z direction.\n")
143 0 : ComputeLexicographicOrder<TDomain::dim>(o, m_vPositions, 2, increasing);
144 0 : ++pos;
145 : increasing = true;
146 0 : break;
147 0 : default:
148 0 : UG_THROW(name() << "::compute: Invalid token in direction string, valid tokens: +, -, x, y, z");
149 : }
150 : }
151 :
152 0 : mat = NULL;
153 0 : }
154 :
155 0 : void check(){
156 0 : if(!is_permutation(o)){
157 0 : UG_THROW(name() << "::check: Not a permutation!");
158 : }
159 0 : }
160 :
161 0 : O_t& ordering(){
162 0 : return o;
163 : }
164 :
165 0 : void init(M_t* A, const V_t& V){
166 0 : if(strcmp(m_dir, "") == 0){
167 0 : UG_THROW(name() << "::init: no direction chosen!");
168 : }
169 :
170 : try{
171 : const GridFunc_t* pGridF;
172 0 : if((pGridF = dynamic_cast<const GridFunc_t*>(&V)) == 0){
173 0 : UG_THROW(name() << "::init: No DoFDistribution specified.");
174 : }
175 :
176 : SmartPtr<DoFDistribution> dd = ((GridFunc_t*) pGridF)->dof_distribution();
177 :
178 : size_t indN = dd->num_indices();
179 :
180 0 : if(indN != A->num_rows ()){
181 0 : UG_THROW(name() << "::init: #indices != #rows");
182 : }
183 :
184 0 : o.resize(indN);
185 0 : ExtractPositions(pGridF->domain(), dd, m_vPositions);
186 : }
187 0 : catch(...){
188 0 : throw;
189 : }
190 :
191 : #ifdef UG_ENABLE_DEBUG_LOGS
192 : UG_LOG("Using " << name() << " in " << m_dir << " direction\n");
193 : #endif
194 :
195 0 : mat = A;
196 0 : }
197 :
198 0 : void init(M_t*){
199 0 : UG_THROW(name() << "::init: Cannot initialize smoother without a geometry. Specify the 2nd argument for init!");
200 : }
201 :
202 0 : void init(M_t*, const V_t&, const O_t&){
203 0 : UG_THROW(name() << "::init: induced subgraph version not implemented yet!");
204 : }
205 :
206 0 : void init(M_t*, const O_t&){
207 0 : UG_THROW(name() << "::init: induced subgraph version not implemented yet!");
208 : }
209 :
210 0 : virtual const char* name() const {return "LexOrdering";}
211 :
212 0 : void set_direction(const char *dir){
213 0 : m_dir = dir;
214 0 : }
215 :
216 : private:
217 : O_t o;
218 : M_t* mat;
219 :
220 : const char *m_dir;
221 : std::vector<Position_t> m_vPositions;
222 : };
223 :
224 : } // end namespace ug
225 :
226 : #endif
|