16 #include "discrete_problem_linear.h"
20 #include "integrals/h1.h"
21 #include "quadrature/limit_order.h"
22 #include "mesh/traverse.h"
23 #include "space/space.h"
24 #include "shapeset/precalc.h"
25 #include "mesh/refmap.h"
26 #include "function/solution.h"
30 using namespace Hermes::Algebra::DenseMatrixOperations;
36 template<
typename Scalar>
42 template<
typename Scalar>
48 template<
typename Scalar>
54 template<
typename Scalar>
59 template<
typename Scalar>
62 bool force_diagonal_blocks,
68 throw Exceptions::Exception(
"Zero DOFs detected in DiscreteProblemLinear::assemble().");
71 this->caughtException = NULL;
73 this->current_mat = mat;
74 this->current_rhs = rhs;
75 this->current_force_diagonal_blocks = force_diagonal_blocks;
76 this->current_block_weights = block_weights;
79 if(block_weights != NULL)
80 if(block_weights->get_size() != this->wf->get_neq())
81 throw Exceptions::LengthException(6, block_weights->get_size(),this-> wf->get_neq());
84 this->create_sparse_structure();
87 for(
unsigned int ext_i = 0; ext_i < this->wf->get_ext().size(); ext_i++)
89 if(!this->wf->get_ext()[ext_i]->isOkay())
90 throw Hermes::Exceptions::Exception(
"Ext function %d is not okay in assemble().", ext_i);
101 this->init_assembling(NULL, pss, spss, refmaps, NULL, als, weakforms);
104 Hermes::vector<const Mesh*> meshes;
105 for(
unsigned int space_i = 0; space_i < this->spaces.size(); space_i++)
106 meshes.push_back(this->spaces[space_i]->get_mesh());
107 for(
unsigned int ext_i = 0; ext_i < this->wf->ext.size(); ext_i++)
108 meshes.push_back(this->wf->ext[ext_i]->get_mesh());
109 for(
unsigned int form_i = 0; form_i < this->wf->get_forms().size(); form_i++)
110 for(
unsigned int ext_i = 0; ext_i < this->wf->get_forms()[form_i]->ext.size(); ext_i++)
111 if(this->wf->get_forms()[form_i]->ext[ext_i] != NULL)
112 meshes.push_back(this->wf->get_forms()[form_i]->ext[ext_i]->get_mesh());
115 unsigned int num_states = trav_master.get_num_states(meshes);
117 trav_master.begin(meshes.size(), &(meshes.front()));
120 Hermes::vector<Transformable *>* fns =
new Hermes::vector<Transformable *>[
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads)];
121 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
123 for (
unsigned j = 0; j < this->spaces.size(); j++)
124 fns[i].push_back(pss[i][j]);
125 for (
unsigned j = 0; j < this->wf->ext.size(); j++)
127 fns[i].push_back(weakforms[i]->ext[j]);
128 weakforms[i]->
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 for(
unsigned int ext_i = 0; ext_i < this->wf->get_forms()[form_i]->ext.size(); ext_i++)
133 if(this->wf->get_forms()[form_i]->ext[ext_i] != NULL)
135 fns[i].push_back(weakforms[i]->get_forms()[form_i]->ext[ext_i]);
136 weakforms[i]->get_forms()[form_i]->ext[ext_i]->set_quad_2d(&g_quad_2d_std);
139 trav[i].begin(meshes.size(), &(meshes.front()), &(fns[i].front()));
140 trav[i].stack = trav_master.stack;
152 int num_threads_used =
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads);
153 #pragma omp parallel shared(trav_master, mat, rhs ) private(state_i, current_pss, current_spss, current_refmaps, current_als, current_weakform) num_threads(num_threads_used)
155 #pragma omp for schedule(dynamic, CHUNKSIZE)
156 for(state_i = 0; state_i < num_states; state_i++)
160 Traverse::State current_state;
162 #pragma omp critical (get_next_state)
163 current_state = trav[omp_get_thread_num()].get_next_state(&trav_master.top, &trav_master.id);
165 current_pss = pss[omp_get_thread_num()];
166 current_spss = spss[omp_get_thread_num()];
167 current_refmaps = refmaps[omp_get_thread_num()];
168 current_als = als[omp_get_thread_num()];
169 current_weakform = weakforms[omp_get_thread_num()];
177 this->assemble_one_state(current_pss, current_spss, current_refmaps, NULL, current_als, ¤t_state, current_weakform);
179 if(this->DG_matrix_forms_present || this->DG_vector_forms_present)
180 this->assemble_one_DG_state(current_pss, current_spss, current_refmaps, NULL, current_als, ¤t_state, current_weakform->
mfDG, current_weakform->
vfDG, trav[omp_get_thread_num()].fn);
182 catch(Hermes::Exceptions::Exception& e)
184 if(this->caughtException == NULL)
185 this->caughtException = e.clone();
189 if(this->caughtException == NULL)
190 this->caughtException =
new Hermes::Exceptions::Exception(e.what());
195 this->deinit_assembling(pss, spss, refmaps, NULL, als, weakforms);
197 trav_master.finish();
198 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
201 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
209 if(this->current_mat != NULL)
210 this->current_mat->finish();
211 if(this->current_rhs != NULL)
212 this->current_rhs->finish();
214 if(this->DG_matrix_forms_present || this->DG_vector_forms_present)
216 Element* element_to_set_nonvisited;
217 for(
unsigned int mesh_i = 0; mesh_i < meshes.size(); mesh_i++)
218 for_all_elements(element_to_set_nonvisited, meshes[mesh_i])
219 element_to_set_nonvisited->
visited =
false;
222 if(this->caughtException != NULL)
223 throw *(this->caughtException);
226 template<
typename Scalar>
232 double block_scaling_coefficient = this->block_scaling_coeff(form);
234 bool tra = (form->i != form->j) && (form->sym != 0);
235 bool sym = (form->i == form->j) && (form->sym == 1);
238 Scalar **local_stiffness_matrix = new_matrix<Scalar>(std::max(current_als_i->cnt, current_als_j->cnt));
242 if(form->
ext.size() > 0)
244 int local_ext_count = form->
ext.size();
246 for(
int ext_i = 0; ext_i < local_ext_count; ext_i++)
247 if(form->
ext[ext_i] != NULL)
248 local_ext[ext_i] = current_state->e[ext_i] == NULL ? NULL :
init_fn(form->
ext[ext_i], order);
250 local_ext[ext_i] = NULL;
254 for (
unsigned int i = 0; i < current_als_i->cnt; i++)
256 if(current_als_i->dof[i] < 0)
259 if((!tra || surface_form) && current_als_i->dof[i] < 0)
261 if(std::abs(current_als_i->coef[i]) < 1e-12)
265 for (
unsigned int j = 0; j < current_als_j->cnt; j++)
268 if(std::abs(current_als_j->coef[j]) < 1e-12)
274 if(current_als_j->dof[j] >= 0)
277 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];
279 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];
285 this->current_rhs->add(current_als_i->dof[i], -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]);
287 this->current_rhs->add(current_als_i->dof[i], -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]);
295 for (
unsigned int j = 0; j < current_als_j->cnt; j++)
297 if(j < i && current_als_j->dof[j] >= 0)
300 if(std::abs(current_als_j->coef[j]) < 1e-12)
306 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];
308 if(current_als_j->dof[j] >= 0)
309 local_stiffness_matrix[i][j] = local_stiffness_matrix[j][i] = val;
312 this->current_rhs->add(current_als_i->dof[i], -val);
319 this->current_mat->add(current_als_i->cnt, current_als_j->cnt, local_stiffness_matrix, current_als_i->dof, current_als_j->dof);
325 chsgn(local_stiffness_matrix, current_als_i->cnt, current_als_j->cnt);
326 transpose(local_stiffness_matrix, current_als_i->cnt, current_als_j->cnt);
328 this->current_mat->add(current_als_j->cnt, current_als_i->cnt, local_stiffness_matrix, current_als_j->dof, current_als_i->dof);
331 for (
unsigned int j = 0; j < current_als_i->cnt; j++)
332 if(current_als_i->dof[j] < 0)
333 for (
unsigned int i = 0; i < current_als_j->cnt; i++)
334 if(current_als_j->dof[i] >= 0)
335 this->current_rhs->add(current_als_j->dof[i], -local_stiffness_matrix[i][j]);
338 if(form->
ext.size() > 0)
340 for(
int ext_i = 0; ext_i < form->
ext.size(); ext_i++)
341 if(form->
ext[ext_i] != NULL)
343 local_ext[ext_i]->free_fn();
344 delete local_ext[ext_i];
350 delete [] local_stiffness_matrix;