16 #include "discrete_problem/discrete_problem_thread_assembler.h"
17 #include "discrete_problem/discrete_problem_selective_assembler.h"
18 #include "shapeset/precalc.h"
19 #include "function/solution.h"
20 #include "weakform/weakform.h"
21 #include "function/exact_solution.h"
27 template<
typename Scalar>
28 DiscreteProblemThreadAssembler<Scalar>::DiscreteProblemThreadAssembler(DiscreteProblemSelectiveAssembler<Scalar>* selectiveAssembler,
bool nonlinear) :
29 pss(nullptr), refmaps(nullptr), u_ext(nullptr),
30 selectiveAssembler(selectiveAssembler), integrationOrderCalculator(selectiveAssembler),
31 ext_funcs(nullptr), ext_funcs_allocated_size(0), ext_funcs_local(nullptr), ext_funcs_local_allocated_size(0),
32 funcs_wf_initialized(false), funcs_space_initialized(false), spaces_size(0), nonlinear(nonlinear), reusable_DOFs(nullptr), reusable_Dirichlet(nullptr)
35 this->init_funcs_memory_pool();
38 template<
typename Scalar>
39 DiscreteProblemThreadAssembler<Scalar>::~DiscreteProblemThreadAssembler()
43 pj_pool_release(this->FuncMemoryPool);
47 template<
typename Scalar>
48 void DiscreteProblemThreadAssembler<Scalar>::init_spaces(
const std::vector<SpaceSharedPtr<Scalar> > spaces)
52 bool reinit_funcs = this->spaces_size != spaces.size();
53 this->spaces_size = spaces.size();
57 this->deinit_funcs_space();
58 this->init_funcs_space();
61 pss = malloc_with_check<PrecalcShapesetAssembling*>(spaces_size);
62 refmaps = malloc_with_check<RefMap*>(spaces_size);
64 for (
unsigned int j = 0; j < spaces_size; j++)
66 pss[j] =
new PrecalcShapesetAssembling(spaces[j]->shapeset);
67 refmaps[j] =
new RefMap();
68 refmaps[j]->set_quad_2d(&g_quad_2d_std);
72 template<
typename Scalar>
73 void DiscreteProblemThreadAssembler<Scalar>::set_weak_formulation(WeakFormSharedPtr<Scalar> wf_)
75 this->deinit_funcs_wf();
76 this->free_weak_formulation();
77 this->wf = WeakFormSharedPtr<Scalar>(wf_->clone());
78 this->wf->cloneMembers(wf_);
79 this->init_funcs_wf();
82 template<
typename Scalar>
83 void DiscreteProblemThreadAssembler<Scalar>::init_u_ext(
const std::vector<SpaceSharedPtr<Scalar> > spaces, Solution<Scalar>** u_ext_sln)
85 assert(this->spaces_size == spaces.size() && this->pss);
88 u_ext = malloc_with_check<Solution<Scalar>*>(spaces_size);
90 for (
unsigned int j = 0; j < spaces_size; j++)
94 u_ext[j] =
new Solution<Scalar>(spaces[j]->get_mesh());
95 u_ext[j]->copy(u_ext_sln[j]);
99 if (spaces[j]->get_shapeset()->get_num_components() == 1)
100 u_ext[j] =
new ZeroSolution<Scalar>(spaces[j]->get_mesh());
102 u_ext[j] =
new ZeroSolutionVector<Scalar>(spaces[j]->get_mesh());
106 this->integrationOrderCalculator.u_ext = this->u_ext;
109 template<
typename Scalar>
110 void DiscreteProblemThreadAssembler<Scalar>::init_assembling(Solution<Scalar>** u_ext_sln,
const std::vector<SpaceSharedPtr<Scalar> >& spaces,
bool add_dirichlet_lift_)
113 this->add_dirichlet_lift = add_dirichlet_lift_;
118 for (
unsigned j = 0; j < this->spaces_size; j++)
120 fns.push_back(pss[j]);
121 pss[j]->set_quad_2d(&g_quad_2d_std);
124 for (
unsigned j = 0; j < this->wf->ext.size(); j++)
126 fns.push_back(this->wf->ext[j].get());
127 this->wf->ext[j]->set_quad_2d(&g_quad_2d_std);
130 for (
unsigned int form_i = 0; form_i < this->wf->get_forms().size(); form_i++)
132 Form<Scalar>* form = this->wf->get_forms()[form_i];
133 for (
unsigned int ext_i = 0; ext_i < form->ext.size(); ext_i++)
135 if (form->ext[ext_i])
137 fns.push_back(form->ext[ext_i].get());
138 form->ext[ext_i]->set_quad_2d(&g_quad_2d_std);
145 init_u_ext(spaces, u_ext_sln);
146 for (
unsigned j = 0; j < this->wf->get_neq(); j++)
148 fns.push_back(u_ext[j]);
149 u_ext[j]->set_quad_2d(&g_quad_2d_std);
154 this->wf->processFormMarkers(spaces);
157 template<
typename Scalar>
158 void DiscreteProblemThreadAssembler<Scalar>::init_funcs_memory_pool()
161 pj_thread_desc rtpdesc;
163 pj_bzero(rtpdesc,
sizeof(rtpdesc));
164 if (!pj_thread_is_registered())
165 pj_thread_register(NULL, rtpdesc, &thread);
167 this->FuncMemoryPool = pj_pool_create(&Hermes2DMemoryPoolCache.factory,
168 "pool-DiscreteProblemThreadAssembler",
173 this->FuncMemoryPool =
nullptr;
177 template<
typename Scalar>
178 void DiscreteProblemThreadAssembler<Scalar>::init_funcs_space()
180 this->funcs_space_initialized =
true;
183 for (
unsigned short space_i = 0; space_i < this->spaces_size; space_i++)
185 for (
unsigned int j = 0; j < H2D_MAX_LOCAL_BASIS_SIZE; j++)
186 this->funcs[space_i][j] = preallocate_fn<double>(this->FuncMemoryPool);
189 for (
unsigned int j = 0; j < H2D_MAX_LOCAL_BASIS_SIZE; j++)
190 this->funcsSurface[edge_i][space_i][j] = preallocate_fn<double>(this->FuncMemoryPool);
193 this->u_ext_funcs[space_i] = preallocate_fn<Scalar>(this->FuncMemoryPool);
197 template<
typename Scalar>
198 void DiscreteProblemThreadAssembler<Scalar>::init_funcs_wf()
200 this->funcs_wf_initialized =
true;
203 int ext_size = this->wf->ext.size();
204 int u_ext_fns_size = this->wf->u_ext_fn.size();
206 if (ext_size + u_ext_fns_size > ext_funcs_allocated_size)
208 ext_funcs_allocated_size = ext_size + u_ext_fns_size;
209 ext_funcs = realloc_with_check<DiscreteProblemThreadAssembler<Scalar>, Func<Scalar>*>(ext_funcs, ext_funcs_allocated_size,
this);
213 if (ext_size > 0 || u_ext_fns_size > 0)
215 for (
int ext_i = 0; ext_i < u_ext_fns_size; ext_i++)
216 this->ext_funcs[ext_i] = preallocate_fn<Scalar>(this->FuncMemoryPool);
218 for (
int ext_i = 0; ext_i < ext_size; ext_i++)
219 this->ext_funcs[u_ext_fns_size + ext_i] = preallocate_fn<Scalar>(this->FuncMemoryPool);
223 unsigned short local_ext_size = 0;
224 unsigned short local_u_ext_fns_size = 0;
225 for (
unsigned short form_i = 0; form_i < this->wf->forms.size(); form_i++)
227 if (this->wf->forms[form_i]->ext.size() > local_ext_size)
228 local_ext_size = this->wf->forms[form_i]->ext.size();
230 if (this->wf->forms[form_i]->u_ext_fn.size() > local_u_ext_fns_size)
231 local_u_ext_fns_size = this->wf->forms[form_i]->u_ext_fn.size();
234 if (local_ext_size > 0 || local_u_ext_fns_size > 0)
237 if (local_ext_size + local_u_ext_fns_size > ext_funcs_local_allocated_size)
239 ext_funcs_local_allocated_size = local_ext_size + local_u_ext_fns_size;
240 ext_funcs_local = realloc_with_check<DiscreteProblemThreadAssembler<Scalar>, Func<Scalar>*>(ext_funcs_local, ext_funcs_local_allocated_size,
this);
244 for (
int ext_i = 0; ext_i < local_u_ext_fns_size; ext_i++)
245 this->ext_funcs_local[ext_i] = preallocate_fn<Scalar>(this->FuncMemoryPool);
247 for (
int ext_i = 0; ext_i < local_ext_size; ext_i++)
248 this->ext_funcs_local[local_u_ext_fns_size + ext_i] = preallocate_fn<Scalar>(this->FuncMemoryPool);
252 template<
typename Scalar>
253 void DiscreteProblemThreadAssembler<Scalar>::deinit_funcs_space()
255 if (!funcs_space_initialized)
258 funcs_space_initialized =
false;
260 for (
unsigned short space_i = 0; space_i < this->spaces_size; space_i++)
263 for (
unsigned int j = 0; j < H2D_MAX_LOCAL_BASIS_SIZE; j++)
264 delete this->funcs[space_i][j];
269 for (
unsigned int j = 0; j < H2D_MAX_LOCAL_BASIS_SIZE; j++)
270 delete this->funcsSurface[edge_i][space_i][j];
275 delete this->u_ext_funcs[space_i];
279 template<
typename Scalar>
280 void DiscreteProblemThreadAssembler<Scalar>::deinit_funcs_wf()
282 if (!funcs_wf_initialized)
285 funcs_wf_initialized =
false;
288 int ext_size = this->wf->ext.size();
289 int u_ext_fns_size = this->wf->u_ext_fn.size();
290 if (ext_size > 0 || u_ext_fns_size > 0)
292 for (
int ext_i = 0; ext_i < u_ext_fns_size; ext_i++)
293 delete this->ext_funcs[ext_i];
295 for (
int ext_i = 0; ext_i < ext_size; ext_i++)
296 delete this->ext_funcs[u_ext_fns_size + ext_i];
300 unsigned short local_ext_size = 0;
301 unsigned short local_u_ext_fns_size = 0;
302 for (
unsigned short form_i = 0; form_i < this->wf->forms.size(); form_i++)
304 if (this->wf->forms[form_i]->ext.size() > local_ext_size)
305 local_ext_size = this->wf->forms[form_i]->ext.size();
307 if (this->wf->forms[form_i]->u_ext_fn.size() > local_u_ext_fns_size)
308 local_u_ext_fns_size = this->wf->forms[form_i]->u_ext_fn.size();
311 if (local_ext_size > 0 || local_u_ext_fns_size > 0)
313 for (
int ext_i = 0; ext_i < local_u_ext_fns_size; ext_i++)
314 delete this->ext_funcs_local[ext_i];
316 for (
int ext_i = 0; ext_i < local_ext_size; ext_i++)
317 delete this->ext_funcs_local[local_u_ext_fns_size + ext_i];
321 template<
typename Scalar>
322 void DiscreteProblemThreadAssembler<Scalar>::deinit_funcs()
324 this->deinit_funcs_wf();
325 this->deinit_funcs_space();
328 template<
typename Scalar>
329 void DiscreteProblemThreadAssembler<Scalar>::init_assembling_one_state(
const std::vector<SpaceSharedPtr<Scalar> >& spaces, Traverse::State* current_state_)
331 current_state = current_state_;
332 this->integrationOrderCalculator.current_state = this->current_state;
335 for (
unsigned short j = 0; j < fns.size(); j++)
337 if (current_state->e[j])
339 fns[j]->set_active_element(current_state->e[j]);
340 fns[j]->set_transform(current_state->sub_idx[j]);
345 for (
int j = 0; j < this->spaces_size; j++)
347 if (current_state->e[j])
349 spaces[j]->get_element_assembly_list(current_state->e[j], &als[j]);
350 refmaps[j]->set_active_element(current_state->e[j]);
351 refmaps[j]->force_transform(pss[j]->get_transform(), pss[j]->get_ctm());
352 rep_refmap = refmaps[j];
357 if (current_state->isBnd && !(this->wf->mfsurf.empty() && this->wf->vfsurf.empty()))
359 for (
int j = 0; j < this->spaces_size; j++)
361 if (current_state->e[j])
363 for (
int k = 0; k < current_state->rep->nvert; k++)
365 if (current_state->bnd[k])
366 spaces[j]->get_boundary_assembly_list(current_state->e[j], k, &alsSurface[k][j]);
373 this->order = this->integrationOrderCalculator.calculate_order(spaces, this->refmaps, this->wf);
376 this->init_calculation_variables();
379 template<
typename Scalar>
380 void DiscreteProblemThreadAssembler<Scalar>::init_calculation_variables()
382 for (
unsigned short space_i = 0; space_i < this->spaces_size; space_i++)
384 if (current_state->e[space_i] ==
nullptr)
387 for (
unsigned int j = 0; j < this->als[space_i].cnt; j++)
389 pss[space_i]->set_active_shape(this->als[space_i].idx[j]);
396 if (current_state->isBnd && (this->wf->mfsurf.size() > 0 || this->wf->vfsurf.size() > 0))
398 int order_local = this->order;
400 for (
unsigned int edge_i = 0; edge_i < this->current_state->rep->nvert; edge_i++)
402 if (!current_state->bnd[edge_i])
405 this->n_quadrature_pointsSurface[edge_i] = init_surface_geometry_points_allocated(this->rep_refmap, this->order, edge_i, current_state->rep->marker, this->geometrySurface[edge_i], this->jacobian_x_weightsSurface[edge_i]);
406 this->orderSurface[edge_i] = this->order;
407 this->order = order_local;
409 for (
unsigned short space_i = 0; space_i < this->spaces_size; space_i++)
411 if (!current_state->e[space_i])
414 for (
unsigned int j = 0; j < this->alsSurface[edge_i][space_i].cnt; j++)
416 pss[space_i]->set_active_shape(this->alsSurface[edge_i][space_i].idx[j]);
417 init_fn_preallocated(this->funcsSurface[edge_i][space_i][j], pss[space_i], refmaps[space_i], this->orderSurface[edge_i]);
424 template<
typename Scalar>
425 void DiscreteProblemThreadAssembler<Scalar>::deinit_calculation_variables()
429 template<
typename Scalar>
430 void DiscreteProblemThreadAssembler<Scalar>::init_u_ext_values(
int order)
434 for (
int i = 0; i < spaces_size; i++)
436 if (u_ext[i]->get_active_element())
442 template<
typename Scalar>
443 template<
typename Geom>
444 void DiscreteProblemThreadAssembler<Scalar>::init_ext_values(Func<Scalar>** target_array, std::vector<MeshFunctionSharedPtr<Scalar> >& ext, std::vector<UExtFunctionSharedPtr<Scalar> >& u_ext_fns,
int order, Func<Scalar>** u_ext_func, Geom* geometry)
446 int ext_size = ext.size();
447 int u_ext_fns_size = u_ext_fns.size();
449 if (ext_size > 0 || u_ext_fns_size > 0)
451 for (
int ext_i = 0; ext_i < ext_size; ext_i++)
455 if (ext[ext_i]->get_active_element())
460 for (
int ext_i = 0; ext_i < u_ext_fns_size; ext_i++)
462 if (u_ext_fns[ext_i])
463 init_fn_preallocated(target_array[ext_i], u_ext_fns[ext_i].
get(), target_array, u_ext_func, order, geometry, current_state->rep->get_mode());
467 if (this->rungeKutta)
469 for (
unsigned short ext_i = 0; ext_i < ext.size(); ext_i++)
470 u_ext_func[ext_i]->add(target_array[ext.size() - this->RK_original_spaces_count + ext_i]);
474 template<
typename Scalar>
475 void DiscreteProblemThreadAssembler<Scalar>::assemble_one_state()
478 this->init_u_ext_values(this->order);
481 this->init_ext_values(this->ext_funcs, this->wf->ext, this->wf->u_ext_fn, this->order, this->u_ext_funcs, &this->geometry);
483 if (this->current_mat || this->add_dirichlet_lift)
485 for (
unsigned short current_mfvol_i = 0; current_mfvol_i < this->wf->mfvol.size(); current_mfvol_i++)
487 if (!selectiveAssembler->form_to_be_assembled(this->wf->mfvol[current_mfvol_i], current_state))
490 int form_i = this->wf->mfvol[current_mfvol_i]->i;
491 int form_j = this->wf->mfvol[current_mfvol_i]->j;
493 this->assemble_matrix_form(this->wf->mfvol[current_mfvol_i], order, funcs[form_j], funcs[form_i], &als[form_i], &als[form_j], n_quadrature_points, &geometry, jacobian_x_weights);
496 if (this->current_rhs)
498 for (
unsigned short current_vfvol_i = 0; current_vfvol_i < this->wf->vfvol.size(); current_vfvol_i++)
500 if (!selectiveAssembler->form_to_be_assembled(this->wf->vfvol[current_vfvol_i], current_state))
503 int form_i = this->wf->vfvol[current_vfvol_i]->i;
505 this->assemble_vector_form(this->wf->vfvol[current_vfvol_i], order, funcs[form_i], &als[form_i], n_quadrature_points, &geometry, jacobian_x_weights);
510 if (current_state->isBnd && (this->wf->mfsurf.size() > 0 || this->wf->vfsurf.size() > 0))
512 for (
unsigned char isurf = 0; isurf < current_state->rep->nvert; isurf++)
514 if (!current_state->bnd[isurf])
517 current_state->isurf = isurf;
520 this->wf->set_active_edge_state(current_state->e, isurf);
523 this->init_u_ext_values(this->orderSurface[isurf]);
526 this->init_ext_values(this->ext_funcs, this->wf->ext, this->wf->u_ext_fn, this->orderSurface[isurf], this->u_ext_funcs, &this->geometrySurface[isurf]);
528 if (this->current_mat || this->add_dirichlet_lift)
530 for (
unsigned short current_mfsurf_i = 0; current_mfsurf_i < this->wf->mfsurf.size(); current_mfsurf_i++)
532 if (!selectiveAssembler->form_to_be_assembled(this->wf->mfsurf[current_mfsurf_i], current_state))
535 int form_i = this->wf->mfsurf[current_mfsurf_i]->i;
536 int form_j = this->wf->mfsurf[current_mfsurf_i]->j;
538 this->assemble_matrix_form(this->wf->mfsurf[current_mfsurf_i], orderSurface[isurf], funcsSurface[isurf][form_j], funcsSurface[isurf][form_i],
539 &alsSurface[isurf][form_i], &alsSurface[isurf][form_j], n_quadrature_pointsSurface[isurf], &geometrySurface[isurf], jacobian_x_weightsSurface[isurf]);
543 if (this->current_rhs)
545 for (
unsigned short current_vfsurf_i = 0; current_vfsurf_i < this->wf->vfsurf.size(); current_vfsurf_i++)
547 if (!selectiveAssembler->form_to_be_assembled(this->wf->vfsurf[current_vfsurf_i], current_state))
550 int form_i = this->wf->vfsurf[current_vfsurf_i]->i;
552 this->assemble_vector_form(this->wf->vfsurf[current_vfsurf_i], orderSurface[isurf], funcsSurface[isurf][form_i], &alsSurface[isurf][form_i],
553 n_quadrature_pointsSurface[isurf], &geometrySurface[isurf], jacobian_x_weightsSurface[isurf]);
560 template<
typename Scalar>
561 template<
typename MatrixFormType,
typename Geom>
562 void DiscreteProblemThreadAssembler<Scalar>::assemble_matrix_form(MatrixFormType* form,
int order, Func<double>** base_fns, Func<double>** test_fns,
563 AsmList<Scalar>* current_als_i, AsmList<Scalar>* current_als_j,
int n_quadrature_points, Geom* geometry,
double* jacobian_x_weights)
565 bool surface_form = (
dynamic_cast<MatrixFormVol<Scalar>*
>(form) ==
nullptr);
567 double block_scaling_coefficient = this->block_scaling_coeff(form);
569 bool tra = (form->i != form->j) && (form->sym != 0);
570 bool sym = (form->i == form->j) && (form->sym == 1);
572 Func<Scalar>** ext_local = this->ext_funcs;
574 if (form->ext.size() > 0 || form->u_ext_fn.size() > 0)
576 this->init_ext_values(this->ext_funcs_local, form->ext, (form->u_ext_fn.size() > 0 ? form->u_ext_fn : this->wf->u_ext_fn), order, this->u_ext_funcs, geometry);
577 ext_local = this->ext_funcs_local;
581 Func<Scalar>** u_ext_local = this->u_ext_funcs;
582 if (this->rungeKutta)
583 u_ext_local += form->u_ext_offset;
586 for (
unsigned int i = 0; i < current_als_i->cnt; i++)
588 if (current_als_i->dof[i] < 0 || std::abs(current_als_i->coef[i]) < Hermes::HermesSqrtEpsilon)
591 if ((!tra || surface_form) && current_als_i->dof[i] < 0)
594 for (
unsigned int j = 0; j < current_als_j->cnt; j++)
596 if (current_als_j->dof[j] >= 0 && this->reusable_DOFs && *this->reusable_DOFs)
598 if ((*this->reusable_DOFs)[current_als_j->dof[j]] && (*this->reusable_DOFs)[current_als_i->dof[i]])
600 unsigned short local_matrix_index_array = i * H2D_MAX_LOCAL_BASIS_SIZE + j;
601 local_stiffness_matrix[local_matrix_index_array] = 0.;
604 unsigned short local_matrix_index_array_transposed = j * H2D_MAX_LOCAL_BASIS_SIZE + i;
605 local_stiffness_matrix[local_matrix_index_array_transposed] = 0.;
611 if (current_als_j->dof[j] < 0 && this->reusable_Dirichlet && *this->reusable_Dirichlet && (*this->reusable_Dirichlet)[form->j])
617 if (sym && j < i && current_als_j->dof[j] >= 0)
621 if (current_als_j->dof[j] >= 0 && !this->current_mat)
624 if (std::abs(current_als_j->coef[j]) < Hermes::HermesEpsilon)
627 Func<double>* u = base_fns[j];
628 Func<double>* v = test_fns[i];
630 Scalar val = block_scaling_coefficient * form->value(n_quadrature_points, jacobian_x_weights, u_ext_local, u, v, geometry, ext_local) * form->scaling_factor * current_als_j->coef[j] * current_als_i->coef[i];
632 if (current_als_j->dof[j] >= 0)
634 unsigned short local_matrix_index_array = i * H2D_MAX_LOCAL_BASIS_SIZE + j;
637 local_stiffness_matrix[local_matrix_index_array] = 0.5 * val;
639 local_stiffness_matrix[local_matrix_index_array] = val;
643 unsigned short local_matrix_index_array_transposed = j * H2D_MAX_LOCAL_BASIS_SIZE + i;
644 local_stiffness_matrix[local_matrix_index_array_transposed] = local_stiffness_matrix[local_matrix_index_array];
647 else if (this->add_dirichlet_lift && this->current_rhs)
649 this->dirichlet_lift_rhs->add(current_als_i->dof[i], -val);
655 if (this->current_mat)
656 this->current_mat->add(current_als_i->cnt, current_als_j->cnt, local_stiffness_matrix, current_als_i->dof, current_als_j->dof, H2D_MAX_LOCAL_BASIS_SIZE);
662 change_sign(local_stiffness_matrix, current_als_i->cnt, current_als_j->cnt, H2D_MAX_LOCAL_BASIS_SIZE);
663 transpose(local_stiffness_matrix, current_als_i->cnt, current_als_j->cnt, H2D_MAX_LOCAL_BASIS_SIZE);
665 if (this->current_mat)
666 this->current_mat->add(current_als_j->cnt, current_als_i->cnt, local_stiffness_matrix, current_als_j->dof, current_als_i->dof, H2D_MAX_LOCAL_BASIS_SIZE);
668 if (this->add_dirichlet_lift && this->current_rhs)
670 for (
unsigned int j = 0; j < current_als_i->cnt; j++)
672 if (current_als_i->dof[j] < 0)
674 for (
unsigned int i = 0; i < current_als_j->cnt; i++)
676 if (current_als_j->dof[i] >= 0)
678 int local_matrix_index_array = i * H2D_MAX_LOCAL_BASIS_SIZE + j;
679 this->dirichlet_lift_rhs->add(current_als_j->dof[i], -local_stiffness_matrix[local_matrix_index_array]);
688 template<
typename Scalar>
689 template<
typename VectorFormType,
typename Geom>
690 void DiscreteProblemThreadAssembler<Scalar>::assemble_vector_form(VectorFormType* form,
int order, Func<double>** test_fns,
691 AsmList<Scalar>* current_als_i,
int n_quadrature_points, Geom* geometry,
double* jacobian_x_weights)
693 bool surface_form = (
dynamic_cast<VectorFormVol<Scalar>*
>(form) ==
nullptr);
695 Func<Scalar>** ext_local = this->ext_funcs;
697 if (form->ext.size() > 0 || form->u_ext_fn.size() > 0)
699 this->init_ext_values(this->ext_funcs_local, form->ext, (form->u_ext_fn.size() > 0 ? form->u_ext_fn : this->wf->u_ext_fn), order, this->u_ext_funcs, geometry);
700 ext_local = this->ext_funcs_local;
704 Func<Scalar>** u_ext_local = this->u_ext_funcs;
705 if (this->rungeKutta)
706 u_ext_local += form->u_ext_offset;
709 for (
unsigned int i = 0; i < current_als_i->cnt; i++)
711 if (current_als_i->dof[i] < 0)
714 if (this->reusable_DOFs && *this->reusable_DOFs)
716 if ((*this->reusable_DOFs)[current_als_i->dof[i]])
721 if (std::abs(current_als_i->coef[i]) < Hermes::HermesSqrtEpsilon)
724 Func<double>* v = test_fns[i];
728 val = 0.5 * form->value(n_quadrature_points, jacobian_x_weights, u_ext_local, v, geometry, ext_local) * form->scaling_factor * current_als_i->coef[i];
730 val = form->value(n_quadrature_points, jacobian_x_weights, u_ext_local, v, geometry, ext_local) * form->scaling_factor * current_als_i->coef[i];
732 this->current_rhs->add(current_als_i->dof[i], val);
736 template<
typename Scalar>
737 void DiscreteProblemThreadAssembler<Scalar>::deinit_assembling_one_state()
739 this->deinit_calculation_variables();
742 template<
typename Scalar>
743 void DiscreteProblemThreadAssembler<Scalar>::deinit_assembling()
747 template<
typename Scalar>
750 this->deinit_funcs();
752 this->free_weak_formulation();
755 free_with_check(ext_funcs,
true);
756 free_with_check(ext_funcs_local,
true);
759 template<
typename Scalar>
765 for (
unsigned int j = 0; j < spaces_size; j++)
767 free_with_check(pss);
769 for (
unsigned int j = 0; j < spaces_size; j++)
771 free_with_check(refmaps);
774 template<
typename Scalar>
775 void DiscreteProblemThreadAssembler<Scalar>::free_weak_formulation()
778 this->wf->free_ext();
781 template<
typename Scalar>
782 void DiscreteProblemThreadAssembler<Scalar>::free_u_ext()
786 for (
unsigned int j = 0; j < spaces_size; j++)
788 free_with_check(u_ext);
792 template class HERMES_API DiscreteProblemThreadAssembler < double > ;
793 template class HERMES_API DiscreteProblemThreadAssembler < std::complex<double> > ;
#define H2D_MAX_NUMBER_EDGES
A maximum number of edges of an element.
HERMES_API void init_fn_preallocated(Func< double > *u, PrecalcShapeset *fu, RefMap *rm, const int order)
Init the shape function for the evaluation of the volumetric/surface integral (transformation of valu...
void free()
Free all data.
This class is a one-thread (non-DG) assembly worker.
HERMES_API unsigned char init_geometry_points_allocated(RefMap **reference_mapping, unsigned short reference_mapping_count, int order, GeomVol< double > &geometry, double *jacobian_x_weights)