43 #include "../memreduce.h"
47 namespace Electromagnetism{
59 template <
typename TDomain,
typename TAlgebra>
68 m_vEdgeInfo.resize (pEdgeDD->
num_indices (),
false);
69 for (
size_t i = 0; i < pEdgeDD->
num_indices (); i++) m_vEdgeInfo[i].clear_flags ();
71 std::vector<size_t> vEdgeInd (1), vVertInd (1);
74 t_edge_iter edgeIterEnd = pEdgeDD->
end<
Edge> ();
75 for (t_edge_iter edgeIter = pEdgeDD->
begin<
Edge> (); edgeIter != edgeIterEnd; ++edgeIter)
77 Edge * pEdge = *edgeIter;
79 UG_THROW (name () <<
": Edge DoF distribution mismatch. Not the Nedelec-Type-1 element?");
80 tEdgeInfo & EdgeInfo = m_vEdgeInfo [vEdgeInd [0]];
84 for (
size_t i = 0; i < 2; i++)
88 UG_THROW (name () <<
": Vertex DoF distribution mismatch. Not the Lagrange-Order-1 element?");
93 if (m_spDirichlet.invalid ())
return;
97 m_spDirichlet->get_dirichlet_subsets (dirichlet_ssgrp);
98 for (
size_t j = 0; j < dirichlet_ssgrp.
size (); j++)
100 int si = dirichlet_ssgrp [j];
102 t_edge_iter iterEnd = pEdgeDD->
end<
Edge> (si);
103 for (t_edge_iter iter = pEdgeDD->
begin<
Edge> (si); iter != iterEnd; iter++)
105 Edge * pEdge = *iter;
107 UG_THROW (name () <<
": Edge DoF distribution mismatch. Not the Nedelec-Type-1 element?");
108 m_vEdgeInfo[vEdgeInd[0]].set_Dirichlet ();
127 template <
typename TDomain,
typename TAlgebra>
130 size_t N_edges = m_spSysMat->num_rows ();
131 size_t N_verts = m_spPotMat->num_rows ();
133 m_spPotMat->set (0.0);
137 vConductiveVertex.
resize (N_verts,
false);
138 memset (& (vConductiveVertex.
at (0)), 0, N_verts * sizeof (
bool));
142 for (
size_t row = 0; row < N_edges; row++)
144 if (! m_vEdgeInfo[row].is_init ())
145 UG_THROW (name () <<
": Uninitialized edge data in the computation of the potential.");
147 bool conductive_edge =
false;
150 size_t startVert [2];
151 memcpy (startVert, m_vEdgeInfo[row].vrt_index, 2 *
sizeof (
size_t));
154 for (
typename matrix_type::row_iterator row_it = m_spSysMat->begin_row(row);
155 row_it != m_spSysMat->end_row(row); ++row_it)
157 double M_entry =
BlockRef (row_it.value (), 1, 0);
160 if (zero_mass_entry (M_entry))
163 conductive_edge =
true;
166 memcpy (destVert, m_vEdgeInfo[row_it.index()].vrt_index, 2 * sizeof (
size_t));
169 (* m_spPotMat) (startVert[0], destVert[0]) += M_entry;
170 (* m_spPotMat) (startVert[0], destVert[1]) -= M_entry;
171 (* m_spPotMat) (startVert[1], destVert[0]) -= M_entry;
172 (* m_spPotMat) (startVert[1], destVert[1]) += M_entry;
177 vConductiveVertex[startVert[0]] = vConductiveVertex[startVert[1]] =
true;
181 (&vConductiveVertex, m_spPotMat->layouts()->master(),
182 m_spPotMat->layouts()->slave(), & (m_spPotMat->layouts()->comm()));
187 for (
size_t row = 0; row < N_edges; row++)
189 tEdgeInfo & EdgeInfo = m_vEdgeInfo [row];
192 = vConductiveVertex[EdgeInfo.
vrt_index[1]] =
false;
196 (&vConductiveVertex, m_spPotMat->layouts()->master(),
197 m_spPotMat->layouts()->slave(), & (m_spPotMat->layouts()->comm()));
203 for (
size_t row = 0; row < N_verts; row++)
204 if (! vConductiveVertex [row])
209 for (
size_t row = 0; row < N_edges; row++)
211 tEdgeInfo & EdgeInfo = m_vEdgeInfo [row];
212 if (vConductiveVertex[EdgeInfo.
vrt_index[0]])
214 if (vConductiveVertex[EdgeInfo.
vrt_index[1]])
241 template <
typename TDomain,
typename TAlgebra>
252 if (N_edges != m_spSysMat->num_rows () || N_edges != m_spSysMat->num_cols ())
253 UG_THROW (name () <<
": smoother not init. or illegal matrix type");
258 m_spPotMat->resize_and_clear (N_verts, N_verts);
260 UG_CATCH_THROW (name () <<
": Failed to allocate the auxiliary matrix for the potential.");
262 m_spPotMat->set_layouts (pVertDD->
layouts ());
266 get_edge_vert_correspondence (pEdgeDD, pVertDD);
281 template <
typename TDomain,
typename TAlgebra>
291 if (m_spVertApproxSpace.invalid())
292 UG_THROW (name() <<
", init: No approx. space for the potential specified.");
295 m_spSysMat = J.template cast_dynamic<MatrixOperator<matrix_type, vector_type> >();
296 if(m_spSysMat.invalid())
297 UG_THROW (name() <<
", init: No or illegal lin. operator passed (not a matrix?).");
301 if ((pGridF =
dynamic_cast<const TGridFunc *
> (&u)) == 0)
302 UG_THROW (name() <<
", init: No DoFDistribution specified.");
303 m_spEdgeDD = ((
TGridFunc *) pGridF)->dof_distribution ();
304 m_GridLevel = m_spEdgeDD->grid_level ();
305 m_spVertDD = m_spVertApproxSpace->dof_distribution (m_GridLevel);
308 delete m_pPotCorRe; m_pPotCorRe = 0;
309 delete m_pPotCorIm; m_pPotCorIm = 0;
314 compute_potential_matrix (m_spEdgeDD.get (), m_spVertDD.get ());
317 m_pPotCorRe =
new TPotGridFunc (m_spVertApproxSpace, m_spVertDD);
318 m_pPotCorIm =
new TPotGridFunc (m_spVertApproxSpace, m_spVertDD);
325 m_pPotCorRe->set (0.0);
326 if (! m_spVertSmoother->init (m_spPotMat, *m_pPotCorRe))
327 UG_THROW (name() <<
", init: Failed to initialize the subordinated vertex-based smoother.");
331 if (! m_spEdgeSmoother->init (J, u))
332 UG_THROW (name() <<
", init: Failed to initialize the subordinated edge-based smoother.");
337 delete m_pPotCorRe; m_pPotCorRe = 0;
338 delete m_pPotCorIm; m_pPotCorIm = 0;
339 m_vEdgeInfo.resize (0,
false);
340 m_spPotMat->resize_and_clear (0, 0);
355 template <
typename TDomain,
typename TAlgebra>
363 size_t N_edges = m_vEdgeInfo.size ();
365 potDefRe.
set (0.0); potDefIm.
set (0.0);
368 for (
size_t edge = 0; edge < N_edges; edge++)
370 tEdgeInfo & EdgeInfo = m_vEdgeInfo [edge];
377 potDefRe [i] -= Re_d;
378 potDefIm [i] -= Im_d;
384 potDefRe [i] += Re_d;
385 potDefIm [i] += Im_d;
393 template <
typename TDomain,
typename TAlgebra>
401 size_t N_edges = m_vEdgeInfo.size ();
404 for (
size_t edge = 0; edge < N_edges; edge++)
406 tEdgeInfo & EdgeInfo = m_vEdgeInfo [edge];
453 template <
typename TDomain,
typename TAlgebra>
465 UG_LOG(
"ERROR in '"<<name()<<
"::apply': Object not initialized.\n");
470 if (d.size() != m_spSysMat->num_rows())
471 UG_THROW(
"ERROR in '"<<name()<<
"::apply': Vector [size= "<<d.size()<<
472 "] and Row [size= "<<m_spSysMat->num_rows()<<
"] sizes have to match!");
473 if (c.size() != m_spSysMat->num_cols())
474 UG_THROW(
"ERROR in '"<<name()<<
"::apply': Vector [size= "<<c.size()<<
475 "] and Column [size= "<<m_spSysMat->num_cols()<<
"] sizes have to match!");
476 if (d.size() != c.size())
477 UG_THROW(
"ERROR in '"<<name()<<
"::apply': Vector [d size= "<<d.size()<<
478 ", c size = " << c.size() <<
"] sizes have to match!");
490 if (! m_spEdgeSmoother->apply_update_defect (c, auxEdgeDef))
511 collect_edge_defect (auxEdgeDef, potDefRe, potDefIm);
514 if (! m_spVertSmoother->apply (*m_pPotCorRe, potDefIm))
516 if (! m_spVertSmoother->apply (*m_pPotCorIm, potDefRe))
524 distribute_vertex_correction (*m_pPotCorRe, *m_pPotCorIm, c);
528 number kappa = this->damping()->damping (c, d, m_spSysMat);
traits< TElem >::iterator begin()
size_t inner_algebra_indices(GridObject *elem, std::vector< size_t > &ind, bool bClear=true) const
size_t num_indices() const
ConstSmartPtr< AlgebraLayouts > layouts() const
traits< TElem >::iterator end()
ConstSmartPtr< ISubsetHandler > subset_handler() const
virtual Vertex * vertex(size_t index) const
void collect_edge_defect(const vector_type &d, pot_vector_type &potDefRe, pot_vector_type &potDefIm)
Computes the vertex-centered defect .
Definition: hiptmair_hybrid_smoother_impl.h:357
bool init(SmartPtr< ILinearOperator< vector_type > > J, const vector_type &u)
Initialization using a matrix and a GridFunction (not merely a vector!)
Definition: hiptmair_hybrid_smoother_impl.h:283
bool apply(vector_type &c, const vector_type &d)
Computes the correction.
Definition: hiptmair_hybrid_smoother_impl.h:455
void compute_GtMG()
Computes the product .
Definition: hiptmair_hybrid_smoother_impl.h:128
void compute_potential_matrix(const DoFDistribution *pEdgeDD, const DoFDistribution *pVertDD)
Computes the matrix for the smoother in the potential space and marks the "conductive nodes".
Definition: hiptmair_hybrid_smoother_impl.h:243
void distribute_vertex_correction(pot_vector_type &potCorRe, pot_vector_type &potCorIm, vector_type &c)
Adds the vertex-centered correction to the edge-centered one:
Definition: hiptmair_hybrid_smoother_impl.h:395
TAlgebra::vector_type vector_type
Vector type.
Definition: hiptmair_hybrid_smoother.h:87
void get_edge_vert_correspondence(const DoFDistribution *pEdgeDD, const DoFDistribution *pVertDD)
Gets the correspondence between the edges and the vertices.
Definition: hiptmair_hybrid_smoother_impl.h:61
void set_storage_type(uint type)
void set_layouts(ConstSmartPtr< AlgebraLayouts > layouts)
bool resize(size_type n, bool bCopyValues=true)
pcl::SingleLevelLayout< pcl::OrderedInterface< size_t, std::vector > > IndexLayout
#define UG_CATCH_THROW(msg)
void SetDirichletRow(TMatrix &mat, const DoFIndex &ind)
const number & BlockRef(const number &m, size_t i)
SurfaceView::traits< TElem >::const_iterator const_iterator
"and" reduction operation class for the conductivity condition
Definition: hiptmair_hybrid_smoother.h:302
"or" reduction operation class for the conductivity condition
Definition: hiptmair_hybrid_smoother.h:297
Structure of the storage for the information about the edge-vertex interconnections.
Definition: hiptmair_hybrid_smoother.h:145
void set_init()
Definition: hiptmair_hybrid_smoother.h:159
bool is_Dirichlet()
Definition: hiptmair_hybrid_smoother.h:150
void set_conductive_vrt_1()
Definition: hiptmair_hybrid_smoother.h:158
bool conductive_vrt_0()
Definition: hiptmair_hybrid_smoother.h:151
void set_conductive_vrt_0()
Definition: hiptmair_hybrid_smoother.h:157
size_t vrt_index[2]
vertex dof's of the beginning and the end of the edge
Definition: hiptmair_hybrid_smoother.h:146
bool conductive_vrt_1()
Definition: hiptmair_hybrid_smoother.h:152