19 #include "discrete_problem.h"
20 #include "function/exact_solution.h"
27 #include "integrals/h1.h"
28 #include "quadrature/limit_order.h"
29 #include "mesh/traverse.h"
30 #include "space/space.h"
31 #include "shapeset/precalc.h"
32 #include "mesh/refmap.h"
33 #include "function/solution.h"
37 using namespace Hermes::Algebra::DenseMatrixOperations;
43 static const std::string H2D_DG_INNER_EDGE =
"-1234567";
45 template<
typename Scalar>
46 double DiscreteProblem<Scalar>::fake_wt = 1.0;
48 template<
typename Scalar>
52 throw Exceptions::NullException(2);
53 unsigned int first_dof_running = 0;
54 for(
unsigned int i = 0; i <
spaces.size(); i++)
57 this->spaces_first_dofs.push_back(first_dof_running);
58 first_dof_running +=
spaces.at(i)->get_num_dofs();
63 template<
typename Scalar>
65 : Hermes::Solvers::DiscreteProblemInterface<Scalar>(), wf(wf)
68 this->spaces_first_dofs.push_back(0);
73 template<
typename Scalar>
103 current_block_weights = NULL;
106 cache_element_stored = NULL;
108 this->do_not_use_cache =
false;
113 template<
typename Scalar>
119 if(this->spaces.size() == 0)
123 for(
unsigned int space_i = 0; space_i < this->spaces.size(); space_i++)
124 this->spaces[space_i]->check();
126 for(
unsigned int space_i = 0; space_i < this->spaces.size(); space_i++)
127 if(!this->spaces[space_i]->is_up_to_date())
128 throw Exceptions::Exception(
"Space is out of date, if you manually refine it, you have to call assign_dofs().");
133 template<
typename Scalar>
138 RK_original_spaces_count = 0;
144 throw Hermes::Exceptions::Exception(
"WeakForm<Scalar>* wf can not be NULL in DiscreteProblem<Scalar>::DiscreteProblem.");
146 if(spaces.size() != (unsigned) wf->get_neq())
147 throw Hermes::Exceptions::Exception(
"Bad number of spaces in DiscreteProblem.");
148 if(spaces.size() == 0)
149 throw Hermes::Exceptions::Exception(
"Zero number of spaces in DiscreteProblem.");
152 sp_seq =
new int[wf->get_neq()];
153 memset(sp_seq, -1,
sizeof(
int) * wf->get_neq());
160 this->is_fvm =
false;
162 this->DG_matrix_forms_present =
false;
163 this->DG_vector_forms_present =
false;
165 if(!this->wf->mfDG.empty())
166 this->DG_matrix_forms_present =
true;
168 if(!this->wf->vfDG.empty())
169 this->DG_vector_forms_present =
true;
175 this->is_linear =
false;
179 current_block_weights = NULL;
181 cache_records_sub_idx =
new std::map<uint64_t, CacheRecordPerSubIdx*>**[spaces.size()];
184 this->cache_size = spaces[0]->get_mesh()->get_max_element_id() + 1;
185 for(
unsigned int i = 1; i < spaces.size(); i++)
187 int cache_size_i = spaces[i]->get_mesh()->get_max_element_id() + 1;
188 if(cache_size_i > cache_size)
189 this->cache_size = cache_size_i;
192 for(
unsigned int i = 0; i < spaces.size(); i++)
194 cache_records_sub_idx[i] = (std::map<uint64_t, CacheRecordPerSubIdx*>**)malloc(this->cache_size *
sizeof(std::map<uint64_t, CacheRecordPerSubIdx*>*));
195 memset(cache_records_sub_idx[i], NULL, this->cache_size *
sizeof(std::map<uint64_t, CacheRecordPerSubIdx*>*));
200 cache_element_stored = NULL;
202 this->do_not_use_cache =
false;
205 template<
typename Scalar>
208 Hermes::vector<Space<Scalar>*> spaces;
209 for(
unsigned int i = 0; i < this->get_spaces().size(); i++)
210 spaces.push_back(const_cast<
Space<Scalar>*>(this->get_space(i)));
216 template<
typename Scalar>
222 template<
typename Scalar>
226 memset(sp_seq, -1,
sizeof(
int) * wf->get_neq());
228 if(sp_seq != NULL)
delete [] sp_seq;
230 this->delete_cache();
233 template<
typename Scalar>
239 template<
typename Scalar>
245 template<
typename Scalar>
251 template<
typename Scalar>
255 throw Hermes::Exceptions::NullException(0);
258 this->have_matrix =
false;
260 if(!this->wf->
mfDG.empty())
261 this->DG_matrix_forms_present =
true;
263 if(!this->wf->
vfDG.empty())
264 this->DG_vector_forms_present =
true;
267 template<
typename Scalar>
270 return wf->is_matrix_free();
273 template<
typename Scalar>
277 bool up_to_date =
true;
281 for (
unsigned int i = 0; i < wf->get_neq(); i++)
283 if(spaces[i]->get_seq() != sp_seq[i])
293 template<
typename Scalar>
299 template<
typename Scalar>
302 for(
unsigned int i = 0; i < spaces.size(); i++)
304 for(
unsigned int j = 0; j < cache_size; j++)
306 if(this->cache_records_sub_idx[i][j] != NULL)
308 for(
typename std::map<uint64_t, CacheRecordPerSubIdx*>::iterator it = this->cache_records_sub_idx[i][j]->begin(); it != this->cache_records_sub_idx[i][j]->end(); it++)
314 this->cache_records_sub_idx[i][j]->clear();
315 delete this->cache_records_sub_idx[i][j];
316 this->cache_records_sub_idx[i][j] = NULL;
318 if(this->cache_records_element[i][j] != NULL)
320 this->cache_records_element[i][j]->clear();
321 delete this->cache_records_element[i][j];
322 this->cache_records_element[i][j] = NULL;
325 free(cache_records_sub_idx[i]);
326 free(cache_records_element[i]);
328 delete [] this->cache_records_sub_idx;
329 delete [] this->cache_records_element;
332 template<
typename Scalar>
335 for(
unsigned int i = 0; i < spacesToSet.size(); i++)
336 spacesToSet[i]->check();
338 if(this->spaces.size() != spacesToSet.size() && this->spaces.size() > 0)
339 throw Hermes::Exceptions::LengthException(0, spacesToSet.size(), this->spaces.size());
341 int originalSize = this->spaces.size();
343 this->spaces = spacesToSet;
348 for(
unsigned int i = 0; i < spacesToSet.size(); i++)
349 if(spacesToSet[i]->get_shapeset()->get_num_components() > 1)
350 this->do_not_use_cache =
true;
354 unsigned int first_dof_running = 0;
355 this->spaces_first_dofs.clear();
356 for(
unsigned int i = 0; i < spaces.size(); i++)
358 this->spaces_first_dofs.push_back(first_dof_running);
359 first_dof_running += spaces.at(i)->get_num_dofs();
362 if(originalSize == 0)
365 sp_seq =
new int[spaces.size()];
366 memset(sp_seq, -1,
sizeof(
int) * spaces.size());
371 cache_records_sub_idx =
new std::map<uint64_t, CacheRecordPerSubIdx*>**[spaces.size()];
374 this->cache_size = spaces[0]->get_mesh()->get_max_element_id() + 1;
375 for(
unsigned int i = 1; i < spaces.size(); i++)
377 int cache_size_i = spaces[i]->get_mesh()->get_max_element_id() + 1;
378 if(cache_size_i > cache_size)
379 this->cache_size = cache_size_i;
382 for(
unsigned int i = 0; i < spaces.size(); i++)
384 cache_records_sub_idx[i] = (std::map<uint64_t, CacheRecordPerSubIdx*>**)malloc(this->cache_size *
sizeof(std::map<uint64_t, CacheRecordPerSubIdx*>*));
385 memset(cache_records_sub_idx[i], NULL, this->cache_size *
sizeof(std::map<uint64_t, CacheRecordPerSubIdx*>*));
390 cache_element_stored = NULL;
394 int max_size = spacesToSet[0]->get_mesh()->get_max_element_id();
395 for(
unsigned int i = 1; i < spacesToSet.size(); i++)
397 int max_size_i = spacesToSet[i]->get_mesh()->get_max_element_id();
398 if(max_size_i > max_size)
399 max_size = max_size_i;
400 sp_seq[i] = spacesToSet[i]->get_seq();
403 if(max_size > this->cache_size + 1)
405 for(
unsigned int i = 0; i < this->spaces.size(); i++)
407 this->cache_records_sub_idx[i] = (std::map<uint64_t, CacheRecordPerSubIdx*>**)realloc(this->cache_records_sub_idx[i], max_size *
sizeof(std::map<uint64_t, CacheRecordPerSubIdx*>*));
408 memset(this->cache_records_sub_idx[i] + this->cache_size, NULL, (max_size - this->cache_size) *
sizeof(std::map<uint64_t, CacheRecordPerSubIdx*>*));
411 memset(this->cache_records_element[i] + this->cache_size, NULL, (max_size - this->cache_size) *
sizeof(
CacheRecordPerElement*));
414 this->cache_size = max_size;
417 for(
unsigned int i = 0; i < spaces.size(); i++)
419 for(
unsigned int j = 0; j < cache_size; j++)
421 if(j < spaces[i]->get_mesh()->get_max_element_id())
423 if(spaces[i]->get_mesh()->get_element(j) == NULL || !spaces[i]->get_mesh()->get_element(j)->active || spaces[i]->get_element_order(spaces[i]->get_mesh()->get_element(j)->
id) < 0)
425 if(this->cache_records_sub_idx[i][j] != NULL)
427 for(
typename std::map<uint64_t, CacheRecordPerSubIdx*>::iterator it = this->cache_records_sub_idx[i][j]->begin(); it != this->cache_records_sub_idx[i][j]->end(); it++)
430 this->cache_records_sub_idx[i][j]->clear();
431 delete this->cache_records_sub_idx[i][j];
432 this->cache_records_sub_idx[i][j] = NULL;
434 if(this->cache_records_element[i][j] != NULL)
436 this->cache_records_element[i][j]->clear();
437 delete this->cache_records_element[i][j];
438 this->cache_records_element[i][j] = NULL;
444 if(this->cache_records_sub_idx[i][j] != NULL)
446 for(
typename std::map<uint64_t, CacheRecordPerSubIdx*>::iterator it = this->cache_records_sub_idx[i][j]->begin(); it != this->cache_records_sub_idx[i][j]->end(); it++)
449 this->cache_records_sub_idx[i][j]->clear();
450 delete this->cache_records_sub_idx[i][j];
451 this->cache_records_sub_idx[i][j] = NULL;
453 if(this->cache_records_element[i][j] != NULL)
455 this->cache_records_element[i][j]->clear();
456 delete this->cache_records_element[i][j];
457 this->cache_records_element[i][j] = NULL;
467 template<
typename Scalar>
470 Hermes::vector<const Space<Scalar>*> spaces;
471 spaces.push_back(space);
472 this->set_spaces(spaces);
475 template<
typename Scalar>
476 double DiscreteProblem<Scalar>::block_scaling_coeff(MatrixForm<Scalar>* form)
const
478 if(current_block_weights != NULL)
479 return current_block_weights->get_A(form->i, form->j);
483 template<
typename Scalar>
486 if(current_state->e[form->i] == NULL || current_state->e[form->j] == NULL)
493 if(current_block_weights != NULL)
494 if(fabs(current_block_weights->get_A(form->i, form->j)) < 1e-12)
499 template<
typename Scalar>
507 bool assemble_this_form =
false;
508 for (
unsigned int ss = 0; ss < form->
areas.size(); ss++)
510 if(form->
areas[ss] == HERMES_ANY)
512 assemble_this_form =
true;
517 bool marker_on_space_m = this->spaces[form->i]->get_mesh()->get_element_markers_conversion().get_internal_marker(form->
areas[ss]).valid;
518 if(marker_on_space_m)
519 marker_on_space_m = (this->spaces[form->i]->get_mesh()->get_element_markers_conversion().get_internal_marker(form->
areas[ss]).marker == current_state->rep->marker);
521 bool marker_on_space_n = this->spaces[form->j]->get_mesh()->get_element_markers_conversion().get_internal_marker(form->
areas[ss]).valid;
522 if(marker_on_space_n)
523 marker_on_space_n = (this->spaces[form->j]->get_mesh()->get_element_markers_conversion().get_internal_marker(form->
areas[ss]).marker == current_state->rep->marker);
525 if(marker_on_space_m && marker_on_space_n)
527 assemble_this_form =
true;
532 if(!assemble_this_form)
537 template<
typename Scalar>
540 if(current_state->rep->en[current_state->isurf]->marker == 0)
543 if(form->areas[0] == H2D_DG_INNER_EDGE)
545 if(!form_to_be_assembled((MatrixForm<Scalar>*)form, current_state))
548 bool assemble_this_form =
false;
549 for (
unsigned int ss = 0; ss < form->areas.size(); ss++)
551 if(form->areas[ss] == HERMES_ANY)
553 assemble_this_form =
true;
558 bool marker_on_space_m = this->spaces[form->i]->get_mesh()->get_boundary_markers_conversion().get_internal_marker(form->areas[ss]).valid;
559 if(marker_on_space_m)
560 marker_on_space_m = (this->spaces[form->i]->get_mesh()->get_boundary_markers_conversion().get_internal_marker(form->areas[ss]).marker == current_state->rep->en[current_state->isurf]->marker);
562 bool marker_on_space_n = this->spaces[form->j]->get_mesh()->get_boundary_markers_conversion().get_internal_marker(form->areas[ss]).valid;
563 if(marker_on_space_n)
564 marker_on_space_n = (this->spaces[form->j]->get_mesh()->get_boundary_markers_conversion().get_internal_marker(form->areas[ss]).marker == current_state->rep->en[current_state->isurf]->marker);
566 if(marker_on_space_m && marker_on_space_n)
568 assemble_this_form =
true;
573 if(assemble_this_form ==
false)
578 template<
typename Scalar>
581 if(current_state->e[form->i] == NULL)
583 if(fabs(form->scaling_factor) < 1e-12)
589 template<
typename Scalar>
592 if(!form_to_be_assembled((VectorForm<Scalar>*)form, current_state))
597 bool assemble_this_form =
false;
598 for (
unsigned int ss = 0; ss < form->areas.size(); ss++)
600 if(form->areas[ss] == HERMES_ANY)
602 assemble_this_form =
true;
607 bool marker_on_space_m = this->spaces[form->i]->get_mesh()->get_element_markers_conversion().get_internal_marker(form->areas[ss]).valid;
608 if(marker_on_space_m)
609 marker_on_space_m = (this->spaces[form->i]->get_mesh()->get_element_markers_conversion().get_internal_marker(form->areas[ss]).marker == current_state->rep->marker);
611 if(marker_on_space_m)
613 assemble_this_form =
true;
618 if(!assemble_this_form)
623 template<
typename Scalar>
626 if(current_state->rep->en[current_state->isurf]->marker == 0)
629 if(form->areas[0] == H2D_DG_INNER_EDGE)
632 if(!form_to_be_assembled((VectorForm<Scalar>*)form, current_state))
635 bool assemble_this_form =
false;
636 for (
unsigned int ss = 0; ss < form->areas.size(); ss++)
638 if(form->areas[ss] == HERMES_ANY)
640 assemble_this_form =
true;
645 bool marker_on_space_m = this->spaces[form->i]->get_mesh()->get_boundary_markers_conversion().get_internal_marker(form->areas[ss]).valid;
646 if(marker_on_space_m)
647 marker_on_space_m = (this->spaces[form->i]->get_mesh()->get_boundary_markers_conversion().get_internal_marker(form->areas[ss]).marker == current_state->rep->en[current_state->isurf]->marker);
649 if(marker_on_space_m)
651 assemble_this_form =
true;
656 if(assemble_this_form ==
false)
661 template<
typename Scalar>
664 this->current_mat = mat;
666 this->current_rhs = rhs;
667 this->create_sparse_structure();
670 template<
typename Scalar>
675 if(current_mat != NULL)
677 if(current_rhs != NULL)
681 if(current_rhs->length() == 0)
682 current_rhs->alloc(this->ndof);
692 for(
unsigned int i = 0; i < this->wf->mfsurf.size(); i++)
694 if(!this->wf->mfDG.empty())
700 for(
unsigned int i = 0; i < this->wf->vfsurf.size() && is_DG ==
false; i++)
702 if(!this->wf->vfDG.empty())
709 if(current_mat != NULL)
714 current_mat->prealloc(this->ndof);
717 const Mesh** meshes =
new const Mesh*[wf->get_neq()];
718 bool **blocks = wf->get_blocks(current_force_diagonal_blocks);
721 for (
unsigned int i = 0; i < wf->get_neq(); i++)
722 meshes[i] = spaces[i]->get_mesh();
725 trav.begin(wf->get_neq(), meshes);
729 Hermes::vector<Space<Scalar>*> mutable_spaces;
730 for(
unsigned int i = 0; i < this->spaces.size(); i++)
732 mutable_spaces.push_back(
const_cast<Space<Scalar>*
>(spaces.at(i)));
733 spaces_first_dofs[i] = 0;
738 Traverse::State* current_state;
740 while ((current_state = trav.get_next_state()) != NULL)
744 for (
unsigned int i = 0; i < wf->get_neq(); i++)
745 if(current_state->e[i] != NULL)
747 spaces[i]->get_element_assembly_list(current_state->e[i], &(al[i]));
749 spaces[i]->get_element_assembly_list(current_state->e[i], &(al[i]), spaces_first_dofs[i]);
754 int num_edges = current_state->e[0]->nvert;
757 Element **** neighbor_elems_arrays =
new Element ***[wf->get_neq()];
758 for(
unsigned int i = 0; i < wf->get_neq(); i++)
759 neighbor_elems_arrays[i] =
new Element **[num_edges];
762 int ** neighbor_elems_counts =
new int *[wf->get_neq()];
763 for(
unsigned int i = 0; i < wf->get_neq(); i++)
764 neighbor_elems_counts[i] =
new int[num_edges];
767 for(
unsigned int el = 0; el < wf->get_neq(); el++)
774 for(
int ed = 0; ed < num_edges; ed++)
777 const Hermes::vector<Element *> *neighbors = ns.
get_neighbors();
780 neighbor_elems_arrays[el][ed] =
new Element *[neighbor_elems_counts[el][ed]];
781 for(
int neigh = 0; neigh < neighbor_elems_counts[el][ed]; neigh++)
782 neighbor_elems_arrays[el][ed][neigh] = (*neighbors)[neigh];
787 for (
unsigned int m = 0; m < wf->get_neq(); m++)
788 for(
unsigned int el = 0; el < wf->get_neq(); el++)
789 for(
int ed = 0; ed < num_edges; ed++)
790 for(
int neigh = 0; neigh < neighbor_elems_counts[el][ed]; neigh++)
791 if((blocks[m][el] || blocks[el][m]) && current_state->e[m] != NULL)
795 spaces[el]->get_element_assembly_list(neighbor_elems_arrays[el][ed][neigh], an);
799 for (
unsigned int i = 0; i < am->cnt; i++)
801 for (
unsigned int j = 0; j < an->cnt; j++)
804 if(blocks[m][el]) current_mat->pre_add_ij(am->dof[i], an->dof[j]);
805 if(blocks[el][m]) current_mat->pre_add_ij(an->dof[j], am->dof[i]);
812 for(
unsigned int el = 0; el < wf->get_neq(); el++)
814 for(
int ed = 0; ed < num_edges; ed++)
815 delete [] neighbor_elems_arrays[el][ed];
816 delete [] neighbor_elems_arrays[el];
818 delete [] neighbor_elems_arrays;
821 for(
unsigned int el = 0; el < wf->get_neq(); el++)
822 delete [] neighbor_elems_counts[el];
823 delete [] neighbor_elems_counts;
827 for (
unsigned int m = 0; m < wf->get_neq(); m++)
829 for (
unsigned int n = 0; n < wf->get_neq(); n++)
831 if(blocks[m][n] && current_state->e[m] != NULL && current_state->e[n] != NULL)
837 for (
unsigned int i = 0; i < am->cnt; i++)
839 for (
unsigned int j = 0; j < an->cnt; j++)
841 current_mat->pre_add_ij(am->dof[i], an->dof[j]);
852 current_mat->alloc();
857 if(current_rhs != NULL)
858 current_rhs->alloc(this->ndof);
861 for (
unsigned int i = 0; i < wf->get_neq(); i++)
862 sp_seq[i] = spaces[i]->get_seq();
865 template<
typename Scalar>
867 bool force_diagonal_blocks, Table* block_weights)
869 Scalar* coeff_vec = NULL;
870 assemble(coeff_vec, mat, rhs, force_diagonal_blocks, block_weights);
873 template<
typename Scalar>
875 bool force_diagonal_blocks, Table* block_weights)
877 assemble(NULL, NULL, rhs, force_diagonal_blocks, block_weights);
880 template<
typename Scalar>
883 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
886 for (
unsigned int j = 0; j < wf->get_neq(); j++)
889 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
891 spss[i] =
new PrecalcShapeset*[wf->get_neq()];
892 for (
unsigned int j = 0; j < wf->get_neq(); j++)
893 spss[i][j] =
new PrecalcShapeset(pss[i][j]);
895 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
897 refmaps[i] =
new RefMap*[wf->get_neq()];
898 for (
unsigned int j = 0; j < wf->get_neq(); j++)
900 refmaps[i][j] =
new RefMap();
907 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
909 if(coeff_vec != NULL)
911 u_ext[i] =
new Solution<Scalar>*[wf->get_neq()];
915 for (
int j = 0; j < wf->get_neq(); j++)
917 u_ext[i][j] =
new Solution<Scalar>(spaces[j]->get_mesh());
918 Solution<Scalar>::vector_to_solution(coeff_vec, spaces[j], u_ext[i][j], !RungeKutta, first_dof);
919 first_dof += spaces[j]->get_num_dofs();
924 for (
int j = 0; j < wf->get_neq(); j++)
926 u_ext[i][j] =
new Solution<Scalar>(spaces[j]->get_mesh());
927 u_ext[i][j]->copy(u_ext[0][j]);
933 u_ext[i] =
new Solution<Scalar>*[wf->get_neq()];
934 for (
int j = 0; j < wf->get_neq(); j++)
936 if(spaces[j]->get_shapeset()->get_num_components() == 1)
937 u_ext[i][j] =
new ZeroSolution<Scalar>(spaces[j]->get_mesh());
939 u_ext[i][j] =
new ZeroSolutionVector<Scalar>(spaces[j]->get_mesh());
945 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
947 als[i] =
new AsmList<Scalar>*[wf->get_neq()];
948 for (
unsigned int j = 0; j < wf->get_neq(); j++)
949 als[i][j] =
new AsmList<Scalar>();
953 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
955 weakforms[i] = this->wf->clone();
956 weakforms[i]->cloneMembers(this->wf);
959 assert(cache_element_stored == NULL);
960 cache_element_stored =
new bool*[this->spaces.size()];
961 for(
unsigned int i = 0; i < this->spaces.size(); i++)
963 cache_element_stored[i] =
new bool[this->spaces[i]->get_mesh()->get_max_element_id()];
964 memset(cache_element_stored[i], 0,
sizeof(
bool) * this->spaces[i]->get_mesh()->get_max_element_id());
968 template<
typename Scalar>
969 void DiscreteProblem<Scalar>::deinit_assembling(PrecalcShapeset*** pss , PrecalcShapeset*** spss, RefMap*** refmaps, Solution<Scalar>*** u_ext, AsmList<Scalar>*** als, WeakForm<Scalar>** weakforms)
971 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
973 for (
unsigned int j = 0; j < wf->get_neq(); j++)
979 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
981 for (
unsigned int j = 0; j < wf->get_neq(); j++)
987 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
989 for (
unsigned int j = 0; j < wf->get_neq(); j++)
990 delete refmaps[i][j];
991 delete [] refmaps[i];
997 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
1001 for (
unsigned int j = 0; j < wf->get_neq(); j++)
1009 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
1011 for (
unsigned int j = 0; j < wf->get_neq(); j++)
1017 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
1019 weakforms[i]->free_ext();
1020 delete weakforms[i];
1022 delete [] weakforms;
1024 for(
unsigned int i = 0; i < this->spaces.size(); i++)
1025 delete [] cache_element_stored[i];
1026 delete [] cache_element_stored;
1027 cache_element_stored = NULL;
1030 template<
typename Scalar>
1036 throw Exceptions::Exception(
"Zero DOFs detected in DiscreteProblem::assemble().");
1039 this->caughtException = NULL;
1043 current_force_diagonal_blocks = force_diagonal_blocks;
1044 current_block_weights = block_weights;
1047 if(block_weights != NULL)
1048 if(block_weights->get_size() != wf->get_neq())
1049 throw Exceptions::LengthException(6, block_weights->get_size(), wf->get_neq());
1052 create_sparse_structure();
1055 for(
unsigned int ext_i = 0; ext_i < this->wf->ext.size(); ext_i++)
1057 if(!this->wf->ext[ext_i]->isOkay())
1058 throw Hermes::Exceptions::Exception(
"Ext function %d is not okay in assemble().", ext_i);
1070 init_assembling(coeff_vec, pss, spss, refmaps, u_ext, als, weakforms);
1073 Hermes::vector<const Mesh*> meshes;
1074 for(
unsigned int space_i = 0; space_i < spaces.size(); space_i++)
1075 meshes.push_back(spaces[space_i]->get_mesh());
1076 for(
unsigned int ext_i = 0; ext_i < this->wf->ext.size(); ext_i++)
1077 meshes.push_back(this->wf->ext[ext_i]->get_mesh());
1078 for(
unsigned int form_i = 0; form_i < this->wf->get_forms().size(); form_i++)
1079 for(
unsigned int ext_i = 0; ext_i < this->wf->get_forms()[form_i]->ext.size(); ext_i++)
1080 if(this->wf->get_forms()[form_i]->ext[ext_i] != NULL)
1081 meshes.push_back(this->wf->get_forms()[form_i]->ext[ext_i]->get_mesh());
1082 for(
unsigned int space_i = 0; space_i < spaces.size(); space_i++)
1083 meshes.push_back(spaces[space_i]->get_mesh());
1086 unsigned int num_states = trav_master.get_num_states(meshes);
1088 trav_master.begin(meshes.size(), &(meshes.front()));
1091 Hermes::vector<Transformable *>* fns =
new Hermes::vector<Transformable *>[
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads)];
1092 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
1094 for (
unsigned j = 0; j < spaces.size(); j++)
1095 fns[i].push_back(pss[i][j]);
1096 for (
unsigned j = 0; j < this->wf->ext.size(); j++)
1098 fns[i].push_back(weakforms[i]->ext[j]);
1099 weakforms[i]->
ext[j]->set_quad_2d(&g_quad_2d_std);
1101 for(
unsigned int form_i = 0; form_i < this->wf->get_forms().size(); form_i++)
1103 for(
unsigned int ext_i = 0; ext_i < this->wf->get_forms()[form_i]->ext.size(); ext_i++)
1104 if(this->wf->get_forms()[form_i]->ext[ext_i] != NULL)
1106 fns[i].push_back(weakforms[i]->get_forms()[form_i]->ext[ext_i]);
1107 weakforms[i]->get_forms()[form_i]->ext[ext_i]->set_quad_2d(&g_quad_2d_std);
1110 for (
unsigned j = 0; j < wf->get_neq(); j++)
1112 fns[i].push_back(u_ext[i][j]);
1115 trav[i].begin(meshes.size(), &(meshes.front()), &(fns[i].front()));
1116 trav[i].stack = trav_master.stack;
1123 RefMap** current_refmaps;
1129 int num_threads_used =
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads);
1130 #pragma omp parallel shared(trav_master, mat, rhs ) private(state_i, current_pss, current_spss, current_refmaps, current_u_ext, current_als, current_weakform) num_threads(num_threads_used)
1132 #pragma omp for schedule(dynamic, CHUNKSIZE)
1133 for(state_i = 0; state_i < num_states; state_i++)
1137 Traverse::State current_state;
1138 #pragma omp critical (get_next_state)
1139 current_state = trav[omp_get_thread_num()].get_next_state(&trav_master.top, &trav_master.id);
1141 current_pss = pss[omp_get_thread_num()];
1142 current_spss = spss[omp_get_thread_num()];
1143 current_refmaps = refmaps[omp_get_thread_num()];
1144 current_u_ext = u_ext[omp_get_thread_num()];
1145 current_als = als[omp_get_thread_num()];
1146 current_weakform = weakforms[omp_get_thread_num()];
1154 assemble_one_state(current_pss, current_spss, current_refmaps, current_u_ext, current_als, ¤t_state, current_weakform);
1156 if(DG_matrix_forms_present || DG_vector_forms_present)
1157 assemble_one_DG_state(current_pss, current_spss, current_refmaps, current_u_ext, current_als, ¤t_state, current_weakform->
mfDG, current_weakform->
vfDG, trav[omp_get_thread_num()].fn);
1159 catch(Hermes::Exceptions::Exception& e)
1161 if(this->caughtException == NULL)
1162 this->caughtException = e.clone();
1166 if(this->caughtException == NULL)
1167 this->caughtException =
new Hermes::Exceptions::Exception(e.what());
1172 deinit_assembling(pss, spss, refmaps, u_ext, als, weakforms);
1174 trav_master.finish();
1175 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
1178 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
1186 if(current_mat != NULL)
1187 current_mat->finish();
1188 if(current_rhs != NULL)
1189 current_rhs->finish();
1191 if(DG_matrix_forms_present || DG_vector_forms_present)
1193 Element* element_to_set_nonvisited;
1194 for(
unsigned int mesh_i = 0; mesh_i < meshes.size(); mesh_i++)
1195 for_all_elements(element_to_set_nonvisited, meshes[mesh_i])
1196 element_to_set_nonvisited->
visited =
false;
1199 if(this->caughtException != NULL)
1200 throw *(this->caughtException);
1203 template<
typename Scalar>
1205 bool force_diagonal_blocks, Table* block_weights)
1207 assemble(coeff_vec, NULL, rhs, force_diagonal_blocks, block_weights);
1210 template<
typename Scalar>
1215 template<
typename Scalar>
1216 void DiscreteProblem<Scalar>::CacheRecordPerSubIdx::clear()
1218 for(
unsigned int i = 0; i < this->asmlistCnt; i++)
1221 delete this->fns[i];
1223 delete [] this->fns;
1225 delete [] this->jacobian_x_weights;
1226 this->geometry->
free();
1227 delete this->geometry;
1229 if(this->fnsSurface != NULL)
1231 for(
unsigned int edge_i = 0; edge_i < nvert; edge_i++)
1233 if(this->fnsSurface[edge_i] == NULL)
1235 delete [] this->jacobian_x_weightsSurface[edge_i];
1236 this->geometrySurface[edge_i]->
free();
1237 delete this->geometrySurface[edge_i];
1239 for(
unsigned int i = 0; i < this->asmlistSurfaceCnt[edge_i]; i++)
1241 this->fnsSurface[edge_i][i]->
free_fn();
1242 delete this->fnsSurface[edge_i][i];
1244 delete [] this->fnsSurface[edge_i];
1247 delete [] this->fnsSurface;
1248 delete [] this->geometrySurface;
1249 delete [] this->jacobian_x_weightsSurface;
1251 delete [] this->n_quadrature_pointsSurface;
1252 delete [] this->orderSurface;
1253 delete [] this->asmlistSurfaceCnt;
1255 this->fnsSurface = NULL;
1259 template<
typename Scalar>
1260 void DiscreteProblem<Scalar>::CacheRecordPerElement::clear()
1262 delete [] this->asmlistIdx;
1265 template<
typename Scalar>
1268 for(
unsigned int i = 0; i < this->spaces.size(); i++)
1270 if(current_state->e[i] == NULL)
1272 if(this->spaces[i]->edata[current_state->e[i]->id].changed_in_last_adaptation)
1276 if(!this->do_not_use_cache)
1278 if(this->cache_records_element[i][current_state->e[i]->id] != NULL)
1280 if(this->cache_records_element[i][current_state->e[i]->id]->asmlistCnt != current_als[i]->cnt)
1284 for(
unsigned int idx_i = 0; idx_i < current_als[i]->cnt; idx_i++)
1285 if(current_als[i]->idx[idx_i] != this->cache_records_element[i][current_state->e[i]->id]->asmlistIdx[idx_i])
1296 template<
typename Scalar>
1300 for(
unsigned int space_i = 0; space_i < this->spaces.size(); space_i++)
1302 bool new_cache =
false;
1303 if(current_state->e[space_i] == NULL)
1307 #pragma omp critical (cache_records_sub_idx_map)
1309 if(this->cache_records_sub_idx[space_i][current_state->e[space_i]->id] == NULL)
1311 this->cache_records_sub_idx[space_i][current_state->e[space_i]->id] =
new std::map<uint64_t, CacheRecordPerSubIdx*>;
1317 typename std::map<uint64_t, CacheRecordPerSubIdx*>::iterator it = this->cache_records_sub_idx[space_i][current_state->e[space_i]->id]->find(current_state->sub_idx[space_i]);
1318 if(it != this->cache_records_sub_idx[space_i][current_state->e[space_i]->id]->end())
1319 (*it).second->clear();
1320 else new_cache =
true;
1325 this->cache_records_sub_idx[space_i][current_state->e[space_i]->id]->insert(std::pair<uint64_t, CacheRecordPerSubIdx*>(current_state->sub_idx[space_i],
new CacheRecordPerSubIdx));
1330 int order = this->
wf->global_integration_order_set ? this->
wf->global_integration_order : 0;
1333 Hermes::vector<MatrixFormVol<Scalar>*> current_mfvol = current_wf->
mfvol;
1334 Hermes::vector<VectorFormVol<Scalar>*> current_vfvol = current_wf->
vfvol;
1336 for(
int current_mfvol_i = 0; current_mfvol_i < current_mfvol.size(); current_mfvol_i++)
1340 current_mfvol[current_mfvol_i]->wf = current_wf;
1341 int orderTemp =
calc_order_matrix_form(current_mfvol[current_mfvol_i], current_refmaps, current_u_ext, current_state);
1342 if(order < orderTemp)
1346 for(
int current_vfvol_i = 0; current_vfvol_i < current_vfvol.size(); current_vfvol_i++)
1350 current_vfvol[current_vfvol_i]->wf = current_wf;
1351 int orderTemp =
calc_order_vector_form(current_vfvol[current_vfvol_i], current_refmaps, current_u_ext, current_state);
1352 if(order < orderTemp)
1356 if(current_state->isBnd)
1358 for(
int current_mfvol_i = 0; current_mfvol_i < current_mfvol.size(); current_mfvol_i++)
1362 current_mfvol[current_mfvol_i]->wf = current_wf;
1363 int orderTemp =
calc_order_matrix_form(current_mfvol[current_mfvol_i], current_refmaps, current_u_ext, current_state);
1364 if(order < orderTemp)
1367 for(
int current_vfvol_i = 0; current_vfvol_i < current_vfvol.size(); current_vfvol_i++)
1371 current_vfvol[current_vfvol_i]->wf = current_wf;
1372 int orderTemp =
calc_order_vector_form(current_vfvol[current_vfvol_i], current_refmaps, current_u_ext, current_state);
1373 if(order < orderTemp)
1379 if(current_state->isBnd && (current_wf->
mfsurf.size() > 0 || current_wf->
vfsurf.size() > 0))
1381 Hermes::vector<MatrixFormSurf<Scalar>*> current_mfsurf = current_wf->
mfsurf;
1382 Hermes::vector<VectorFormSurf<Scalar>*> current_vfsurf = current_wf->
vfsurf;
1384 for (current_state->isurf = 0; current_state->isurf < current_state->rep->nvert; current_state->isurf++)
1386 if(!current_state->bnd[current_state->isurf])
1388 for(
int current_mfsurf_i = 0; current_mfsurf_i < current_mfsurf.size(); current_mfsurf_i++)
1392 current_mfsurf[current_mfsurf_i]->wf = current_wf;
1393 int orderTemp =
calc_order_matrix_form(current_mfsurf[current_mfsurf_i], current_refmaps, current_u_ext, current_state);
1394 if(order < orderTemp)
1398 for(
int current_vfsurf_i = 0; current_vfsurf_i < current_vfsurf.size(); current_vfsurf_i++)
1402 current_vfsurf[current_vfsurf_i]->wf = current_wf;
1403 int orderTemp =
calc_order_vector_form(current_vfsurf[current_vfsurf_i], current_refmaps, current_u_ext, current_state);
1404 if(order < orderTemp)
1413 for(
unsigned int i = 0; i < this->spaces.size(); i++)
1415 if(current_state->e[i] == NULL)
1418 bool computingThread =
false;
1419 if(!this->cache_element_stored[i][current_state->e[i]->id])
1421 #pragma omp critical (cache_for_element_preparation)
1422 if(!this->cache_element_stored[i][current_state->e[i]->id])
1424 computingThread =
true;
1425 this->cache_element_stored[i][current_state->e[i]->id] =
true;
1431 if(this->cache_records_element[i][current_state->e[i]->id] == NULL)
1434 this->cache_records_element[i][current_state->e[i]->id]->clear();
1436 this->cache_records_element[i][current_state->e[i]->id]->asmlistCnt = current_als[i]->cnt;
1437 this->cache_records_element[i][current_state->e[i]->id]->asmlistIdx =
new int[current_als[i]->cnt];
1438 for(
unsigned int asmlist_i = 0; asmlist_i < current_als[i]->cnt; asmlist_i++)
1439 this->cache_records_element[i][current_state->e[i]->id]->asmlistIdx[asmlist_i] = current_als[i]->idx[asmlist_i];
1440 this->cache_element_stored[i][current_state->e[i]->id] =
true;
1445 #pragma omp critical (cache_records_sub_idx_map)
1446 newRecord = (*this->cache_records_sub_idx[i][current_state->e[i]->id]->find(current_state->sub_idx[i])).second;
1448 newRecord->nvert = current_state->rep->nvert;
1449 newRecord->order = order;
1453 current_spss[i]->set_master_transform();
1456 current_refmaps[i]->force_transform(current_pss[i]->get_transform(), current_pss[i]->get_ctm());
1457 newRecord->fns =
new Func<double>*[current_als[i]->cnt];
1458 newRecord->asmlistCnt = current_als[i]->cnt;
1459 for (
unsigned int j = 0; j < current_als[i]->cnt; j++)
1462 newRecord->fns[j] =
init_fn(current_spss[i], current_refmaps[i], newRecord->order);
1465 newRecord->n_quadrature_points =
init_geometry_points(current_refmaps[i], newRecord->order, newRecord->geometry, newRecord->jacobian_x_weights);
1467 if(current_state->isBnd && (current_wf->
mfsurf.size() > 0 || current_wf->
vfsurf.size() > 0))
1469 newRecord->fnsSurface =
new Func<double>**[newRecord->nvert];
1470 memset(newRecord->fnsSurface, NULL,
sizeof(
Func<double>**) * newRecord->nvert);
1472 newRecord->geometrySurface =
new Geom<double>*[newRecord->nvert];
1473 newRecord->jacobian_x_weightsSurface =
new double*[newRecord->nvert];
1475 newRecord->n_quadrature_pointsSurface =
new int[newRecord->nvert];
1476 newRecord->orderSurface =
new int[newRecord->nvert];
1477 newRecord->asmlistSurfaceCnt =
new int[newRecord->nvert];
1479 int order = newRecord->order;
1480 for (current_state->isurf = 0; current_state->isurf < newRecord->nvert; current_state->isurf++)
1482 if(!current_state->bnd[current_state->isurf])
1484 newRecord->n_quadrature_pointsSurface[current_state->isurf] = init_surface_geometry_points(current_refmaps[i], order, current_state, newRecord->geometrySurface[current_state->isurf], newRecord->jacobian_x_weightsSurface[current_state->isurf]);
1485 newRecord->orderSurface[current_state->isurf] = order;
1486 order = newRecord->order;
1489 for (current_state->isurf = 0; current_state->isurf < newRecord->nvert; current_state->isurf++)
1491 if(!current_state->bnd[current_state->isurf])
1493 newRecord->asmlistSurfaceCnt[current_state->isurf] = current_alsSurface[i][current_state->isurf].cnt;
1495 newRecord->fnsSurface[current_state->isurf] =
new Func<double>*[current_alsSurface[i][current_state->isurf].cnt];
1496 for (
unsigned int j = 0; j < current_alsSurface[i][current_state->isurf].cnt; j++)
1498 current_spss[i]->
set_active_shape(current_alsSurface[i][current_state->isurf].idx[j]);
1499 newRecord->fnsSurface[current_state->isurf][j] =
init_fn(current_spss[i], current_refmaps[i], newRecord->orderSurface[current_state->isurf]);
1506 template<
typename Scalar>
1511 int rep_space_i = -1;
1514 for(
unsigned int space_i = 0; space_i < this->spaces.size(); space_i++)
1515 if(current_state->e[space_i] != NULL)
1517 rep_space_i = space_i;
1519 spaces[space_i]->get_element_assembly_list(current_state->e[space_i], current_als[space_i], spaces_first_dofs[space_i]);
1522 if(rep_space_i == -1)
1526 bool changedInLastAdaptation = this->do_not_use_cache ?
true : this->
state_needs_recalculation(current_als, current_state);
1530 if(current_state->isBnd && (current_wf->
mfsurf.size() > 0 || current_wf->
vfsurf.size() > 0 || current_wf->
mfDG.size() > 0 || current_wf->
vfDG.size() > 0))
1533 for(
unsigned int space_i = 0; space_i < this->spaces.size(); space_i++)
1535 if(current_state->e[space_i] == NULL)
1537 current_alsSurface[space_i] =
new AsmList<Scalar>[current_state->rep->nvert];
1538 for (current_state->isurf = 0; current_state->isurf < current_state->rep->nvert; current_state->isurf++)
1539 if(current_state->bnd[current_state->isurf])
1540 spaces[space_i]->get_boundary_assembly_list(current_state->e[space_i], current_state->isurf, ¤t_alsSurface[space_i][current_state->isurf], spaces_first_dofs[space_i]);
1547 if(changedInLastAdaptation)
1548 this->
calculate_cache_records(current_pss, current_spss, current_refmaps, current_u_ext, current_als, current_state, current_alsSurface, current_wf);
1551 for(
int temp_i = 0; temp_i < this->spaces.size(); temp_i++)
1553 if(current_state->e[temp_i] == NULL)
1555 #pragma omp critical (cache_records_sub_idx_map)
1557 typename std::map<uint64_t, CacheRecordPerSubIdx*>::iterator it = this->cache_records_sub_idx[temp_i][current_state->e[temp_i]->id]->find(current_state->sub_idx[temp_i]);
1558 if(it != this->cache_records_sub_idx[temp_i][current_state->e[temp_i]->id]->end())
1559 cacheRecordPerSubIdx[temp_i] = it->second;
1565 int order = cacheRecordPerSubIdx[rep_space_i]->order;
1569 int prevNewtonSize = this->
wf->get_neq();
1574 if(current_u_ext != NULL)
1575 for(
int u_ext_i = 0; u_ext_i < prevNewtonSize; u_ext_i++)
1576 if(current_u_ext[u_ext_i] != NULL)
1577 u_ext[u_ext_i] =
init_fn(current_u_ext[u_ext_i], order);
1579 u_ext[u_ext_i] = NULL;
1581 for(
int u_ext_i = 0; u_ext_i < prevNewtonSize; u_ext_i++)
1582 u_ext[u_ext_i] = NULL;
1586 int current_extCount = this->
wf->ext.size();
1588 if(current_extCount > 0)
1591 for(
int ext_i = 0; ext_i < current_extCount; ext_i++)
1592 if(current_wf->
ext[ext_i] != NULL)
1593 ext[ext_i] =
init_fn(current_wf->
ext[ext_i], order);
1600 u_ext[ext_i]->add(ext[current_extCount - this->RK_original_spaces_count + ext_i]);
1604 for(
int current_mfvol_i = 0; current_mfvol_i <
wf->mfvol.size(); current_mfvol_i++)
1611 int form_i = mfv->i;
1612 int form_j = mfv->j;
1617 CacheRecordPerSubIdxI->order,
1618 CacheRecordPerSubIdxJ->fns,
1619 CacheRecordPerSubIdxI->fns,
1622 current_als[form_i],
1623 current_als[form_j],
1625 CacheRecordPerSubIdxI->n_quadrature_points,
1626 CacheRecordPerSubIdxI->geometry,
1627 CacheRecordPerSubIdxI->jacobian_x_weights);
1630 if(current_rhs != NULL)
1632 for(
int current_vfvol_i = 0; current_vfvol_i <
wf->vfvol.size(); current_vfvol_i++)
1639 int form_i = vfv->i;
1643 CacheRecordPerSubIdxI->order,
1644 CacheRecordPerSubIdxI->fns,
1647 current_als[form_i],
1649 CacheRecordPerSubIdxI->n_quadrature_points,
1650 CacheRecordPerSubIdxI->geometry,
1651 CacheRecordPerSubIdxI->jacobian_x_weights);
1656 if(current_u_ext != NULL)
1658 for(
int u_ext_i = 0; u_ext_i < prevNewtonSize; u_ext_i++)
1659 if(current_u_ext[u_ext_i] != NULL && current_state->e[u_ext_i] != NULL)
1662 delete u_ext[u_ext_i];
1668 for(
int ext_i = 0; ext_i < current_extCount; ext_i++)
1669 if(current_wf->
ext[ext_i] != NULL)
1677 if(current_state->isBnd && (current_wf->
mfsurf.size() > 0 || current_wf->
vfsurf.size() > 0))
1679 for (current_state->isurf = 0; current_state->isurf < current_state->rep->nvert; current_state->isurf++)
1681 if(!current_state->bnd[current_state->isurf])
1686 int orderSurf = cacheRecordPerSubIdx[rep_space_i]->orderSurface[current_state->isurf];
1688 int prevNewtonSize = this->
wf->get_neq();
1693 if(current_u_ext != NULL)
1694 for(
int u_ext_surf_i = 0; u_ext_surf_i < prevNewtonSize; u_ext_surf_i++)
1695 if(current_u_ext[u_ext_surf_i] != NULL)
1696 u_extSurf[u_ext_surf_i] = current_state->e[u_ext_surf_i] == NULL ? NULL :
init_fn(current_u_ext[u_ext_surf_i], orderSurf);
1698 u_extSurf[u_ext_surf_i] = NULL;
1700 for(
int u_ext_surf_i = 0; u_ext_surf_i < prevNewtonSize; u_ext_surf_i++)
1701 u_extSurf[u_ext_surf_i] = NULL;
1704 int current_extCount = this->
wf->ext.size();
1706 for(
int ext_surf_i = 0; ext_surf_i < current_extCount; ext_surf_i++)
1707 if(current_wf->
ext[ext_surf_i] != NULL)
1708 extSurf[ext_surf_i] = current_state->e[ext_surf_i] == NULL ? NULL :
init_fn(current_wf->
ext[ext_surf_i], orderSurf);
1710 extSurf[ext_surf_i] = NULL;
1714 u_extSurf[ext_surf_i]->add(extSurf[current_extCount - this->RK_original_spaces_count + ext_surf_i]);
1718 for(
int current_mfsurf_i = 0; current_mfsurf_i <
wf->mfsurf.size(); current_mfsurf_i++)
1723 int form_i = current_wf->
mfsurf[current_mfsurf_i]->i;
1724 int form_j = current_wf->
mfsurf[current_mfsurf_i]->j;
1729 CacheRecordPerSubIdxI->orderSurface[current_state->isurf],
1730 CacheRecordPerSubIdxJ->fnsSurface[current_state->isurf],
1731 CacheRecordPerSubIdxI->fnsSurface[current_state->isurf],
1734 ¤t_alsSurface[form_i][current_state->isurf],
1735 ¤t_alsSurface[form_j][current_state->isurf],
1737 CacheRecordPerSubIdxI->n_quadrature_pointsSurface[current_state->isurf],
1738 CacheRecordPerSubIdxI->geometrySurface[current_state->isurf],
1739 CacheRecordPerSubIdxI->jacobian_x_weightsSurface[current_state->isurf]);
1743 if(current_rhs != NULL)
1745 for(
int current_vfsurf_i = 0; current_vfsurf_i <
wf->vfsurf.size(); current_vfsurf_i++)
1750 int form_i = current_wf->
vfsurf[current_vfsurf_i]->i;
1754 CacheRecordPerSubIdxI->orderSurface[current_state->isurf],
1755 CacheRecordPerSubIdxI->fnsSurface[current_state->isurf],
1758 ¤t_alsSurface[form_i][current_state->isurf],
1760 CacheRecordPerSubIdxI->n_quadrature_pointsSurface[current_state->isurf],
1761 CacheRecordPerSubIdxI->geometrySurface[current_state->isurf],
1762 CacheRecordPerSubIdxI->jacobian_x_weightsSurface[current_state->isurf]);
1766 if(current_u_ext != NULL)
1768 for(
int u_ext_surf_i = 0; u_ext_surf_i < prevNewtonSize; u_ext_surf_i++)
1769 if(current_u_ext[u_ext_surf_i] != NULL)
1771 u_extSurf[u_ext_surf_i]->
free_fn();
1772 delete u_extSurf[u_ext_surf_i];
1774 delete [] u_extSurf;
1777 for(
int ext_surf_i = 0; ext_surf_i < current_extCount; ext_surf_i++)
1778 if(current_wf->
ext[ext_surf_i] != NULL)
1780 extSurf[ext_surf_i]->
free_fn();
1781 delete extSurf[ext_surf_i];
1786 for(
unsigned int i = 0; i < this->spaces.size(); i++)
1787 if(current_state->e[i] != NULL)
1788 delete [] current_alsSurface[i];
1791 if(cacheRecordPerSubIdx != NULL)
1792 delete [] cacheRecordPerSubIdx;
1793 if(current_alsSurface != NULL)
1794 delete [] current_alsSurface;
1797 template<
typename Scalar>
1809 int ext_size = std::max(form->
ext.size(), form->wf->ext.size());
1812 init_ext_orders(form, u_ext_ord, ext_ord, current_u_ext, current_state);
1815 int max_order_j = this->spaces[form->j]->get_element_order(current_state->e[form->j]->id);
1816 int max_order_i = this->spaces[form->i]->get_element_order(current_state->e[form->i]->id);
1818 max_order_i = H2D_GET_V_ORDER(max_order_i);
1822 max_order_j = H2D_GET_V_ORDER(max_order_j);
1826 for (
unsigned int k = 0; k < current_state->rep->nvert; k++)
1828 int eo = this->spaces[form->i]->get_edge_order(current_state->e[form->i], k);
1829 if(eo > max_order_i)
1831 eo = this->spaces[form->j]->get_edge_order(current_state->e[form->j], k);
1832 if(eo > max_order_j)
1840 Hermes::Ord o = form->ord(1, &
fake_wt, u_ext_ord, ou, ov, &
geom_ord, ext_ord);
1846 delete [] u_ext_ord;
1855 template<
typename Scalar>
1861 double block_scaling_coefficient = this->block_scaling_coeff(form);
1863 bool tra = (form->i != form->j) && (form->sym != 0);
1864 bool sym = (form->i == form->j) && (form->sym == 1);
1867 Scalar **local_stiffness_matrix = new_matrix<Scalar>(std::max(current_als_i->cnt, current_als_j->cnt));
1871 if(form->
ext.size() > 0)
1873 int local_ext_count = form->
ext.size();
1875 for(
int ext_i = 0; ext_i < local_ext_count; ext_i++)
1876 if(form->
ext[ext_i] != NULL)
1877 local_ext[ext_i] = current_state->e[ext_i] == NULL ? NULL :
init_fn(form->
ext[ext_i], order);
1879 local_ext[ext_i] = NULL;
1887 for (
unsigned int i = 0; i < current_als_i->cnt; i++)
1889 if(current_als_i->dof[i] < 0)
1892 if((!tra || surface_form) && current_als_i->dof[i] < 0)
1894 if(std::abs(current_als_i->coef[i]) < 1e-12)
1898 for (
unsigned int j = 0; j < current_als_j->cnt; j++)
1900 if(current_als_j->dof[j] >= 0)
1903 if(std::abs(current_als_j->coef[j]) < 1e-12)
1910 local_stiffness_matrix[i][j] = 0.5 * block_scaling_coefficient * form->value(n_quadrature_points, jacobian_x_weights, u_ext, u, v, geometry, local_ext) * form->
scaling_factor * current_als_j->coef[j] * current_als_i->coef[i];
1912 local_stiffness_matrix[i][j] = block_scaling_coefficient * form->value(n_quadrature_points, jacobian_x_weights, u_ext, u, v, geometry, local_ext) * form->
scaling_factor * current_als_j->coef[j] * current_als_i->coef[i];
1919 for (
unsigned int j = 0; j < current_als_j->cnt; j++)
1921 if(j < i && current_als_j->dof[j] >= 0)
1923 if(current_als_j->dof[j] >= 0)
1926 if(std::abs(current_als_j->coef[j]) < 1e-12)
1932 Scalar val = block_scaling_coefficient * form->value(n_quadrature_points, jacobian_x_weights, u_ext, u, v, geometry, local_ext) * form->
scaling_factor * current_als_j->coef[j] * current_als_i->coef[i];
1934 local_stiffness_matrix[i][j] = local_stiffness_matrix[j][i] = val;
1942 current_mat->add(current_als_i->cnt, current_als_j->cnt, local_stiffness_matrix, current_als_i->dof, current_als_j->dof);
1948 chsgn(local_stiffness_matrix, current_als_i->cnt, current_als_j->cnt);
1949 transpose(local_stiffness_matrix, current_als_i->cnt, current_als_j->cnt);
1951 current_mat->add(current_als_j->cnt, current_als_i->cnt, local_stiffness_matrix, current_als_j->dof, current_als_i->dof);
1954 if(form->
ext.size() > 0)
1956 for(
int ext_i = 0; ext_i < form->
ext.size(); ext_i++)
1957 if(form->
ext[ext_i] != NULL)
1959 local_ext[ext_i]->free_fn();
1960 delete local_ext[ext_i];
1962 delete [] local_ext;
1969 delete [] local_stiffness_matrix;
1972 template<
typename Scalar>
1984 int ext_size = std::max(form->
ext.size(), form->wf->ext.size());
1987 init_ext_orders(form, u_ext_ord, ext_ord, current_u_ext, current_state);
1990 int max_order_i = this->spaces[form->i]->get_element_order(current_state->e[form->i]->id);
1992 max_order_i = H2D_GET_V_ORDER(max_order_i);
1996 for (
unsigned int k = 0; k < current_state->rep->nvert; k++)
1998 int eo = this->spaces[form->i]->get_edge_order(current_state->e[form->i], k);
1999 if(eo > max_order_i)
2005 Hermes::Ord o = form->ord(1, &
fake_wt, u_ext_ord, ov, &
geom_ord, ext_ord);
2011 delete [] u_ext_ord;
2018 template<
typename Scalar>
2020 AsmList<Scalar>* current_als_i, Traverse::State* current_state,
int n_quadrature_points,
Geom<double>* geometry,
double* jacobian_x_weights)
2027 if(form->
ext.size() > 0)
2029 int local_ext_count = form->
ext.size();
2031 for(
int ext_i = 0; ext_i < local_ext_count; ext_i++)
2032 if(form->
ext[ext_i] != NULL)
2033 local_ext[ext_i] =
init_fn(form->
ext[ext_i], order);
2035 local_ext[ext_i] = NULL;
2043 for (
unsigned int i = 0; i < current_als_i->cnt; i++)
2045 if(current_als_i->dof[i] < 0)
2049 if(std::abs(current_als_i->coef[i]) < 1e-12)
2056 val = 0.5 * form->value(n_quadrature_points, jacobian_x_weights, u_ext, v, geometry, local_ext) * form->
scaling_factor * current_als_i->coef[i];
2058 val = form->value(n_quadrature_points, jacobian_x_weights, u_ext, v, geometry, local_ext) * form->
scaling_factor * current_als_i->coef[i];
2060 current_rhs->add(current_als_i->dof[i], val);
2063 if(form->
ext.size() > 0)
2065 for(
int ext_i = 0; ext_i < form->
ext.size(); ext_i++)
2066 if(form->
ext[ext_i] != NULL)
2069 delete local_ext[ext_i];
2071 delete [] local_ext;
2078 template<
typename Scalar>
2089 jacobian_x_weights =
new double[np];
2090 for(
int i = 0; i < np; i++)
2095 jacobian_x_weights[i] = pt[i][2] * jac[i];
2100 template<
typename Scalar>
2103 int eo = reference_mapping->
get_quad_2d()->get_edge_points(current_state->isurf, order, reference_mapping->
get_active_element()->get_mode());
2109 geometry =
init_geom_surf(reference_mapping, current_state->isurf, current_state->rep->en[current_state->isurf]->marker, eo, tan);
2110 jacobian_x_weights =
new double[np];
2111 for(
int i = 0; i < np; i++)
2112 jacobian_x_weights[i] = pt[i][2] * tan[i][2];
2117 template<
typename Scalar>
2121 bool surface_form = (current_state->isurf > -1);
2123 if(current_u_ext != NULL)
2124 for(
int i = 0; i < prev_size; i++)
2133 for(
int i = 0; i < prev_size; i++)
2136 if(form->
ext.size() > 0)
2138 for (
int i = 0; i < form->
ext.size(); i++)
2140 oext[i] =
init_fn_ord(form->
ext[i]->get_edge_fn_order(current_state->isurf) + (form->
ext[i]->get_num_components() > 1 ? 1 : 0));
2142 oext[i] =
init_fn_ord(form->
ext[i]->get_fn_order() + (form->
ext[i]->get_num_components() > 1 ? 1 : 0));
2147 for (
int i = 0; i < form->wf->ext.size(); i++)
2149 oext[i] =
init_fn_ord(form->wf->ext[i]->get_edge_fn_order(current_state->isurf) + (form->wf->ext[i]->get_num_components() > 1 ? 1 : 0));
2151 oext[i] =
init_fn_ord(form->wf->ext[i]->get_fn_order() + (form->wf->ext[i]->get_num_components() > 1 ? 1 : 0));
2155 template<
typename Scalar>
2159 for(
int i = 0; i < prev_size; i++)
2167 if(form->
ext.size() > 0)
2168 for (
int i = 0; i < form->
ext.size(); i++)
2174 for (
int i = 0; i < form->wf->ext.size(); i++)
2184 template<
typename Scalar>
2190 order += o->get_order();
2191 limit_order(order, current_refmaps[coordinate]->get_active_element()->get_mode());
2194 template<
typename Scalar>
2199 unsigned int min_dg_mesh_seq = 0;
2200 for(
unsigned int i = 0; i < spaces.size(); i++)
2201 if(spaces[i]->get_mesh()->get_seq() < min_dg_mesh_seq || i == 0)
2202 min_dg_mesh_seq = spaces[i]->get_mesh()->get_seq();
2205 std::map<unsigned int, PrecalcShapeset *> npss;
2206 std::map<unsigned int, PrecalcShapeset *> nspss;
2207 std::map<unsigned int, RefMap *> nrefmap;
2213 for (
unsigned int i = 0; i < spaces.size(); i++)
2216 npss.insert(std::pair<unsigned int, PrecalcShapeset*>(i, new_ps));
2218 nspss.insert(std::pair<unsigned int, PrecalcShapeset*>(i, new_pss));
2221 nrefmap.insert(std::pair<unsigned int, RefMap*>(i, new_rm));
2225 bool** processed =
new bool*[current_state->rep->nvert];
2226 LightArray<NeighborSearch<Scalar>*>** neighbor_searches =
new LightArray<NeighborSearch<Scalar>*>*[current_state->rep->nvert];
2228 unsigned int* num_neighbors =
new unsigned int[current_state->rep->nvert];
2232 intra_edge_passed_DG[a] =
false;
2234 #pragma omp critical (DG)
2236 for(
unsigned int i = 0; i < current_state->num; i++)
2237 current_state->e[i]->visited =
true;
2239 for(current_state->isurf = 0; current_state->isurf < current_state->rep->nvert; current_state->isurf++)
2241 if(current_state->rep->en[current_state->isurf]->marker == 0)
2243 neighbor_searches[current_state->isurf] =
new LightArray<NeighborSearch<Scalar>*>(5);
2245 if(!
init_neighbors((*neighbor_searches[current_state->isurf]), current_state, min_dg_mesh_seq))
2247 intra_edge_passed_DG[current_state->isurf] =
true;
2254 #ifdef DEBUG_DG_ASSEMBLING
2255 #pragma omp critical (debug_DG)
2259 if(DEBUG_DG_ASSEMBLING_ELEMENT != -1)
2261 for(
unsigned int i = 0; i < (*neighbor_searches[current_state->isurf]).get_size(); i++)
2262 if((*neighbor_searches[current_state->isurf]).present(i))
2263 if((*neighbor_searches[current_state->isurf]).get(i)->central_el->id == DEBUG_DG_ASSEMBLING_ELEMENT)
2270 if(DEBUG_DG_ASSEMBLING_ISURF != -1)
2271 if(current_state->isurf != DEBUG_DG_ASSEMBLING_ISURF)
2276 for(
unsigned int i = 0; i < (*neighbor_searches[current_state->isurf]).get_size(); i++)
2278 if((*neighbor_searches[current_state->isurf]).present(i))
2281 std::cout << (
std::string)
"The " << ++
id << (
std::string)
"-th Neighbor search:: " << (
std::string)
"Central element: " << ns->central_el->id << (
std::string)
", Isurf: " << current_state->isurf << (
std::string)
", Original sub_idx: " << ns->original_central_el_transform << std::endl;
2282 for(
int j = 0; j < ns->n_neighbors; j++)
2284 std::cout <<
'\t' << (
std::string)
"The " << j << (
std::string)
"-th neighbor element: " << ns->neighbors[j]->id << std::endl;
2285 if(ns->central_transformations.present(j))
2287 std::cout <<
'\t' << (
std::string)
"Central transformations: " << std::endl;
2288 for(
int k = 0; k < ns->central_transformations.get(j)->num_levels; k++)
2289 std::cout <<
'\t' <<
'\t' << ns->central_transformations.get(j)->transf[k] << std::endl;
2291 if(ns->neighbor_transformations.present(j))
2293 std::cout <<
'\t' << (
std::string)
"Neighbor transformations: " << std::endl;
2294 for(
int k = 0; k < ns->neighbor_transformations.get(j)->num_levels; k++)
2295 std::cout <<
'\t' <<
'\t' << ns->neighbor_transformations.get(j)->transf[k] << std::endl;
2309 num_neighbors[current_state->isurf] = 0;
2310 for(
unsigned int i = 0; i < (*neighbor_searches[current_state->isurf]).get_size(); i++)
2312 if((*neighbor_searches[current_state->isurf]).present(i))
2316 if(num_neighbors[current_state->isurf] == 0)
2317 num_neighbors[current_state->isurf] = ns->n_neighbors;
2318 if(ns->n_neighbors != num_neighbors[current_state->isurf])
2319 throw Hermes::Exceptions::Exception(
"Num_neighbors of different NeighborSearches not matching in DiscreteProblem<Scalar>::assemble_surface_integrals().");
2326 processed[current_state->isurf] =
new bool[num_neighbors[current_state->isurf]];
2328 for(
unsigned int neighbor_i = 0; neighbor_i < num_neighbors[current_state->isurf]; neighbor_i++)
2333 processed[current_state->isurf][neighbor_i] =
true;
2334 for(
unsigned int i = 0; i < (*neighbor_searches[current_state->isurf]).get_size(); i++)
2336 if((*neighbor_searches[current_state->isurf]).present(i))
2338 if(!(*neighbor_searches[current_state->isurf]).get(i)->neighbors.at(neighbor_i)->visited)
2340 processed[current_state->isurf][neighbor_i] =
false;
2350 for(current_state->isurf = 0; current_state->isurf < current_state->rep->nvert; current_state->isurf++)
2352 if(intra_edge_passed_DG[current_state->isurf])
2354 if(current_state->rep->en[current_state->isurf]->marker != 0)
2357 for(
unsigned int neighbor_i = 0; neighbor_i < num_neighbors[current_state->isurf]; neighbor_i++)
2362 assemble_DG_one_neighbor(processed[current_state->isurf][neighbor_i], neighbor_i, current_pss, current_spss, current_refmaps, current_u_ext, current_als,
2363 current_state, current_mfDG, current_vfDG, fn,
2364 npss, nspss, nrefmap, (*neighbor_searches[current_state->isurf]), min_dg_mesh_seq);
2368 for(
unsigned int i = 0; i < (*neighbor_searches[current_state->isurf]).get_size(); i++)
2369 if((*neighbor_searches[current_state->isurf]).present(i))
2370 delete (*neighbor_searches[current_state->isurf]).get(i);
2371 delete neighbor_searches[current_state->isurf];
2372 delete [] processed[current_state->isurf];
2375 delete [] processed;
2376 delete [] neighbor_searches;
2377 delete [] num_neighbors;
2382 for(std::map<unsigned int, PrecalcShapeset *>::iterator it = nspss.begin(); it != nspss.end(); it++)
2384 for(std::map<unsigned int, PrecalcShapeset *>::iterator it = npss.begin(); it != npss.end(); it++)
2386 for(std::map<unsigned int, RefMap *>::iterator it = nrefmap.begin(); it != nrefmap.end(); it++)
2391 template<
typename Scalar>
2395 std::map<unsigned int, PrecalcShapeset *> npss, std::map<unsigned int, PrecalcShapeset *> nspss, std::map<unsigned int, RefMap *> nrefmap,
2399 for(
unsigned int i = 0; i < neighbor_searches.get_size(); i++)
2401 if(neighbor_searches.present(i))
2404 ns->active_segment = neighbor_i;
2405 ns->neighb_el = ns->neighbors[neighbor_i];
2406 ns->neighbor_edge = ns->neighbor_edges[neighbor_i];
2412 for(
unsigned int fns_i = 0; fns_i < current_state->num; fns_i++)
2414 const Mesh * mesh_i;
2415 if(dynamic_cast<PrecalcShapeset*>(fn[fns_i]) != NULL)
2416 mesh_i = spaces[fns_i]->get_mesh();
2420 if(ns->central_transformations.present(neighbor_i))
2421 ns->central_transformations.get(neighbor_i)->apply_on(fn[fns_i]);
2427 for(
unsigned int idx_i = 0; idx_i < spaces.size(); idx_i++)
2429 NeighborSearch<Scalar>* ns = neighbor_searches.get(spaces[idx_i]->get_mesh()->get_seq() - min_dg_mesh_seq);
2430 npss[idx_i]->set_active_element((*ns->
get_neighbors())[neighbor_i]);
2431 if(ns->neighbor_transformations.present(neighbor_i))
2432 ns->neighbor_transformations.get(neighbor_i)->apply_on(npss[idx_i]);
2437 for (
unsigned int i = 0; i < spaces.size(); i++)
2439 current_spss[i]->set_master_transform();
2440 current_refmaps[i]->force_transform(current_pss[i]->get_transform(), current_pss[i]->get_ctm());
2445 nspss[i]->set_active_element(npss[i]->get_active_element());
2446 nspss[i]->set_master_transform();
2447 nrefmap[i]->set_active_element(npss[i]->get_active_element());
2448 nrefmap[i]->force_transform(npss[i]->get_transform(), npss[i]->get_ctm());
2456 for(
int current_mfsurf_i = 0; current_mfsurf_i <
wf->mfDG.size(); current_mfsurf_i++)
2462 int order_base = 20;
2473 NeighborSearch<Scalar>* nbs_u = neighbor_searches.get(spaces[n]->get_mesh()->get_seq() - min_dg_mesh_seq);
2474 NeighborSearch<Scalar>* nbs_v = neighbor_searches.get(spaces[m]->get_mesh()->get_seq() - min_dg_mesh_seq);
2480 int n_quadrature_points;
2482 double* jacobian_x_weights = NULL;
2483 n_quadrature_points = init_surface_geometry_points(current_refmaps[mfs->i], order_base, current_state, geometry, jacobian_x_weights);
2486 nbs_u->neighb_el->id, nbs_u->neighb_el->get_diameter());
2491 if(current_u_ext != NULL)
2493 for (
int i = 0; i < prev_size; i++)
2497 neighbor_searches.get(current_u_ext[i]->get_mesh()->get_seq() - min_dg_mesh_seq)->set_quad_order(order);
2498 prev[i] = neighbor_searches.get(current_u_ext[i]->get_mesh()->get_seq() - min_dg_mesh_seq)->init_ext_fn(current_u_ext[i]);
2505 for (
int i = 0; i < prev_size; i++)
2515 bool support_neigh_u, support_neigh_v;
2517 Scalar **local_stiffness_matrix = new_matrix<Scalar>(std::max(ext_asmlist_u->
cnt, ext_asmlist_v->
cnt));
2518 for (
int i = 0; i < ext_asmlist_v->
cnt; i++)
2520 if(ext_asmlist_v->
dof[i] < 0)
2523 if(!ext_asmlist_v->has_support_on_neighbor(i))
2526 fv = current_spss[m];
2527 rv = current_refmaps[m];
2528 support_neigh_v =
false;
2535 support_neigh_v =
true;
2537 for (
int j = 0; j < ext_asmlist_u->
cnt; j++)
2540 if(!ext_asmlist_u->has_support_on_neighbor(j))
2543 fu = current_pss[n];
2544 ru = current_refmaps[n];
2545 support_neigh_u =
false;
2552 support_neigh_u =
true;
2555 if(ext_asmlist_u->
dof[j] >= 0)
2559 support_neigh_u, nbs_u->neighbor_edge.orientation);
2561 support_neigh_v, nbs_v->neighbor_edge.orientation);
2563 Scalar res = mfs->value(n_quadrature_points, jacobian_x_weights, prev, u, v, e, ext) * mfs->
scaling_factor;
2570 Scalar val = block_scaling_coeff(mfs) * 0.5 * res * (support_neigh_u ? ext_asmlist_u->
neighbor_al->coef[j - ext_asmlist_u->
central_al->cnt]: ext_asmlist_u->
central_al->coef[j])
2572 local_stiffness_matrix[i][j] = val;
2578 current_mat->add(ext_asmlist_v->
cnt, ext_asmlist_u->
cnt, local_stiffness_matrix, ext_asmlist_v->
dof, ext_asmlist_u->
dof);
2580 delete [] local_stiffness_matrix;
2583 for (
int i = 0; i < prev_size; i++)
2596 for(
unsigned int i = 0; i < mfs->wf->ext.size(); i++)
2607 delete [] jacobian_x_weights;
2609 delete ext_asmlist_u;
2610 delete ext_asmlist_v;
2616 for (
unsigned int ww = 0; ww <
wf->vfDG.size(); ww++)
2619 int order_base = 20;
2622 if(vfs->
areas[0] != H2D_DG_INNER_EDGE)
2631 NeighborSearch<Scalar>* nbs_v = (neighbor_searches.get(spaces[m]->get_mesh()->get_seq() - min_dg_mesh_seq));
2635 int n_quadrature_points;
2637 double* jacobian_x_weights = NULL;
2638 n_quadrature_points = init_surface_geometry_points(current_refmaps[vfs->i], order_base, current_state, geometry, jacobian_x_weights);
2641 nbs_v->neighb_el->id, nbs_v->neighb_el->get_diameter());
2646 if(current_u_ext != NULL)
2647 for (
int i = 0; i < prev_size; i++)
2650 neighbor_searches.get(current_u_ext[i]->get_mesh()->get_seq() - min_dg_mesh_seq)->set_quad_order(order);
2651 prev[i] = neighbor_searches.get(current_u_ext[i]->get_mesh()->get_seq() - min_dg_mesh_seq)->init_ext_fn(current_u_ext[i]);
2656 for (
int i = 0; i < prev_size; i++)
2660 for (
unsigned int dof_i = 0; dof_i < current_als[m]->cnt; dof_i++)
2662 if(current_als[m]->dof[dof_i] < 0)
2669 current_rhs->add(current_als[m]->dof[dof_i], 0.5 * vfs->value(n_quadrature_points, jacobian_x_weights, prev, v, e, ext) * vfs->
scaling_factor * current_als[m]->coef[dof_i]);
2676 for (
int i = 0; i < prev_size; i++)
2689 for(
unsigned int i = 0; i < vfs->wf->ext.size(); i++)
2696 delete [] jacobian_x_weights;
2702 for(
unsigned int fns_i = 0; fns_i < current_state->num; fns_i++)
2704 const Mesh * mesh_i;
2705 if(dynamic_cast<PrecalcShapeset*>(fn[fns_i]) != NULL)
2706 mesh_i = spaces[fns_i]->get_mesh();
2710 fn[fns_i]->
set_transform(neighbor_searches.get(mesh_i->
get_seq() - min_dg_mesh_seq)->original_central_el_transform);
2714 for (
unsigned int i = 0; i < spaces.size(); i++)
2716 current_spss[i]->set_master_transform();
2717 current_refmaps[i]->force_transform(current_pss[i]->get_transform(), current_pss[i]->get_ctm());
2721 template<
typename Scalar>
2726 for(
unsigned int j = 0; j < ext.size(); j++)
2728 neighbor_searches.get(ext[j]->get_mesh()->get_seq() - min_dg_mesh_seq)->set_quad_order(order);
2729 ext_fns[j] = neighbor_searches.get(ext[j]->get_mesh()->get_seq() - min_dg_mesh_seq)->init_ext_fn(ext[j]);
2735 template<
typename Scalar>
2737 Traverse::State* current_state,
unsigned int min_dg_mesh_seq)
2740 for(
unsigned int i = 0; i < spaces.size(); i++)
2742 if(i > 0 && spaces[i - 1]->get_mesh()->get_seq() == spaces[i]->get_mesh()->get_seq())
2745 if(!neighbor_searches.present(spaces[i]->get_mesh()->get_seq() - min_dg_mesh_seq))
2748 ns->original_central_el_transform = current_state->sub_idx[i];
2749 neighbor_searches.add(ns, spaces[i]->get_mesh()->get_seq() - min_dg_mesh_seq);
2757 bool DG_intra =
false;
2758 for(
unsigned int i = 0; i < spaces.size(); i++)
2760 if(!(i > 0 && spaces[i]->get_mesh()->get_seq() - min_dg_mesh_seq == spaces[i-1]->get_mesh()->get_seq() - min_dg_mesh_seq))
2762 if(neighbor_searches.get(spaces[i]->get_mesh()->get_seq() - min_dg_mesh_seq)->set_active_edge_multimesh(current_state->isurf) && spaces[i]->get_type() == HERMES_L2_SPACE)
2764 neighbor_searches.get(spaces[i]->get_mesh()->get_seq() - min_dg_mesh_seq)->clear_initial_sub_idx();
2770 template<
typename Scalar>
2774 for(
unsigned int i = 0; i < neighbor_searches.get_size(); i++)
2775 if(neighbor_searches.present(i))
2778 if(ns->n_neighbors == 1 &&
2779 (ns->central_transformations.get_size() == 0 || ns->central_transformations.get(0)->num_levels == 0))
2781 for(
unsigned int j = 0; j < ns->n_neighbors; j++)
2782 if(ns->central_transformations.present(j))
2783 insert_into_multimesh_tree(root, ns->central_transformations.get(j)->transf, ns->central_transformations.get(j)->num_levels);
2787 template<
typename Scalar>
2789 unsigned int* transformations,
2790 unsigned int transformation_count)
2793 if(transformation_count == 0)
2796 if(node->get_left_son() == NULL && node->get_right_son() == NULL)
2798 node->set_left_son(
new NeighborNode(node, transformations[0]));
2806 if(node->get_left_son()->get_transformation() == transformations[0])
2809 else if(node->get_right_son() != NULL)
2811 if(node->get_right_son()->get_transformation() == transformations[0])
2814 throw Hermes::Exceptions::Exception(
"More than two possible sons in insert_into_multimesh_tree().");
2819 node->set_right_son(
new NeighborNode(node, transformations[0]));
2825 template<
typename Scalar>
2829 Hermes::vector<Hermes::vector<unsigned int>*> running_transformations;
2831 running_transformations.push_back(
new Hermes::vector<unsigned int>);
2834 return running_transformations;
2837 template<
typename Scalar>
2839 Hermes::vector<Hermes::vector<unsigned int>*>& running_transformations)
2842 if(node->get_transformation() == 0)
2844 if(node->get_left_son() != NULL)
2846 if(node->get_right_son() != NULL)
2849 delete running_transformations.back();
2850 running_transformations.pop_back();
2854 if(node->get_left_son() == NULL && node->get_right_son() == NULL)
2857 Hermes::vector<unsigned int>* new_neighbor_transformations =
new Hermes::vector<unsigned int>;
2859 for(
unsigned int i = 0; i < running_transformations.back()->size(); i++)
2860 new_neighbor_transformations->push_back((*running_transformations.back())[i]);
2862 running_transformations.back()->push_back(node->get_transformation());
2864 running_transformations.push_back(new_neighbor_transformations);
2869 running_transformations.back()->push_back(node->get_transformation());
2870 if(node->get_left_son() != NULL)
2872 if(node->get_right_son() != NULL)
2874 running_transformations.back()->pop_back();
2880 template<
typename Scalar>
2886 for(
unsigned int i = 0; i < num_neighbors; i++)
2890 if(ns->central_transformations.present(i))
2891 node =
find_node(ns->central_transformations.get(i)->transf, ns->central_transformations.get(i)->num_levels, multimesh_tree);
2893 node = multimesh_tree;
2898 num_neighbors += added;
2902 template<
typename Scalar>
2904 unsigned int transformation_count,
2908 if(transformation_count == 0)
2912 if(node->get_left_son() != NULL)
2914 if(node->get_left_son()->get_transformation() == transformations[0])
2915 return find_node(transformations + 1, transformation_count - 1, node->get_left_son());
2917 if(node->get_right_son() != NULL)
2919 if(node->get_right_son()->get_transformation() == transformations[0])
2920 return find_node(transformations + 1, transformation_count - 1, node->get_right_son());
2925 Hermes::Exceptions::Exception(
"Transformation of a central element not found in the multimesh tree.");
2929 template<
typename Scalar>
2937 if(node->get_left_son() == NULL)
2939 if(node->get_right_son() != NULL)
2940 throw Hermes::Exceptions::Exception(
"Only one son (right) not null in DiscreteProblem<Scalar>::update_ns_subtree.");
2946 Element* neighbor = ns->neighbors[ith_neighbor];
2950 Hermes::vector<Hermes::vector<unsigned int>*> running_central_transformations;
2952 running_central_transformations.push_back(
new Hermes::vector<unsigned int>);
2953 if(ns->central_transformations.present(ith_neighbor))
2954 ns->central_transformations.get(ith_neighbor)->copy_to(running_central_transformations.back());
2957 Hermes::vector<Hermes::vector<unsigned int>*> running_neighbor_transformations;
2959 running_neighbor_transformations.push_back(
new Hermes::vector<unsigned int>);
2960 if(ns->neighbor_transformations.present(ith_neighbor))
2961 ns->neighbor_transformations.get(ith_neighbor)->copy_to(running_neighbor_transformations.back());
2967 if(node->get_left_son() != NULL)
2969 running_neighbor_transformations, edge_info, ns->active_edge,
2970 ns->central_el->get_mode());
2971 if(node->get_right_son() != NULL)
2973 running_neighbor_transformations, edge_info, ns->active_edge,
2974 ns->central_el->get_mode());
2977 delete running_central_transformations.back();
2978 running_central_transformations.pop_back();
2979 delete running_neighbor_transformations.back();
2980 running_neighbor_transformations.pop_back();
2983 for(
unsigned int i = 0; i < running_central_transformations.size(); i++)
2985 ns->neighbors.push_back(neighbor);
2986 ns->neighbor_edges.push_back(edge_info);
2988 if(!ns->central_transformations.present(ns->n_neighbors))
2990 if(!ns->neighbor_transformations.present(ns->n_neighbors))
2992 ns->central_transformations.get(ns->n_neighbors)->copy_from(*running_central_transformations[i]);
2993 ns->neighbor_transformations.get(ns->n_neighbors)->copy_from(*running_neighbor_transformations[i]);
2998 for(
unsigned int i = 0; i < running_central_transformations.size(); i++)
2999 delete running_central_transformations[i];
3000 for(
unsigned int i = 0; i < running_neighbor_transformations.size(); i++)
3001 delete running_neighbor_transformations[i];
3007 template<
typename Scalar>
3009 Hermes::vector<Hermes::vector<unsigned int>*>& running_central_transformations,
3010 Hermes::vector<Hermes::vector<unsigned int>*>& running_neighbor_transformations,
3014 if(node->get_left_son() == NULL && node->get_right_son() == NULL)
3017 Hermes::vector<unsigned int>* new_neighbor_central_transformations =
new Hermes::vector<unsigned int>;
3018 Hermes::vector<unsigned int>* new_neighbor_neighbor_transformations =
new Hermes::vector<unsigned int>;
3021 for(
unsigned int i = 0; i < running_central_transformations.back()->size(); i++)
3022 new_neighbor_central_transformations->push_back((*running_central_transformations.back())[i]);
3023 for(
unsigned int i = 0; i < running_neighbor_transformations.back()->size(); i++)
3024 new_neighbor_neighbor_transformations->push_back((*running_neighbor_transformations.back())[i]);
3027 running_central_transformations.back()->push_back(node->get_transformation());
3030 running_central_transformations.push_back(new_neighbor_central_transformations);
3034 if(mode == HERMES_MODE_TRIANGLE)
3035 if((active_edge == 0 && node->get_transformation() == 0) ||
3036 (active_edge == 1 && node->get_transformation() == 1) ||
3037 (active_edge == 2 && node->get_transformation() == 2))
3043 if((active_edge == 0 && (node->get_transformation() == 0 || node->get_transformation() == 6)) ||
3044 (active_edge == 1 && (node->get_transformation() == 1 || node->get_transformation() == 4)) ||
3045 (active_edge == 2 && (node->get_transformation() == 2 || node->get_transformation() == 7)) ||
3046 (active_edge == 3 && (node->get_transformation() == 3 || node->get_transformation() == 5)))
3052 running_neighbor_transformations.push_back(new_neighbor_neighbor_transformations);
3059 running_central_transformations.back()->push_back(node->get_transformation());
3063 if(mode == HERMES_MODE_TRIANGLE)
3064 if((active_edge == 0 && node->get_transformation() == 0) ||
3065 (active_edge == 1 && node->get_transformation() == 1) ||
3066 (active_edge == 2 && node->get_transformation() == 2))
3072 if((active_edge == 0 && (node->get_transformation() == 0 || node->get_transformation() == 6)) ||
3073 (active_edge == 1 && (node->get_transformation() == 1 || node->get_transformation() == 4)) ||
3074 (active_edge == 2 && (node->get_transformation() == 2 || node->get_transformation() == 7)) ||
3075 (active_edge == 3 && (node->get_transformation() == 3 || node->get_transformation() == 5)))
3081 if(node->get_left_son() != NULL)
3083 edge_info, active_edge, mode);
3084 if(node->get_right_son() != NULL)
3086 edge_info, active_edge, mode);
3089 running_central_transformations.back()->pop_back();
3090 running_neighbor_transformations.back()->pop_back();
3096 NeighborNode::NeighborNode(
NeighborNode* parent,
unsigned int transformation) : parent(parent), transformation(transformation)
3098 left_son = right_son = NULL;
3100 NeighborNode::~NeighborNode()
3102 if(left_son != NULL)
3107 if(right_son != NULL)
3113 void NeighborNode::set_left_son(NeighborNode* left_son)
3115 this->left_son = left_son;
3117 void NeighborNode::set_right_son(NeighborNode* right_son)
3119 this->right_son = right_son;
3121 void NeighborNode::set_transformation(
unsigned int transformation)
3123 this->transformation = transformation;
3125 NeighborNode* NeighborNode::get_left_son()
3129 NeighborNode* NeighborNode::get_right_son()
3133 unsigned int NeighborNode::get_transformation()
3135 return this->transformation;
3138 template class HERMES_API DiscreteProblem<double>;
3139 template class HERMES_API DiscreteProblem<std::complex<double> >;