ExcIndexRange(child,0,GeometryInfo<dim>::n_children(refinement_case)));
// initialization upon first request
- Threads::Mutex::ScopedLock lock(this->mutex);
if (this->prolongation[refinement_case-1][child].n() == 0)
{
+ Threads::Mutex::ScopedLock lock(this->mutex);
+
+ // if matrix got updated while waiting for the lock
+ if (this->prolongation[refinement_case-1][child].n() ==
+ this->dofs_per_cell)
+ return this->prolongation[refinement_case-1][child];
+
// distinguish q/q_dg0 case: only treat Q dofs first
const unsigned int q_dofs_per_cell = Utilities::fixed_power<dim>(this->degree+1);
}
}
- FullMatrix<double>& prolongate = const_cast<FullMatrix<double>&>
- (this->prolongation[refinement_case-1][child]);
- prolongate.reinit(this->dofs_per_cell, this->dofs_per_cell);
+ FullMatrix<double> prolongate (this->dofs_per_cell, this->dofs_per_cell);
// go through the points in diagonal to capture variation in all
// directions simultaneously
Assert (std::fabs(sum-1.) < eps, ExcInternalError());
}
#endif
+
+ // swap matrices
+ std::swap(const_cast<FullMatrix<double> &>
+ (this->prolongation[refinement_case-1][child]), prolongate);
}
// finally return the matrix
ExcIndexRange(child,0,GeometryInfo<dim>::n_children(refinement_case)));
// initialization upon first request
- Threads::Mutex::ScopedLock lock(this->mutex);
if (this->restriction[refinement_case-1][child].n() == 0)
{
- FullMatrix<double> &restriction =
- const_cast<FullMatrix<double> &>(this->restriction[refinement_case-1][child]);
+ Threads::Mutex::ScopedLock lock(this->mutex);
+
+ // if matrix got updated while waiting for the lock...
+ if (this->restriction[refinement_case-1][child].n() ==
+ this->dofs_per_cell)
+ return this->restriction[refinement_case-1][child];
+ FullMatrix<double> restriction(this->dofs_per_cell, this->dofs_per_cell);
// distinguish q/q_dg0 case
const unsigned int q_dofs_per_cell = Utilities::fixed_power<dim>(this->degree+1);
restriction(this->dofs_per_cell-1,this->dofs_per_cell-1) =
1./GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case));
}
+
+ // swap matrices
+ std::swap(const_cast<FullMatrix<double> &>
+ (this->restriction[refinement_case-1][child]), restriction);
+
}
+
return this->restriction[refinement_case-1][child];
}
Threads::Mutex::ScopedLock lock(this->mutex);
if (this->restriction[refinement_case-1][child].n() == 0)
{
+ Threads::Mutex::ScopedLock lock(this->mutex);
+
+ // check if updated while waiting for lock
+ if (this->restriction[refinement_case-1][child].n() ==
+ this->dofs_per_cell)
+ return this->restriction[refinement_case-1][child];
+
// Check if some of the matrices of the base elements are void.
bool do_restriction = true;
// if we did not encounter void matrices, initialize the matrix sizes
if (do_restriction)
{
- FullMatrix<double> &restriction =
- const_cast<FullMatrix<double>&>(this->restriction[refinement_case-1]
- [child]);
- restriction.reinit(this->dofs_per_cell, this->dofs_per_cell);
+ FullMatrix<double> restriction(this->dofs_per_cell,
+ this->dofs_per_cell);
// distribute the matrices of the base finite elements to the
// matrices of this object. for this, loop over all degrees of
// entries of the matrices:
restriction(i,j) = (*base_matrices[base])(base_index_i,base_index_j);
}
+
+ std::swap(restriction, const_cast<FullMatrix<double> &>
+ (this->restriction[refinement_case-1][child]));
}
}
Assert (child<GeometryInfo<dim>::n_children(refinement_case),
ExcIndexRange(child,0,GeometryInfo<dim>::n_children(refinement_case)));
- // initialization upon first request
- Threads::Mutex::ScopedLock lock(this->mutex);
+ // initialization upon first request, construction completely analogous to
+ // restriction matrix
if (this->prolongation[refinement_case-1][child].n() == 0)
{
- // Check if some of the matrices of the base elements are void.
- bool do_prolongation = true;
+ Threads::Mutex::ScopedLock lock(this->mutex);
+
+ if (this->prolongation[refinement_case-1][child].n() ==
+ this->dofs_per_cell)
+ return this->prolongation[refinement_case-1][child];
- // shortcut for accessing local prolongations further down
+ bool do_prolongation = true;
std::vector<const FullMatrix<double> *>
base_matrices(this->n_base_elements());
-
for (unsigned int i=0; i<this->n_base_elements(); ++i)
{
base_matrices[i] =
Assert(do_prolongation,
(typename FiniteElement<dim,spacedim>::ExcEmbeddingVoid()));
-
if (do_prolongation)
{
- FullMatrix<double> &prolongate =
- const_cast<FullMatrix<double> &>(this->prolongation[refinement_case-1][child]);
- prolongate.reinit(this->dofs_per_cell, this->dofs_per_cell);
+ FullMatrix<double> prolongate (this->dofs_per_cell,
+ this->dofs_per_cell);
- // distribute the matrices of the base finite elements to the
- // matrices of this object. for this, loop over all degrees of
- // freedom and take the respective entry of the underlying base
- // element.
- //
- // note that we by definition of a base element, they are
- // independent, i.e. do not couple. only DoFs that belong to the
- // same instance of a base element may couple
for (unsigned int i=0; i<this->dofs_per_cell; ++i)
for (unsigned int j=0; j<this->dofs_per_cell; ++j)
{
- // first find out to which base element indices i and j
- // belong, and which instance thereof in case the base element
- // has a multiplicity greater than one. if they should not
- // happen to belong to the same instance of a base element,
- // then they cannot couple, so go on with the next index
if (this->system_to_base_table[i].first !=
this->system_to_base_table[j].first)
continue;
-
- // so get the common base element and the indices therein:
const unsigned int
base = this->system_to_base_table[i].first.first;
const unsigned int
base_index_i = this->system_to_base_table[i].second,
base_index_j = this->system_to_base_table[j].second;
-
- // if we are sure that DoFs i and j may couple, then copy
- // entries of the matrices:
prolongate(i,j) = (*base_matrices[base])(base_index_i,base_index_j);
}
+ std::swap(prolongate, const_cast<FullMatrix<double> &>
+ (this->prolongation[refinement_case-1][child]));
}
}