116 typedef typename grid_func_type::template traits<TElem>::const_iterator ElemIter;
119 static const size_t num_corners = ref_elem_t::numCorners;
123 std::vector<DoFIndex> ind (1);
125 number lsf_values [num_corners];
127 for (
int si = 0; si < lsf.num_subsets (); si++)
129 if (m_ssGrp.subset_handler().valid () && ! m_ssGrp.contains (si))
132 number ss_vol_plus = 0, ss_vol_minus = 0;
133 ElemIter iterEnd = lsf.template end<TElem> (si);
134 for (ElemIter iter = lsf.template begin<TElem> (si); iter != iterEnd; ++iter)
136 TElem * elem = *iter;
139 for (
size_t i = 0; i < num_corners; i++)
141 Vertex * vrt = elem->vertex (i);
142 corners [i] = aaPos [vrt];
143 if (lsf.inner_dof_indices (vrt, 0, ind) != 1)
144 UG_THROW (
"LSVolume: Not a scalar grid function for the LSF!");
145 lsf_values [i] =
DoFRef (lsf, ind [0]);
149 number vol_plus, vol_minus;
153 m_volume_plus += vol_plus; m_volume_minus += vol_minus;
156 ss_vol_plus += vol_plus; ss_vol_minus += vol_minus;
159 if (m_check_positivity && (vol_plus < 0 || vol_minus < 0))
161 UG_LOG (
"Warning in LSVolume: V+ = " << vol_plus <<
" < 0 or V- = "
162 << vol_minus <<
" < 0\n");
163 for (
size_t i = 0; i < num_corners; i++)
165 UG_LOG (
" - corner[" << i <<
"] = " << corners[i]
166 <<
", grid_data_index = " << elem->vertex(i)->grid_data_index ()
167 <<
", lsf = " << lsf_values[i] <<
'\n');
191 m_ss_vol_plus[si] += ss_vol_plus; m_ss_vol_minus[si] += ss_vol_minus;
206 typedef typename grid_func_type::template traits<TElem>::const_iterator ElemIter;
209 static const size_t num_corners = ref_elem_t::numCorners;
213 std::vector<DoFIndex> ind (1);
215 number lsf_values [num_corners];
217 for (
int si = 0; si < lsf.num_subsets (); si++)
219 if (m_ssGrp.subset_handler().valid () && ! m_ssGrp.contains (si))
222 number ss_vol_plus = 0, ss_vol_minus = 0;
223 ElemIter iterEnd = lsf.template end<TElem> (si);
224 for (ElemIter iter = lsf.template begin<TElem> (si); iter != iterEnd; ++iter)
226 TElem * elem = *iter;
230 for (
size_t i = 0; i < num_corners; i++)
232 Vertex * vrt = elem->vertex (i);
233 midpoint += (corners [i] = aaPos [vrt]);
234 if (lsf.inner_dof_indices (vrt, 0, ind) != 1)
235 UG_THROW (
"LSVolume: Not a scalar grid function for the LSF!");
236 lsf_values [i] =
DoFRef (lsf, ind [0]);
238 midpoint /= num_corners;
241 number vol_plus, vol_minus;
246 (* pDensity) (density, midpoint, time, si);
247 vol_plus *= density; vol_minus *= density;
250 m_volume_plus += vol_plus; m_volume_minus += vol_minus;
253 ss_vol_plus += vol_plus; ss_vol_minus += vol_minus;
256 if (m_check_positivity && (vol_plus < 0 || vol_minus < 0))
258 UG_LOG (
"Warning in LSVolume: V+ = " << vol_plus <<
" < 0 or V- = "
259 << vol_minus <<
" < 0\n");
260 for (
size_t i = 0; i < num_corners; i++)
262 UG_LOG (
" - corner[" << i <<
"] = " << corners[i]
263 <<
", grid_data_index = " << elem->vertex(i)->grid_data_index ()
264 <<
", lsf = " << lsf_values[i] <<
'\n');
268 m_ss_vol_plus[si] += ss_vol_plus; m_ss_vol_minus[si] += ss_vol_minus;
458 number vol = ElementSize<ref_element_type, dim> (corner);
461 int i_pos[2], i_neg[2];
462 i_pos[0] = -1; i_pos[1] = -1;
463 i_neg[0] = -1; i_neg[1] = -1;
465 for (
int i = 0; i < 4; i++)
468 if (i_neg[0] < 0) i_neg[0] = i;
else i_neg[1] = i;
473 if (i_pos[0] < 0) i_pos[0] = i;
else i_pos[1] = i;
479 vol_plus = vol; vol_minus = 0;
484 vol_plus = 0; vol_minus = vol;
489 if (num_neg == 1 || num_neg == 3)
491 int i_0 = (num_neg == 1)? i_neg[0] : i_pos[0];
493 for (
int i = 0; i < 4; i++)
495 cut_tet [i] = corner [i];
498 number t = lsf[i] / (lsf[i] - lsf[i_0]);
499 VecScaleAdd (cut_tet [i], t, corner[i_0], 1 - t, corner[i]);
502 number cut_vol = ElementSize<ReferenceTetrahedron, dim> (cut_tet);
505 vol_minus = cut_vol; vol_plus = vol - cut_vol;
509 vol_plus = cut_vol; vol_minus = vol - cut_vol;
522 for (k = 0; k < 3; k++)
523 if (side_co [k] == i_neg[0])
break;
524 UG_ASSERT (k < 3,
"LSElementSize<ReferenceTetrahedron, WDim>::compute: internal error.");
525 i_pos[0] = side_co [(k + 1) % 3];
526 i_pos[1] = side_co [(k + 2) % 3];
530 for (
int k = 0; k < 2; k++)
533 neg_prism [3 * k] = corner [i_0];
534 for (
int l = 0; l < 2; l++)
537 number t = lsf[i] / (lsf[i] - lsf[i_0]);
538 VecScaleAdd (neg_prism [3 * k + l + 1], t, corner[i_0], 1 - t, corner[i]);
541 vol_minus = ElementSize<ReferencePrism, dim> (neg_prism);
542 vol_plus = vol - vol_minus;
558 number vol = ElementSize<ref_element_type, dim> (corner);
561 int i_pos[3], i_neg[3];
562 i_pos[0] = -1; i_pos[1] = -1; i_pos[2] = -1;
563 i_neg[0] = -1; i_neg[1] = -1; i_neg[2] = -1;
565 for (
int i = 0; i < 6; i++)
568 if (i_neg[0] < 0) i_neg[0] = i;
569 else if (i_neg[1] < 0) i_neg[1] = i;
575 if (i_pos[0] < 0) i_pos[0] = i;
576 else if (i_pos[1] < 0) i_pos[1] = i;
586 vol_plus = vol; vol_minus = 0;
591 vol_plus = 0; vol_minus = vol;
596 if (num_neg == 1 || num_neg == 5)
598 int i_0 = (num_neg == 1)? i_neg[0] : i_pos[0];
599 int shift = (i_0 < 3)? 0 : 3;
601 for (
int k = 0; k < 3; k++)
605 cut_tet [k] = corner [i];
608 number t = lsf[i] / (lsf[i] - lsf[i_0]);
609 VecScaleAdd (cut_tet [k], t, corner[i_0], 1 - t, corner[i]);
617 cut_tet[3] = cut_tet[2];
618 cut_tet[2] = cut_tet[1];
619 cut_tet[1] = cut_tet[3];
621 int i_1 = (i_0 + 3) % 6;
622 number t_1 = lsf[i_1] / (lsf[i_1] - lsf[i_0]);
623 VecScaleAdd (cut_tet [3], t_1, corner[i_0], 1 - t_1, corner[i_1]);
624 number cut_vol = ElementSize<ReferenceTetrahedron, dim> (cut_tet);
627 vol_minus = cut_vol; vol_plus = vol - cut_vol;
631 vol_plus = cut_vol; vol_minus = vol - cut_vol;
638 if (num_neg == 2 || num_neg == 4)
643 i_0 = i_neg[0]; i_1 = i_neg[1];
647 i_0 = i_pos[0]; i_1 = i_pos[1];
652 if (i_1 < 3 || i_0 >= 3)
654 int shift = (i_0 < 3)? 0 : 3;
656 for (
int k = 0; k < 3; k++)
659 if (i_2 != i_0 && i_2 != i_1)
break;
661 int i_0a = (i_0 + 3) % 6;
662 int i_1a = (i_1 + 3) % 6;
677 if ((i_1 < 3 && (i_0 + 1) % 3 != i_1) || (i_0 >= 3 && i_0a != (i_1a + 1) % 3))
680 i = i_0; i_0 = i_1; i_1 = i;
681 i = i_0a; i_0a = i_1a; i_1a = i;
684 cut_prism [0] = corner[i_0];
685 t = lsf[i_2] / (lsf[i_2] - lsf[i_0]);
686 VecScaleAdd (cut_prism [1], t, corner[i_0], 1 - t, corner[i_2]);
687 t = lsf[i_0a] / (lsf[i_0a] - lsf[i_0]);
688 VecScaleAdd (cut_prism [2], t, corner[i_0], 1 - t, corner[i_0a]);
690 cut_prism [3] = corner[i_1];
691 t = lsf[i_2] / (lsf[i_2] - lsf[i_1]);
692 VecScaleAdd (cut_prism [4], t, corner[i_1], 1 - t, corner[i_2]);
693 t = lsf[i_1a] / (lsf[i_1a] - lsf[i_1]);
694 VecScaleAdd (cut_prism [5], t, corner[i_1], 1 - t, corner[i_1a]);
696 number cut_vol = ElementSize<ReferencePrism, dim> (cut_prism);
700 vol_plus = vol - cut_vol;
705 vol_minus = vol - cut_vol;
719 cut_prism [0] = corner [i_0];
720 cut_prism [3] = corner [i_1];
722 int i = (i_0 + 1) % 3;
int j = i + 3;
724 t = lsf[i] / (lsf[i] - lsf[i_0]);
725 VecScaleAdd (cut_prism [1], t, corner[i_0], 1 - t, corner[i]);
726 t = lsf[j] / (lsf[j] - lsf[i_1]);
727 VecScaleAdd (cut_prism [4], t, corner[i_1], 1 - t, corner[j]);
730 int i = (i_0 + 2) % 3;
int j = i + 3;
732 t = lsf[i] / (lsf[i] - lsf[i_0]);
733 VecScaleAdd (cut_prism [2], t, corner[i_0], 1 - t, corner[i]);
734 t = lsf[j] / (lsf[j] - lsf[i_1]);
735 VecScaleAdd (cut_prism [5], t, corner[i_1], 1 - t, corner[j]);
737 number cut_vol = ElementSize<ReferencePrism, dim> (cut_prism);
741 vol_plus = vol - cut_vol;
746 vol_minus = vol - cut_vol;
755 number tmp_lsf [6], tmp_vol;
756 memcpy (tmp_lsf, lsf, 6 *
sizeof (
number));
762 tmp_lsf [i_neg[0]] = 1;
766 tmp_lsf [i_neg[0]] = lsf [i_neg[0]];
767 tmp_lsf [i_neg[1]] = 1;
769 vol_minus += neg_vol;
771 vol_plus = vol - vol_minus;
779 tmp_lsf [i_pos[0]] = -1;
783 tmp_lsf [i_pos[0]] = lsf [i_pos[0]];
784 tmp_lsf [i_pos[1]] = -1;
788 vol_minus = vol - vol_plus;
794 if ((i_neg[0] == 0 && i_neg[2] == 2) || (i_neg[0] == 3 && i_neg[2] == 5))
799 for (
int i = 0; i < 3; i++) cut_prism [i] = corner [i];
800 for (
int i = 0; i < 3; i++)
803 number t = lsf[j] / (lsf[j] - lsf[i]);
804 VecScaleAdd (cut_prism [j], t, corner [i], 1 - t, corner [j]);
806 cut_vol = ElementSize<ReferencePrism, dim> (cut_prism);
811 vol_plus = vol - cut_vol;
816 vol_minus = vol - cut_vol;
839 for (
int i = 0; i < 3; i++)
842 part_prism [i] = corner [i]; part_lsf [i] = lsf [i];
843 part_prism [j] = corner [j]; part_lsf [j] = lsf [j];
844 if ((lsf[i] >= 0 && lsf[j] < 0)
845 || (lsf[i] < 0 && lsf[j] >= 0))
847 base_i = (lsf[i] < 0)? i : j;
848 part_lsf[base_i] = 0;
849 number t = lsf[j] / (lsf[j] - lsf[i]);
850 VecScaleAdd (part_prism [base_i], t, corner [i], 1 - t, corner [j]);
853 UG_ASSERT (base_i >= 0,
"LSElementSize<ReferencePrism, dim>::compute: internal error");
854 number part_prism_vol_plus, part_prism_vol_minus;
856 part_prism_vol_plus, part_prism_vol_minus);
859 int shift = (base_i < 3)? 0 : 3;
860 for (
int k = 0; k < 3; k++)
862 part_tet [k] = corner [k + shift];
863 part_lsf [k] = lsf [k + shift];
870 part_tet[3] = part_tet[2]; part_lsf[3] = part_lsf[2];
871 part_tet[2] = part_tet[1]; part_lsf[2] = part_lsf[1];
872 part_tet[1] = part_tet[3]; part_lsf[1] = part_lsf[3];
874 part_tet [3] = part_prism [base_i];
876 number part_tet_vol_plus, part_tet_vol_minus;
878 part_tet_vol_plus, part_tet_vol_minus);
880 vol_plus = part_prism_vol_plus + part_tet_vol_plus;
881 vol_minus = part_prism_vol_minus + part_tet_vol_minus;