Hermes2D  3.0
weakforms_h1.cpp
1 // This file is part of Hermes2D.
2 //
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.
7 //
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.
12 //
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/>.
15 
16 #include "weakform_library/weakforms_h1.h"
17 #include "weakform_library/integrals_h1.h"
18 
19 namespace Hermes
20 {
21  namespace Hermes2D
22  {
23  namespace WeakFormsH1
24  {
25  template<>
26  DefaultMatrixFormVol<double>::DefaultMatrixFormVol(int i, int j, std::string area, Hermes2DFunction<double>* coeff, SymFlag sym, GeomType gt)
27  : MatrixFormVol<double>(i, j), coeff(coeff), gt(gt)
28  {
29  this->set_area(area);
30  this->setSymFlag(sym);
31 
32  if (coeff == nullptr)
33  {
34  this->coeff = new Hermes2DFunction<double>(1.0);
35  this->own_coeff = true;
36  }
37  else
38  this->own_coeff = false;
39  }
40 
41  template<>
42  DefaultMatrixFormVol<std::complex<double> >::DefaultMatrixFormVol
43  (int i, int j, std::string area, Hermes2DFunction<std::complex<double> >* coeff, SymFlag sym, GeomType gt)
44  : MatrixFormVol<std::complex<double> >(i, j), coeff(coeff), gt(gt)
45  {
46  this->set_area(area);
47  this->setSymFlag(sym);
48  if (coeff == nullptr)
49  {
50  this->coeff = new Hermes2DFunction<std::complex<double> >(std::complex<double>(1.0, 1.0));
51  this->own_coeff = true;
52  }
53  else
54  this->own_coeff = false;
55  }
56 
57  template<>
58  DefaultMatrixFormVol<double>::DefaultMatrixFormVol
59  (int i, int j, std::vector<std::string> areas,
60  Hermes2DFunction<double>* coeff, SymFlag sym, GeomType gt)
61  : MatrixFormVol<double>(i, j), coeff(coeff), gt(gt)
62  {
63  this->set_areas(areas);
64  this->setSymFlag(sym);
65  if (coeff == nullptr)
66  {
67  this->coeff = new Hermes2DFunction<double>(1.0);
68  this->own_coeff = true;
69  }
70  else
71  this->own_coeff = false;
72  }
73  template<>
74  DefaultMatrixFormVol<std::complex<double> >::DefaultMatrixFormVol
75  (int i, int j, std::vector<std::string> areas,
76  Hermes2DFunction<std::complex<double> >* coeff, SymFlag sym, GeomType gt)
77  : MatrixFormVol<std::complex<double> >(i, j), coeff(coeff), gt(gt)
78  {
79  this->set_areas(areas);
80  this->setSymFlag(sym);
81  if (coeff == nullptr)
82  {
83  this->coeff = new Hermes2DFunction<std::complex<double> >(std::complex<double>(1.0, 1.0));
84  this->own_coeff = true;
85  }
86  else
87  this->own_coeff = false;
88  }
89 
90  template<typename Scalar>
91  DefaultMatrixFormVol<Scalar>::~DefaultMatrixFormVol()
92  {
93  if (this->own_coeff)
94  delete coeff;
95  };
96 
97  template<typename Scalar>
98  Scalar DefaultMatrixFormVol<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *u, Func<double> *v,
99  GeomVol<double> *e, Func<Scalar> **ext) const
100  {
101  Scalar result = 0;
102  if (gt == HERMES_PLANAR)
103  {
104  if (coeff->is_constant())
105  {
106  for (int i = 0; i < n; i++)
107  result += wt[i] * u->val[i] * v->val[i];
108  result *= coeff->value(e->x[0], e->y[0]);
109  }
110  else
111  {
112  for (int i = 0; i < n; i++)
113  result += wt[i] * coeff->value(e->x[i], e->y[i]) * u->val[i] * v->val[i];
114  }
115  }
116  else {
117  if (gt == HERMES_AXISYM_X) {
118  for (int i = 0; i < n; i++) {
119  result += wt[i] * e->y[i] * coeff->value(e->x[i], e->y[i]) * u->val[i] * v->val[i];
120  }
121  }
122  else {
123  for (int i = 0; i < n; i++) {
124  result += wt[i] * e->x[i] * coeff->value(e->x[i], e->y[i]) * u->val[i] * v->val[i];
125  }
126  }
127  }
128 
129  return result;
130  }
131 
132  template<typename Scalar>
133  Ord DefaultMatrixFormVol<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *u,
134  Func<Ord> *v, GeomVol<Ord> *e, Func<Ord> **ext) const
135  {
136  Ord result = Ord(0);
137  if (gt == HERMES_PLANAR) {
138  for (int i = 0; i < n; i++) {
139  result += wt[i] * coeff->value(e->x[i], e->y[i]) * u->val[i] * v->val[i];
140  }
141  }
142  else {
143  if (gt == HERMES_AXISYM_X) {
144  for (int i = 0; i < n; i++) {
145  result += wt[i] * e->y[i] * coeff->value(e->x[i], e->y[i]) * u->val[i] * v->val[i];
146  }
147  }
148  else {
149  for (int i = 0; i < n; i++) {
150  result += wt[i] * e->x[i] * coeff->value(e->x[i], e->y[i]) * u->val[i] * v->val[i];
151  }
152  }
153  }
154 
155  return result;
156  }
157 
158  template<typename Scalar>
159  MatrixFormVol<Scalar>* DefaultMatrixFormVol<Scalar>::clone() const
160  {
161  return new DefaultMatrixFormVol<Scalar>(this->i, this->j, this->areas, this->coeff, this->sym, this->gt);
162  }
163 
164  template<typename Scalar>
165  DefaultJacobianDiffusion<Scalar>::DefaultJacobianDiffusion(int i, int j, std::string area,
166  Hermes1DFunction<Scalar>* coeff,
167  SymFlag sym, GeomType gt)
168  : MatrixFormVol<Scalar>(i, j), coeff(coeff), gt(gt)
169  {
170  this->set_area(area);
171  this->setSymFlag(sym);
172  if (coeff == nullptr)
173  {
174  this->coeff = new Hermes1DFunction<Scalar>(1.0);
175  this->own_coeff = true;
176  }
177  else
178  this->own_coeff = false;
179  };
180 
181  template<typename Scalar>
182  DefaultJacobianDiffusion<Scalar>::DefaultJacobianDiffusion(int i, int j, std::vector<std::string> areas,
183  Hermes1DFunction<Scalar>* coeff, SymFlag sym, GeomType gt)
184  : MatrixFormVol<Scalar>(i, j), coeff(coeff), gt(gt)
185  {
186  this->set_areas(areas);
187  this->setSymFlag(sym);
188  if (coeff == nullptr)
189  {
190  this->coeff = new Hermes1DFunction<Scalar>(1.0);
191  this->own_coeff = true;
192  }
193  else
194  this->own_coeff = false;
195  }
196 
197  template<typename Scalar>
198  DefaultJacobianDiffusion<Scalar>::~DefaultJacobianDiffusion()
199  {
200  if (this->own_coeff)
201  delete coeff;
202  };
203 
204  template<typename Scalar>
205  Scalar DefaultJacobianDiffusion<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *u,
206  Func<double> *v, GeomVol<double> *e, Func<Scalar> **ext) const
207  {
208  Scalar result = 0;
209  if (gt == HERMES_PLANAR)
210  {
211  if (coeff->is_constant())
212  {
213  Scalar result_der = 0;
214  for (int i = 0; i < n; i++)
215  {
216  result += wt[i] * ((u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]));
217  result_der += wt[i] * (u->val[i] * (u_ext[this->previous_iteration_space_index]->dx[i] * v->dx[i] + u_ext[this->previous_iteration_space_index]->dy[i] * v->dy[i]));
218  }
219  result *= coeff->value(u_ext[this->previous_iteration_space_index]->val[0]);
220  result_der *= coeff->derivative(u_ext[this->previous_iteration_space_index]->val[0]);
221  result += result_der;
222  }
223  else
224  {
225  for (int i = 0; i < n; i++)
226  {
227  result += wt[i] * (coeff->derivative(u_ext[this->previous_iteration_space_index]->val[i]) * u->val[i] *
228  (u_ext[this->previous_iteration_space_index]->dx[i] * v->dx[i] + u_ext[this->previous_iteration_space_index]->dy[i] * v->dy[i])
229  + coeff->value(u_ext[this->previous_iteration_space_index]->val[i])
230  * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]));
231  }
232  }
233  }
234  else {
235  if (gt == HERMES_AXISYM_X) {
236  for (int i = 0; i < n; i++) {
237  result += wt[i] * e->y[i] * (coeff->derivative(u_ext[this->previous_iteration_space_index]->val[i]) * u->val[i] *
238  (u_ext[this->previous_iteration_space_index]->dx[i] * v->dx[i] + u_ext[this->previous_iteration_space_index]->dy[i] * v->dy[i])
239  + coeff->value(u_ext[this->previous_iteration_space_index]->val[i])
240  * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]));
241  }
242  }
243  else {
244  for (int i = 0; i < n; i++) {
245  result += wt[i] * e->x[i] * (coeff->derivative(u_ext[this->previous_iteration_space_index]->val[i]) * u->val[i] *
246  (u_ext[this->previous_iteration_space_index]->dx[i] * v->dx[i] + u_ext[this->previous_iteration_space_index]->dy[i] * v->dy[i])
247  + coeff->value(u_ext[this->previous_iteration_space_index]->val[i])
248  * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]));
249  }
250  }
251  }
252 
253  return result;
254  }
255 
256  template<typename Scalar>
257  Ord DefaultJacobianDiffusion<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *u, Func<Ord> *v,
258  GeomVol<Ord> *e, Func<Ord> **ext) const
259  {
260  Ord result = Ord(0);
261  if (gt == HERMES_PLANAR) {
262  for (int i = 0; i < n; i++) {
263  result += wt[i] * (coeff->derivative(u_ext[this->previous_iteration_space_index]->val[i]) * u->val[i] *
264  (u_ext[this->previous_iteration_space_index]->dx[i] * v->dx[i] + u_ext[this->previous_iteration_space_index]->dy[i] * v->dy[i])
265  + coeff->value(u_ext[this->previous_iteration_space_index]->val[i])
266  * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]));
267  }
268  }
269  else {
270  if (gt == HERMES_AXISYM_X) {
271  for (int i = 0; i < n; i++) {
272  result += wt[i] * e->y[i] * (coeff->derivative(u_ext[this->previous_iteration_space_index]->val[i]) * u->val[i] *
273  (u_ext[this->previous_iteration_space_index]->dx[i] * v->dx[i] + u_ext[this->previous_iteration_space_index]->dy[i] * v->dy[i])
274  + coeff->value(u_ext[this->previous_iteration_space_index]->val[i])
275  * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]));
276  }
277  }
278  else {
279  for (int i = 0; i < n; i++) {
280  result += wt[i] * e->x[i] * (coeff->derivative(u_ext[this->previous_iteration_space_index]->val[i]) * u->val[i] *
281  (u_ext[this->previous_iteration_space_index]->dx[i] * v->dx[i] + u_ext[this->previous_iteration_space_index]->dy[i] * v->dy[i])
282  + coeff->value(u_ext[this->previous_iteration_space_index]->val[i])
283  * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]));
284  }
285  }
286  }
287 
288  return result;
289  }
290 
291  template<typename Scalar>
292  MatrixFormVol<Scalar>* DefaultJacobianDiffusion<Scalar>::clone() const
293  {
294  return new DefaultJacobianDiffusion<Scalar>(this->i, this->j, this->areas, this->coeff, this->sym, this->gt);
295  }
296 
297  template<typename Scalar>
298  DefaultMatrixFormDiffusion<Scalar>::DefaultMatrixFormDiffusion(int i, int j, std::string area,
299  Hermes1DFunction<Scalar>* coeff,
300  SymFlag sym, GeomType gt)
301  : MatrixFormVol<Scalar>(i, j), coeff(coeff), gt(gt)
302  {
303  this->set_area(area);
304  this->setSymFlag(sym);
305  if (coeff == nullptr)
306  {
307  this->coeff = new Hermes1DFunction<Scalar>(1.0);
308  this->own_coeff = true;
309  }
310  else
311  this->own_coeff = false;
312  };
313 
314  template<typename Scalar>
315  DefaultMatrixFormDiffusion<Scalar>::DefaultMatrixFormDiffusion(int i, int j, std::vector<std::string> areas,
316  Hermes1DFunction<Scalar>* coeff, SymFlag sym, GeomType gt)
317  : MatrixFormVol<Scalar>(i, j), coeff(coeff), gt(gt)
318  {
319  this->set_areas(areas);
320  this->setSymFlag(sym);
321  if (coeff == nullptr)
322  {
323  this->coeff = new Hermes1DFunction<Scalar>(1.0);
324  this->own_coeff = true;
325  }
326  else
327  this->own_coeff = false;
328  }
329 
330  template<typename Scalar>
331  DefaultMatrixFormDiffusion<Scalar>::~DefaultMatrixFormDiffusion()
332  {
333  if (this->own_coeff)
334  delete coeff;
335  };
336 
337  template<typename Scalar>
338  Scalar DefaultMatrixFormDiffusion<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *u,
339  Func<double> *v, GeomVol<double> *e, Func<Scalar> **ext) const
340  {
341 
342  Scalar result = 0;
343  for (int i = 0; i < n; i++)
344  {
345  result += wt[i] * (8.854e-12*e->x[i] * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]));
346  }
347 
348  return result;
349  }
350 
351  template<typename Scalar>
352  Ord DefaultMatrixFormDiffusion<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *u, Func<Ord> *v,
353  GeomVol<Ord> *e, Func<Ord> **ext) const
354  {
355  Ord result = Ord(0);
356  for (int i = 0; i < n; i++)
357  {
358  result += wt[i] * (8.854e-12*e->x[i] * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]));
359  }
360 
361  return result;
362  }
363 
364  template<typename Scalar>
365  MatrixFormVol<Scalar>* DefaultMatrixFormDiffusion<Scalar>::clone() const
366  {
367  return new DefaultMatrixFormDiffusion<Scalar>(this->i, this->j, this->areas, this->coeff, this->sym, this->gt);
368  }
369 
370  template<typename Scalar>
371  DefaultJacobianAdvection<Scalar>::DefaultJacobianAdvection(int i, int j, std::string area,
372  Hermes1DFunction<Scalar>* coeff1,
373  Hermes1DFunction<Scalar>* coeff2,
374  GeomType gt)
375  : MatrixFormVol<Scalar>(i, j), coeff1(coeff1), coeff2(coeff2), gt(gt)
376  {
377  this->set_area(area);
378 
379  if (gt != HERMES_PLANAR) throw Hermes::Exceptions::Exception("Axisymmetric advection forms not implemented yet.");
380 
381  // If coeff1 == nullptr or coeff22 == nullptr, initialize it to be constant 1.0.
382  if (coeff1 == nullptr)
383  {
384  this->coeff1 = new Hermes1DFunction<Scalar>(1.0);
385  this->own_coeff1 = true;
386  }
387  else
388  this->own_coeff1 = false;
389  if (coeff2 == nullptr)
390  {
391  this->coeff2 = new Hermes1DFunction<Scalar>(1.0);
392  this->own_coeff2 = true;
393  }
394  else
395  this->own_coeff2 = false;
396  }
397 
398  template<typename Scalar>
399  DefaultJacobianAdvection<Scalar>::DefaultJacobianAdvection(int i, int j, std::vector<std::string> areas,
400  Hermes1DFunction<Scalar>* coeff1,
401  Hermes1DFunction<Scalar>* coeff2,
402  GeomType gt)
403  : MatrixFormVol<Scalar>(i, j), coeff1(coeff1), coeff2(coeff2), gt(gt)
404  {
405  this->set_areas(areas);
406 
407  if (gt != HERMES_PLANAR) throw Hermes::Exceptions::Exception("Axisymmetric advection forms not implemented yet.");
408 
409  // If coeff1 == nullptr or coeff22 == nullptr, initialize it to be constant 1.0.
410  if (coeff1 == nullptr)
411  {
412  this->coeff1 = new Hermes1DFunction<Scalar>(1.0);
413  this->own_coeff1 = true;
414  }
415  else
416  this->own_coeff1 = false;
417  if (coeff2 == nullptr)
418  {
419  this->coeff2 = new Hermes1DFunction<Scalar>(1.0);
420  this->own_coeff2 = true;
421  }
422  else
423  this->own_coeff2 = false;
424  }
425 
426  template<typename Scalar>
427  DefaultJacobianAdvection<Scalar>::~DefaultJacobianAdvection()
428  {
429  if (this->own_coeff1)
430  delete coeff1;
431  if (this->own_coeff2)
432  delete coeff2;
433  };
434 
435  template<typename Scalar>
436  Scalar DefaultJacobianAdvection<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *u,
437  Func<double> *v, GeomVol<double> *e, Func<Scalar> **ext) const
438  {
439  Scalar result = 0;
440  for (int i = 0; i < n; i++) {
441  result += wt[i] * (coeff1->derivative(u_ext[this->previous_iteration_space_index]->val[i]) * u->val[i] * u_ext[this->previous_iteration_space_index]->dx[i] * v->val[i]
442  + coeff1->value(u_ext[this->previous_iteration_space_index]->val[i]) * u->dx[i] * v->val[i]
443  + coeff2->derivative(u_ext[this->previous_iteration_space_index]->val[i]) * u->val[i] * u_ext[this->previous_iteration_space_index]->dy[i] * v->val[i]
444  + coeff2->value(u_ext[this->previous_iteration_space_index]->val[i]) * u->dy[i] * v->val[i]);
445  }
446  return result;
447  }
448 
449  template<typename Scalar>
450  Ord DefaultJacobianAdvection<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *u, Func<Ord> *v,
451  GeomVol<Ord> *e, Func<Ord> **ext) const
452  {
453  Ord result = Ord(0);
454  for (int i = 0; i < n; i++) {
455  result += wt[i] * (coeff1->derivative(u_ext[this->previous_iteration_space_index]->val[i]) * u->val[i] * u_ext[this->previous_iteration_space_index]->dx[i] * v->val[i]
456  + coeff1->value(u_ext[this->previous_iteration_space_index]->val[i]) * u->dx[i] * v->val[i]
457  + coeff2->derivative(u_ext[this->previous_iteration_space_index]->val[i]) * u->val[i] * u_ext[this->previous_iteration_space_index]->dy[i] * v->val[i]
458  + coeff2->value(u_ext[this->previous_iteration_space_index]->val[i]) * u->dy[i] * v->val[i]);
459  }
460  return result;
461  }
462 
463  // This is to make the form usable in rk_time_step_newton().
464  template<typename Scalar>
465  MatrixFormVol<Scalar>* DefaultJacobianAdvection<Scalar>::clone() const
466  {
467  return new DefaultJacobianAdvection<Scalar>(this->i, this->j, this->areas, this->coeff1, this->coeff2, this->gt);
468  }
469 
470  template<typename Scalar>
471  DefaultVectorFormVol<Scalar>::DefaultVectorFormVol(int i, std::string area,
472  Hermes2DFunction<Scalar>* coeff,
473  GeomType gt)
474  : VectorFormVol<Scalar>(i), coeff(coeff), gt(gt)
475  {
476  this->set_area(area);
477  if (coeff == nullptr)
478  {
479  this->coeff = new Hermes2DFunction<Scalar>(1.0);
480  this->own_coeff = true;
481  }
482  else
483  this->own_coeff = false;
484  }
485 
486  template<typename Scalar>
487  DefaultVectorFormVol<Scalar>::DefaultVectorFormVol(int i, std::vector<std::string> areas,
488  Hermes2DFunction<Scalar>* coeff,
489  GeomType gt)
490  : VectorFormVol<Scalar>(i), coeff(coeff), gt(gt)
491  {
492  this->set_areas(areas);
493  if (coeff == nullptr)
494  {
495  this->coeff = new Hermes2DFunction<Scalar>(1.0);
496  this->own_coeff = true;
497  }
498  else
499  this->own_coeff = false;
500  }
501 
502  template<typename Scalar>
503  DefaultVectorFormVol<Scalar>::~DefaultVectorFormVol()
504  {
505  if (this->own_coeff)
506  delete coeff;
507  };
508 
509  template<typename Scalar>
510  Scalar DefaultVectorFormVol<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *v,
511  GeomVol<double> *e, Func<Scalar> **ext) const
512  {
513  Scalar result = 0;
514  if (gt == HERMES_PLANAR) {
515  for (int i = 0; i < n; i++) {
516  result += wt[i] * coeff->value(e->x[i], e->y[i]) * v->val[i];
517  }
518  }
519  else {
520  if (gt == HERMES_AXISYM_X) {
521  for (int i = 0; i < n; i++) {
522  result += wt[i] * e->y[i] * coeff->value(e->x[i], e->y[i]) * v->val[i];
523  }
524  }
525  else {
526  for (int i = 0; i < n; i++) {
527  result += wt[i] * e->x[i] * coeff->value(e->x[i], e->y[i]) * v->val[i];
528  }
529  }
530  }
531  return result;
532  }
533 
534  template<typename Scalar>
535  Ord DefaultVectorFormVol<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *v,
536  GeomVol<Ord> *e, Func<Ord> **ext) const
537  {
538  Ord result = Ord(0);
539  if (gt == HERMES_PLANAR) {
540  for (int i = 0; i < n; i++) {
541  result += wt[i] * coeff->value(e->x[i], e->y[i]) * v->val[i];
542  }
543  }
544  else {
545  if (gt == HERMES_AXISYM_X) {
546  for (int i = 0; i < n; i++) {
547  result += wt[i] * e->y[i] * coeff->value(e->x[i], e->y[i]) * v->val[i];
548  }
549  }
550  else {
551  for (int i = 0; i < n; i++) {
552  result += wt[i] * e->x[i] * coeff->value(e->x[i], e->y[i]) * v->val[i];
553  }
554  }
555  }
556 
557  return result;
558  }
559 
560  template<typename Scalar>
561  VectorFormVol<Scalar>* DefaultVectorFormVol<Scalar>::clone() const
562  {
563  return new DefaultVectorFormVol<Scalar>(this->i, this->areas, this->coeff, this->gt);
564  }
565 
566  template<typename Scalar>
567  DefaultResidualVol<Scalar>::DefaultResidualVol(int i, std::string area,
568  Hermes2DFunction<Scalar>* coeff,
569  GeomType gt)
570  : VectorFormVol<Scalar>(i), coeff(coeff), gt(gt)
571  {
572  this->set_area(area);
573  if (coeff == nullptr)
574  {
575  this->coeff = new Hermes2DFunction<Scalar>(1.0);
576  this->own_coeff = true;
577  }
578  else
579  this->own_coeff = false;
580  }
581 
582  template<typename Scalar>
583  DefaultResidualVol<Scalar>::DefaultResidualVol(int i, std::vector<std::string> areas,
584  Hermes2DFunction<Scalar>* coeff,
585  GeomType gt)
586  : VectorFormVol<Scalar>(i), coeff(coeff), gt(gt)
587  {
588  this->set_areas(areas);
589  if (coeff == nullptr)
590  {
591  this->coeff = new Hermes2DFunction<Scalar>(1.0);
592  this->own_coeff = true;
593  }
594  else
595  this->own_coeff = false;
596  }
597 
598  template<typename Scalar>
599  DefaultResidualVol<Scalar>::~DefaultResidualVol()
600  {
601  if (this->own_coeff)
602  delete coeff;
603  };
604 
605  template<typename Scalar>
606  Scalar DefaultResidualVol<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *v,
607  GeomVol<double> *e, Func<Scalar> **ext) const
608  {
609  Scalar result = 0;
610  if (gt == HERMES_PLANAR) {
611  for (int i = 0; i < n; i++) {
612  result += wt[i] * coeff->value(e->x[i], e->y[i]) * u_ext[this->previous_iteration_space_index]->val[i] * v->val[i];
613  }
614  }
615  else {
616  if (gt == HERMES_AXISYM_X) {
617  for (int i = 0; i < n; i++) {
618  result += wt[i] * e->y[i] * coeff->value(e->x[i], e->y[i]) * u_ext[this->previous_iteration_space_index]->val[i] * v->val[i];
619  }
620  }
621  else {
622  for (int i = 0; i < n; i++) {
623  result += wt[i] * e->x[i] * coeff->value(e->x[i], e->y[i]) * u_ext[this->previous_iteration_space_index]->val[i] * v->val[i];
624  }
625  }
626  }
627  return result;
628  }
629 
630  template<typename Scalar>
631  Ord DefaultResidualVol<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *v,
632  GeomVol<Ord> *e, Func<Ord> **ext) const
633  {
634  Ord result = Ord(0);
635  if (gt == HERMES_PLANAR) {
636  for (int i = 0; i < n; i++) {
637  result += wt[i] * coeff->value(e->x[i], e->y[i]) * u_ext[this->previous_iteration_space_index]->val[i] * v->val[i];
638  }
639  }
640  else {
641  if (gt == HERMES_AXISYM_X) {
642  for (int i = 0; i < n; i++) {
643  result += wt[i] * e->y[i] * coeff->value(e->x[i], e->y[i]) * u_ext[this->previous_iteration_space_index]->val[i] * v->val[i];
644  }
645  }
646  else {
647  for (int i = 0; i < n; i++) {
648  result += wt[i] * e->x[i] * coeff->value(e->x[i], e->y[i]) * u_ext[this->previous_iteration_space_index]->val[i] * v->val[i];
649  }
650  }
651  }
652 
653  return result;
654  }
655 
656  template<typename Scalar>
657  VectorFormVol<Scalar>* DefaultResidualVol<Scalar>::clone() const
658  {
659  return new DefaultResidualVol(this->i, this->areas, this->coeff, this->gt);
660  }
661 
662  template<typename Scalar>
663  DefaultResidualDiffusion<Scalar>::DefaultResidualDiffusion(int i, std::string area,
664  Hermes1DFunction<Scalar>* coeff, GeomType gt)
665  : VectorFormVol<Scalar>(i), coeff(coeff), gt(gt)
666  {
667  this->set_area(area);
668  if (coeff == nullptr)
669  {
670  this->coeff = new Hermes1DFunction<Scalar>(1.0);
671  this->own_coeff = true;
672  }
673  else
674  this->own_coeff = false;
675  };
676 
677  template<typename Scalar>
678  DefaultResidualDiffusion<Scalar>::DefaultResidualDiffusion(int i, std::vector<std::string> areas,
679  Hermes1DFunction<Scalar>* coeff, GeomType gt)
680  : VectorFormVol<Scalar>(i), coeff(coeff), gt(gt)
681  {
682  this->set_areas(areas);
683  if (coeff == nullptr)
684  {
685  this->coeff = new Hermes1DFunction<Scalar>(1.0);
686  this->own_coeff = true;
687  }
688  else
689  this->own_coeff = false;
690  }
691 
692  template<typename Scalar>
693  DefaultResidualDiffusion<Scalar>::~DefaultResidualDiffusion()
694  {
695  if (this->own_coeff)
696  delete coeff;
697  };
698 
699  template<typename Scalar>
700  Scalar DefaultResidualDiffusion<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *v,
701  GeomVol<double> *e, Func<Scalar> **ext) const
702  {
703  Scalar result = 0;
704  if (gt == HERMES_PLANAR) {
705  for (int i = 0; i < n; i++) {
706  result += wt[i] * coeff->value(u_ext[this->previous_iteration_space_index]->val[i])
707  * (u_ext[this->previous_iteration_space_index]->dx[i] * v->dx[i] + u_ext[this->previous_iteration_space_index]->dy[i] * v->dy[i]);
708  }
709  }
710  else {
711  if (gt == HERMES_AXISYM_X) {
712  for (int i = 0; i < n; i++) {
713  result += wt[i] * e->y[i] * coeff->value(u_ext[this->previous_iteration_space_index]->val[i])
714  * (u_ext[this->previous_iteration_space_index]->dx[i] * v->dx[i] + u_ext[this->previous_iteration_space_index]->dy[i] * v->dy[i]);
715  }
716  }
717  else {
718  for (int i = 0; i < n; i++) {
719  result += wt[i] * e->x[i] * coeff->value(u_ext[this->previous_iteration_space_index]->val[i])
720  * (u_ext[this->previous_iteration_space_index]->dx[i] * v->dx[i] + u_ext[this->previous_iteration_space_index]->dy[i] * v->dy[i]);
721  }
722  }
723  }
724 
725  return result;
726  }
727 
728  template<typename Scalar>
729  Ord DefaultResidualDiffusion<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *v,
730  GeomVol<Ord> *e, Func<Ord> **ext) const
731  {
732  Ord result = Ord(0);
733  for (int i = 0; i < n; i++) {
734  result += wt[i] * coeff->value(u_ext[this->previous_iteration_space_index]->val[i])
735  * (u_ext[this->previous_iteration_space_index]->dx[i] * v->dx[i] + u_ext[this->previous_iteration_space_index]->dy[i] * v->dy[i]);
736  }
737  if (gt != HERMES_PLANAR) result = result * Ord(1);
738 
739  return result;
740  }
741 
742  template<typename Scalar>
743  VectorFormVol<Scalar>* DefaultResidualDiffusion<Scalar>::clone() const
744  {
745  return new DefaultResidualDiffusion<Scalar>(this->i, this->areas, this->coeff, this->gt);
746  }
747 
748  template<typename Scalar>
749  DefaultResidualAdvection<Scalar>::DefaultResidualAdvection(int i, std::string area,
750  Hermes1DFunction<Scalar>* coeff1,
751  Hermes1DFunction<Scalar>* coeff2,
752  GeomType gt)
753  : VectorFormVol<Scalar>(i), coeff1(coeff1), coeff2(coeff2), gt(gt)
754  {
755  this->set_area(area);
756 
757  if (gt != HERMES_PLANAR) throw Hermes::Exceptions::Exception("Axisymmetric advection forms not implemented yet.");
758 
759  // If coeff1 == nullptr or coeff22 == nullptr, initialize it to be constant 1.0.
760  if (coeff1 == nullptr)
761  {
762  this->coeff1 = new Hermes1DFunction<Scalar>(1.0);
763  this->own_coeff1 = true;
764  }
765  else
766  this->own_coeff1 = false;
767  if (coeff2 == nullptr)
768  {
769  this->coeff2 = new Hermes1DFunction<Scalar>(1.0);
770  this->own_coeff2 = true;
771  }
772  else
773  this->own_coeff2 = false;
774  }
775 
776  template<typename Scalar>
777  DefaultResidualAdvection<Scalar>::DefaultResidualAdvection(int i, std::vector<std::string> areas, \
778  Hermes1DFunction<Scalar>* coeff1,
779  Hermes1DFunction<Scalar>* coeff2,
780  GeomType gt)
781  : VectorFormVol<Scalar>(i), coeff1(coeff1), coeff2(coeff2), gt(gt)
782  {
783  this->set_areas(areas);
784 
785  if (gt != HERMES_PLANAR) throw Hermes::Exceptions::Exception("Axisymmetric advection forms not implemented yet.");
786 
787  // If coeff1 == nullptr or coeff22 == nullptr, initialize it to be constant 1.0.
788  if (coeff1 == nullptr)
789  {
790  this->coeff1 = new Hermes1DFunction<Scalar>(1.0);
791  this->own_coeff1 = true;
792  }
793  else
794  this->own_coeff1 = false;
795  if (coeff2 == nullptr)
796  {
797  this->coeff2 = new Hermes1DFunction<Scalar>(1.0);
798  this->own_coeff2 = true;
799  }
800  else
801  this->own_coeff2 = false;
802  }
803 
804  template<typename Scalar>
805  DefaultResidualAdvection<Scalar>::~DefaultResidualAdvection()
806  {
807  if (this->own_coeff1)
808  delete coeff1;
809  if (this->own_coeff2)
810  delete coeff2;
811  };
812 
813  template<typename Scalar>
814  Scalar DefaultResidualAdvection<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *v,
815  GeomVol<double> *e, Func<Scalar> **ext) const
816  {
817  Scalar result = 0;
818  Func<Scalar>* u_prev = u_ext[this->previous_iteration_space_index];
819  for (int i = 0; i < n; i++) {
820  result += wt[i] * (coeff1->value(u_prev->val[i]) * (u_prev->dx[i] * v->val[i])
821  + coeff2->value(u_prev->val[i]) * (u_prev->dy[i] * v->val[i]));
822  }
823  return result;
824  }
825 
826  template<typename Scalar>
827  Ord DefaultResidualAdvection<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *v,
828  GeomVol<Ord> *e, Func<Ord> **ext) const
829  {
830  Ord result = Ord(0);
831  Func<Ord>* u_prev = u_ext[this->previous_iteration_space_index];
832  for (int i = 0; i < n; i++) {
833  result += wt[i] * (coeff1->value(u_prev->val[i]) * (u_prev->dx[i] * v->val[i])
834  + coeff2->value(u_prev->val[i]) * (u_prev->dy[i] * v->val[i]));
835  }
836  return result;
837  }
838 
839  template<typename Scalar>
840  VectorFormVol<Scalar>* DefaultResidualAdvection<Scalar>::clone() const
841  {
842  return new DefaultResidualAdvection<Scalar>(this->i, this->areas, this->coeff1, this->coeff2, this->gt);
843  }
844 
845  template<typename Scalar>
846  DefaultMatrixFormSurf<Scalar>::DefaultMatrixFormSurf(int i, int j, std::string area,
847  Hermes2DFunction<Scalar>* coeff,
848  GeomType gt)
849  : MatrixFormSurf<Scalar>(i, j), coeff(coeff), gt(gt)
850  {
851  this->set_area(area);
852  if (coeff == nullptr)
853  {
854  this->coeff = new Hermes2DFunction<Scalar>(1.0);
855  this->own_coeff = true;
856  }
857  else
858  this->own_coeff = false;
859  }
860 
861  template<typename Scalar>
862  DefaultMatrixFormSurf<Scalar>::DefaultMatrixFormSurf(int i, int j, std::vector<std::string> areas,
863  Hermes2DFunction<Scalar>* coeff,
864  GeomType gt)
865  : MatrixFormSurf<Scalar>(i, j), coeff(coeff), gt(gt)
866  {
867  this->set_areas(areas);
868  if (coeff == nullptr)
869  {
870  this->coeff = new Hermes2DFunction<Scalar>(1.0);
871  this->own_coeff = true;
872  }
873  else
874  this->own_coeff = false;
875  }
876 
877  template<typename Scalar>
878  DefaultMatrixFormSurf<Scalar>::~DefaultMatrixFormSurf()
879  {
880  if (this->own_coeff)
881  delete coeff;
882  };
883 
884  template<typename Scalar>
885  Scalar DefaultMatrixFormSurf<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *u, Func<double> *v,
886  GeomSurf<double> *e, Func<Scalar> **ext) const
887  {
888  Scalar result = 0;
889  if (gt == HERMES_PLANAR) {
890  for (int i = 0; i < n; i++) {
891  result += wt[i] * coeff->value(e->x[i], e->y[i]) * u->val[i] * v->val[i];
892  }
893  }
894  else {
895  if (gt == HERMES_AXISYM_X) {
896  for (int i = 0; i < n; i++) {
897  result += wt[i] * e->y[i] * coeff->value(e->x[i], e->y[i]) * u->val[i] * v->val[i];
898  }
899  }
900  else {
901  for (int i = 0; i < n; i++) {
902  result += wt[i] * e->x[i] * coeff->value(e->x[i], e->y[i]) * u->val[i] * v->val[i];
903  }
904  }
905  }
906 
907  return result;
908  }
909 
910  template<typename Scalar>
911  Ord DefaultMatrixFormSurf<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *u,
912  Func<Ord> *v, GeomSurf<Ord> *e, Func<Ord> **ext) const
913  {
914  Ord result = Ord(0);
915  if (gt == HERMES_PLANAR) {
916  for (int i = 0; i < n; i++) {
917  result += wt[i] * coeff->value(e->x[i], e->y[i]) * u->val[i] * v->val[i];
918  }
919  }
920  else {
921  if (gt == HERMES_AXISYM_X) {
922  for (int i = 0; i < n; i++) {
923  result += wt[i] * e->y[i] * coeff->value(e->x[i], e->y[i]) * u->val[i] * v->val[i];
924  }
925  }
926  else {
927  for (int i = 0; i < n; i++) {
928  result += wt[i] * e->x[i] * coeff->value(e->x[i], e->y[i]) * u->val[i] * v->val[i];
929  }
930  }
931  }
932 
933  return result;
934  }
935 
936  template<typename Scalar>
937  MatrixFormSurf<Scalar>* DefaultMatrixFormSurf<Scalar>::clone() const
938  {
939  return new DefaultMatrixFormSurf<Scalar>(this->i, this->j, this->areas, this->coeff, this->gt);
940  }
941 
942  template<typename Scalar>
943  DefaultJacobianFormSurf<Scalar>::DefaultJacobianFormSurf(int i, int j, std::string area,
944  Hermes1DFunction<Scalar>* coeff,
945  GeomType gt)
946  : MatrixFormSurf<Scalar>(i, j), coeff(coeff), gt(gt)
947  {
948  this->set_area(area);
949  if (coeff == nullptr)
950  {
951  this->coeff = new Hermes1DFunction<Scalar>(1.0);
952  this->own_coeff = true;
953  }
954  else
955  this->own_coeff = false;
956  }
957 
958  template<typename Scalar>
959  DefaultJacobianFormSurf<Scalar>::DefaultJacobianFormSurf(int i, int j, std::vector<std::string> areas,
960  Hermes1DFunction<Scalar>* coeff,
961  GeomType gt)
962  : MatrixFormSurf<Scalar>(i, j), coeff(coeff), gt(gt)
963  {
964  this->set_areas(areas);
965  if (coeff == nullptr)
966  {
967  this->coeff = new Hermes1DFunction<Scalar>(1.0);
968  this->own_coeff = true;
969  }
970  else
971  this->own_coeff = false;
972  }
973 
974  template<typename Scalar>
975  DefaultJacobianFormSurf<Scalar>::~DefaultJacobianFormSurf()
976  {
977  if (this->own_coeff)
978  delete coeff;
979  };
980 
981  template<typename Scalar>
982  Scalar DefaultJacobianFormSurf<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *u, Func<double> *v,
983  GeomSurf<double> *e, Func<Scalar> **ext) const
984  {
985  Scalar result = 0;
986  for (int i = 0; i < n; i++) {
987  result += wt[i] * (coeff->derivative(u_ext[this->previous_iteration_space_index]->val[i]) * u_ext[this->previous_iteration_space_index]->val[i]
988  + coeff->value(u_ext[this->previous_iteration_space_index]->val[i]))
989  * u->val[i] * v->val[i];
990  }
991  return result;
992  }
993 
994  template<typename Scalar>
995  Ord DefaultJacobianFormSurf<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *u,
996  Func<Ord> *v, GeomSurf<Ord> *e, Func<Ord> **ext) const
997  {
998  Ord result = Ord(0);
999  for (int i = 0; i < n; i++) {
1000  result += wt[i] * (coeff->derivative(u_ext[this->previous_iteration_space_index]->val[i]) * u_ext[this->previous_iteration_space_index]->val[i]
1001  + coeff->value(u_ext[this->previous_iteration_space_index]->val[i]))
1002  * u->val[i] * v->val[i];
1003  }
1004  return result;
1005  }
1006 
1007  template<typename Scalar>
1008  MatrixFormSurf<Scalar>* DefaultJacobianFormSurf<Scalar>::clone() const
1009  {
1010  return new DefaultJacobianFormSurf<Scalar>(this->i, this->j, this->areas, this->coeff, this->gt);
1011  }
1012 
1013  template<typename Scalar>
1014  DefaultVectorFormSurf<Scalar>::DefaultVectorFormSurf(int i, std::string area,
1015  Hermes2DFunction<Scalar>* coeff,
1016  GeomType gt)
1017  : VectorFormSurf<Scalar>(i), coeff(coeff), gt(gt)
1018  {
1019  this->set_area(area);
1020  if (coeff == nullptr)
1021  {
1022  this->coeff = new Hermes2DFunction<Scalar>(1.0);
1023  this->own_coeff = true;
1024  }
1025  else
1026  this->own_coeff = false;
1027  }
1028 
1029  template<typename Scalar>
1030  DefaultVectorFormSurf<Scalar>::DefaultVectorFormSurf(int i, std::vector<std::string> areas,
1031  Hermes2DFunction<Scalar>* coeff,
1032  GeomType gt)
1033  : VectorFormSurf<Scalar>(i), coeff(coeff), gt(gt)
1034  {
1035  this->set_areas(areas);
1036 
1037  if (coeff == nullptr)
1038  {
1039  this->coeff = new Hermes2DFunction<Scalar>(1.0);
1040  this->own_coeff = true;
1041  }
1042  else
1043  this->own_coeff = false;
1044  }
1045 
1046  template<typename Scalar>
1047  DefaultVectorFormSurf<Scalar>::~DefaultVectorFormSurf()
1048  {
1049  if (this->own_coeff)
1050  delete coeff;
1051  };
1052 
1053  template<typename Scalar>
1054  Scalar DefaultVectorFormSurf<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *v,
1055  GeomSurf<double> *e, Func<Scalar> **ext) const
1056  {
1057  Scalar result = 0;
1058  if (gt == HERMES_PLANAR) {
1059  for (int i = 0; i < n; i++) {
1060  result += wt[i] * coeff->value(e->x[i], e->y[i]) * v->val[i];
1061  }
1062  }
1063  else {
1064  if (gt == HERMES_AXISYM_X) {
1065  for (int i = 0; i < n; i++) {
1066  result += wt[i] * e->y[i] * coeff->value(e->x[i], e->y[i]) * v->val[i];
1067  }
1068  }
1069  else {
1070  for (int i = 0; i < n; i++) {
1071  result += wt[i] * e->x[i] * coeff->value(e->x[i], e->y[i]) * v->val[i];
1072  }
1073  }
1074  }
1075 
1076  return result;
1077  }
1078 
1079  template<typename Scalar>
1080  Ord DefaultVectorFormSurf<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *v,
1081  GeomSurf<Ord> *e, Func<Ord> **ext) const
1082  {
1083  Ord result = Ord(0);
1084  if (gt == HERMES_PLANAR) {
1085  for (int i = 0; i < n; i++) {
1086  result += wt[i] * coeff->value(e->x[i], e->y[i]) * v->val[i];
1087  }
1088  }
1089  else {
1090  if (gt == HERMES_AXISYM_X) {
1091  for (int i = 0; i < n; i++) {
1092  result += wt[i] * e->y[i] * coeff->value(e->x[i], e->y[i]) * v->val[i];
1093  }
1094  }
1095  else {
1096  for (int i = 0; i < n; i++) {
1097  result += wt[i] * e->x[i] * coeff->value(e->x[i], e->y[i]) * v->val[i];
1098  }
1099  }
1100  }
1101 
1102  return result;
1103  }
1104 
1105  template<typename Scalar>
1106  VectorFormSurf<Scalar>* DefaultVectorFormSurf<Scalar>::clone() const
1107  {
1108  return new DefaultVectorFormSurf<Scalar>(this->i, this->areas, this->coeff, this->gt);
1109  }
1110 
1111  template<typename Scalar>
1112  DefaultResidualSurf<Scalar>::DefaultResidualSurf(int i, std::string area,
1113  Hermes2DFunction<Scalar>* coeff,
1114  GeomType gt)
1115  : VectorFormSurf<Scalar>(i), coeff(coeff), gt(gt)
1116  {
1117  this->set_area(area);
1118  if (coeff == nullptr)
1119  {
1120  this->coeff = new Hermes2DFunction<Scalar>(1.0);
1121  this->own_coeff = true;
1122  }
1123  else
1124  this->own_coeff = false;
1125  }
1126 
1127  template<typename Scalar>
1128  DefaultResidualSurf<Scalar>::DefaultResidualSurf(int i, std::vector<std::string> areas,
1129  Hermes2DFunction<Scalar>* coeff,
1130  GeomType gt)
1131  : VectorFormSurf<Scalar>(i), coeff(coeff), gt(gt)
1132  {
1133  this->set_areas(areas);
1134  if (coeff == nullptr)
1135  {
1136  this->coeff = new Hermes2DFunction<Scalar>(1.0);
1137  this->own_coeff = true;
1138  }
1139  else
1140  this->own_coeff = false;
1141  }
1142 
1143  template<typename Scalar>
1144  DefaultResidualSurf<Scalar>::~DefaultResidualSurf()
1145  {
1146  if (this->own_coeff)
1147  delete coeff;
1148  };
1149 
1150  template<typename Scalar>
1151  Scalar DefaultResidualSurf<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *v,
1152  GeomSurf<double> *e, Func<Scalar> **ext) const
1153  {
1154  Scalar result = 0;
1155  if (gt == HERMES_PLANAR) {
1156  for (int i = 0; i < n; i++) {
1157  result += wt[i] * coeff->value(e->x[i], e->y[i]) * u_ext[this->previous_iteration_space_index]->val[i] * v->val[i];
1158  }
1159  }
1160  else {
1161  if (gt == HERMES_AXISYM_X) {
1162  for (int i = 0; i < n; i++) {
1163  result += wt[i] * e->y[i] * coeff->value(e->x[i], e->y[i]) * u_ext[this->previous_iteration_space_index]->val[i] * v->val[i];
1164  }
1165  }
1166  else {
1167  for (int i = 0; i < n; i++) {
1168  result += wt[i] * e->x[i] * coeff->value(e->x[i], e->y[i]) * u_ext[this->previous_iteration_space_index]->val[i] * v->val[i];
1169  }
1170  }
1171  }
1172 
1173  return result;
1174  }
1175 
1176  template<typename Scalar>
1177  Ord DefaultResidualSurf<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *v,
1178  GeomSurf<Ord> *e, Func<Ord> **ext) const
1179  {
1180  Ord result = Ord(0);
1181  if (gt == HERMES_PLANAR) {
1182  for (int i = 0; i < n; i++) {
1183  result += wt[i] * coeff->value(e->x[i], e->y[i]) * u_ext[this->previous_iteration_space_index]->val[i] * v->val[i];
1184  }
1185  }
1186  else {
1187  if (gt == HERMES_AXISYM_X) {
1188  for (int i = 0; i < n; i++) {
1189  result += wt[i] * e->y[i] * coeff->value(e->x[i], e->y[i]) * u_ext[this->previous_iteration_space_index]->val[i] * v->val[i];
1190  }
1191  }
1192  else {
1193  for (int i = 0; i < n; i++) {
1194  result += wt[i] * e->x[i] * coeff->value(e->x[i], e->y[i]) * u_ext[this->previous_iteration_space_index]->val[i] * v->val[i];
1195  }
1196  }
1197  }
1198 
1199  return result;
1200  }
1201 
1202  template<typename Scalar>
1203  VectorFormSurf<Scalar>* DefaultResidualSurf<Scalar>::clone() const
1204  {
1205  return new DefaultResidualSurf(this->i, this->areas, this->coeff, this->gt);
1206  }
1207 
1208  template<typename Scalar>
1209  DefaultWeakFormLaplace<Scalar>::DefaultWeakFormLaplace(std::string area,
1210  Hermes1DFunction<Scalar>* coeff,
1211  GeomType gt) : WeakForm<Scalar>()
1212  {
1213  // Jacobian.
1214  this->add_matrix_form(new DefaultJacobianDiffusion<Scalar>(0, 0, area, coeff, HERMES_NONSYM, gt));
1215 
1216  // Residual.
1217  this->add_vector_form(new DefaultResidualDiffusion<Scalar>(0, area, coeff, gt));
1218  };
1219 
1220  template<typename Scalar>
1221  DefaultWeakFormLaplaceLinear<Scalar>::DefaultWeakFormLaplaceLinear(std::string area, GeomType gt) : WeakForm<Scalar>()
1222  {
1223  // Jacobian.
1224  this->add_matrix_form(new DefaultMatrixFormDiffusion<Scalar>(0, 0, area, nullptr, HERMES_SYM, gt));
1225  };
1226 
1227  template<typename Scalar>
1228  DefaultWeakFormPoisson<Scalar>::DefaultWeakFormPoisson() : WeakForm<Scalar>()
1229  {
1230  };
1231 
1232  template<typename Scalar>
1233  DefaultWeakFormPoisson<Scalar>::DefaultWeakFormPoisson(std::string area,
1234  Hermes1DFunction<Scalar>* coeff,
1235  Hermes2DFunction<Scalar>* f,
1236  GeomType gt) : WeakForm<Scalar>()
1237  {
1238  // Jacobian.
1239  // NOTE: The flag HERMES_NONSYM is important here.
1240  this->add_matrix_form(new DefaultJacobianDiffusion<Scalar>(0, 0, area, coeff, HERMES_NONSYM, gt));
1241 
1242  // Residual.
1243  this->add_vector_form(new DefaultResidualDiffusion<Scalar>(0, area, coeff, gt));
1244  this->add_vector_form(new DefaultVectorFormVol<Scalar>(0, area, f, gt));
1245  };
1246 
1247  template<typename Scalar>
1248  DefaultWeakFormPoissonLinear<Scalar>::DefaultWeakFormPoissonLinear(std::string area,
1249  Hermes2DFunction<Scalar>* f,
1250  GeomType gt) : WeakForm<Scalar>()
1251  {
1252  // Jacobian.
1253  this->add_matrix_form(new DefaultMatrixFormDiffusion<Scalar>(0, 0, area, nullptr, HERMES_SYM));
1254 
1255  // Residual.
1256  this->add_vector_form(new DefaultVectorFormVol<Scalar>(0, area, f));
1257  };
1258 
1259  template class HERMES_API DefaultMatrixFormVol < double > ;
1260  template class HERMES_API DefaultMatrixFormVol < std::complex<double> > ;
1261  template class HERMES_API DefaultJacobianDiffusion < double > ;
1262  template class HERMES_API DefaultJacobianDiffusion < std::complex<double> > ;
1263  template class HERMES_API DefaultMatrixFormDiffusion < double > ;
1264  template class HERMES_API DefaultMatrixFormDiffusion < std::complex<double> > ;
1265  template class HERMES_API DefaultResidualAdvection < double > ;
1266  template class HERMES_API DefaultResidualAdvection < std::complex<double> > ;
1267  template class HERMES_API DefaultJacobianAdvection < double > ;
1268  template class HERMES_API DefaultJacobianAdvection < std::complex<double> > ;
1269  template class HERMES_API DefaultResidualDiffusion < double > ;
1270  template class HERMES_API DefaultResidualDiffusion < std::complex<double> > ;
1271  template class HERMES_API DefaultMatrixFormSurf < double > ;
1272  template class HERMES_API DefaultMatrixFormSurf < std::complex<double> > ;
1273  template class HERMES_API DefaultVectorFormSurf < double > ;
1274  template class HERMES_API DefaultVectorFormSurf < std::complex<double> > ;
1275  template class HERMES_API DefaultVectorFormVol < double > ;
1276  template class HERMES_API DefaultVectorFormVol < std::complex<double> > ;
1277  template class HERMES_API DefaultJacobianFormSurf < double > ;
1278  template class HERMES_API DefaultJacobianFormSurf < std::complex<double> > ;
1279  template class HERMES_API DefaultWeakFormLaplace < double > ;
1280  template class HERMES_API DefaultWeakFormLaplace < std::complex<double> > ;
1281  template class HERMES_API DefaultWeakFormLaplaceLinear < double > ;
1282  template class HERMES_API DefaultWeakFormLaplaceLinear < std::complex<double> > ;
1283  template class HERMES_API DefaultWeakFormPoisson < double > ;
1284  template class HERMES_API DefaultWeakFormPoisson < std::complex<double> > ;
1285  template class HERMES_API DefaultWeakFormPoissonLinear < double > ;
1286  template class HERMES_API DefaultWeakFormPoissonLinear < std::complex<double> > ;
1287  template class HERMES_API DefaultResidualSurf < double > ;
1288  template class HERMES_API DefaultResidualSurf < std::complex<double> > ;
1289  template class HERMES_API DefaultResidualVol < double > ;
1290  template class HERMES_API DefaultResidualVol < std::complex<double> > ;
1291  };
1292  }
1293 }
Definition: adapt.h:24
void set_area(std::string area)
Definition: weakform.cpp:326
SymFlag
Bilinear form symmetry flag, see WeakForm::add_matrix_form.
Definition: global.h:156
::xsd::cxx::tree::string< char, simple_type > string
C++ type corresponding to the string XML Schema built-in type.
GeomType
Geometrical type of weak forms.
Definition: global.h:148