42 namespace Electromagnetism{
55 template <
typename TDomain,
typename TAlgebra,
typename TElem>
71 ((
MultiGrid *) mg)->associated_elements (vrts, parent);
72 size_t n_co = vrts.
size ();
73 UG_ASSERT (n_co != 0,
"GetRegularLocalCoordinate: No associated vertices.")
80 for (
size_t co = 0; co < n_co; co++)
84 UG_THROW (
"GetRegularLocalCoordinate: No (implicit) parent-child relation between the vertex and the base element.");
85 local += rRefElem.corner (i);
100 template <
typename TDomain,
typename TAlgebra>
107 std::vector<bool> & vIsRestricted
113 std::vector<DoFIndex> c_ind (1), f_ind (1);
119 size_t num_fct = coarseDD.
num_fct ();
120 UG_ASSERT (num_fct == fineDD.
num_fct (),
"NedelecTransfer: Coarse and find DD mismatch.");
123 for (
int si = 0; si < coarseDD.
num_subsets (); si++)
126 iterator e_end = coarseDD.template end<RegularEdge> (si);
127 for (iterator edge_iter = coarseDD.template begin<RegularEdge> (si);
128 edge_iter != e_end; ++edge_iter)
131 Edge * c_edge = * edge_iter;
132 const size_t n_children =
grid->num_children<
Edge,
Edge> (c_edge);
136 else if (n_children == 1)
142 if (corner_0 == (
GridObject *) (c_edge->vertex (0)))
144 else if (corner_0 == (
GridObject *) (c_edge->vertex (1)))
147 UG_THROW (
"NedelecTransfer: Cannot find out the edge orientation.");
150 for (
size_t fct = 0; fct < num_fct; fct++)
156 "More than one DoF per edge. Not the Nedelec-type-1 element?");
158 DoFRef (mat, f_ind[0], c_ind[0]) += coef;
159 vIsRestricted [c_ind[0][0]] =
true;
162 else if (n_children == 2)
164 for (
size_t child = 0; child < 2; child++)
171 if (corner_0 == (
GridObject *) (c_edge->vertex (0))
172 || corner_1 == (
GridObject *) (c_edge->vertex (1)))
174 else if (corner_0 == (
GridObject *) (c_edge->vertex (1))
175 || corner_1 == (
GridObject *) (c_edge->vertex (0)))
178 UG_THROW (
"NedelecTransfer: Cannot find out the edge orientation.");
181 for (
size_t fct = 0; fct < num_fct; fct++)
187 "More than one DoF per edge. Not the Nedelec-type-1 element?");
189 DoFRef (mat, f_ind[0], c_ind[0]) += coef;
190 vIsRestricted [c_ind[0][0]] =
true;
195 UG_THROW (
"NedelecTransfer: Only regular refinement is supported,"
196 " but some edge is subdivided into " << n_children <<
" ones.");
207 template <
typename TDomain,
typename TAlgebra,
typename TElem>
214 std::vector<bool> & vIsRestricted
221 std::vector<DoFIndex> c_ind (ref_elem_type::numEdges), f_ind (1);
230 size_t num_fct = coarseDD.
num_fct ();
231 UG_ASSERT (num_fct == fineDD.
num_fct (),
"NedelecTransfer: Coarse and find DD mismatch.");
234 for (
int si = 0; si < coarseDD.
num_subsets (); si++)
237 iterator e_end = coarseDD.template end<TElem> (si);
238 for (iterator elem_iter = coarseDD.template begin<TElem> (si);
239 elem_iter != e_end; ++elem_iter)
241 TElem * c_elem = * elem_iter;
242 const size_t n_children =
grid->num_children<
Edge, TElem> (c_elem);
249 for (
size_t co = 0; co < (size_t) ref_elem_type::numCorners; co++)
250 aCorners [co] = aaPos [c_elem->vertex (co)];
253 for (
size_t child = 0; child < n_children; child++)
256 Edge * edge =
grid->get_child<
Edge, TElem> (c_elem, child);
260 GetRegularLocalCoordinate (
grid, edge->
vertex (0), c_elem, loc_0);
261 GetRegularLocalCoordinate (
grid, edge->
vertex (1), c_elem, loc_1);
262 VecAdd (loc_center, loc_0, loc_1);
276 for (
size_t fct = 0; fct < num_fct; fct++)
279 if (coarseDD.
dof_indices (c_elem, fct, c_ind) != (
size_t) ref_elem_type::numEdges
282 "More than one DoF per edge. Not the Nedelec-type-1 element?");
284 for (
size_t i = 0; i < (size_t) ref_elem_type::numEdges; i++)
287 DoFRef (mat, f_ind [0], c_ind [i]) += coef;
288 vIsRestricted [c_ind [i] [0]] =
true;
300 template <
typename TDomain,
typename TAlgebra>
307 check_approximation_space ();
310 const DoFDistribution & coarseDD = * m_spApproxSpace->dof_distribution (m_coarseLevel);
311 const DoFDistribution & fineDD = * m_spApproxSpace->dof_distribution (m_fineLevel);
315 const size_t numCoarseDoFs = coarseDD.
num_indices ();
318 m_vIsRestricted.clear (); m_vIsRestricted.resize (numCoarseDoFs,
false);
321 m_prolongation_matrix.resize_and_clear (numFineDoFs, numCoarseDoFs);
323 UG_CATCH_THROW (
"NedelecTransfer: Failed to allocate the prolongation matrix.");
338 template <
typename TDomain,
typename TAlgebra>
346 UG_THROW(
"NedelecTransfer: Operator not initialized.");
349 UG_ASSERT(uFine.size () >= m_prolongation_matrix.num_rows (),
"Vector ["
350 << uFine.size() <<
"] must be >= Row size " << m_prolongation_matrix.num_rows ());
351 UG_ASSERT(uCoarse.size () >= m_prolongation_matrix.num_cols (),
"Vector ["
352 << uCoarse.size() <<
"] must be >= Col size " << m_prolongation_matrix.num_cols ());
355 if (! m_prolongation_matrix.apply (uFine, uCoarse))
357 std::stringstream ss;
358 ss <<
"NedelecTransfer::prolongate: Cannot apply matrix. ";
360 ss <<
"(Type uCoarse = " << uCoarse.get_storage_mask ();
368 for (
size_t i = 0; i < m_vConstraint.size (); ++i)
370 m_vConstraint[i]->adjust_defect (uFine, uFine,
371 m_spApproxSpace->dof_distribution (m_fineLevel),
CT_DIRICHLET);
373 UG_CATCH_THROW(
"NedelecTransfer::prolongate: Error while setting dirichlet defect to zero.");
379 for (
size_t i = 0; i < m_vConstraint.size (); ++i)
380 if (m_vConstraint[i]->
type() &
type)
381 m_vConstraint[i]->adjust_prolongation (uFine, m_fineLevel, uCoarse, m_coarseLevel,
type);
383 UG_CATCH_THROW(
"NedelecTransfer::prolongate: Error while setting dirichlet defect to zero.");
390 template <
typename TDomain,
typename TAlgebra>
398 UG_THROW(
"NedelecTransfer: Operator not initialized.");
403 UG_ASSERT (uFine.size () >= m_prolongation_matrix.num_rows (),
"Vector ["
404 << uFine.size () <<
"] must be >= Row size " << m_prolongation_matrix.num_rows ());
405 UG_ASSERT (uCoarse.size () >= m_prolongation_matrix.num_cols (),
"Vector ["
406 << uCoarse.size() <<
"] must be >= Col size " << m_prolongation_matrix.num_cols ());
409 if (! m_prolongation_matrix.apply_transposed (uTmp, uFine))
410 UG_THROW (
"NedelecTransfer::restrict: Cannot apply transposed matrix.");
416 for (
size_t i = 0; i < uTmp.size (); ++i)
417 if (m_vIsRestricted [i])
418 uCoarse[i] = uTmp[i];
423 for(
size_t i = 0; i < m_vConstraint.size (); ++i)
425 m_vConstraint[i]->adjust_defect (uCoarse, uCoarse,
426 m_spApproxSpace->dof_distribution (m_coarseLevel),
CT_DIRICHLET);
428 UG_CATCH_THROW(
"NedelecTransfer::restrict: Error while setting dirichlet defect to zero.");
434 for (
size_t i = 0; i < m_vConstraint.size (); ++i)
435 if (m_vConstraint[i]->
type() &
type)
436 m_vConstraint[i]->adjust_restriction (uCoarse, m_coarseLevel, uFine, m_fineLevel,
type);
438 UG_CATCH_THROW(
"NedelecTransfer::restrict: Error while setting dirichlet defect to zero.");
444 template <
typename TDomain,
typename TAlgebra>
447 if (m_spApproxSpace.invalid ())
448 UG_THROW (
"NedelecTransfer: Approximation space not set.");
450 for (
size_t fct = 0; fct < m_spApproxSpace->num_fct (); fct++)
453 "All the functions should be based on the Nedelec element "
454 "but function #" << fct <<
" is not.");
460 template <
typename TDomain,
typename TAlgebra>
468 m_fineLevel = fineLevel;
469 m_coarseLevel = coarseLevel;
471 if(m_fineLevel.level () - m_coarseLevel.level () != 1)
472 UG_THROW(
"NedelecTransfer: Can only project between successive level.");
475 UG_THROW(
"NedelecTransfer: Can only project between level dof distributions, but fine="
476 << m_fineLevel <<
", coarse=" << m_coarseLevel);
482 template <
typename TDomain,
typename TAlgebra>
487 for(
size_t i = 0; i < m_vConstraint.size (); ++i)
488 op->add_constraint (m_vConstraint[i]);
virtual void local_to_global(MathVector< worldDim > &globPos, const MathVector< dim > &locPos) const=0
virtual void update(const MathVector< worldDim > *vCornerCoord)=0
size_t dof_indices(GridObject *elem, size_t fct, std::vector< DoFIndex > &ind, bool bHang=false, bool bClear=true) const
size_t inner_dof_indices(GridObject *elem, size_t fct, std::vector< DoFIndex > &ind, bool bClear=true) const
size_t num_indices() const
SmartPtr< MultiGrid > multi_grid()
virtual Vertex * vertex(size_t index) const
TAlgebra::matrix_type matrix_type
Type of Vector.
Definition: nedelec_transfer.h:112
TDomain domain_type
Type of Domain.
Definition: nedelec_transfer.h:106
TDomain domain_type
Type of Domain.
Definition: nedelec_transfer.h:57
static void GetRegularLocalCoordinate(const MultiGrid *mg, Vertex *vrt, TElem *base, MathVector< TElem::dim > &local)
computes the local coordinates of a vertex according to the assumption of the regular refinement
Definition: nedelec_transfer_impl.h:57
reference_element_traits< TElem >::reference_element_type ref_elem_type
reference element type
Definition: nedelec_transfer.h:69
static void assemble_prolongation_matrix(const domain_type &domain, const DoFDistribution &coarseDD, const DoFDistribution &fineDD, matrix_type &mat, std::vector< bool > &vIsRestricted)
assembles the prolongation matrix for one type of the grid elements
Definition: nedelec_transfer_impl.h:209
TDomain::position_type position_type
position type in the domain
Definition: nedelec_transfer.h:75
TAlgebra::matrix_type matrix_type
Type of Vector.
Definition: nedelec_transfer.h:63
static void get_shapes(const TDomain *domain, TElem *elem, const position_type *corners, const MathVector< dim > local, MathVector< WDim > shapes[])
computes the Nedelec shapes at a given point
Definition: nedelec_local_ass.h:156
Class of the prolongation and the restriction of the Nedelec DoFs.
Definition: nedelec_transfer.h:168
void prolongate(vector_type &uFineOut, const vector_type &uCoarse)
applies the prolongation
Definition: nedelec_transfer_impl.h:340
TAlgebra::vector_type vector_type
Type of Vector.
Definition: nedelec_transfer.h:183
void do_restrict(vector_type &uCoarse, const vector_type &uFine)
apples the restriction = transposed prolongation
Definition: nedelec_transfer_impl.h:392
void init()
initializes the operator (computes the prolongation matrix etc)
Definition: nedelec_transfer_impl.h:301
void check_approximation_space()
checks the approximation space
Definition: nedelec_transfer_impl.h:445
virtual void set_levels(GridLevel coarseLevel, GridLevel fineLevel)
Set levels.
Definition: nedelec_transfer_impl.h:462
SmartPtr< ITransferOperator< TDomain, TAlgebra > > clone()
returns new instance with same setting
Definition: nedelec_transfer_impl.h:483
GridObject * get_parent(Edge *o) const
Grid::VertexAttachmentAccessor< position_attachment_type > position_accessor_type
int GetVertexIndex(EdgeVertices *e, Vertex *v)
#define UG_ASSERT(expr, msg)
#define UG_CATCH_THROW(msg)
void VecAdd(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
void VecSubtract(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
int local(bglp_vertex_descriptor p)
const number & DoFRef(const TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
SurfaceView::traits< TElem >::const_iterator const_iterator
a helper class to call all the type-dependent assembling functions
Definition: nedelec_transfer.h:230