16 #include "discrete_problem/discrete_problem_selective_assembler.h"
17 #include "neighbor_search.h"
23 template<
typename Scalar>
24 DiscreteProblemSelectiveAssembler<Scalar>::DiscreteProblemSelectiveAssembler()
27 matrix_structure_reusable(false),
28 previous_mat(nullptr),
29 vector_structure_reusable(false),
34 template<
typename Scalar>
35 DiscreteProblemSelectiveAssembler<Scalar>::~DiscreteProblemSelectiveAssembler()
41 template<
typename Scalar>
46 if (matrix_structure_reusable && mat && mat == this->previous_mat)
49 if (vector_structure_reusable && rhs && rhs == this->previous_rhs)
51 if (rhs->get_size() == 0)
57 if ((!matrix_structure_reusable || (mat != this->previous_mat)) && mat)
60 matrix_structure_reusable =
true;
66 unsigned int cnts_m, cnts_n;
67 bool **blocks = this->wf->get_blocks(this->force_diagonal_blocks);
71 for (
unsigned int state_i = 0; state_i < num_states; state_i++)
77 for (
unsigned int i = 0; i < spaces_size; i++)
79 if (current_state->e[i])
80 spaces[i]->get_element_assembly_list(current_state->e[i], &(al[i]));
82 if (this->wf->is_DG() && !this->wf->mfDG.empty())
85 int num_edges = current_state->e[0]->
nvert;
89 for (
unsigned int i = 0; i < spaces_size; i++)
90 neighbor_elems_arrays[i] =
new Element **[num_edges];
93 int ** neighbor_elems_counts =
new int *[spaces_size];
94 for (
unsigned int i = 0; i < spaces_size; i++)
95 neighbor_elems_counts[i] =
new int[num_edges];
98 for (
unsigned int el = 0; el < spaces_size; el++)
102 for (
int ed = 0; ed < num_edges; ed++)
104 if (current_state->e[el]->
en[ed]->
bnd)
108 const std::vector<Element *> *neighbors = ns.get_neighbors();
110 neighbor_elems_counts[el][ed] = ns.get_num_neighbors();
111 neighbor_elems_arrays[el][ed] =
new Element *[neighbor_elems_counts[el][ed]];
112 for (
int neigh = 0; neigh < neighbor_elems_counts[el][ed]; neigh++)
113 neighbor_elems_arrays[el][ed][neigh] = (*neighbors)[neigh];
118 for (
unsigned int m = 0; m < spaces_size; m++)
120 for (
unsigned int el = 0; el < spaces_size; el++)
122 for (
int ed = 0; ed < num_edges; ed++)
124 if (current_state->e[el]->
en[ed]->
bnd)
127 for (
int neigh = 0; neigh < neighbor_elems_counts[el][ed]; neigh++)
129 if ((blocks[m][el] || blocks[el][m]) && current_state->e[m])
133 spaces[el]->get_element_assembly_list(neighbor_elems_arrays[el][ed][neigh], an);
137 for (
unsigned int i = 0; i < am->
cnt; i++)
141 for (
unsigned int j = 0; j < an->
cnt; j++)
145 if (blocks[m][el]) mat->pre_add_ij(am->
dof[i], an->
dof[j]);
146 if (blocks[el][m]) mat->pre_add_ij(an->
dof[j], am->
dof[i]);
160 for (
unsigned int el = 0; el < spaces_size; el++)
162 for (
int ed = 0; ed < num_edges; ed++)
164 if (!current_state->e[el]->
en[ed]->
bnd)
165 delete[] neighbor_elems_arrays[el][ed];
167 delete[] neighbor_elems_arrays[el];
169 delete[] neighbor_elems_arrays;
172 for (
unsigned int el = 0; el < spaces_size; el++)
173 delete[] neighbor_elems_counts[el];
174 delete[] neighbor_elems_counts;
178 if (spaces_size == 1)
182 if (blocks[0][0] && current_state->e[0])
184 for (
unsigned int i = 0; i < cnts_m; i++)
188 for (
unsigned int j = 0; j < cnts_m; j++)
190 mat->pre_add_ij(dofs_m[i], dofs_m[j]);
197 for (
unsigned int m = 0; m < spaces_size; m++)
201 for (
unsigned int n = 0; n < spaces_size; n++)
203 if (blocks[m][n] && current_state->e[m] && current_state->e[n])
209 for (
unsigned int i = 0; i < cnts_m; i++)
212 for (
unsigned int j = 0; j < cnts_n; j++)
214 mat->pre_add_ij(dofs_m[i], dofs_n[j]);
222 this->info(
"\tDiscreteProblemSelectiveAssembler: Loop: %s.", this->last_str().c_str());
227 free_with_check(blocks,
true);
231 this->info(
"\tDiscreteProblemSelectiveAssembler: Finish: %s.", this->last_str().c_str());
236 if ((!vector_structure_reusable || (rhs != this->previous_rhs)) && rhs)
238 vector_structure_reusable =
true;
247 template<
typename Scalar>
253 this->spaces_size = spacesToSet.size();
254 sp_seq =
new int[spaces_size];
255 memset(sp_seq, -1,
sizeof(
int)* spaces_size);
259 for (
unsigned int i = 0; i < spaces_size; i++)
261 int new_sp_seq = spacesToSet[i]->get_seq();
263 if (new_sp_seq != sp_seq[i])
265 matrix_structure_reusable =
false;
266 vector_structure_reusable =
false;
268 sp_seq[i] = new_sp_seq;
273 template<
typename Scalar>
278 this->matrix_structure_reusable =
false;
279 this->vector_structure_reusable =
false;
281 if (spaces_size == 0)
285 template<
typename Scalar>
288 if (current_state->e[form->i] && current_state->e[form->j])
290 if (fabs(form->scaling_factor) < Hermes::HermesSqrtEpsilon)
295 if (this->block_weights)
296 if (fabs(this->block_weights->get_A(form->i / this->RK_original_spaces_count, form->j / this->RK_original_spaces_count)) < Hermes::HermesSqrtEpsilon)
303 template<
typename Scalar>
312 int this_marker = current_state->rep->
marker;
320 template<
typename Scalar>
326 if (current_state->rep->
en[current_state->isurf]->
marker == 0)
332 int this_marker = current_state->rep->
en[current_state->isurf]->
marker;
340 template<
typename Scalar>
346 template<
typename Scalar>
349 if (!current_state->e[form->i])
351 if (fabs(form->scaling_factor) < Hermes::HermesSqrtEpsilon)
357 template<
typename Scalar>
366 int this_marker = current_state->rep->
marker;
374 template<
typename Scalar>
380 if (current_state->rep->
en[current_state->isurf]->
marker == 0)
386 int this_marker = current_state->rep->
en[current_state->isurf]->
marker;
394 template<
typename Scalar>
bool prepare_sparse_structure(SparseMatrix< Scalar > *mat, Vector< Scalar > *rhs, std::vector< SpaceSharedPtr< Scalar > > spaces, Traverse::State **&states, unsigned int &num_states)
Stores one element of a mesh.
Provides capabilities to (re-)assemble a matrix / vector only where necessary. See also Solver::keep_...
Used to pass the instances of Space around.
int dof[H2D_MAX_LOCAL_BASIS_SIZE]
array of basis function numbers (DOFs)
unsigned char nvert
number of vertices (3 or 4)
int get_num_dofs() const
Returns the number of basis functions contained in the space.
Node * en[H2D_MAX_NUMBER_EDGES]
edge node pointers
unsigned short cnt
the number of items in the arrays idx, dof and coef
unsigned bnd
1 = boundary node; 0 = inner node
This class characterizes a neighborhood of a given edge in terms of adjacent elements and provides me...
void set_weak_formulation(WeakFormSharedPtr< Scalar > wf)
Set the weak forms.
bool form_to_be_assembled(MatrixForm< Scalar > *form, Traverse::State *current_state)
Decides if the form will be assembled on this State.
void set_active_edge(int edge)
void set_spaces(std::vector< SpaceSharedPtr< Scalar > > spaces)
Sets new_ spaces for the instance.