1
// This file is part of Hermes2D.
3
// Hermes2D is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 2 of the License, or
6
// (at your option) any later version.
8
// Hermes2D is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
// GNU General Public License for more details.
13
// You should have received a copy of the GNU General Public License
14
// along with Hermes2D. If not, see <http://www.gnu.org/licenses/>.
26
template<typename Scalar>
27
Filter<Scalar>::Filter()
31
template<typename Scalar>
32
Filter<Scalar>::Filter(MeshFunctionSharedPtr<Scalar>* solutions, int num) : MeshFunction<Scalar>()
35
if (num > H2D_MAX_COMPONENTS)
36
throw Hermes::Exceptions::Exception("Attempt to create an instance of Filter with more than 10 MeshFunctions.");
37
for (int i = 0; i < this->num; i++)
38
this->sln[i] = solutions[i];
42
template<typename Scalar>
43
Filter<Scalar>::Filter(Hermes::vector<MeshFunctionSharedPtr<Scalar> > solutions) : MeshFunction<Scalar>()
45
this->num = solutions.size();
46
if (num > H2D_MAX_COMPONENTS)
47
throw Hermes::Exceptions::Exception("Attempt to create an instance of Filter with more than 10 MeshFunctions.");
48
for (int i = 0; i < this->num; i++)
49
this->sln[i] = solutions.at(i);
53
template<typename Scalar>
54
void Filter<Scalar>::init(Hermes::vector<MeshFunctionSharedPtr<Scalar> > solutions)
56
this->num = solutions.size();
57
if (num > H2D_MAX_COMPONENTS)
58
throw Hermes::Exceptions::Exception("Attempt to create an instance of Filter with more than 10 MeshFunctions.");
59
for (int i = 0; i < this->num; i++)
60
this->sln[i] = solutions.at(i);
64
template<typename Scalar>
65
void Filter<Scalar>::init()
67
// construct the union mesh, if necessary
68
MeshSharedPtr meshes[H2D_MAX_COMPONENTS];
69
for (int i = 0; i < this->num; i++)
70
meshes[i] = this->sln[i]->get_mesh();
71
this->mesh = meshes[0];
73
Solution<Scalar>* sln = dynamic_cast<Solution<Scalar>*>(this->sln[0].get());
75
this->space_type = HERMES_INVALID_SPACE;
77
this->space_type = sln->get_space_type();
81
for (int i = 1; i < num; i++)
84
if (meshes[i] == nullptr)
86
this->warn("You may be initializing a Filter with Solution that is missing a Mesh.");
87
throw Hermes::Exceptions::Exception("this->meshes[%d] is nullptr in Filter<Scalar>::init().", i);
89
if (meshes[i]->get_seq() != this->mesh->get_seq())
95
sln = dynamic_cast<Solution<Scalar>*>(this->sln[i].get());
96
if (sln == nullptr || sln->get_space_type() != this->space_type)
97
this->space_type = HERMES_INVALID_SPACE;
102
this->mesh = MeshSharedPtr(new Mesh);
103
this->unidata = Traverse::construct_union_mesh(num, meshes, this->mesh);
107
this->num_components = 1;
110
memset(sln_sub, 0, sizeof(sln_sub));
111
set_quad_2d(&g_quad_2d_std);
114
template<typename Scalar>
115
Filter<Scalar>::~Filter()
120
template<typename Scalar>
121
void Filter<Scalar>::set_quad_2d(Quad2D* quad_2d)
123
MeshFunction<Scalar>::set_quad_2d(quad_2d);
124
for (int i = 0; i < num; i++)
125
this->sln[i]->set_quad_2d(quad_2d); // nodup
128
template<typename Scalar>
129
void Filter<Scalar>::set_active_element(Element* e)
131
MeshFunction<Scalar>::set_active_element(e);
134
for (int i = 0; i < num; i++)
135
this->sln[i]->set_active_element(e); // nodup
136
memset(sln_sub, 0, sizeof(sln_sub));
140
for (int i = 0; i < num; i++)
142
this->sln[i]->set_active_element(unidata[i][e->id].e);
143
this->sln[i]->set_transform(unidata[i][e->id].idx);
144
sln_sub[i] = this->sln[i]->get_transform();
148
this->order = 20; // fixme
151
template<typename Scalar>
152
void Filter<Scalar>::free()
156
for (int i = 0; i < num; i++)
157
free_with_check(unidata[i]);
158
free_with_check(unidata);
162
template<typename Scalar>
163
void Filter<Scalar>::reinit()
169
template<typename Scalar>
170
void Filter<Scalar>::push_transform(int son)
172
MeshFunction<Scalar>::push_transform(son);
173
for (int i = 0; i < num; i++)
175
// sln_sub[i] contains the value sln[i]->sub_idx, which the Filter thinks
176
// the solution has, or at least had last time. If the filter graph is
177
// cyclic, it could happen that some solutions would get pushed the transform
178
// more than once. This mechanism prevents it. If the filter sees that the
179
// solution already has a different sub_idx than it thinks it should have,
180
// it assumes someone else has already pushed the correct transform. This
181
// is actually the case for cyclic filter graphs and filters used in multi-mesh
184
if (this->sln[i]->get_transform() == sln_sub[i])
185
this->sln[i]->push_transform(son);
186
sln_sub[i] = this->sln[i]->get_transform();
190
template<typename Scalar>
191
void Filter<Scalar>::pop_transform()
193
MeshFunction<Scalar>::pop_transform();
194
for (int i = 0; i < num; i++)
196
if (this->sln[i]->get_transform() == sln_sub[i] && sln_sub[i] != 0)
197
this->sln[i]->pop_transform();
198
sln_sub[i] = this->sln[i]->get_transform();
202
template<typename Scalar>
203
SimpleFilter<Scalar>::SimpleFilter() : Filter<Scalar>()
207
template<typename Scalar>
208
SimpleFilter<Scalar>::SimpleFilter(Hermes::vector<MeshFunctionSharedPtr<Scalar> > solutions, const Hermes::vector<int> items)
210
this->num = solutions.size();
211
if (this->num > H2D_MAX_COMPONENTS)
212
throw Hermes::Exceptions::Exception("Attempt to create an instance of Filter with more than 10 MeshFunctions.");
213
if (items.size() != (unsigned) this->num)
214
if (items.size() > 0)
215
throw Hermes::Exceptions::Exception("Attempt to create an instance of SimpleFilter with different supplied number of MeshFunctions than the number of types of data used from them.");
217
for (int i = 0; i < this->num; i++)
220
this->sln[i] = solutions.at(i);
221
if (items.size() > 0)
222
this->item[i] = items.at(i);
224
this->item[i] = H2D_FN_VAL;
230
template<typename Scalar>
231
SimpleFilter<Scalar>::~SimpleFilter()
235
template<typename Scalar>
236
void SimpleFilter<Scalar>::init_components()
238
bool vec1 = false, vec2 = false;
239
for (int i = 0; i < this->num; i++)
241
if (this->sln[i]->get_num_components() > 1) vec1 = true;
242
if ((item[i] & H2D_FN_COMPONENT_0) && (item[i] & H2D_FN_COMPONENT_1)) vec2 = true;
243
if (this->sln[i]->get_num_components() == 1) item[i] &= H2D_FN_COMPONENT_0;
245
this->num_components = (vec1 && vec2) ? 2 : 1;
248
template<typename Scalar>
249
void SimpleFilter<Scalar>::precalculate(int order, int mask)
251
#ifdef H2D_USE_SECOND_DERIVATIVES
252
if (mask & (H2D_FN_DX | H2D_FN_DY | H2D_FN_DXX | H2D_FN_DYY | H2D_FN_DXY))
254
if (mask & (H2D_FN_DX | H2D_FN_DY))
256
throw Hermes::Exceptions::Exception("SimpleFilter not defined for derivatives.");
258
Quad2D* quad = this->quads[this->cur_quad];
259
int np = quad->get_num_points(order, this->element->get_mode());
261
// precalculate all solutions
262
for (int i = 0; i < this->num; i++)
263
this->sln[i]->set_quad_order(order, item[i]);
265
for (int j = 0; j < this->num_components; j++)
267
// obtain corresponding tables
268
Scalar* tab[H2D_MAX_COMPONENTS];
269
for (int i = 0; i < this->num; i++)
271
int a = 0, b = 0, mask = item[i];
272
if (mask >= 0x40) { a = 1; mask >>= 6; }
273
while (!(mask & 1)) { mask >>= 1; b++; }
274
tab[i] = const_cast<Scalar*>(this->sln[i]->get_values(this->num_components == 1 ? a : j, b));
275
if (tab[i] == nullptr)
276
throw Hermes::Exceptions::Exception("Value of 'item%d' is incorrect in filter definition.", i + 1);
279
Hermes::vector<Scalar*> values;
280
for (int i = 0; i < this->num; i++)
281
values.push_back(tab[i]);
284
filter_fn(np, values, this->values[j][0]);
288
template<typename Scalar>
289
Func<Scalar>* SimpleFilter<Scalar>::get_pt_value(double x, double y, bool use_MeshHashGrid, Element* e)
291
Scalar val[H2D_MAX_COMPONENTS];
292
for (int i = 0; i < this->num; i++)
293
val[i] = this->sln[i]->get_pt_value(x, y, use_MeshHashGrid, e)->val[0];
295
Func<Scalar>* toReturn = new Func<Scalar>(1, 1);
298
Hermes::vector<Scalar*> values;
299
for (int i = 0; i < this->num; i++)
300
values.push_back(&val[i]);
303
filter_fn(1, values, &result);
305
toReturn->val[0] = result;
309
ComplexFilter::ComplexFilter() : Filter<double>()
312
this->unimesh = false;
315
ComplexFilter::ComplexFilter(MeshFunctionSharedPtr<std::complex<double> > solution, int item) : Filter<double>()
318
this->unimesh = false;
319
this->sln_complex = solution;
320
this->num_components = solution->get_num_components();
321
this->mesh = solution->get_mesh();
322
set_quad_2d(&g_quad_2d_std);
325
ComplexFilter::~ComplexFilter()
330
void ComplexFilter::free()
334
void ComplexFilter::set_quad_2d(Quad2D* quad_2d)
336
MeshFunction<double>::set_quad_2d(quad_2d);
337
this->sln_complex->set_quad_2d(quad_2d);
340
void ComplexFilter::set_active_element(Element* e)
342
MeshFunction<double>::set_active_element(e);
344
this->sln_complex->set_active_element(e);
346
memset(sln_sub, 0, sizeof(sln_sub));
348
this->order = 20; // fixme
351
void ComplexFilter::push_transform(int son)
353
MeshFunction<double>::push_transform(son);
354
this->sln_complex->push_transform(son);
357
void ComplexFilter::pop_transform()
359
MeshFunction<double>::pop_transform();
360
this->sln_complex->pop_transform();
363
void ComplexFilter::precalculate(int order, int mask)
365
#ifdef H2D_USE_SECOND_DERIVATIVES
366
if (mask & (H2D_FN_DX | H2D_FN_DY | H2D_FN_DXX | H2D_FN_DYY | H2D_FN_DXY))
368
if (mask & (H2D_FN_DX | H2D_FN_DY))
370
throw Hermes::Exceptions::Exception("Filter not defined for derivatives.");
372
Quad2D* quad = this->quads[this->cur_quad];
373
int np = quad->get_num_points(order, this->element->get_mode());
375
this->sln_complex->set_quad_order(order, H2D_FN_VAL);
377
// obtain corresponding tables
378
filter_fn(np, const_cast<std::complex<double>*>(this->sln_complex->get_values(0, 0)), this->values[0][0]);
379
if (num_components > 1)
380
filter_fn(np, const_cast<std::complex<double>*>(this->sln_complex->get_values(1, 0)), this->values[1][0]);
383
Func<double>* ComplexFilter::get_pt_value(double x, double y, bool use_MeshHashGrid, Element* e)
385
Func<std::complex<double> >* val = this->sln_complex->get_pt_value(x, y, use_MeshHashGrid, e);
387
Func<double>* toReturn = new Func<double>(1, this->num_components);
392
filter_fn(1, val->val, &result);
394
if (this->num_components == 1)
396
toReturn->val[0] = result;
397
toReturn->dx[0] = 0.0;
398
toReturn->dy[0] = 0.0;
402
this->warn("ComplexFilter only implemented for scalar functions.");
407
template<typename Scalar>
408
DXDYFilter<Scalar>::DXDYFilter() : Filter<Scalar>()
412
template<typename Scalar>
413
DXDYFilter<Scalar>::DXDYFilter(Hermes::vector<MeshFunctionSharedPtr<Scalar> > solutions) : Filter<Scalar>(solutions)
418
template<typename Scalar>
419
DXDYFilter<Scalar>::~DXDYFilter()
423
template<typename Scalar>
424
void DXDYFilter<Scalar>::init_components()
426
this->num_components = this->sln[0]->get_num_components();
427
for (int i = 1; i < this->num; i++)
428
if (this->sln[i]->get_num_components() != this->num_components)
429
throw Hermes::Exceptions::Exception("Filter: Solutions do not have the same number of components!");
432
template<typename Scalar>
433
void DXDYFilter<Scalar>::init(Hermes::vector<MeshFunctionSharedPtr<Scalar> > solutions)
435
Filter<Scalar>::init(solutions);
439
template<typename Scalar>
440
void DXDYFilter<Scalar>::precalculate(int order, int mask)
442
Quad2D* quad = this->quads[this->cur_quad];
443
int np = quad->get_num_points(order, this->element->get_mode());
445
// precalculate all solutions
446
for (int i = 0; i < this->num; i++)
447
this->sln[i]->set_quad_order(order, H2D_FN_DEFAULT);
449
for (int j = 0; j < this->num_components; j++)
451
// obtain solution tables
453
const Scalar *val[H2D_MAX_COMPONENTS], *dx[H2D_MAX_COMPONENTS], *dy[H2D_MAX_COMPONENTS];
454
x = this->sln[0]->get_refmap()->get_phys_x(order);
455
y = this->sln[0]->get_refmap()->get_phys_y(order);
457
for (int i = 0; i < this->num; i++)
459
val[i] = this->sln[i]->get_fn_values(j);
460
dx[i] = this->sln[i]->get_dx_values(j);
461
dy[i] = this->sln[i]->get_dy_values(j);
464
Hermes::vector<const Scalar *> values_vector;
465
Hermes::vector<const Scalar *> dx_vector;
466
Hermes::vector<const Scalar *> dy_vector;
468
for (int i = 0; i < this->num; i++)
470
values_vector.push_back(val[i]);
471
dx_vector.push_back(dx[i]);
472
dy_vector.push_back(dy[i]);
476
filter_fn(np, x, y, values_vector, dx_vector, dy_vector, this->values[j][0], this->values[j][1], this->values[j][2]);
480
template<typename Scalar>
481
Func<Scalar>* DXDYFilter<Scalar>::get_pt_value(double x, double y, bool use_MeshHashGrid, Element* e)
483
this->warn("DXDYFilter<Scalar>::get_pt_value not implemented.");
487
template<typename Scalar>
488
void MagFilter<Scalar>::filter_fn(int n, Hermes::vector<Scalar*> values, Scalar* result)
490
for (int i = 0; i < n; i++)
494
for (unsigned int j = 0; j < values.size(); j++)
495
result[i] += sqr(values.at(j)[i]);
496
result[i] = sqrt(result[i]);
500
template<typename Scalar>
501
MagFilter<Scalar>::MagFilter(Hermes::vector<MeshFunctionSharedPtr<Scalar> > solutions, Hermes::vector<int> items) : SimpleFilter<Scalar>(solutions, items)
505
template<typename Scalar>
506
MagFilter<Scalar>::MagFilter(MeshFunctionSharedPtr<Scalar> sln1, int item1)
507
: SimpleFilter<Scalar>(Hermes::vector<MeshFunctionSharedPtr<Scalar> >(sln1, sln1),
508
Hermes::vector<int>(item1 & H2D_FN_COMPONENT_0, item1 & H2D_FN_COMPONENT_1))
510
if (sln1->get_num_components() < 2)
511
throw Hermes::Exceptions::Exception("The single-argument constructor is intended for vector-valued solutions.");
514
template<typename Scalar>
515
MagFilter<Scalar>::~MagFilter()
519
template<typename Scalar>
520
MeshFunction<Scalar>* MagFilter<Scalar>::clone() const
522
Hermes::vector<MeshFunctionSharedPtr<Scalar> > slns;
523
Hermes::vector<int> items;
524
for (int i = 0; i < this->num; i++)
526
slns.push_back(this->sln[i]->clone());
527
items.push_back(this->item[i]);
529
MagFilter<Scalar>* filter = new MagFilter<Scalar>(slns, items);
533
void TopValFilter::filter_fn(int n, Hermes::vector<double*> values, double* result)
535
for (int i = 0; i < n; i++)
538
for (unsigned int j = 0; j < values.size(); j++)
539
if (values.at(j)[i] > limits[j])
540
result[i] = limits[j];
542
result[i] = values.at(j)[i];
546
TopValFilter::TopValFilter(Hermes::vector<MeshFunctionSharedPtr<double> > solutions, Hermes::vector<double> limits, Hermes::vector<int> items) : SimpleFilter<double>(solutions, items), limits(limits)
550
TopValFilter::TopValFilter(MeshFunctionSharedPtr<double> sln, double limit, int item)
551
: SimpleFilter<double>()
553
this->limits.push_back(limit);
555
this->item[0] = item;
557
Filter<double>::init();
560
TopValFilter::~TopValFilter()
564
MeshFunction<double>* TopValFilter::clone() const
566
Hermes::vector<MeshFunctionSharedPtr<double> > slns;
567
Hermes::vector<int> items;
568
for (int i = 0; i < this->num; i++)
570
slns.push_back(this->sln[i]->clone());
571
items.push_back(this->item[i]);
573
TopValFilter* filter = new TopValFilter(slns, limits, items);
577
void BottomValFilter::filter_fn(int n, Hermes::vector<double*> values, double* result)
579
for (int i = 0; i < n; i++)
582
for (unsigned int j = 0; j < values.size(); j++)
583
if (values.at(j)[i] < limits[j])
584
result[i] = limits[j];
586
result[i] = values.at(j)[i];
590
BottomValFilter::BottomValFilter(Hermes::vector<MeshFunctionSharedPtr<double> > solutions, Hermes::vector<double> limits, Hermes::vector<int> items) : SimpleFilter<double>(solutions, items), limits(limits)
594
BottomValFilter::BottomValFilter(MeshFunctionSharedPtr<double> sln, double limit, int item)
595
: SimpleFilter<double>()
597
this->limits.push_back(limit);
599
this->item[0] = item;
601
Filter<double>::init();
604
BottomValFilter::~BottomValFilter()
608
MeshFunction<double>* BottomValFilter::clone() const
610
Hermes::vector<MeshFunctionSharedPtr<double> > slns;
611
Hermes::vector<int> items;
612
for (int i = 0; i < this->num; i++)
614
slns.push_back(this->sln[i]->clone());
615
items.push_back(this->item[i]);
617
BottomValFilter* filter = new BottomValFilter(slns, limits, items);
621
void ValFilter::filter_fn(int n, Hermes::vector<double*> values, double* result)
623
for (int i = 0; i < n; i++)
626
for (unsigned int j = 0; j < values.size(); j++)
627
if (values.at(j)[i] < low_limits[j])
628
result[i] = low_limits[j];
630
if (values.at(j)[i] > high_limits[j])
631
result[i] = high_limits[j];
633
result[i] = values.at(j)[i];
637
ValFilter::ValFilter(Hermes::vector<MeshFunctionSharedPtr<double> > solutions, Hermes::vector<double> low_limits, Hermes::vector<double> high_limits, Hermes::vector<int> items) : SimpleFilter<double>(solutions, items), low_limits(low_limits), high_limits(high_limits)
641
ValFilter::ValFilter(MeshFunctionSharedPtr<double> sln, double low_limit, double high_limit, int item)
642
: SimpleFilter<double>()
644
this->low_limits.push_back(low_limit);
645
this->high_limits.push_back(high_limit);
647
this->item[0] = item;
649
Filter<double>::init();
652
ValFilter::~ValFilter()
656
MeshFunction<double>* ValFilter::clone() const
658
Hermes::vector<MeshFunctionSharedPtr<double> > slns;
659
Hermes::vector<int> items;
660
for (int i = 0; i < this->num; i++)
662
slns.push_back(this->sln[i]->clone());
663
items.push_back(this->item[i]);
665
ValFilter* filter = new ValFilter(slns, low_limits, high_limits, items);
669
template<typename Scalar>
670
void DiffFilter<Scalar>::filter_fn(int n, Hermes::vector<Scalar*> values, Scalar* result)
672
for (int i = 0; i < n; i++) result[i] = values.at(0)[i] - values.at(1)[i];
675
template<typename Scalar>
676
DiffFilter<Scalar>::DiffFilter(Hermes::vector<MeshFunctionSharedPtr<Scalar> > solutions, Hermes::vector<int> items) : SimpleFilter<Scalar>(solutions, items) {}
678
template<typename Scalar>
679
DiffFilter<Scalar>::~DiffFilter()
683
template<typename Scalar>
684
MeshFunction<Scalar>* DiffFilter<Scalar>::clone() const
686
Hermes::vector<MeshFunctionSharedPtr<Scalar> > slns;
687
Hermes::vector<int> items;
688
for (int i = 0; i < this->num; i++)
690
slns.push_back(this->sln[i]->clone());
691
items.push_back(this->item[i]);
693
DiffFilter* filter = new DiffFilter<Scalar>(slns, items);
697
template<typename Scalar>
698
void SumFilter<Scalar>::filter_fn(int n, Hermes::vector<Scalar*> values, Scalar* result)
700
for (int i = 0; i < n; i++)
703
for (unsigned int j = 0; j < values.size(); j++)
704
result[i] += values.at(j)[i];
708
template<typename Scalar>
709
SumFilter<Scalar>::SumFilter(Hermes::vector<MeshFunctionSharedPtr<Scalar> > solutions, Hermes::vector<int> items) : SimpleFilter<Scalar>(solutions, items) {}
711
template<typename Scalar>
712
SumFilter<Scalar>::~SumFilter()
716
template<typename Scalar>
717
MeshFunction<Scalar>* SumFilter<Scalar>::clone() const
719
Hermes::vector<MeshFunctionSharedPtr<Scalar> > slns;
720
Hermes::vector<int> items;
721
for (int i = 0; i < this->num; i++)
723
slns.push_back(this->sln[i]->clone());
724
items.push_back(this->item[i]);
726
SumFilter<Scalar>* filter = new SumFilter<Scalar>(slns, items);
731
void SquareFilter<double>::filter_fn(int n, Hermes::vector<double *> v1, double* result)
733
for (int i = 0; i < n; i++)
734
result[i] = sqr(v1.at(0)[i]);
738
void SquareFilter<std::complex<double> >::filter_fn(int n, Hermes::vector<std::complex<double> *> v1, std::complex<double> * result)
740
for (int i = 0; i < n; i++)
741
result[i] = std::norm(v1.at(0)[i]);
744
template<typename Scalar>
745
SquareFilter<Scalar>::SquareFilter(Hermes::vector<MeshFunctionSharedPtr<Scalar> > solutions, Hermes::vector<int> items)
746
: SimpleFilter<Scalar>(solutions, items)
748
if (solutions.size() > 1)
749
throw Hermes::Exceptions::Exception("SquareFilter only supports one MeshFunction.");
752
template<typename Scalar>
753
SquareFilter<Scalar>::~SquareFilter()
757
template<typename Scalar>
758
MeshFunction<Scalar>* SquareFilter<Scalar>::clone() const
760
Hermes::vector<MeshFunctionSharedPtr<Scalar> > slns;
761
Hermes::vector<int> items;
762
for (int i = 0; i < this->num; i++)
764
slns.push_back(this->sln[i]->clone());
765
items.push_back(this->item[i]);
767
SquareFilter<Scalar>* filter = new SquareFilter<Scalar>(slns, items);
771
void AbsFilter::filter_fn(int n, Hermes::vector<double*> v1, double * result)
773
for (int i = 0; i < n; i++)
774
result[i] = std::abs(v1.at(0)[i]);
777
AbsFilter::AbsFilter(Hermes::vector<MeshFunctionSharedPtr<double> > solutions, Hermes::vector<int> items)
778
: SimpleFilter<double>(solutions, items)
780
if (solutions.size() > 1)
781
throw Hermes::Exceptions::Exception("AbsFilter only supports one MeshFunction.");
784
AbsFilter::AbsFilter(MeshFunctionSharedPtr<double> solution)
785
: SimpleFilter<double>()
788
this->sln[0] = solution;
790
this->item[0] = H2D_FN_VAL;
796
AbsFilter::~AbsFilter()
800
MeshFunction<double>* AbsFilter::clone() const
802
Hermes::vector<MeshFunctionSharedPtr<double> > slns;
803
Hermes::vector<int> items;
804
for (int i = 0; i < this->num; i++)
806
slns.push_back(this->sln[i]->clone());
807
items.push_back(this->item[i]);
809
AbsFilter* filter = new AbsFilter(slns, items);
813
void RealFilter::filter_fn(int n, std::complex<double>* values, double* result)
815
for (int i = 0; i < n; i++)
816
result[i] = values[i].real();
819
MeshFunction<double>* RealFilter::clone() const
821
RealFilter* filter = new RealFilter(this->sln_complex->clone(), this->item);
825
RealFilter::RealFilter()
830
RealFilter::RealFilter(MeshFunctionSharedPtr<std::complex<double> > solution, int item)
831
: ComplexFilter(solution, item)
835
RealFilter::~RealFilter()
839
void ImagFilter::filter_fn(int n, std::complex<double>* values, double* result)
841
for (int i = 0; i < n; i++)
842
result[i] = values[i].imag();
845
ImagFilter::ImagFilter(MeshFunctionSharedPtr<std::complex<double> > solution, int item)
846
: ComplexFilter(solution, item)
850
ImagFilter::~ImagFilter()
854
MeshFunction<double>* ImagFilter::clone() const
856
ImagFilter* filter = new ImagFilter(this->sln_complex->clone(), this->item);
860
void ComplexAbsFilter::filter_fn(int n, std::complex<double>* values, double* result)
862
for (int i = 0; i < n; i++)
863
result[i] = sqrt(sqr(values[i].real()) + sqr(values[i].imag()));
866
MeshFunction<double>* ComplexAbsFilter::clone() const
868
ComplexAbsFilter* filter = new ComplexAbsFilter(this->sln_complex->clone(), this->item);
872
ComplexAbsFilter::ComplexAbsFilter(MeshFunctionSharedPtr<std::complex<double> > solution, int item)
873
: ComplexFilter(solution, item)
877
ComplexAbsFilter::~ComplexAbsFilter()
881
void AngleFilter::filter_fn(int n, Hermes::vector<std::complex<double>*> v1, double* result)
883
for (int i = 0; i < n; i++)
884
result[i] = atan2(v1.at(0)[i].imag(), v1.at(0)[i].real());
887
AngleFilter::AngleFilter(Hermes::vector<MeshFunctionSharedPtr<std::complex<double> > > solutions, Hermes::vector<int> items)
888
: SimpleFilter<std::complex<double> >(solutions, items)
890
if (solutions.size() > 1)
891
throw Hermes::Exceptions::Exception("RealFilter only supports one MeshFunction.");
894
AngleFilter::~AngleFilter()
898
void VonMisesFilter::precalculate(int order, int mask)
900
#ifdef H2D_USE_SECOND_DERIVATIVES
901
if (mask & (H2D_FN_DX | H2D_FN_DY | H2D_FN_DXX | H2D_FN_DYY | H2D_FN_DXY))
903
if (mask & (H2D_FN_DX | H2D_FN_DY))
905
throw Hermes::Exceptions::Exception("VonMisesFilter not defined for derivatives.");
907
Quad2D* quad = this->quads[this->cur_quad];
908
int np = quad->get_num_points(order, this->element->get_mode());
910
this->sln[0]->set_quad_order(order, H2D_FN_VAL | H2D_FN_DX | H2D_FN_DY);
911
this->sln[1]->set_quad_order(order, H2D_FN_DX | H2D_FN_DY);
913
const double *dudx = this->sln[0]->get_dx_values();
914
const double *dudy = this->sln[0]->get_dy_values();
915
const double *dvdx = this->sln[1]->get_dx_values();
916
const double *dvdy = this->sln[1]->get_dy_values();
917
const double *uval = this->sln[0]->get_fn_values();
919
double *x = refmap->get_phys_x(order);
921
for (int i = 0; i < np; i++)
924
double tz = lambda*(dudx[i] + dvdy[i]);
925
double tx = tz + 2 * mu*dudx[i];
926
double ty = tz + 2 * mu*dvdy[i];
927
if (cyl) tz += 2 * mu*uval[i] / x[i];
928
double txy = mu*(dudy[i] + dvdx[i]);
931
this->values[0][0][i] = 1.0 / sqrt(2.0) * sqrt(sqr(tx - ty) + sqr(ty - tz) + sqr(tz - tx) + 6 * sqr(txy));
935
Func<double>* VonMisesFilter::get_pt_value(double x, double y, bool use_MeshHashGrid, Element* e)
937
this->warn("VonMisesFilter<Scalar>::get_pt_value not implemented.");
941
VonMisesFilter::VonMisesFilter(Hermes::vector<MeshFunctionSharedPtr<double> > solutions, double lambda, double mu,
942
int cyl, int item1, int item2)
943
: Filter<double>(solutions)
946
this->lambda = lambda;
952
VonMisesFilter::VonMisesFilter(MeshFunctionSharedPtr<double>* solutions, int num, double lambda, double mu,
953
int cyl, int item1, int item2) : Filter<double>(solutions, num)
956
this->lambda = lambda;
962
VonMisesFilter::~VonMisesFilter()
966
MeshFunction<double>* VonMisesFilter::clone() const
968
Hermes::vector<MeshFunctionSharedPtr<double> > slns;
969
for (int i = 0; i < num; i++)
970
slns.push_back(sln[i]->clone());
971
VonMisesFilter* filter = new VonMisesFilter(&slns[0], num, lambda, mu, cyl, item1, item2);
975
template<typename Scalar>
976
void LinearFilter<Scalar>::precalculate(int order, int mask)
978
Quad2D* quad = this->quads[this->cur_quad];
979
int np = quad->get_num_points(order, this->element->get_mode());
980
struct Filter<Scalar>::Node* node = this->new_node(H2D_FN_DEFAULT, np);
982
// precalculate all solutions
983
for (int i = 0; i < this->num; i++)
984
this->sln[i]->set_quad_order(order);
986
for (int j = 0; j < this->num_components; j++)
988
// obtain solution tables
989
Scalar *val[H2D_MAX_COMPONENTS], *dx[H2D_MAX_COMPONENTS], *dy[H2D_MAX_COMPONENTS];
990
for (int i = 0; i < this->num; i++)
992
val[i] = this->sln[i]->get_fn_values(j);
993
dx[i] = this->sln[i]->get_dx_values(j);
994
dy[i] = this->sln[i]->get_dy_values(j);
997
for (int i = 0; i < np; i++)
999
node->values[j][0][i] = tau_frac * (val[1][i] - val[0][i]) + val[1][i];
1000
node->values[j][1][i] = tau_frac * (dx[1][i] - dx[0][i]) + dx[1][i];
1001
node->values[j][2][i] = tau_frac * (dy[1][i] - dy[0][i]) + dy[1][i];
1004
for (int i = 0; i < np; i++)
1006
node->values[j][0][i] = val[0][i];
1007
node->values[j][1][i] = dx[0][i];
1008
node->values[j][2][i] = dy[0][i];
1012
if (this->nodes->present(order))
1014
assert(this->nodes->get(order) == this->cur_node);
1015
free_with_check(this->nodes->get(order));
1017
this->nodes->add(node, order);
1018
this->cur_node = node;
1021
template<typename Scalar>
1022
Func<Scalar>* LinearFilter<Scalar>::get_pt_value(double x, double y, bool use_MeshHashGrid, Element* e)
1024
this->warn("LinearFilter<Scalar>::get_pt_value not implemented.");
1028
template<typename Scalar>
1029
LinearFilter<Scalar>::LinearFilter(MeshFunctionSharedPtr<Scalar> old) // : Filter(old)
1034
template<typename Scalar>
1035
LinearFilter<Scalar>::LinearFilter(MeshFunctionSharedPtr<Scalar> older, MeshFunctionSharedPtr<Scalar> old, double tau_frac)
1036
: Filter<Scalar>(Hermes::vector<MeshFunctionSharedPtr<Scalar> >(older, old))
1038
this->tau_frac = tau_frac;
1042
template<typename Scalar>
1043
LinearFilter<Scalar>::~LinearFilter()
1047
template<typename Scalar>
1048
void LinearFilter<Scalar>::init_components()
1050
this->num_components = this->sln[0]->get_num_components();
1051
for (int i = 1; i < this->num; i++)
1052
if (this->sln[i]->get_num_components() != this->num_components)
1053
throw Hermes::Exceptions::Exception("Filter: Solutions do not have the same number of components!");
1056
template<typename Scalar>
1057
void LinearFilter<Scalar>::set_active_element(Element* e)
1059
Filter<Scalar>::set_active_element(e);
1062
for (int i = 0; i < this->num; i++)
1064
int o = this->sln[i]->get_fn_order();
1065
if (o > this->order) this->order = o;
1069
template class HERMES_API Filter<double>;
1070
template class HERMES_API Filter<std::complex<double> >;
1071
template class HERMES_API SimpleFilter<double>;
1072
template class HERMES_API SimpleFilter<std::complex<double> >;
1073
template class HERMES_API DXDYFilter<double>;
1074
template class HERMES_API DXDYFilter<std::complex<double> >;
1075
template class HERMES_API MagFilter<double>;
1076
template class HERMES_API MagFilter<std::complex<double> >;
1077
template class HERMES_API DiffFilter<double>;
1078
template class HERMES_API DiffFilter<std::complex<double> >;
1079
template class HERMES_API SumFilter<double>;
1080
template class HERMES_API SumFilter<std::complex<double> >;
1081
template class HERMES_API SquareFilter<double>;
1082
template class HERMES_API SquareFilter<std::complex<double> >;