18 #include "quadrature/quad_all.h"
22 #include "function/solution.h"
23 #include "quadrature/limit_order.h"
24 #include "integrals/h1.h"
25 #include "discrete_problem.h"
33 template<
typename Scalar>
34 double Global<Scalar>::get_l2_norm(Vector<Scalar>* vec)
37 for (
unsigned int i = 0; i < vec->length(); i++)
39 Scalar inc = vec->get(i);
40 val = val + inc*conj(inc);
42 return sqrt(std::abs(val));
45 template<
typename Scalar>
46 double Global<Scalar>::calc_abs_error(MeshFunction<Scalar>* sln1, MeshFunction<Scalar>* sln2,
int norm_type)
49 if(sln1 == NULL)
throw Hermes::Exceptions::Exception(
"sln1 is NULL in calc_abs_error().");
50 if(sln2 == NULL)
throw Hermes::Exceptions::Exception(
"sln2 is NULL in calc_abs_error().");
52 Quad2D* quad = &g_quad_2d_std;
53 sln1->set_quad_2d(quad);
54 sln2->set_quad_2d(quad);
56 const Mesh* meshes[2] = { sln1->get_mesh(), sln2->get_mesh() };
57 Transformable* tr[2] = { sln1, sln2 };
59 trav.begin(2, meshes, tr);
63 while ((ee = trav.get_next_state()) != NULL)
65 update_limit_table(ee->e[0]->get_mode());
67 RefMap* ru = sln1->get_refmap();
68 RefMap* rv = sln2->get_refmap();
72 error += error_fn_l2(sln1, sln2, ru, rv);
75 error += error_fn_h1(sln1, sln2, ru, rv);
77 case HERMES_HCURL_NORM:
78 error += error_fn_hc(sln1, sln2, ru, rv);
80 case HERMES_HDIV_NORM:
81 error += error_fn_hdiv(sln1, sln2, ru, rv);
83 default:
throw Hermes::Exceptions::Exception(
"Unknown norm in calc_error().");
90 template<
typename Scalar>
93 double error = calc_abs_error(sln, ref_sln, norm_type);
94 double norm = calc_norm(ref_sln, norm_type);
99 template<
typename Scalar>
102 Quad2D* quad = &g_quad_2d_std;
107 const Mesh* mesh = sln->get_mesh();
109 for_all_active_elements(e, mesh)
112 update_limit_table(e->get_mode());
115 RefMap* ru = sln->get_refmap();
120 norm += norm_fn_l2(sln, ru);
123 norm += norm_fn_h1(sln, ru);
125 case HERMES_HCURL_NORM:
126 norm += norm_fn_hc(sln, ru);
128 case HERMES_HDIV_NORM:
129 norm += norm_fn_hdiv(sln, ru);
131 default:
throw Hermes::Exceptions::Exception(
"Unknown norm in calc_norm().");
137 template<
typename Scalar>
141 Hermes::vector<double> norms;
143 for (
int i = 0; i<n; i++)
145 switch (slns[i]->get_space_type())
147 case HERMES_H1_SPACE: norms.push_back(calc_norm(slns[i], HERMES_H1_NORM));
break;
148 case HERMES_HCURL_SPACE: norms.push_back(calc_norm(slns[i], HERMES_HCURL_NORM));
break;
149 case HERMES_HDIV_SPACE: norms.push_back(calc_norm(slns[i], HERMES_HDIV_NORM));
break;
150 case HERMES_L2_SPACE: norms.push_back(calc_norm(slns[i], HERMES_L2_NORM));
break;
151 default:
throw Hermes::Exceptions::Exception(
"Internal in calc_norms(): unknown space type.");
156 for (
int i = 0; i < n; i++)
157 result += norms[i] * norms[i];
161 template<
typename Scalar>
165 Hermes::vector<double> errors;
166 int n = slns1.size();
167 for (
int i = 0; i < n; i++)
169 switch (slns1[i]->get_space_type())
171 case HERMES_H1_SPACE: errors.push_back(calc_abs_error(slns1[i], slns2[i], HERMES_H1_NORM));
break;
172 case HERMES_HCURL_SPACE: errors.push_back(calc_abs_error(slns1[i], slns2[i], HERMES_HCURL_NORM));
break;
173 case HERMES_HDIV_SPACE: errors.push_back(calc_abs_error(slns1[i], slns2[i], HERMES_HDIV_NORM));
break;
174 case HERMES_L2_SPACE: errors.push_back(calc_abs_error(slns1[i], slns2[i], HERMES_L2_NORM));
break;
175 default:
throw Hermes::Exceptions::Exception(
"Internal in calc_norms(): unknown space type.");
180 for (
int i = 0; i < n; i++)
181 result += errors[i] * errors[i];
185 template<
typename Scalar>
186 double Global<Scalar>::calc_rel_errors(Hermes::vector<Solution<Scalar>*> slns1, Hermes::vector<Solution<Scalar>*> slns2)
188 return calc_abs_errors(slns1, slns2) / calc_norms(slns2);
191 template<
typename Scalar>
192 double Global<Scalar>::error_fn_h1(MeshFunction<Scalar>* sln1, MeshFunction<Scalar>* sln2, RefMap* ru, RefMap* rv)
194 Quad2D* quad = sln1->get_quad_2d();
196 int o = 2*std::max(sln1->get_fn_order(), sln2->get_fn_order()) + ru->get_inv_ref_order();
197 limit_order_nowarn(o, ru->get_active_element()->get_mode());
199 sln1->set_quad_order(o);
200 sln2->set_quad_order(o);
202 Scalar *uval, *vval, *dudx, *dudy, *dvdx, *dvdy;
203 uval = sln1->get_fn_values();
204 vval = sln2->get_fn_values();
205 sln1->get_dx_dy_values(dudx, dudy);
206 sln2->get_dx_dy_values(dvdx, dvdy);
209 h1_integrate_expression(Hermes::sqr(uval[i] - vval[i]) +
210 sqr(dudx[i] - dvdx[i]) + sqr(dudy[i] - dvdy[i]));
214 template<
typename Scalar>
215 double Global<Scalar>::norm_fn_h1(MeshFunction<Scalar>* sln, RefMap* ru)
217 Quad2D* quad = sln->get_quad_2d();
219 int o = 2 * sln->get_fn_order() + ru->get_inv_ref_order();
220 limit_order_nowarn(o, ru->get_active_element()->get_mode());
222 sln->set_quad_order(o);
224 Scalar *uval, *dudx, *dudy;
225 uval = sln->get_fn_values();
226 sln->get_dx_dy_values(dudx, dudy);
229 h1_integrate_expression(sqr(uval[i]) + sqr(dudx[i]) + sqr(dudy[i]));
233 template<
typename Scalar>
234 double Global<Scalar>::error_fn_l2(MeshFunction<Scalar>* sln1, MeshFunction<Scalar>* sln2, RefMap* ru, RefMap* rv)
236 Quad2D* quad = sln1->get_quad_2d();
238 int o = 2*std::max(sln1->get_fn_order(), sln2->get_fn_order()) + ru->get_inv_ref_order();
239 limit_order_nowarn(o, ru->get_active_element()->get_mode());
245 uval = sln1->get_fn_values();
246 vval = sln2->get_fn_values();
249 h1_integrate_expression(Hermes::sqr(uval[i] - vval[i]));
253 template<
typename Scalar>
254 double Global<Scalar>::norm_fn_l2(MeshFunction<Scalar>* sln, RefMap* ru)
256 Quad2D* quad = sln->get_quad_2d();
258 int o = 2 *sln->get_fn_order() + ru->get_inv_ref_order();
259 limit_order_nowarn(o, ru->get_active_element()->get_mode());
263 Scalar* uval = sln->get_fn_values();
266 h1_integrate_expression(Hermes::sqr(uval[i]));
270 template<
typename Scalar>
271 double Global<Scalar>::error_fn_hc(MeshFunction<Scalar>* sln1, MeshFunction<Scalar>* sln2, RefMap* ru, RefMap* rv)
273 Quad2D* quad = sln1->get_quad_2d();
275 int o = 2 * std::max(sln1->get_fn_order(), sln2->get_fn_order()) + 2 + ru->get_inv_ref_order();
276 limit_order_nowarn(o, ru->get_active_element()->get_mode());
278 sln1->set_quad_order(o);
279 sln2->set_quad_order(o);
281 Scalar *uval0 = sln1->get_fn_values(0), *uval1 = sln1->get_fn_values(1);
282 Scalar *udx1 = sln1->get_dx_values(1), *udy0 = sln1->get_dy_values(0);
283 Scalar *vval0 = sln2->get_fn_values(0), *vval1 = sln2->get_fn_values(1);
284 Scalar *vdx1 = sln2->get_dx_values(1), *vdy0 = sln2->get_dy_values(0);
287 h1_integrate_expression(Hermes::sqr(uval0[i] - vval0[i]) + Hermes::sqr(uval1[i] - vval1[i]) +
288 sqr((udx1[i] - udy0[i]) - (vdx1[i] - vdy0[i])));
292 template<
typename Scalar>
293 double Global<Scalar>::norm_fn_hc(MeshFunction<Scalar>* sln, RefMap* ru)
295 Quad2D* quad = sln->get_quad_2d();
297 int o = 2 * sln->get_fn_order() + 2 + ru->get_inv_ref_order();
298 limit_order_nowarn(o, ru->get_active_element()->get_mode());
300 sln->set_quad_order(o);
302 Scalar *uval0 = sln->get_fn_values(0), *uval1 = sln->get_fn_values(1);
303 Scalar *udx1 = sln->get_dx_values(1), *udy0 = sln->get_dy_values(0);
306 h1_integrate_expression(Hermes::sqr(uval0[i]) + Hermes::sqr(uval1[i]) + Hermes::sqr(udx1[i] - udy0[i]));
310 template<
typename Scalar>
311 double Global<Scalar>::error_fn_hcl2(MeshFunction<Scalar>* sln1, MeshFunction<Scalar>* sln2, RefMap* ru, RefMap* rv)
313 Quad2D* quad = sln1->get_quad_2d();
315 int o = 2 * std::max(sln1->get_fn_order(), sln2->get_fn_order()) + 2 + ru->get_inv_ref_order();
316 limit_order_nowarn(o, ru->get_active_element()->get_mode());
318 sln1->set_quad_order(o);
319 sln2->set_quad_order(o);
321 Scalar *uval0 = sln1->get_fn_values(0), *uval1 = sln1->get_fn_values(1);
322 Scalar *vval0 = sln2->get_fn_values(0), *vval1 = sln2->get_fn_values(1);
325 h1_integrate_expression(Hermes::sqr(uval0[i] - vval0[i]) + Hermes::sqr(uval1[i] - vval1[i]));
329 template<
typename Scalar>
330 double Global<Scalar>::norm_fn_hcl2(MeshFunction<Scalar>* sln, RefMap* ru)
332 Quad2D* quad = sln->get_quad_2d();
334 int o = 2 * sln->get_fn_order() + 2 + ru->get_inv_ref_order();
335 limit_order_nowarn(o, ru->get_active_element()->get_mode());
337 sln->set_quad_order(o);
339 Scalar *uval0 = sln->get_fn_values(0), *uval1 = sln->get_fn_values(1);
340 Scalar *udx1 = sln->get_dx_values(1), *udy0 = sln->get_dy_values(0);
343 h1_integrate_expression(Hermes::sqr(uval0[i]) + Hermes::sqr(uval1[i]));
347 template<
typename Scalar>
348 double Global<Scalar>::error_fn_hdiv(MeshFunction<Scalar>* sln1, MeshFunction<Scalar>* sln2, RefMap* ru, RefMap* rv)
350 throw Hermes::Exceptions::Exception(
"error_fn_hdiv() not implemented yet.");
353 Quad2D* quad = sln1->get_quad_2d();
355 int o = 2 * std::max(sln1->get_fn_order(), sln2->get_fn_order()) + 2 + ru->get_inv_ref_order();
356 limit_order_nowarn(o, ru->get_active_element()->get_mode());
358 sln1->set_quad_order(o);
359 sln2->set_quad_order(o);
361 Scalar *uval0 = sln1->get_fn_values(0), *uval1 = sln1->get_fn_values(1);
362 Scalar *udx1 = sln1->get_dx_values(1), *udy0 = sln1->get_dy_values(0);
363 Scalar *vval0 = sln2->get_fn_values(0), *vval1 = sln2->get_fn_values(1);
364 Scalar *vdx1 = sln2->get_dx_values(1), *vdy0 = sln2->get_dy_values(0);
367 h1_integrate_expression(Hermes::sqr(uval0[i] - vval0[i]) + Hermes::sqr(uval1[i] - vval1[i]) +
368 Hermes::sqr((udx1[i] - udy0[i]) - (vdx1[i] - vdy0[i])));
372 template<
typename Scalar>
373 double Global<Scalar>::norm_fn_hdiv(MeshFunction<Scalar>* sln, RefMap* ru)
375 throw Hermes::Exceptions::Exception(
"norm_fn_hdiv() not implemented yet.");
378 Quad2D* quad = sln->get_quad_2d();
380 int o = 2 * sln->get_fn_order() + 2 + ru->get_inv_ref_order();
381 limit_order_nowarn(o, ru->get_active_element()->get_mode());
383 sln->set_quad_order(o);
385 Scalar *uval0 = sln->get_fn_values(0), *uval1 = sln->get_fn_values(1);
386 Scalar *udx1 = sln->get_dx_values(1), *udy0 = sln->get_dy_values(0);
389 h1_integrate_expression(Hermes::sqr(uval0[i]) + Hermes::sqr(uval1[i]) + Hermes::sqr(udx1[i] - udy0[i]));
393 template class HERMES_API Global<double>;
394 template class HERMES_API Global<std::complex<double> >;