50#define LS_CLASSIC_GHOST_FLUID
58template<
typename TGr
idFunction>
66 for (
size_t co = 0; co < noc; co++)
68 if (lsf [co] >= - lsf_threshold () && lsf [co] <= lsf_threshold ())
70 if (lsf [co] < 0) neg = 1;
79template<
typename TGr
idFunction>
91 if (! m_spLSF.valid ())
return;
97 ElemIterator iterEnd = m_spLSF->template end<ElemType> ();
98 for (
ElemIterator iter = m_spLSF->template begin<ElemType> (); iter != iterEnd; ++iter)
103 size_t noc = elem->num_vertices ();
104 m_spLSF->indices (elem, locInd);
107 for (
size_t i = 0; i < noc; i++)
108 lsf[i] = locLSF (0, i);
110 if (lsf_sign (noc, lsf) == 0)
111 for (
size_t i = 0; i < elem->num_vertices (); i++)
112 aaCoIE[elem->vertex (i)] =
true;
123template<
typename TGr
idFunction>
137 for (
size_t co = 0; co < geo.
num_scv (); co++)
138 if (lsf [co] * lsf [base] > 0)
143 if (if_val_data == NULL)
149 number s = lsf[co] / (lsf[co] - lsf[base]);
150 VecScaleAdd (if_pnt_coord,
s, co_coord[base], 1 -
s, co_coord[co]);
151 VecScaleAdd (if_pnt_local,
s, co_local[base], 1 -
s, co_local[co]);
152 (* if_val_data) (&interface_val, &if_pnt_coord, m_time, si,
153 geo.
elem (), co_coord, &if_pnt_local, 1, NULL);
156 number t = lsf[co] / lsf[base];
157 ext[co] = sol[base] * t + interface_val * (1 - t);
164template<
typename TGr
idFunction>
192 corr_up = u_up - 0.5 * m_dt * (grad_up * vel_up);
194 corr_up += grad_up * distVec;
201 corr_up -= u_up - 0.5 * m_dt * (grad_up * vel_up);
204 corr_down -= u_down - 0.5 * m_dt * (grad_down * vel_down);
210 corr_down = corr_up = u_up;
220 if (! m_antiderivSrc)
221 src_up = src_down = 0;
227 src_down = vel_down * hVec;
234template<
typename TGr
idFunction>
254 corr = u - 0.5 * m_dt * (grad * vel);
256 corr += grad * distVec;
261 corr -= u - 0.5 * m_dt * (grad * vel);
278template<
typename TGr
idFunction>
295 if (lsf_sign == 0 && m_imVelocity.valid ())
300 for (
size_t i = 0; i < noc; i++)
301 co_vel[i] *= m_gamma;
303 else if (lsf_sign == 0 && m_imNormalVel.valid ())
305 number normal_vel [maxNumCo];
310 for (
size_t i = 0; i < noc; i++)
317 VecScale (co_vel[i], grad[i], m_gamma * normal_vel[i] / vnorm);
323 else if (m_delta != 0)
324 for (
size_t i = 0; i < noc; i++)
331 VecScale (co_vel[i], grad[i], m_delta / vnorm);
337 for (
size_t i = 0; i < noc; i++) co_vel[i] = 0;
346template<
typename TGr
idFunction>
367 for (
size_t i = 0; i < elem->num_vertices (); ++i)
369 vVrt[i] = elem->vertex (i);
370 coCoord[i] = aaPos[vVrt[i]];
374 geo.
update (elem, coCoord, domain.subset_handler().get ());
381 for (
size_t i=0; i < noc; i++)
383 uValue[i] = uOld (0, i);
384 grad[i] = aaGradient[vVrt[i]];
385 vel_grad[i] = aaVelGrad[vVrt[i]];
390 get_nodal_vel (elem, coCoord, geo, uOld, vel_grad, coVelocity, sign);
393 bool outBndCo[maxNumCo];
394 for (
size_t i = 0; i < noc; i++) outBndCo[i] =
false;
395 for (
size_t k = 0; k < m_neumann_sg.size (); k++)
397 int si = m_neumann_sg [k];
398 for (
size_t i = 0; i < geo.
num_bf (si); i++)
402 const size_t nodeID = bf.
node_id ();
405 outBndCo[nodeID] =
true;
410 for (
size_t co = 0; co < noc; co++)
416 bnd_sol_update (
true, bf.
global_ip (), coCoord[nodeID], uValue[nodeID],
417 grad[nodeID], coVelocity[nodeID], corr);
418 aaUpdate[ vVrt[nodeID] ] -= bipNormalVel * corr / aaVolume[ vVrt[nodeID] ];
421 if (m_spCourant.valid ())
423 number localCFL = m_dt * bipNormalVel / aaVolume[ vVrt[nodeID] ];
425 const size_t index = ind.
index (0, nodeID), comp = ind.
comp (0, nodeID);
429 if (bipNormalVel > 0)
430 CFL_entry += localCFL;
434 CFL_entry += std::fabs (localCFL);
441 for (
size_t ip = 0; ip < geo.
num_scvf (); ++ip)
445 size_t from = scvf.
from ();
446 size_t to = scvf.
to ();
452 for (
size_t co = 0; co < noc; co++)
459 size_t up_co, down_co;
462 up_co = from; down_co =
to;
466 up_co =
to; down_co = from; ipNormalVel = - ipNormalVel;
470 number corr_up, corr_down;
472 sol_update (outBndCo[up_co],
473 ipCoord, coCoord[up_co], uValue[up_co], grad[up_co], coVelocity[up_co],
474 coCoord[down_co], uValue[down_co], grad[down_co], coVelocity[down_co],
475 corr_up, corr_down, src_up, src_down);
477 aaUpdate[ vVrt[up_co] ] -= ipNormalVel * corr_up / aaVolume[ vVrt[up_co] ];
478 aaUpdate[ vVrt[down_co] ] += ipNormalVel * corr_down / aaVolume[ vVrt[down_co] ];
482 (*aaSrc)[ vVrt[up_co] ] -= ipNormalVel * src_up / aaVolume[ vVrt[up_co] ];
483 (*aaSrc)[ vVrt[down_co] ] += ipNormalVel * src_down / aaVolume[ vVrt[down_co] ];
487 if (m_spCourant.valid ())
494 number localCFL = m_dt * ipNormalVel / aaVolume[ vVrt[up_co] ];
495 index = ind.
index (0, up_co); comp = ind.
comp (0, up_co);
497 CFL_entry += localCFL;
501 number localCFL = m_dt * ipNormalVel / aaVolume[ vVrt[down_co] ];
502 index = ind.
index (0, down_co); comp = ind.
comp (0, down_co);
504 CFL_entry += localCFL;
513template<
typename TGr
idFunction>
532 size_t co, noc = geo.
num_scv ();
536 delta = (lsf[co] >= 0)? 1 : -1;
537 extrapolate_by_lsf (NULL, 0, geo, u, lsf, co, ext_u);
539 for (
size_t sh = 0; sh < noc; sh++)
543 from_flux = delta * (grad_ip * scvf.
normal ()) / norm;
548 VecScale (from_co_vel, grad[co], delta / norm);
554 delta = (lsf[co] >= 0)? 1 : -1;
555 extrapolate_by_lsf (NULL, 0, geo, u, lsf, co, ext_u);
557 for (
size_t sh = 0; sh < noc; sh++)
561 to_flux = delta * (grad_ip * scvf.
normal ()) / norm;
566 VecScale (to_co_vel, grad[co], delta / norm);
574template<
typename TGr
idFunction>
589 size_t co, noc = geo.
num_scv ();
592 delta = (lsf[co] >= 0)? 1 : -1;
593 extrapolate_by_lsf (NULL, 0, geo, u, lsf, co, ext_u);
595 for (
size_t sh = 0; sh < noc; sh++)
599 flux = delta * (grad_ip * bf.
normal ()) / norm;
604 VecScale (co_vel, grad[co], delta / norm);
617template<
typename TGr
idFunction>
641 for (
size_t i = 0; i < elem->num_vertices (); i++)
642 lsf[i] = locLSF (0, i);
643 int sign = lsf_sign (elem->num_vertices (), lsf);
650 for (
size_t i = 0; i < elem->num_vertices (); i++)
652 vVrt[i] = elem->vertex (i);
653 coCoord[i] = aaPos[vVrt[i]];
657 geo.
update (elem, coCoord, domain.subset_handler().get ());
666 for (
size_t i = 0; i < noc; i++)
668 uValue[i] = uOld (0, i);
669 vel_pot[i] = locVelPot (0, i);
670 grad[i] = aaGradient[vVrt[i]];
671 vel_grad[i] = aaVelGrad[vVrt[i]];
675 for (
size_t k = 0; k < m_neumann_sg.size (); k++)
677 int si = m_neumann_sg [k];
678 for(
size_t i = 0; i < geo.
num_bf (si); i++)
682 const size_t nodeID = bf.
node_id ();
687 get_bf_vel_on_if (geo, bf, vel_pot, vel_grad, lsf, co_vel, flux);
691 aaUpdate[ vVrt[nodeID] ] -= flux * uValue[nodeID] / aaVolume[ vVrt[nodeID] ];
694 if (m_spCourant.valid ())
700 number localCFL = m_dt * flux / aaVolume[ vVrt[nodeID] ];
702 const size_t index = ind.
index (0, nodeID), comp = ind.
comp (0, nodeID);
704 CFL_entry += localCFL;
711# ifndef LS_CLASSIC_GHOST_FLUID
714 for (
size_t ip = 0; ip < geo.
num_scvf (); ip++)
721 size_t from = scvf.
from ();
722 size_t to = scvf.
to ();
726 number from_flux, to_flux;
727 get_scvf_vel_on_if (geo, scvf, vel_pot, vel_grad, lsf,
728 from_co_vel, from_flux, to_co_vel, to_flux);
731 sol_update (
false, ipCoord, coCoord[from], uValue[from], grad[from], from_co_vel,
732 coCoord[
to], uValue[
to], grad[
to], to_co_vel, corr, t, src, t);
733 aaUpdate[ vVrt[from] ] -= from_flux * corr / aaVolume[ vVrt[from] ];
735 (*aaSrc) [ vVrt[from] ] -= from_flux * src / aaVolume[ vVrt[from] ];
738 sol_update (
false, ipCoord, coCoord[
to], uValue[
to], grad[
to], to_co_vel,
739 coCoord[from], uValue[from], grad[from], from_co_vel, corr, t, src, t);
740 aaUpdate[ vVrt[
to] ] += to_flux * corr / aaVolume[ vVrt[
to] ];
742 (*aaSrc) [ vVrt[
to] ] += to_flux * src / aaVolume[ vVrt[
to] ];
745 if (m_spCourant.valid ())
752 number localCFL = m_dt * std::abs (from_flux) / aaVolume[ vVrt[from] ];
753 index = ind.
index (0, from); comp = ind.
comp (0, from);
755 CFL_entry += localCFL;
759 number localCFL = m_dt * std::abs (to_flux) / aaVolume[ vVrt[
to] ];
762 CFL_entry += localCFL;
770 for (
size_t base_co = 0; base_co < noc; base_co++)
773 number extValue [maxNumCo];
774 extrapolate_by_lsf (if_val_data, si, geo, uValue, lsf, base_co, extValue);
777 for (
size_t ip = 0; ip < geo.
num_scvf (); ++ip)
781 size_t from = scvf.
from ();
782 size_t to = scvf.
to ();
783 if (from != base_co &&
to != base_co)
790 number from_ipNormalVel, to_ipNormalVel;
791 get_scvf_vel_on_if (geo, scvf, vel_pot, vel_grad, lsf,
792 from_co_vel, from_ipNormalVel, to_co_vel, to_ipNormalVel);
795 number ipNormalVel = (base_co == from)? from_ipNormalVel : to_ipNormalVel;
798 size_t up_co, down_co;
802 up_co = from; down_co =
to;
803 up_co_vel = from_co_vel; down_co_vel = to_co_vel;
807 up_co =
to; down_co = from; ipNormalVel = - ipNormalVel;
808 up_co_vel = to_co_vel; down_co_vel = from_co_vel;
812 number corr_up, corr_down;
815 ipCoord, coCoord[up_co], extValue[up_co], grad[up_co], up_co_vel,
816 coCoord[down_co], extValue[down_co], grad[down_co], down_co_vel,
817 corr_up, corr_down, src_up, src_down);
818 if (base_co == up_co)
820 aaUpdate[ vVrt[base_co] ] -= ipNormalVel * corr_up / aaVolume[ vVrt[up_co] ];
822 (*aaSrc) [ vVrt[base_co] ] -= ipNormalVel * src_up / aaVolume[ vVrt[up_co] ];
826 aaUpdate[ vVrt[base_co] ] += ipNormalVel * corr_down / aaVolume[ vVrt[down_co] ];
828 (*aaSrc) [ vVrt[base_co] ] += ipNormalVel * src_down / aaVolume[ vVrt[down_co] ];
832 if (m_spCourant.valid ())
839 number localCFL = m_dt * ipNormalVel / aaVolume[ vVrt[from] ];
840 index = ind.
index (0, from); comp = ind.
comp (0, from);
842 CFL_entry += localCFL;
846 number localCFL = m_dt * ipNormalVel / aaVolume[ vVrt[
to] ];
849 CFL_entry += localCFL;
863template<
typename TGr
idFunction>
886 for (
int si = 0; si < domain.subset_handler()->
num_subsets (); si++)
890 for (
ElemIterator iter = u.template begin<ElemType> (si); iter != iterEnd; ++iter)
898 const size_t numVertices = elem->num_vertices ();
899 for (
size_t i = 0; i < numVertices; i++)
901 vVrt[i] = elem->vertex (i);
902 coCoord[i] = aaPos[vVrt[i]];
906 geo.
update (elem, coCoord, domain.subset_handler().get ());
910 for (
size_t i = 0; i < noc; i++)
911 aaVolume[vVrt[i]] += geo.
scv(i).volume ();
923template<
typename TGr
idFunction>
937 if (lsf == NULL || lsf_sign (noc, lsf) != 0)
940 for (
size_t i = 0; i < noc; i++)
947 for (
size_t sh = 0; sh < noc; sh++)
954 for (
size_t i = 0; i < noc; i++)
957 if (lsf[i] <= lsf_threshold () && lsf[i] >= - lsf_threshold ())
965 number extValue [maxNumCo];
966 extrapolate_by_lsf (if_val_data, si, geo, uValue, lsf, i, extValue);
973 for (
size_t sh = 0; sh < noc; sh++)
982template<
typename TGr
idFunction>
990 TGridFunction * pLSF,
1004 std::vector<DoFIndex> multInd;
1015 number lsfValue[maxNumCo], * lsf;
1018 for (
int si = 0; si < domain.subset_handler()->
num_subsets (); si++)
1027 for (
ElemIterator iter = u.template begin<ElemType> (si); iter != iterEnd; ++iter)
1033 const size_t numVertices = elem->num_vertices ();
1034 for (
size_t i = 0; i < numVertices; i++)
1036 vVrt[i] = elem->vertex (i);
1037 coCoord[i] = aaPos[vVrt[i]];
1041 geo.
update (elem, coCoord, domain.subset_handler().get ());
1045 u.indices (elem, locInd);
1048 for (
size_t i = 0; i < noc; i++)
1049 uValue[i] = locU (0, i);
1056 for (
size_t i = 0; i < noc; i++)
1057 lsfValue[i] = locLSF (0, i);
1064 compute_elem_grad (geo, uValue, globalGrad, lsf, if_val_data, si);
1067 for (
size_t i = 0; i < noc; i++)
1070 globalGrad[i] *= geo.
scv(i).volume ();
1073 aaGradient[vVrt[i]] += globalGrad[i];
1083 for (
int si = 0; si < u.num_subsets (); si++)
1086 iter != u.template end<Vertex> (si); ++iter)
1090 if (aaVolume[vrt] != 0)
1091 aaGradient[vrt] /= aaVolume[vrt];
1099template<
typename TGr
idFunction>
1102 TGridFunction& numsol
1110 std::vector<DoFIndex> ind (1);
1111 for (
size_t i = 0; i < m_dirichlet_sg.size (); i++)
1113 const int si = m_dirichlet_sg[i];
1116 iter != numsol.template end<Vertex> (si); ++iter)
1123 numsol.inner_dof_indices (vrt, 0, ind);
1126 if (m_imDirichlet.valid ())
1127 (*m_imDirichlet) (&exactVal, &aaPos[vrt], m_time, si, 1);
1129 exactVal =
DoFRef (*m_oldSol, ind[0]);
1130 DoFRef (numsol, ind[0]) = exactVal;
1141template<
typename TGr
idFunction>
1144 TGridFunction& uOld,
1151 std::vector<DoFIndex> ind;
1158 grid.attach_to_vertices (aMin);
1159 grid.attach_to_vertices (aMax);
1164 for (
int si = 0; si < uOld.num_subsets(); si++)
1167 iter != uOld.template end<Vertex> (si); ++iter)
1174 uOld.inner_dof_indices (vrt, 0, ind);
1175 aaMax[vrt] =
DoFRef (uOld, ind[0]);
1176 aaMin[vrt] =
DoFRef (uOld, ind[0]);
1179 for (
int si = 0; si < uOld.num_subsets (); si++)
1183 iter != uOld.template end<Edge> (si); ++iter)
1188 uOld.inner_dof_indices (vi, 0, ind);
1190 uOld.inner_dof_indices (vj, 0, ind);
1203 for (
int si = 0; si < uOld.num_subsets (); si++)
1207 if (m_dirichlet_sg.size () != 0)
if (m_dirichlet_sg.contains (si))
continue;
1211 iter != uOld.template end<Edge> (si); ++iter)
1221 uOld.inner_dof_indices (vi, 0, ind);
1223 uOld.inner_dof_indices (vj, 0, ind);
1227 number uij = ui + distVec*gradi;
1231 if (uij > aaMax[vi]) alpha = (aaMax[vi] - ui) / (distVec * gradi);
1236 aaGrad[vi] *= alpha;
1241 if (uij < aaMin[vi]) alpha = (aaMin[vi] - ui) / (distVec * gradi);
1246 aaGrad[vi] *= alpha;
1250 uij = uj + distVec*gradj;
1254 if (uij > aaMax[vj]) alpha = (aaMax[vj] - uj) / (distVec * gradj);
1259 aaGrad[vj] *= alpha;
1264 if (uij < aaMin[vj]) alpha = (aaMin[vj] - uj) / (distVec * gradj);
1269 aaGrad[vj] *= alpha;
1280 ElemIterator iterEnd = uOld.template end<ElemType> (si);
1281 for (
ElemIterator iter = uOld.template begin<ElemType> (si); iter != iterEnd; ++iter)
1292 size_t noc = elem->num_vertices ();
1293 for (
size_t i = 0; i < noc; i++)
1295 vVrt[i] = elem->vertex (i);
1296 coCoord[i] = aaPos[vVrt[i]];
1297 grad[i] = aaGrad[vVrt[i]] ;
1299 uOld.inner_dof_indices (vVrt[i], 0, ind);
1300 u[i] =
DoFRef (uOld, ind[0]);
1303 for (
size_t i = 0; i < noc; i++)
1309 uCenter = u[i] + distVec * grad[i];
1312 if (uCenter > aaMax[vVrt[i]]) alpha = (aaMax[vVrt[i]] - u[i]) / (distVec * grad[i]);
1316 aaGrad[vVrt[i]] *= alpha;
1321 if (uCenter < aaMin[vVrt[i]]) alpha = (aaMin[vVrt[i]] - u[i]) / (distVec * grad[i]);
1325 aaGrad[vVrt[i]] *= alpha;
1332 grid.detach_from_vertices (aMin);
1333 grid.detach_from_vertices (aMax);
1342template<
typename TGr
idFunction>
1346 if (m_nrOfSteps <= 0)
return;
1349 if (m_oldSol.invalid () || m_newSol.invalid ())
1350 UG_THROW (
"Grid functions for the solutions not specified.");
1351 TGridFunction& uOld = *m_oldSol;
1352 TGridFunction& uNew = *m_newSol;
1382 grid.attach_to_vertices (aScvVolume);
1383 grid.attach_to_vertices (aGradient);
1384 grid.attach_to_vertices (aUpdate);
1385 grid.attach_to_vertices (aSrc);
1386 grid.attach_to_vertices (aCoIE);
1404 for (
size_t i = 0; i < m_neumann_sg.size (); i++)
1408 compute_volumes (uNew, geo, aScvVolume, aaVolume);
1411 if (m_spVelPot.valid () && m_spVelPot != m_oldSol)
1414 grid.attach_to_vertices (aVelGrad);
1416 compute_vertex_grad (*m_spVelPot, geo, aaVolume, aVelGrad, aaVelGrad, m_spLSF.get());
1418 limit_grad (*m_spVelPot, aaVelGrad);
1427 if (m_spLSF.valid ())
1429 if (m_spSDF.invalid ())
1430 UG_THROW (
"Computation with the LSF interface is only possible with the SDF. Specify it!");
1432 if (m_spSDF == m_oldSol)
1437 else if (m_spSDF == m_spVelPot)
1442 grid.attach_to_vertices (aSDFUpdate);
1448 grid.attach_to_vertices (aSDFGrad);
1450 compute_vertex_grad (*m_spSDF, geo, aaVolume, aSDFGrad, aaSDFGrad, m_spLSF.get());
1452 limit_grad (*m_spSDF, aaSDFGrad);
1454 grid.attach_to_vertices (aSDFUpdate);
1460 mark_CoIE (
grid, aCoIE, aaCoIE);
1463 std::vector<DoFIndex> ind;
1468 if (this->debug_writer_valid())
1470 this->write_debug (uNew,
"HR-FB-LSM-sol_step_0");
1481 if (m_spCourant.valid ())
1483 (* m_spCourant) = 0.0;
1491 UG_THROW (
"Time control is only possible if a grid function is specified for CFL (by save_CourantNumber_to)");
1495 bool wrong_sgn_at_if_A =
false, wrong_sgn_at_if_B =
false;
1498 compute_vertex_grad (uOld, geo, aaVolume, aGradient, aaGradient, m_spLSF.get(), m_imInterfaceVal.get ());
1500 limit_grad (uOld, aaGradient);
1505 if (m_spLSF.valid () && m_spSDF != m_oldSol)
1509 for (
int si = 0; si < uOld.num_subsets (); si++)
1512 ElemIterator iterEnd = uNew.template end<ElemType> (si);
1513 for (
ElemIterator iter = uNew.template begin<ElemType> (si); iter != iterEnd; ++iter)
1516 uNew.indices (elem, locInd);
1520 if (m_spLSF.invalid ())
1521 assemble_element (elem, geo, domain, locOldU, aaGradient, aaVelGrad, aaVolume, 0, aaUpdate, &aaSrc);
1525 int sign = assemble_cut_element
1526 (elem, geo, domain, locOldU, locLSF, locVelPot,
1527 aaGradient, aaVelGrad, aaVolume, aaUpdate, &aaSrc, m_imInterfaceVal.get (), si);
1529 assemble_element (elem, geo, domain, locOldU,
1530 aaGradient, aaVelGrad, aaVolume, sign, aaUpdate, &aaSrc);
1535 if (m_spLSF.valid () && m_spSDF != m_oldSol)
1536 for (
ElemIterator iter = uNew.template begin<ElemType> (si); iter != iterEnd; ++iter)
1541 for (
size_t co = 0; co < elem->num_vertices (); co++)
1542 if (aaCoIE [elem->vertex (co)])
1544 m_spSDF->indices (elem, locInd);
1548 int sign = assemble_cut_element
1549 (elem, geo, domain, locOldU, locLSF, locVelPot,
1550 aaSDFGrad, aaVelGrad, aaVolume, aaSDFUpdate, NULL, NULL, si);
1552 assemble_element (elem, geo, domain, locOldU,
1553 aaSDFGrad, aaVelGrad, aaVolume, sign, aaSDFUpdate, NULL);
1563 if (m_spLSF.valid () && m_spSDF != m_oldSol)
1565 if (m_spCourant.valid ())
1570 if (m_spCourant.valid ())
1574 iter != m_spCourant->template end<Vertex> (); ++iter)
1576 m_spCourant->inner_dof_indices (*iter, 0, ind);
1578 if (local_CFL > current_CFL)
1579 current_CFL = local_CFL;
1588 if (m_time_control && current_CFL > 1e-10 && (current_CFL < m_minCFL || current_CFL > m_maxCFL))
1591 m_dt = m_dt / current_CFL * (m_minCFL + m_maxCFL) / 2;
1593 UG_LOG (
"CFL " << current_CFL <<
" ... resetting time step: " << old_dt <<
" -> " << m_dt <<
"\n");
1598 for (
int si = 0; si < uOld.num_subsets (); si++)
1601 if (m_dirichlet_sg.size () != 0)
if (m_dirichlet_sg.contains (si))
continue;
1604 iter != uNew.template end<Vertex> (si); ++iter)
1607 uNew.inner_dof_indices (vrt, 0, ind);
1611 if (m_spLSF.valid ())
1612 co_source = (
DoFRef (*m_spLSF, ind[0]) >= 0)? m_source_pos : m_source_neg;
1614 co_source = m_source_pos;
1615 if (m_antiderivSrc) co_source *= aaSrc[vrt];
1616 DoFRef (uNew, ind[0]) += m_dt * (aaUpdate[vrt] + co_source);
1621 number sdf_update = aaSDFUpdate[vrt];
1622 number dt_eff = -
DoFRef (*m_spSDF, ind[0]) / sdf_update;
1625 if (lsf_val > lsf_threshold ())
1627 if (sdf_update >= 0)
1629 wrong_sgn_at_if_A =
true;
1630 DoFRef (uNew, ind[0]) += m_dt * m_source_pos;
1634 number co_source = m_source_pos;
1635 if (m_antiderivSrc) co_source *= aaSrc[vrt];
1636 DoFRef (uNew, ind[0]) += dt_eff * (aaUpdate[vrt] + co_source);
1639 else if (lsf_val < - lsf_threshold ())
1641 if (sdf_update <= 0)
1643 wrong_sgn_at_if_B =
true;
1644 DoFRef (uNew, ind[0]) += m_dt * m_source_neg;
1648 number co_source = m_source_neg;
1649 if (m_antiderivSrc) co_source *= aaSrc[vrt];
1650 DoFRef (uNew, ind[0]) += dt_eff * (aaUpdate[vrt] + co_source);
1655 if (m_imInterfaceVal.invalid ())
1656 DoFRef (uNew, ind[0]) = 0;
1658 (* m_imInterfaceVal) (
DoFRef (uNew, ind[0]), aaPos[vrt], m_time, si, vrt);
1665 if (wrong_sgn_at_if_A)
1666 UG_LOG (
"advect: Wrong (non-negative) sign of the gradient occured!\n");
1667 if (wrong_sgn_at_if_B)
1668 UG_LOG (
"advect: Wrong (non-positive) sign of the gradient occured!\n");
1674 assign_dirichlet (uNew);
1677 if (current_CFL > m_CFL) m_CFL = current_CFL;
1682 UG_LOG (
"step length: " << m_dt <<
" (step # " << step <<
")\n");
1683 UG_LOG (
"time: " << m_time <<
"\n");
1684 UG_LOG (
"CFL in step: " << current_CFL <<
"\n");
1686 UG_LOG (
"advect: TS # " << step <<
", time " << m_time <<
" (dt = " << m_dt <<
")");
1687 if (m_spCourant.valid ())
1688 UG_LOG (
", CFL = " << current_CFL);
1692 if (this->debug_writer_valid())
1694 char debug_file_name [128];
1695 snprintf (debug_file_name, 128,
"HR-FB-LSM-sol_step_%d", (
int) step);
1696 this->write_debug (uNew, debug_file_name);
1700 if (step >= m_nrOfSteps)
1711 UG_LOG (
"advect: " << step <<
" step(s) done, last dt: " << m_dt);
1712 if (m_spCourant.valid ())
1713 UG_LOG (
", max. CFL = " << m_CFL);
1718 if (m_spVelPot.valid () && m_spVelPot != m_oldSol)
1719 grid.detach_from_vertices (aVelGrad);
1720 if (m_spLSF.valid () && m_spSDF != m_oldSol)
1722 grid.detach_from_vertices (aSDFUpdate);
1723 if (m_spSDF != m_spVelPot)
1724 grid.detach_from_vertices (aSDFGrad);
1726 grid.detach_from_vertices (aCoIE);
1727 grid.detach_from_vertices (aSrc);
1728 grid.detach_from_vertices (aUpdate);
1729 grid.detach_from_vertices (aGradient);
1730 grid.detach_from_vertices (aScvVolume);
1736template<
typename TGr
idFunction>
1744 if (! m_spLSF.valid ())
1745 UG_THROW (
"Specify the level-set function!");
1748 domain_type& domain = * (m_spLSF->domain().get ());
1762 for (
size_t i = 0; i < m_neumann_sg.size (); i++)
1767 grid.attach_to_vertices (aScvVolume);
1769 compute_volumes (*m_spLSF, geo, aScvVolume, aaVolume);
1773 grid.attach_to_vertices (aGradient);
1775 compute_vertex_grad (*m_spLSF, geo, aaVolume, aGradient, aaGradient);
1777 limit_grad (*m_spLSF, aaGradient);
1780 std::vector<DoFIndex> ind;
1789 for (
int si = 0; si < m_spLSF->num_subsets (); si++)
1791 ElemIterator iterEnd = m_spLSF->template end<ElemType> (si);
1792 for (
ElemIterator iter = m_spLSF->template begin<ElemType> (si); iter != iterEnd; ++iter)
1799 bool elem_outside =
true;
1800 for (
size_t i = 0; i < elem->num_vertices (); ++i)
1802 Vertex* vrt = elem->vertex (i);
1803 m_spLSF->inner_dof_indices ((vVrt[i] = vrt), 0, ind);
1804 uValue[i] =
DoFRef (*m_spLSF, ind[0]);
1805 if (uValue[i] < - lsf_threshold ())
1806 elem_outside =
false;
1814 for (
size_t i = 0; i < elem->num_vertices (); ++i)
1815 coCoord[i] = aaPos[vVrt[i]];
1818 geo.
update (elem, coCoord, domain.subset_handler().get ());
1825 (*spVelField) (co_vel, geo.
coe_global (), m_time, si,
1827 for (
size_t i = 1; i < noc; i++) co_vel[i] = co_vel[0];
1834 for (
size_t i = 0; i < noc; i++)
1839 if (gnorm >= lsf_threshold ())
1841 spNormVel->inner_dof_indices (vrt, 0, ind);
1842 DoFRef (*spNormVel, ind[0]) += (co_vel [i] * aaGradient [vrt]) * vol / gnorm;
1844 aaVolume[vrt] += vol;
1856 for (
int si = 0; si < m_spLSF->num_subsets (); si++)
1859 iter != m_spLSF->template end<Vertex> (si); ++iter)
1862 number vol = aaVolume[vrt];
1865 spNormVel->inner_dof_indices (vrt, 0, ind);
1866 DoFRef (*spNormVel, ind[0]) /= vol;
1871 grid.detach_from_vertices (aGradient);
1872 grid.detach_from_vertices (aScvVolume);
1878template<
typename TGr
idFunction>
1886 if (! m_spLSF.valid ())
1887 UG_THROW (
"Specify the level-set function!");
1890 domain_type& domain = * (m_spLSF->domain().get ());
1904 for (
size_t i = 0; i < m_neumann_sg.size (); i++)
1909 grid.attach_to_vertices (aNVelocity);
1915 grid.attach_to_vertices (aScvVolume);
1917 compute_volumes (*m_spLSF, geo, aScvVolume, aaVolume);
1921 grid.attach_to_vertices (aGradient);
1923 compute_vertex_grad (*m_spLSF, geo, aaVolume, aGradient, aaGradient);
1925 limit_grad (*m_spLSF, aaGradient);
1928 std::vector<DoFIndex> ind;
1934 for (
int si = 0; si < m_spLSF->num_subsets (); si++)
1936 ElemIterator iterEnd = m_spLSF->template end<ElemType> (si);
1937 for (
ElemIterator iter = m_spLSF->template begin<ElemType> (si); iter != iterEnd; ++iter)
1944 bool elem_outside =
true;
1945 for (
size_t i = 0; i < elem->num_vertices (); ++i)
1947 Vertex* vrt = elem->vertex (i);
1948 m_spLSF->inner_dof_indices ((vVrt[i] = vrt), 0, ind);
1949 uValue[i] =
DoFRef (*m_spLSF, ind[0]);
1950 if (uValue[i] < - lsf_threshold ())
1951 elem_outside =
false;
1959 for (
size_t i = 0; i < elem->num_vertices (); ++i)
1960 coCoord[i] = aaPos[vVrt[i]];
1963 geo.
update (elem, coCoord, domain.subset_handler().get ());
1967 number co_nVel[maxNumCo];
1972 for (
size_t i = 0; i < noc; i++)
1977 if (gnorm >= lsf_threshold ())
1979 aaNVel [vrt] += (co_nVel [i] * aaGradient [vrt] [dim-1]) * vol / gnorm;
1981 aaVolume[vrt] += vol;
1992 for (
int si = 0; si < m_spLSF->num_subsets (); si++)
1995 iter != m_spLSF->template end<Vertex> (si); ++iter)
1998 number vol = aaVolume[vrt];
2001 spNormVel->inner_dof_indices (vrt, 0, ind);
2002 DoFRef (*spNormVel, ind[0]) += aaNVel [vrt] / vol;
2007 grid.detach_from_vertices (aGradient);
2008 grid.detach_from_vertices (aScvVolume);
2009 grid.detach_from_vertices (aNVelocity);
2015template<
typename TGr
idFunction>
2021 if (m_dirichlet_sg.subset_handler().invalid ())
2023 if (m_newSol.invalid ())
2024 UG_THROW (
"Grid function for the solution not set.");
2025 m_dirichlet_sg.set_subset_handler (m_newSol->subset_handler ());
2034template<
typename TGr
idFunction>
2040 if (m_neumann_sg.subset_handler().invalid ())
2042 if (m_newSol.invalid ())
2043 UG_THROW (
"Grid function for the solution not set.");
2044 m_neumann_sg.set_subset_handler (m_newSol->subset_handler ());
2053template<
typename TGr
idFunction>
2060 if (m_newSol.invalid ())
2061 UG_THROW (
"compare_lsf_with: Solution is not specified!\n");
2063 bool check_failed =
false;
2064 std::vector<DoFIndex> ind;
2067 domain_type& domain = * (m_newSol->domain().get ());
2073 UG_LOG (
"--- Checking solution, phase 1: Nodal values\n");
2074 for (
int si = 0; si < domain.subset_handler()->
num_subsets (); si++)
2076 UG_LOG (
" -- subset "<< si <<
"\n");
2078 iter != m_newSol->template end<Vertex> (si); ++iter)
2083 m_newSol->inner_dof_indices (vrt, 0, ind);
2087 if (lsf_1 * lsf_2 <= 0 && (lsf_1 != 0 || lsf_2 != 0))
2089 check_failed =
true;
2091 for (
size_t i = 1; i < dim; i++)
2092 UG_LOG (
", " << aaPos[vrt][i]);
2093 UG_LOG (
"): sol = " << lsf_1 <<
", lsf = " << lsf_2 <<
"\n");
2099 UG_LOG (
"--- failed.\n");
2102 UG_LOG (
"--- passed.\n");
2105 UG_LOG (
"--- Checking solution, phase 2: Interface in the elements\n");
2106 for (
int si = 0; si < domain.subset_handler()->
num_subsets (); si++)
2108 UG_LOG (
" -- subset "<< si <<
"\n");
2110 ElemIterator iterEnd = m_newSol->template end<ElemType> (si);
2111 for (
ElemIterator iter = m_newSol->template begin<ElemType> (si); iter != iterEnd; ++iter)
2114 const size_t numVertices = elem->num_vertices ();
2118 number lsf_1 [maxNumCo], lsf_2 [maxNumCo];
2121 for (
size_t i = 0; i < numVertices; i++)
2123 vVrt[i] = elem->vertex (i);
2124 m_newSol->inner_dof_indices (vVrt[i], 0, ind);
2125 lsf_1[i] =
DoFRef (*m_newSol, ind[0]);
2126 lsf_2[i] =
DoFRef (*spLSF2, ind[0]);
2130 if (lsf_sign (numVertices, lsf_1) != 0)
2134 bool bad_if_elem =
false;
2135 number param_1 [maxNumCo][maxNumCo];
2136 number param_2 [maxNumCo][maxNumCo];
2137 memset (param_1, 0, maxNumCo * maxNumCo *
sizeof (
number));
2138 memset (param_2, 0, maxNumCo * maxNumCo *
sizeof (
number));
2139 for (
size_t i = 0; i < numVertices; i++)
2140 for (
size_t j = i + 1; j < numVertices; j++)
2142 if (lsf_1[i] * lsf_1[j] > 0)
continue;
2143 param_1[i][j] = lsf_1[i] / (lsf_1[i] - lsf_1[j]);
2144 param_2[i][j] = lsf_2[i] / (lsf_2[i] - lsf_2[j]);
2145 if (std::fabs (param_1[i][j] - param_2[i][j]) >= eps)
2150 check_failed =
true;
2151 UG_LOG (
" > elem " << elem->grid_data_index() <<
" (" << numVertices <<
" corners):\n");
2152 for (
size_t i = 0; i < numVertices; i++)
2154 UG_LOG (
" : " << i <<
" @ (" << aaPos[vVrt[i]][0]);
2155 for (
size_t j = 1; j < dim; j++)
2156 UG_LOG (
", " << aaPos[vVrt[i]][j]);
2157 UG_LOG (
"): sol = " << lsf_1[i] <<
", lsf = " << lsf_2[i] <<
"\n");
2159 for (
size_t i = 0; i < numVertices; i++)
2160 for (
size_t j = i + 1; j < numVertices; j++)
2161 if (std::fabs (param_1[i][j] - param_2[i][j]) >= eps)
2162 UG_LOG (
" ! " << i <<
" to " << j <<
": sol = " << param_1[i][j] <<
", lsf = " << param_2[i][j] <<
"\n");
2168 UG_LOG (
"--- failed.\n");
2171 UG_LOG (
"--- passed.\n");
parameterString s
Definition Biogas.lua:2
size_t allreduce(const size_t &t, pcl::ReduceOperation op) const
number shape(size_t sh) const
const MathVector< worldDim > & normal() const
const MathVector< worldDim > & global_ip() const
const MathVector< worldDim > & global_grad(size_t sh) const
const MathVector< worldDim > & normal() const
const MathVector< worldDim > & global_ip() const
number shape(size_t sh) const
const MathVector< worldDim > & global_grad(size_t sh) const
const MathVector< worldDim > & global_grad(size_t sh) const
const MathVector< worldDim > * coe_global() const
const MathVector< worldDim > * scv_global_ips() const
const SCVF & scvf(size_t i) const
const MathVector< dim > * coe_local() const
const MathVector< worldDim > * corners() const
const MathVector< dim > * scv_local_ips() const
void update(GridObject *elem, const MathVector< worldDim > *vCornerCoords, const ISubsetHandler *ish=NULL)
const std::vector< BF > & bf(int si) const
GridObject * elem() const
void add_boundary_subset(int subsetIndex)
const SCV & scv(size_t i) const
virtual Vertex * vertex(size_t index) const
bool access(Grid &grid, TAttachment &a)
uint grid_data_index() const
void compare_lsf_with(SmartPtr< TGridFunction > spLSF2, number eps)
compare the solution with a given level-set function
Definition hrfblsm_discr_impl.h:2055
void assign_dirichlet(TGridFunction &numsol)
assign Dirichlet values
Definition hrfblsm_discr_impl.h:1101
void sol_update(bool redOrder, const MathVector< dim > &ip, const MathVector< dim > &x_up, number u_up, const MathVector< dim > &grad_up, const MathVector< dim > &vel_up, const MathVector< dim > &x_down, number u_down, const MathVector< dim > &grad_down, const MathVector< dim > &vel_down, number &corr_up, number &curr_down, number &src_up, number &src_down)
computes the scvf-update of the solution in an element
Definition hrfblsm_discr_impl.h:166
TGridFunction::template dim_traits< dim >::const_iterator ElemIterator
grid element iterator
Definition hrfblsm_discr.h:130
void assemble_element(ElemType *elem, DimFV1Geometry< dim > &geo, domain_type &grid, LocalVector &uOld, t_aaGrad &aaGradient, t_aaGrad &aaVelGrad, t_aaVol &aaVolume, int sign, t_aaUpd &aaUpdate, t_aaUpd *aaSrc)
assemble local contributions of one element
Definition hrfblsm_discr_impl.h:348
int assemble_cut_element(ElemType *elem, DimFV1Geometry< dim > &geo, domain_type &domain, LocalVector &uOld, LocalVector &locLSF, LocalVector &locVelPot, t_aaGrad &aaGradient, t_aaGrad &aaVelGrad, t_aaVol &aaVolume, t_aaUpd &aaUpdate, t_aaUpd *aaSrc, CplUserData< number, dim > *if_val_data, int si)
assemble an element intersected by the interface
Definition hrfblsm_discr_impl.h:619
void compute_vertex_grad(TGridFunction &u, DimFV1Geometry< dim > &geo, t_aaVol &aaVolume, ADimVector &aGradient, t_aaGrad &aaGradient, TGridFunction *pLSF=NULL, CplUserData< number, dim > *if_val_data=NULL)
compute gradients and volumes
Definition hrfblsm_discr_impl.h:984
void set_dirichlet_boundary(const char *subsets)
boundary condition subset handling: dirichlet boundary
Definition hrfblsm_discr_impl.h:2017
TGridFunction::template traits< Edge >::const_iterator EdgeConstIterator
edge iterator
Definition hrfblsm_discr.h:124
void get_bf_vel_on_if(DimFV1Geometry< dim > &geo, const typename DimFV1Geometry< dim >::BF &bf, number u[], MathVector< dim > grad[], number lsf[], MathVector< dim > &co_vel, number &flux)
get the velocity for a given BF in an element intersected by the interface
Definition hrfblsm_discr_impl.h:576
void advect()
computes the time steps of the discretization of the level-set equation
Definition hrfblsm_discr_impl.h:1343
void compute_volumes(TGridFunction &u, DimFV1Geometry< dim > &geo, ANumber &aVolume, t_aaVol &aaVolume)
compute CV volumes
Definition hrfblsm_discr_impl.h:865
void compute_normal_vel(SmartPtr< CplUserData< MathVector< dim >, dim > > spVelField, SmartPtr< TGridFunction > spNormVel)
compute the normal velocity using a user-data object
Definition hrfblsm_discr_impl.h:1738
domain_type::grid_type grid_type
grid type
Definition hrfblsm_discr.h:100
void mark_CoIE(grid_type &grid, ABool &aCoIE, t_aaCoIE &aaCoIE)
mark corners at the interface
Definition hrfblsm_discr_impl.h:81
void bnd_sol_update(bool redOrder, const MathVector< dim > &bip, const MathVector< dim > &x, number u, const MathVector< dim > &grad, const MathVector< dim > &vel, number &curr)
computes the bf-update of the solution in an element
Definition hrfblsm_discr_impl.h:236
void set_outflow_boundary(const char *subsets)
boundary condition subset handling: outflow boundary
Definition hrfblsm_discr_impl.h:2036
void get_nodal_vel(ElemType *elem, MathVector< dim > coCoord[], DimFV1Geometry< dim > &geo, LocalVector &u, MathVector< dim > grad[], MathVector< dim > co_vel[], int lsf_sign)
gets corner velocity and source
Definition hrfblsm_discr_impl.h:280
int lsf_sign(size_t noc, number lsf[])
sign of the LSF
Definition hrfblsm_discr_impl.h:60
void compute_elem_grad(DimFV1Geometry< dim > &geo, number uValue[], MathVector< dim > co_grad[], number *lsf, CplUserData< number, dim > *if_val_data, int si)
compute gradients in an element
Definition hrfblsm_discr_impl.h:925
domain_type::position_accessor_type position_accessor_type
type of the position accessor
Definition hrfblsm_discr.h:103
void limit_grad(TGridFunction &uOld, t_aaGrad &aaGradient)
slope limiter
Definition hrfblsm_discr_impl.h:1143
void append_vertical_to_normal_vel(SmartPtr< CplUserData< number, dim > > spNVelField, SmartPtr< TGridFunction > spNormVel)
appends a vertical vector the the normal velocity (using a user-data object)
Definition hrfblsm_discr_impl.h:1880
TGridFunction::domain_type domain_type
domain type
Definition hrfblsm_discr.h:91
TGridFunction::template dim_traits< dim >::grid_base_object ElemType
type of base grid object
Definition hrfblsm_discr.h:121
void get_scvf_vel_on_if(DimFV1Geometry< dim > &geo, const typename DimFV1Geometry< dim >::SCVF &scvf, number u[], MathVector< dim > grad[], number lsf[], MathVector< dim > &from_co_vel, number &from_flux, MathVector< dim > &to_co_vel, number &to_flux)
get the velocity for a given SCVF in an element intersected by the interface
Definition hrfblsm_discr_impl.h:515
TGridFunction::template traits< Vertex >::const_iterator VertexConstIterator
vertex base iterator
Definition hrfblsm_discr.h:127
void extrapolate_by_lsf(const CplUserData< number, dim > *if_val_data, int si, DimFV1Geometry< dim > &geo, number sol[], number lsf[], size_t base, number ext[])
extrapolation by the LSF
Definition hrfblsm_discr_impl.h:125
index_type & index(size_t fct, size_t dof)
comp_type & comp(size_t fct, size_t dof)
const LocalIndices & get_indices() const
void resize(const LocalIndices &ind)
void VecAssign(GPUVector< T > &dest, const GPUVector< T > &v1)
size_t num_subsets() const
void SetAttachmentValues(TAttachmentAccessor &aaVal, TIter elemsBegin, TIter elemsEnd, const TVal &val)
vector< string > TokenizeString(const char *str, const char delimiter=',')
vector_t::value_type VecLength(const vector_t &v)
void VecScaleAppend(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1)
void VecAppend(vector_t &vOut, const vector_t &v1)
void VecSubtract(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
void VecScale(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
const number & DoFRef(const TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
const number & BlockRef(const number &m, size_t i)
void GetLocalVector(LocalVector &lvec, const TVector &vec)
void VecScaleAdd(double &dest, double alpha1, const double &v1, double alpha2, const double &v2)