Plugins
Loading...
Searching...
No Matches
fract_lexorder_impl.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2025 Gesellschaft fuer Anlagen- und Reaktorsicherheit gGmbH
3 * SPDX-License-Identifier: EUPL-1.2
4 * SPDX-FileContributor: Dmitry Logashenko
5 * SPDX-FileContributor: Goethe Universität Frankfurt
6 * SPDX-FileType: SOURCE
7 *
8 * This file is part of d3f++.
9 * d3f++ is an extension for UG4. Licensing information and citation requirements of UG4 are provided in LICENSES/UG4-LGPL_2.1
10 */
11
12/*
13 * Implementation of the ordering of vertices (dofs) for domains with degenerated
14 * fractures.
15 */
16
19
20namespace ug {
21namespace d3f {
22
26template <typename TDomain>
28(
31 std::vector<typename std::pair<MathVector<TDomain::dim>, size_t> >& vPositions,
33 number step
34)
35{
36 static const int dim = TDomain::dim;
38 typedef typename DegeneratedLayerManager<dim>::side_type side_type;
40 static const size_t maxLayerSideCorners = DegeneratedLayerManager<dim>::maxLayerSideCorners;
41
42// do we have fractures?
43 if (dLayerManager == NULL) return;
44
45// algebra indices vector
46 std::vector<size_t> ind;
47
48// loop over fracture elements
49 for (size_t ss_grp_i = 0; ss_grp_i < dLayerManager->subset_grp().size (); ss_grp_i++)
50 {
51 size_t si = dLayerManager->subset_grp() [ss_grp_i];
52 t_elem_iter e_end = dd->template end<element_type> (si);
53 for (t_elem_iter e_iter = dd->template begin<element_type> (si);
54 e_iter != e_end; ++e_iter)
55 {
56 element_type * elem = *e_iter;
57 size_t n_co, inner_side_idx, outer_side_idx;
58 size_t inner_side_corners [maxLayerSideCorners];
59 size_t outer_side_corners [maxLayerSideCorners];
60 side_type * inner_side, * outer_side;
61 size_t ass_co [maxLayerSideCorners];
62
63 // get the fracture sides
64 dLayerManager->get_layer_sides (elem, n_co,
65 inner_side, inner_side_idx, inner_side_corners,
66 outer_side, outer_side_idx, outer_side_corners, ass_co);
67
68 // get the vertices of the outer side (ordered as in the ref. elem. to get the OUTER normal)
69 const ReferenceElement & ref_elem = ReferenceElementProvider::get (elem->reference_object_id ());
70 ReferenceObjectID sideRoid = ref_elem.roid (dim - 1, outer_side_idx);
71 size_t n_side_co = ref_elem.num (dim - 1, outer_side_idx, 0);
72 Vertex * side_vert [maxLayerSideCorners];
73 for (size_t co = 0; co < n_side_co; co++)
74 side_vert [co] = elem->vertex (ref_elem.id (dim - 1, outer_side_idx, 0, co));
75
76 // get the outer normal of the fracture
77 const typename TDomain::position_accessor_type & aaPos = domain->position_accessor();
78 MathVector<dim> vSideCoords [maxLayerSideCorners];
79 MathVector<dim> outer_normal;
80 number outer_normal_norm;
81 for (size_t co = 0; co < n_side_co; ++co)
82 vSideCoords [co] = aaPos [side_vert [co]];
83 ElementNormal<dim> (sideRoid, outer_normal, vSideCoords);
84 if ((outer_normal_norm = VecLength (outer_normal)) < 1e-32)
85 UG_THROW ("Cannot get the unit normal to a fracture.");
86
87 // Compute the reference distance: The minimum distance between the corners of the side
88 UG_ASSERT (n_side_co >= 2, "To few corners of a side: 1d?");
89 number min_edge, t;
90 min_edge = VecDistanceSq (vSideCoords[0], vSideCoords[1]);
91 for (size_t i = 0; i < n_side_co; i++)
92 for (size_t j = i + 1; j < n_side_co; j++)
93 if (min_edge > (t = VecDistanceSq (vSideCoords[i], vSideCoords[j])))
94 min_edge = t;
95 if ((min_edge = std::sqrt (min_edge)) < 1e-32)
96 UG_THROW ("Too short edges in the element!");
97
98 // correct the corresponding positions
99 outer_normal *= step * min_edge / outer_normal_norm;
100 for (size_t co = 0; co < n_side_co; ++co)
101 {
102 dd->inner_algebra_indices (side_vert [co], ind);
103 for(size_t i = 0; i < ind.size (); i++)
104 vPositions [ind[i]].first += outer_normal;
105 }
106 }
107 }
108}
109
115template <typename TDomain>
117(
121 number step
122)
123{
125 static const int dim = TDomain::dim;
126
127// We work with Lagrange P1 only:
128 for (size_t fct = 0; fct < dd->num_fct(); fct++)
129 if (dd->local_finite_element_id (fct) != LFEID (LFEID::LAGRANGE, dim, 1))
130 UG_THROW ("FractOrderLexForDofDist: Lex. order for fract. domains implemented for LagrangeP1 only!");
131
132// get positions
133 std::vector<typename std::pair<MathVector<TDomain::dim>, size_t> > vPositions;
134 ExtractPositions<TDomain> (domain, dd, vPositions);
135
136// correct the positions at the fractures
137 CorrectFractPositions (domain, dd, vPositions, dLayerManager, step);
138
139// get mapping: old -> new index
140 std::vector<size_t> vNewIndex (dd->num_indices());
141 ComputeLexicographicOrder<TDomain::dim> (vNewIndex, vPositions);
142
143// reorder indices
144 dd->permute_indices (vNewIndex);
145}
146
148template <typename TDomain>
150(
151 ApproximationSpace<TDomain>& approxSpace,
153 number step
154)
155{
156 std::vector<SmartPtr<DoFDistribution> > vDD = approxSpace.dof_distributions ();
157
158 for(size_t i = 0; i < vDD.size (); i++)
159 FractOrderLexForDofDist<TDomain> (vDD[i], approxSpace.domain (), dLayerManager, step);
160}
161
162} // namespace d3f
163} // end namespace ug
164
165/* End of File */
SmartPtr< TDomain > domain()
grid_dim_traits< dim >::grid_base_object element_type
const SubsetGroup & subset_grp()
grid_dim_traits< dim >::side_type side_type
void get_layer_sides(element_type *elem, size_t &num_fract_co, side_type *&inner_side, size_t &inner_side_idx, size_t inner_side_corners[], side_type *&outer_side, size_t &outer_side_idx, size_t outer_side_corners[], size_t ass_co[]=NULL)
std::vector< SmartPtr< DoFDistribution > > dof_distributions() const
size_t num(int dim) const
ReferenceObjectID roid() const
int id(int dim_i, size_t i, int dim_j, size_t j) const
static const DimReferenceElement< dim > & get(ReferenceObjectID roid)
int element_type() const
#define UG_ASSERT(expr, msg)
#define UG_THROW(msg)
double number
vector_t::value_type VecLength(const vector_t &v)
void FractOrderLex(ApproximationSpace< TDomain > &approxSpace, DegeneratedLayerManager< TDomain::dim > *dLayerManager, number step)
orders the all DofDistributions of the ApproximationSpace using lexicographic order
Definition fract_lexorder_impl.h:150
void CorrectFractPositions(ConstSmartPtr< TDomain > domain, SmartPtr< DoFDistribution > dd, std::vector< typename std::pair< MathVector< TDomain::dim >, size_t > > &vPositions, DegeneratedLayerManager< TDomain::dim > *dLayerManager, number step)
Definition fract_lexorder_impl.h:28
void FractOrderLexForDofDist(SmartPtr< DoFDistribution > dd, ConstSmartPtr< TDomain > domain, DegeneratedLayerManager< TDomain::dim > *dLayerManager, number step)
orders a dof distribution using lexicographic order
Definition fract_lexorder_impl.h:117
ReferenceObjectID
TVector::value_type VecDistanceSq(const TVector &v1, const TVector &v2, const TMatrix &M)