16 #include "adapt/error_calculator.h"
17 #include "function/exact_solution.h"
18 #include "adapt/error_thread_calculator.h"
25 template<
typename Scalar>
28 elements_stored(false),
29 element_references(nullptr),
30 errors_squared_sum(0.0),
31 norms_squared_sum(0.0)
33 memset(
errors, 0,
sizeof(
double*)* H2D_MAX_COMPONENTS);
34 memset(norms, 0,
sizeof(
double*)* H2D_MAX_COMPONENTS);
37 template<
typename Scalar>
43 template<
typename Scalar>
46 if (component >= this->component_count)
47 throw Exceptions::ValueException(
"component", component, this->component_count);
51 if (this->errorMeshFunction[component])
52 return this->errorMeshFunction[component];
56 return this->errorMeshFunction[component];
60 template<
typename Scalar>
63 this->num_act_elems = 0;
64 errors_squared_sum = 0.;
65 norms_squared_sum = 0.;
70 for (
int i = 0; i < this->component_count; i++)
72 int num_elements_i = this->coarse_solutions[i]->get_mesh()->get_max_element_id();
74 this->errors[i] = realloc_with_check<ErrorCalculator<Scalar>,
double>(errors[i], num_elements_i,
this);
75 memset(this->errors[i], 0,
sizeof(
double)* num_elements_i);
77 this->norms[i] = realloc_with_check<ErrorCalculator<Scalar>,
double>(norms[i], num_elements_i,
this);
78 memset(this->norms[i], 0,
sizeof(
double)* num_elements_i);
80 component_errors[i] = 0.;
81 component_norms[i] = 0.;
82 int num_active_elements_i = this->coarse_solutions[i]->get_mesh()->get_num_active_elements();
83 element_count[i] = num_active_elements_i;
84 this->num_act_elems += num_active_elements_i;
88 free_with_check(this->element_references);
89 this->element_references = malloc_with_check<ErrorCalculator<Scalar>,
ElementReference>(this->num_act_elems,
this);
91 int running_count_total = 0;
92 for (
int i = 0; i < this->component_count; i++)
95 for_all_active_elements(e, this->coarse_solutions[i]->get_mesh())
102 for (
int i = 0; i < this->component_count; i++)
103 if (this->errorMeshFunction[i])
104 this->errorMeshFunction[i].reset();
107 template<
typename Scalar>
110 for (
int i = 0; i < this->component_count; i++)
112 free_with_check(errors[i],
true);
113 free_with_check(norms[i],
true);
116 free_with_check(this->element_references);
119 template<
typename Scalar>
122 std::vector<MeshFunctionSharedPtr<Scalar> > coarse_solutions;
123 coarse_solutions.push_back(coarse_solution);
124 std::vector<MeshFunctionSharedPtr<Scalar> > fine_solutions;
125 fine_solutions.push_back(fine_solution);
126 this->calculate_errors(coarse_solutions, fine_solutions, sort_and_store);
129 template<
typename Scalar>
136 Helpers::check_length(this->fine_solutions, this->component_count);
144 if (this->mfvol.empty() && this->mfsurf.empty() && this->mfDG.empty())
147 throw Exceptions::Exception(
"No error forms - instances of NormForm<Scalar> passed to ErrorCalculator via add_error_form().");
153 template<
typename Scalar>
156 this->coarse_solutions = coarse_solutions_;
157 this->fine_solutions = fine_solutions_;
158 this->component_count = this->coarse_solutions.size();
162 this->init_data_storage();
165 std::vector<MeshSharedPtr> meshes;
167 for (
int i = 0; i < this->component_count; i++)
168 meshes.push_back(coarse_solutions[i]->get_mesh());
169 for (
int i = 0; i < this->component_count; i++)
170 meshes.push_back(fine_solutions[i]->get_mesh());
172 unsigned int num_states;
173 Traverse trav(this->component_count);
176 #pragma omp parallel num_threads(this->num_threads_used)
178 int thread_number = omp_get_thread_num();
179 int start = (num_states / this->num_threads_used) * thread_number;
180 int end = (num_states / this->num_threads_used) * (thread_number + 1);
181 if (thread_number == this->num_threads_used - 1)
190 for (
int state_i = start; state_i < end; state_i++)
191 errorThreadCalculator.evaluate_one_state(states[state_i]);
193 catch (Hermes::Exceptions::Exception& e)
195 #pragma omp critical (exceptionMessageCaughtInParallelBlock)
196 this->exceptionMessageCaughtInParallelBlock = e.info();
200 #pragma omp critical (exceptionMessageCaughtInParallelBlock)
201 this->exceptionMessageCaughtInParallelBlock = e.what();
205 for (
int i = 0; i < num_states; i++)
207 free_with_check(states);
210 for (
int i = 0; i < this->component_count; i++)
213 for_all_active_elements(e, coarse_solutions[i]->get_mesh())
215 for_all_active_elements(e, fine_solutions[i]->get_mesh())
219 if (!this->exceptionMessageCaughtInParallelBlock.empty())
220 throw Hermes::Exceptions::Exception(this->exceptionMessageCaughtInParallelBlock.c_str());
223 this->postprocess_error();
227 std::qsort(this->element_references, this->num_act_elems,
sizeof(
ElementReference), &this->compareElementReference);
228 elements_stored =
true;
231 elements_stored =
false;
234 template<
typename Scalar>
238 int running_indexer = 0;
239 for (
int i = 0; i < this->component_count; i++)
241 for (
int j = 0; j < this->element_count[i]; j++)
243 component_errors[i] += *(this->element_references[running_indexer + j].error);
244 component_norms[i] += *(this->element_references[running_indexer + j].norm);
246 if (this->errorType == RelativeErrorToElementNorm)
247 *(this->element_references[running_indexer + j].error) /= *(this->element_references[running_indexer + j].norm);
250 if (this->errorType == RelativeErrorToGlobalNorm)
251 for (
int j = 0; j < this->element_count[i]; j++)
253 if (component_norms[i] < Hermes::HermesEpsilon)
254 *(this->element_references[running_indexer + j].error) = 0.;
256 *(this->element_references[running_indexer + j].error) /= component_norms[i];
259 norms_squared_sum += component_norms[i];
260 errors_squared_sum += component_errors[i];
262 if (this->errorType == RelativeErrorToGlobalNorm || this->errorType == RelativeErrorToElementNorm)
264 if (component_norms[i] < Hermes::HermesEpsilon)
265 component_errors[i] = 0.;
267 component_errors[i] /= component_norms[i];
270 running_indexer += this->element_count[i];
273 if (this->errorType == RelativeErrorToGlobalNorm || this->errorType == RelativeErrorToElementNorm)
275 if (norms_squared_sum < Hermes::HermesEpsilon)
276 errors_squared_sum = 0.;
278 errors_squared_sum /= norms_squared_sum;
282 template<
typename Scalar>
285 this->mfvol.push_back(form);
288 template<
typename Scalar>
291 this->mfsurf.push_back(form);
294 template<
typename Scalar>
297 this->mfDG.push_back(form);
300 template<
typename Scalar>
303 if (!this->element_references)
305 throw Hermes::Exceptions::Exception(
"Elements / norms have not been calculated so far.");
312 template<
typename Scalar>
315 return this->element_references[
id];
318 template<
typename Scalar>
321 if (!this->data_prepared_for_querying())
324 if (component >= this->component_count)
325 throw Hermes::Exceptions::ValueException(
"component", component, this->component_count);
327 return this->errors[component][element_id];
330 template<
typename Scalar>
333 if (!this->data_prepared_for_querying())
335 if (component >= this->component_count)
336 throw Hermes::Exceptions::ValueException(
"component", component, this->component_count);
338 return this->norms[component][element_id];
341 template<
typename Scalar>
342 double ErrorCalculator<Scalar>::get_error_squared(
int component)
const
344 if (!this->data_prepared_for_querying())
346 if (component >= this->component_count)
347 throw Hermes::Exceptions::ValueException(
"component", component, this->component_count);
349 return this->component_errors[component];
352 template<
typename Scalar>
353 double ErrorCalculator<Scalar>::get_norm_squared(
int component)
const
355 if (!this->data_prepared_for_querying())
357 if (component >= this->component_count)
358 throw Hermes::Exceptions::ValueException(
"component", component, this->component_count);
360 return this->component_norms[component];
363 template<
typename Scalar>
364 double ErrorCalculator<Scalar>::get_total_error_squared()
const
366 if (!this->data_prepared_for_querying())
368 return this->errors_squared_sum;
371 template<
typename Scalar>
372 double ErrorCalculator<Scalar>::get_total_norm_squared()
const
374 if (!this->data_prepared_for_querying())
376 return this->norms_squared_sum;
379 template<
typename Scalar, NormType normType>
380 DefaultErrorCalculator<Scalar, normType>::DefaultErrorCalculator(
CalculatedErrorType errorType,
int component_count) : ErrorCalculator<Scalar>(errorType)
384 this->
add_error_form(
new DefaultNormFormVol<Scalar>(i, i, normType));
388 template<
typename Scalar, NormType normType>
389 DefaultNormCalculator<Scalar, normType>::DefaultNormCalculator(
int component_count) : ErrorCalculator<Scalar>(AbsoluteError)
393 this->
add_error_form(
new DefaultNormFormVol<Scalar>(i, i, normType));
397 template<
typename Scalar, NormType normType>
400 std::vector<MeshFunctionSharedPtr<Scalar> > zero_fine_solutions;
401 for (
unsigned short i = 0; i < solutions.size(); i++)
403 this->calculate_errors(solutions, zero_fine_solutions,
false);
405 return this->get_total_error_squared();
408 template<
typename Scalar, NormType normType>
412 this->calculate_errors(solution, zero_fine_solution,
false);
414 return this->get_total_error_squared();
417 template<
typename Scalar, NormType normType>
420 for (
unsigned short i = 0; i < this->mfvol.size(); i++)
421 delete this->mfvol[i];
424 template<
typename Scalar, NormType normType>
425 DefaultNormCalculator<Scalar, normType>::~DefaultNormCalculator()
427 for (
unsigned short i = 0; i < this->mfvol.size(); i++)
428 delete this->mfvol[i];
431 template HERMES_API
class DefaultErrorCalculator < double, HERMES_H1_NORM > ;
432 template HERMES_API
class DefaultErrorCalculator < std::complex<double>, HERMES_H1_NORM > ;
433 template HERMES_API
class DefaultErrorCalculator < double, HERMES_L2_NORM > ;
434 template HERMES_API
class DefaultErrorCalculator < std::complex<double>, HERMES_L2_NORM > ;
435 template HERMES_API
class DefaultErrorCalculator < double, HERMES_H1_SEMINORM > ;
436 template HERMES_API
class DefaultErrorCalculator < std::complex<double>, HERMES_H1_SEMINORM > ;
437 template HERMES_API
class DefaultErrorCalculator < double, HERMES_HCURL_NORM > ;
438 template HERMES_API
class DefaultErrorCalculator < std::complex<double>, HERMES_HCURL_NORM > ;
439 template HERMES_API
class DefaultErrorCalculator < double, HERMES_HDIV_NORM > ;
440 template HERMES_API
class DefaultErrorCalculator < std::complex<double>, HERMES_HDIV_NORM > ;
442 template HERMES_API
class DefaultNormCalculator < double, HERMES_H1_NORM > ;
443 template HERMES_API
class DefaultNormCalculator < std::complex<double>, HERMES_H1_NORM > ;
444 template HERMES_API
class DefaultNormCalculator < double, HERMES_L2_NORM > ;
445 template HERMES_API
class DefaultNormCalculator < std::complex<double>, HERMES_L2_NORM > ;
446 template HERMES_API
class DefaultNormCalculator < double, HERMES_H1_SEMINORM > ;
447 template HERMES_API
class DefaultNormCalculator < std::complex<double>, HERMES_H1_SEMINORM > ;
448 template HERMES_API
class DefaultNormCalculator < double, HERMES_HCURL_NORM > ;
449 template HERMES_API
class DefaultNormCalculator < std::complex<double>, HERMES_HCURL_NORM > ;
450 template HERMES_API
class DefaultNormCalculator < double, HERMES_HDIV_NORM > ;
451 template HERMES_API
class DefaultNormCalculator < std::complex<double>, HERMES_HDIV_NORM > ;
453 template HERMES_API
class ErrorCalculator < double > ;
454 template HERMES_API
class ErrorCalculator < std::complex<double> > ;
::xsd::cxx::tree::id< char, ncname > id
C++ type corresponding to the ID XML Schema built-in type.
A reference to an element.
ErrorCalculator(CalculatedErrorType errorType)
Stores one element of a mesh.
bool visited
true if the element has been visited during assembling
bool data_prepared_for_querying() const
Common check for data querying.
void add_error_form(NormFormVol< Scalar > *form)
void calculate_errors(std::vector< MeshFunctionSharedPtr< Scalar > > coarse_solutions, std::vector< MeshFunctionSharedPtr< Scalar > > fine_solutions, bool sort_and_store=true)
::xsd::cxx::tree::exception< char > exception
Root of the C++/Tree exception hierarchy.
double * errors[H2D_MAX_COMPONENTS]
Errors of elements. Meaning of the error depeds on the errorType.
double calculate_norm(MeshFunctionSharedPtr< Scalar > solution)
Norms calculation.
double calculate_norms(std::vector< MeshFunctionSharedPtr< Scalar > > &solutions)
Norms calculation.
const ElementReference & get_element_reference(unsigned int id) const
A queue of elements which should be processes. The queue had to be filled by the method fill_regular_...
double get_element_error_squared(int component, int element_id) const
Returns a squared error of an element.
int component_count
Number of solution components.
CalculatedErrorType
Enum passed to the class ErrorCalculator specifying the calculated errors.
Evaluation of an error between a (coarse) solution and a reference solution.
MeshFunctionSharedPtr< double > get_errorMeshFunction(int component=0)
State ** get_states(std::vector< MeshSharedPtr > meshes, unsigned int &states_count)
void init_data_storage()
Initialize the data storage.
virtual ~ErrorCalculator()
Destructor. Deallocates allocated private data.
virtual bool isOkay() const
State querying helpers.
void free()
Frees the data.