37template<
typename TDomain>
40 const std::vector<LFEID> & vLfeID,
47 " The discretization does not support hanging nodes.\n");
50 if (vLfeID.size () != 2)
51 UG_THROW (
"FractDDF_FV1: The density driven flow requires two coponents in every vertex.");
55 UG_THROW (
"FractDDF_FV1: This discretization works with the LagrangeP1-elements only.");
63template<
typename TDomain>
66 if (m_spVolStabData.valid())
68 m_spVolStabData->reset_flux();
70 if (m_sss_mngr.valid ())
73 m_sss_mngr->init_all_point_sss ();
74 m_sss_mngr->init_all_line_sss ();
79template<
typename TDomain>
80template<
typename TElem>
88 if (! m_spFractManager.valid())
92 if (! m_spFractManager->is_closed ())
93 UG_THROW (
"FractDDF_FV1: Fracture manager not closed");
94 m_isFracture = m_spFractManager->contains (si);
98 if (!m_imDensityCo.data_given())
99 UG_THROW (
"FractDDF_FV1: Missing Import 'density at corners'.");
100 if (!m_imDensityIP.data_given())
101 UG_THROW (
"FractDDF_FV1: Missing Import 'density at IPs'.");
102 if (!m_imViscosityCo.data_given())
103 UG_THROW (
"FractDDF_FV1: Missing Import 'viscosity at corners'.");
104 if (!m_imViscosityIP.data_given())
105 UG_THROW (
"FractDDF_FV1: Missing Import 'viscosity at IP's'.");
106 if (!m_imConstGravity.data_given())
107 UG_THROW (
"FractDDF_FV1: Missing Import 'gravity'.");
108 if (!m_imPorosity.data_given())
109 UG_THROW (
"FractDDF_FV1: Missing Import 'porosity'.");
110 if(m_spVolStabData.valid() && !m_imOldDensityCo.data_given())
111 UG_THROW (
"FractDDF_FV1: Missing Import 'density at corners'.");
114 if (m_imConstGravity.constant())
115 (*m_imConstGravity.user_data()) (m_Gravity,
MathVector<dim>(), 0.0, 0);
117 UG_THROW (
"FractDDF_FV1: Gravity must be constant.");
121 this->
template bulk_prepare_element_loop<TElem> (roid, si);
123 this->
template fract_prepare_element_loop<TElem> (roid, si);
126 m_bVolStabDataActive = (m_spVolStabData.valid() && m_spVolStabData->flux_is_active());
130template<
typename TDomain>
131template<
typename TElem>
141 if (!m_imPermeability.data_given())
142 UG_THROW (
"FractDDF_FV1: Missing Import 'full-dim. permeability'.");
143 if (!m_imDiffusion.data_given())
144 UG_THROW (
"FractDDF_FV1: Missing Import 'full_dim. diffusion'.");
147 if (m_spUpwind.invalid())
148 UG_THROW(
"FractDDF_FV1: Upwind has not been set.");
151 static const int refDim = TElem::dim;
154 m_imFractDarcyVelIP.set_data(
SPNULL);
158 size_t numSCVFip = bulk_geo.num_scvf_ips();
159 m_imDensityIP.template set_local_ips<refDim> (vSCVFip, numSCVFip,
false);
160 m_imViscosityIP.template set_local_ips<refDim> (vSCVFip, numSCVFip,
false);
163 size_t numSCVip = bulk_geo.num_scv_ips();
164 m_imDensityCo.template set_local_ips<refDim> (vSCVip, numSCVip,
false);
165 m_imViscosityCo.template set_local_ips<refDim> (vSCVip, numSCVip,
false);
166 if (m_spVolStabData.valid ())
167 m_imOldDensityCo.template set_local_ips<refDim> (vSCVip, numSCVip, 1,
false);
170 m_imPorosity.template set_local_ips<refDim> (coe_local, 1,
false);
171 m_imPermeability.template set_local_ips<refDim> (coe_local, 1,
false);
172 m_imDiffusion.template set_local_ips<refDim> (coe_local, 1,
false);
175 if(! m_spUpwind->template set_geometry_type<TBulkFVGeom>(bulk_geo))
176 UG_THROW(
"FractDDF_FV1: Cannot init upwind for bulk element type.");
180template<
typename TDomain>
181template<
typename TElem>
189 static const int refDim = TElem::dim;
196 m_imFractDarcyVelIP.set_data(m_exFractDarcyVel);
199 if (!m_imAperture.data_given())
200 UG_THROW (
"FractDDF_FV1: Missing Import 'fracture width (aperture)'.");
201 if (!m_imFractPermeability.data_given())
202 UG_THROW (
"FractDDF_FV1: Missing Import 'permeability along fracture'.");
203 if (!m_imPermeability.data_given() && !m_imOrthoPermeability.data_given())
204 UG_THROW (
"FractDDF_FV1: Missing Import 'permeability' (for the fract.-bulk interface interaction).");
205 if (!m_imFractDiffusion.data_given())
206 UG_THROW (
"FractDDF_FV1: Missing Import 'diffusion along fracture'.");
207 if (!m_imDiffusion.data_given() && !m_imOrthoDiffusion.data_given())
208 UG_THROW (
"FractDDF_FV1: Missing Import 'diffusion' (for the fract.-bulk interface interaction).");
211 if (m_spUpwind.invalid())
212 UG_THROW(
"FractDDF_FV1: Upwind has not been set.");
218 m_imDensityCo.template set_local_ips<refDim> (rRefElem.corners(), ref_elem_type::numCorners,
false);
219 m_imViscosityCo.template set_local_ips<refDim> (rRefElem.corners(), ref_elem_type::numCorners,
false);
220 if(m_spVolStabData.valid())
221 m_imOldDensityCo.template set_local_ips<refDim> (rRefElem.corners(), ref_elem_type::numCorners, 1,
false);
225template<
typename TDomain>
226template<
typename TElem>
232template<
typename TDomain>
233template<
typename TElem>
242 TElem * pElem =
static_cast<TElem*
> (elem);
246 this->
template bulk_prepare_element<TElem> (u, pElem, vCornerCoords);
248 this->
template fract_prepare_element<TElem> (u, pElem, vCornerCoords);
252template<
typename TDomain>
253template<
typename TElem>
269 UG_CATCH_THROW(
"FractDDF_FV1: Cannot update the Finite Volume Geometry for a bulk element.");
273 size_t numSCVFip = bulk_geo.num_scvf_ips();
274 m_imDensityIP.set_global_ips (vSCVFip, numSCVFip);
275 m_imViscosityIP.set_global_ips (vSCVFip, numSCVFip);
278 size_t numSCVip = bulk_geo.num_scv_ips();
279 m_imDensityCo.set_global_ips (vSCVip, numSCVip);
280 m_imViscosityCo.set_global_ips (vSCVip, numSCVip);
281 if(m_spVolStabData.valid())
282 m_imOldDensityCo.set_global_ips (vSCVip, numSCVip);
285 m_imPorosity.set_global_ips (coe_global, 1);
286 m_imPermeability.set_global_ips (coe_global, 1);
287 m_imDiffusion.set_global_ips (coe_global, 1);
291template<
typename TDomain>
292template<
typename TElem>
306 m_spFractManager->get_layer_sides
308 m_numFractCo, m_innerFractSide, m_innerFractSideIdx, m_innerSideCo,
309 m_outerFractSide, m_outerFractSideIdx, m_outerSideCo,
312 UG_CATCH_THROW(
"FractDDF_FV1: Cannot find orientation of a fracture element.");
318 for (
size_t co = 0; co < m_numFractCo; co++)
319 vSideCornerCoords [co] = vCornerCoords [m_innerSideCo [co]];
320 m_pFractGeo->update (m_innerFractSide, vSideCornerCoords, &(this->
subset_handler()));
322 UG_CATCH_THROW(
"FractDDF_FV1: Cannot update the Finite Volume Geometry for a fracture element.");
323 size_t numSCVFip = m_pFractGeo->num_scvf_ips ();
330 = ReferenceMappingProvider::get<low_dim, dim> (m_innerFractSide->reference_object_id ());
331 for (
size_t co = 0; co < m_numFractCo; co++)
332 vSideLocCornerCoords [co] = rRefElem.corner (m_innerSideCo [co]);
333 rMapping.
update (vSideLocCornerCoords);
335 rMapping.
local_to_global (m_elem_loc_coe, *(m_pFractGeo->coe_local ()));
336 rMapping.
local_to_global (m_elem_loc_scvf, m_pFractGeo->scvf_local_ips (), numSCVFip);
338 UG_CATCH_THROW(
"FractDDF_FV1: Cannot transform local side coordinates to local element coordinates in a fracture element.");
341 m_imDensityIP.template set_local_ips<dim> (m_elem_loc_scvf, numSCVFip);
342 m_imViscosityIP.template set_local_ips<dim> (m_elem_loc_scvf, numSCVFip);
344 m_imAperture.template set_local_ips<dim> (&m_elem_loc_coe, 1);
345 m_imPorosity.template set_local_ips<dim> (&m_elem_loc_coe, 1);
346 m_imFractPermeability.template set_local_ips<dim> (&m_elem_loc_coe, 1);
347 if (m_imOrthoPermeability.data_given ())
348 m_imOrthoPermeability.template set_local_ips<dim> (&m_elem_loc_coe, 1);
350 m_imPermeability.template set_local_ips<dim> (&m_elem_loc_coe, 1);
351 m_imFractDiffusion.template set_local_ips<dim> (&m_elem_loc_coe, 1);
352 if (m_imOrthoDiffusion.data_given ())
353 m_imOrthoDiffusion.template set_local_ips<dim> (&m_elem_loc_coe, 1);
355 m_imDiffusion.template set_local_ips<dim> (&m_elem_loc_coe, 1);
359 m_imDensityIP.set_global_ips (vSCVFip, numSCVFip);
360 m_imViscosityIP.set_global_ips (vSCVFip, numSCVFip);
363 m_imAperture.set_global_ips (coe_global, 1);
364 m_imPorosity.set_global_ips (coe_global, 1);
365 m_imFractPermeability.set_global_ips (coe_global, 1);
366 if (m_imOrthoPermeability.data_given ())
367 m_imOrthoPermeability.set_global_ips (coe_global, 1);
369 m_imPermeability.set_global_ips (coe_global, 1);
370 m_imFractDiffusion.set_global_ips (coe_global, 1);
371 if (m_imOrthoDiffusion.data_given ())
372 m_imOrthoDiffusion.set_global_ips (coe_global, 1);
374 m_imDiffusion.set_global_ips (coe_global, 1);
387 m_imDensityCo.set_global_ips (vCornerCoords, ref_elem_type::numCorners);
388 m_imViscosityCo.set_global_ips (vCornerCoords, ref_elem_type::numCorners);
389 if(m_spVolStabData.valid())
390 m_imOldDensityCo.set_global_ips (vCornerCoords, ref_elem_type::numCorners);
393 m_imFractDarcyVelIP.template set_local_ips<dim> (m_elem_loc_scvf, numSCVFip);
394 m_imFractDarcyVelIP.set_global_ips(vSCVFip, numSCVFip);
397 SideNormal<ref_elem_type, dim> (m_unitOuterNormal, m_outerFractSideIdx, vCornerCoords);
399 if (outerNormalNorm < 1e-32)
400 UG_THROW (
"FractDDF_FV1: Cannot get the normal to a fracture.")
401 m_unitOuterNormal /= outerNormalNorm;
402 m_orthGravity =
VecDot (m_Gravity, m_unitOuterNormal);
405 if(! m_spUpwind->template set_geometry_type<TFractFVGeom>(*m_pFractGeo))
406 UG_THROW(
"FractDDF_FV1: Cannot init upwind for fracture element type.");
410template<
typename TDomain>
411template<
typename TFVGeom,
typename TConsGravity>
417 TConsGravity& ConsGravityMethod,
423 const typename TFVGeom::SCVF& scvf = geo.scvf(ip);
426 ConsGravityMethod.template compute<dim>
427 (Vel, scvf.local_ip(), scvf.JTInv(), scvf.local_grad_vector(), vConsGravity);
430 for (
size_t sh = 0; sh < scvf.num_sh(); sh++)
438template<
typename TDomain>
439template<
typename TElem>
448 TElem * pElem =
static_cast<TElem*
> (elem);
453 this->
template bulk_ass_dA_elem<TElem> (d, u, pElem, vCornerCoords);
457 this->
template fract_ass_dA_elem<TElem> (d, u, pElem, vCornerCoords);
458 this->
template fract_bulk_ass_dA_elem<TElem> (d, u, pElem, vCornerCoords);
463template<
typename TDomain>
464template<
typename TElem>
479 MathVector<dim> Vel[TBulkFVGeom::numSCVF], DarcyVel[TBulkFVGeom::numSCVF];
485 const size_t numSh = bulk_geo.num_sh();
486 const size_t numScvf = bulk_geo.num_scvf();
489 TConsGravity ConsGravityMethod;
495 ConsGravityMethod.template prepare<dim>
496 (vConsGravity, numSh, vCornerCoords, m_imDensityCo.values(), m_Gravity);
498 UG_CATCH_THROW (
"FractDDF_FV1::bulk_ass_dA_elem: Cannot prepare Consistent Gravity.");
501 number vPressure [ref_elem_type::numCorners];
502 for (
size_t sh = 0; sh < numSh; sh++)
503 vPressure[sh] = u(_P_, sh);
506 MatScale(Diffusion[0], m_imPorosity[0], m_imDiffusion[0]);
507 for (
size_t ip = 1; ip < numScvf; ip++)
508 Diffusion[ip] = Diffusion[0];
512 for (
size_t ip = 0; ip < numScvf; ip++)
514 this->
template compute_ip_Darcy_velocity<TBulkFVGeom, TConsGravity>
515 (Vel[ip], ip, bulk_geo, ConsGravityMethod, vConsGravity, vPressure,
516 m_imViscosityIP[ip]);
517 MatVecMult (DarcyVel[ip], m_imPermeability[0], Vel[ip]);
521 if(!m_spUpwind->update(&bulk_geo, DarcyVel, Diffusion,
false))
522 UG_THROW(
"FractDDF_FV1::bulk_ass_dA_elem: Cannot compute convection shapes.");
529 for (
size_t ip = 0; ip < numScvf; ip++)
532 const typename TBulkFVGeom::SCVF& scvf = bulk_geo.scvf(ip);
536 for (
size_t sh = 0; sh < scvf.num_sh(); sh++)
546 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
547 flux += convShape(ip, sh) * u(_C_, sh);
550 MatVecMult(Dgrad_c_ip, Diffusion[ip], grad_c_ip);
551 const number diffFlux =
VecDot(Dgrad_c_ip, scvf.normal());
555 if(!m_BoussinesqTransport) flux *= m_imDensityIP[ip];
558 d(_C_,scvf.from()) += flux;
559 d(_C_,scvf.to()) -= flux;
566 flux =
VecDot(DarcyVel[ip], scvf.normal());
567 if(!m_BoussinesqFlow) flux *= m_imDensityIP[ip];
570 d(_P_,scvf.from()) += flux;
571 d(_P_,scvf.to()) -= flux;
574 if(m_bVolStabDataActive)
576 m_spVolStabData->stiff(pElem->vertex(scvf.from())) -= flux;
577 m_spVolStabData->stiff(pElem->vertex(scvf.to())) += flux;
584 if (m_sss_mngr.valid () && (m_sss_mngr->num_points () != 0 || m_sss_mngr->num_lines () != 0))
586 typedef typename domain_type::position_accessor_type t_pos_accessor;
588 point_iterator<TElem,t_pos_accessor,TBulkFVGeom> t_pnt_sss_iter;
590 line_iterator<TElem,t_pos_accessor,TBulkFVGeom> t_lin_sss_iter;
592 t_pos_accessor& aaPos = this->domain()->position_accessor ();
595 for(
size_t ip = 0; ip < bulk_geo.num_scv(); ip++)
597 size_t co = bulk_geo.scv(ip).node_id ();
600 for (t_pnt_sss_iter pnt (m_sss_mngr.get (), pElem,
grid, aaPos, bulk_geo, co);
601 ! pnt.is_over (); ++pnt)
604 if (! pnt_sss->marked_for (pElem, co))
606 pnt_sss->compute (pnt_sss->
position (), this->time (), -1);
607 ass_sss_dA_elem (d, u, pElem, co, pnt_sss->intensity (), pnt_sss->concentration ());
611 for (t_lin_sss_iter line (m_sss_mngr.get (), pElem,
grid, aaPos, bulk_geo, co);
612 ! line.is_over (); ++line)
616 line_sss->compute (line.seg_start (), this->time (), -1);
617 ass_sss_dA_elem (d, u, pElem, co, line_sss->intensity () * len, line_sss->concentration ());
624template<
typename TDomain>
625template<
typename TElem>
634 const number half_fr_width = m_imAperture[0] / 2;
640 const size_t numSh = m_pFractGeo->num_sh();
641 const size_t numScvf = m_pFractGeo->num_scvf();
644 number vConcentration [maxFractSideCorners];
645 for (
size_t sh = 0; sh < numSh; sh++)
647 size_t co = m_innerSideCo[sh];
648 vConcentration[sh] = u(_C_, co);
653 MatDiagSet (Diffusion[0], m_imPorosity[0] * m_imFractDiffusion[0]);
654 for (
size_t ip = 1; ip < numScvf; ip++)
655 Diffusion[ip] = Diffusion[0];
659 if(!m_spUpwind->update(m_pFractGeo, m_imFractDarcyVelIP.values(), Diffusion,
false))
660 UG_THROW(
"FractDDF_FV1::fract_ass_dA_elem: Cannot compute convection shapes.");
667 for (
size_t ip = 0; ip < numScvf; ip++)
670 const typename TFractFVGeom::SCVF& scvf = m_pFractGeo->scvf(ip);
674 for (
size_t sh = 0; sh < scvf.num_sh(); sh++)
675 VecScaleAppend (grad_c_ip, vConcentration[sh], scvf.global_grad(sh));
684 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
685 flux += convShape(ip, sh) * vConcentration[sh];
688 MatVecMult(Dgrad_c_ip, Diffusion[ip], grad_c_ip);
689 const number diffFlux =
VecDot(Dgrad_c_ip, scvf.normal());
692 flux = (flux - diffFlux) * half_fr_width;
693 if(!m_BoussinesqTransport) flux *= m_imDensityIP[ip];
696 d(_C_, m_innerSideCo[scvf.from()]) += flux;
697 d(_C_, m_innerSideCo[scvf.to()]) -= flux;
704 flux =
VecDot(m_imFractDarcyVelIP[ip], scvf.normal()) * half_fr_width;
706 if(!m_BoussinesqFlow) flux *= m_imDensityIP[ip];
709 d(_P_, m_innerSideCo[scvf.from()]) += flux;
710 d(_P_, m_innerSideCo[scvf.to()]) -= flux;
713 if(m_bVolStabDataActive)
715 m_spVolStabData->stiff(pElem->vertex(m_innerSideCo[scvf.from()])) -= flux;
716 m_spVolStabData->stiff(pElem->vertex(m_innerSideCo[scvf.to()])) += flux;
723 if (m_sss_mngr.valid () && m_sss_mngr->num_lines () != 0)
725 typedef typename domain_type::position_accessor_type t_pos_accessor;
727 line_iterator<side_type,t_pos_accessor,TFractFVGeom> t_lin_sss_iter;
729 t_pos_accessor& aaPos = this->domain()->position_accessor ();
732 for(
size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
735 size_t side_co = m_pFractGeo->scv(ip).node_id ();
737 size_t co = m_innerSideCo [m_pFractGeo->scv(ip).node_id ()];
740 for (t_lin_sss_iter line (m_sss_mngr.get (), m_innerFractSide,
grid, aaPos, *m_pFractGeo, side_co);
741 ! line.is_over (); ++line)
744 if (! line_sss->marked_for (m_innerFractSide, side_co))
746 line_sss->compute (line.seg_start (), this->time (), -1);
747 ass_sss_dA_elem (d, u, pElem, co, line_sss->intensity () / 2, line_sss->concentration ());
755template<
typename TDomain>
756template<
typename TElem>
767 if (m_imOrthoPermeability.data_given ())
768 orthPermeability = m_imOrthoPermeability[0];
772 MatVecMult (orthPermeabilityVec, m_imPermeability[0], m_unitOuterNormal);
773 orthPermeability =
VecDot (orthPermeabilityVec, m_unitOuterNormal);
778 if (m_imOrthoDiffusion.data_given())
779 orthDiffusion = m_imPorosity[0] * m_imOrthoDiffusion[0];
783 MatVecMult (orthDiffusionVec, m_imDiffusion[0], m_unitOuterNormal);
784 orthDiffusion = m_imPorosity[0] *
VecDot (orthDiffusionVec, m_unitOuterNormal);
788 const number half_fr_width = m_imAperture[0] / 2;
791 for (
size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
794 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
797 const int co = m_innerSideCo [scv.node_id()];
800 const number orthC_f = u(_C_, co);
801 const number orthC_m = u(_C_, m_assCo[co]);
802 const number orthP_f = u(_P_, co);
803 const number orthP_m = u(_P_, m_assCo[co]);
804 const number fractDensity = m_imDensityCo[co];
805 const number orthDensity = m_imDensityCo [m_assCo[co]];
806 const number orthViscosity = m_imViscosityCo [m_assCo[co]];
809 const number orthVelocity = (m_orthGravity * (orthDensity - fractDensity)
810 - (orthP_m - orthP_f) / half_fr_width)
811 * orthPermeability / orthViscosity;
820 flux = orthDiffusion * (orthC_m - orthC_f) / half_fr_width;
822 flux -= orthVelocity * ((orthVelocity >= 0)? orthC_f : orthC_m);
823 flux *= scv.volume();
824 if (! m_BoussinesqTransport) flux *= orthDensity;
825 d(_C_, m_assCo[co]) += flux;
832 flux = orthVelocity * scv.volume();
833 if (! m_BoussinesqFlow) flux *= orthDensity;
834 d(_P_, m_assCo[co]) -= flux;
838 if(m_bVolStabDataActive)
840 m_spVolStabData->stiff(pElem->vertex(m_assCo[co])) += flux;
841 m_spVolStabData->stiff(pElem->vertex(co)) -= flux;
849template<
typename TDomain>
850template<
typename TFVGeom,
typename TConsGravity,
size_t maxCorners>
858 TConsGravity& ConsGravityMethod,
865 const typename TFVGeom::SCVF& scvf = geo.scvf(ip);
867 const size_t numSh = geo.num_sh();
870 for (
size_t sh = 0; sh < numSh; sh++)
872 ConsGravityMethod.template compute<dim>
873 (Vel_c[sh], scvf.local_ip(), scvf.JTInv(), scvf.local_grad_vector(),
875 VecScale (Vel_c[sh], Vel_c[sh], InvVisco);
877 VecScale (Vel_p[sh], scvf.global_grad(sh), -InvVisco);
881 if (Viscosity_c != NULL)
882 for (
size_t sh = 0; sh < numSh; sh++)
887template<
typename TDomain>
888template<
typename TElem>
897 TElem * pElem =
static_cast<TElem*
> (elem);
901 this->
template bulk_ass_JA_elem<TElem> (J, u, pElem, vCornerCoords);
904 this->
template fract_ass_JA_elem<TElem> (J, u, pElem, vCornerCoords);
905 this->
template fract_bulk_ass_JA_elem<TElem> (J, u, pElem, vCornerCoords);
910template<
typename TDomain>
911template<
typename TElem>
923 static const size_t numCorners = ref_elem_type::numCorners;
928 const size_t numSh = bulk_geo.num_sh();
929 const size_t numScvf = bulk_geo.num_scvf();
933 MathVector<dim> Vel[TBulkFVGeom::numSCVF], DarcyVel[TBulkFVGeom::numSCVF];
937 number vDFlux_c [numCorners], vDFlux_p [numCorners];
938 number vViscosity_c [numCorners], * pViscosity_c;
941 TConsGravity ConsGravityMethod;
948 ConsGravityMethod.template prepare<dim>
949 (vConsGravity, numSh, vCornerCoords, m_imDensityCo.values(), m_Gravity);
951 number co_density [numCorners];
952 memset (co_density, 0, ref_elem_type::numCorners *
sizeof (
number));
953 for (
size_t sh = 0; sh < numSh; sh++)
955 co_density[sh] = (m_imDensityCo.constant() ? 0.0 : m_imDensityCo.deriv (sh, _C_, sh));
956 ConsGravityMethod.template prepare<dim>
957 (vConsGravity_c[sh], numSh, vCornerCoords, co_density, m_Gravity);
958 co_density[sh] = 0.0;
961 UG_CATCH_THROW (
"FractDDF_FV1::bulk_ass_JA_elem: Cannot prepare Consistent Gravity or its derivatives.");
964 number vPressure [numCorners];
965 for (
size_t sh = 0; sh < numSh; sh++)
966 vPressure[sh] = u(_P_, sh);
969 MatScale(Diffusion[0], m_imPorosity[0], m_imDiffusion[0]);
970 for (
size_t ip = 1; ip < numScvf; ip++)
971 Diffusion[ip] = Diffusion[0];
975 for (
size_t ip = 0; ip < numScvf; ip++)
977 this->
template compute_ip_Darcy_velocity<TBulkFVGeom, TConsGravity>
978 (Vel[ip], ip, bulk_geo, ConsGravityMethod, vConsGravity, vPressure,
979 m_imViscosityIP[ip]);
980 MatVecMult (DarcyVel[ip], m_imPermeability[0], Vel[ip]);
984 if(!m_spUpwind->update(&bulk_geo, DarcyVel, Diffusion,
true))
985 UG_THROW(
"FractDDF_FV1::bulk_ass_dA_elem: Cannot compute convection shapes.");
992 for (
size_t ip = 0; ip < numScvf; ip++)
995 const typename TBulkFVGeom::SCVF& scvf = bulk_geo.scvf(ip);
999 for (
size_t sh = 0; sh < scvf.num_sh(); sh++)
1003 if (m_imViscosityIP.constant ())
1004 pViscosity_c = NULL;
1007 for (
size_t sh = 0; sh < numSh; sh++)
1008 vViscosity_c[sh] = (m_imViscosityIP.constant() ? 0.0 : m_imViscosityIP.deriv(ip, _C_, sh));
1009 pViscosity_c = vViscosity_c;
1013 this->
template compute_J_ip_Darcy_velocity <TBulkFVGeom, TConsGravity, numCorners>
1014 (Vel[ip], Vel_c, Vel_p, ip, bulk_geo, ConsGravityMethod, vConsGravity_c, vPressure,
1015 m_imViscosityIP[ip], pViscosity_c);
1016 for (
size_t sh = 0; sh < numSh; sh++)
1018 MatVecMult (vDDarcyVel_c[sh], m_imPermeability[0], Vel_c[sh]);
1019 MatVecMult (vDDarcyVel_p[sh], m_imPermeability[0], Vel_p[sh]);
1027 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1030 vDFlux_c[sh] = convShape(ip, sh);
1034 for(
size_t sh1 = 0; sh1 < scvf.num_sh(); ++sh1)
1036 vDFlux_c[sh] += u(_C_, sh1) *
VecDot(convShape.
D_vel(ip, sh1), vDDarcyVel_c[sh]);
1037 vDFlux_p[sh] += u(_C_, sh1) *
VecDot(convShape.
D_vel(ip, sh1), vDDarcyVel_p[sh]);
1043 MatVecMult(Dgrad, Diffusion[ip], scvf.global_grad(sh));
1044 vDFlux_c[sh] -=
VecDot(Dgrad, scvf.normal());
1048 if(!m_BoussinesqTransport)
1052 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1053 flux += convShape(ip, sh) * u(_C_, sh);
1057 flux -=
VecDot(Dgrad, scvf.normal());
1060 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1062 vDFlux_c[sh] = m_imDensityIP[ip] * vDFlux_c[sh] +
1063 (m_imDensityIP.constant() ? 0.0 : m_imDensityIP.deriv(ip, _C_, sh)) * flux;
1064 vDFlux_p[sh] *= m_imDensityIP[ip];
1069 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1071 J(_C_, scvf.from(), _C_, sh) += vDFlux_c[sh];
1072 J(_C_, scvf.to(), _C_, sh) -= vDFlux_c[sh];
1073 J(_C_, scvf.from(), _P_, sh) += vDFlux_p[sh];
1074 J(_C_, scvf.to(), _P_, sh) -= vDFlux_p[sh];
1082 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1084 vDFlux_c[sh] =
VecDot(vDDarcyVel_c[sh], scvf.normal());
1085 vDFlux_p[sh] =
VecDot(vDDarcyVel_p[sh], scvf.normal());
1090 if(!m_BoussinesqFlow)
1092 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1094 vDFlux_c[sh] = m_imDensityIP[ip] * vDFlux_c[sh] +
1095 (m_imDensityIP.constant() ? 0.0 : m_imDensityIP.deriv(ip, _C_, sh)) * flux;
1096 vDFlux_p[sh] *= m_imDensityIP[ip];
1099 flux *= m_imDensityIP[ip];
1103 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1105 J(_P_, scvf.from(), _C_, sh) += vDFlux_c[sh];
1106 J(_P_, scvf.to(), _C_, sh) -= vDFlux_c[sh];
1107 J(_P_, scvf.from(), _P_, sh) += vDFlux_p[sh];
1108 J(_P_, scvf.to(), _P_, sh) -= vDFlux_p[sh];
1113 if(m_bVolStabDataActive)
1115 m_spVolStabData->stiff(pElem->vertex(scvf.from())) -= flux;
1116 m_spVolStabData->stiff(pElem->vertex(scvf.to())) += flux;
1123 if (m_sss_mngr.valid () && (m_sss_mngr->num_points () != 0 || m_sss_mngr->num_lines () != 0))
1125 typedef typename domain_type::position_accessor_type t_pos_accessor;
1127 point_iterator<TElem,t_pos_accessor,TBulkFVGeom> t_pnt_sss_iter;
1129 line_iterator<TElem,t_pos_accessor,TBulkFVGeom> t_lin_sss_iter;
1131 t_pos_accessor& aaPos = this->domain()->position_accessor ();
1134 for(
size_t ip = 0; ip < bulk_geo.num_scv(); ip++)
1136 size_t co = bulk_geo.scv(ip).node_id ();
1139 for (t_pnt_sss_iter pnt (m_sss_mngr.get (), pElem,
grid, aaPos, bulk_geo, co);
1140 ! pnt.is_over (); ++pnt)
1143 if (! pnt_sss->marked_for (pElem, co))
1145 pnt_sss->compute (pnt_sss->
position (), this->time (), -1);
1146 ass_sss_JA_elem (J, u, pElem, co, pnt_sss->intensity (), pnt_sss->concentration ());
1150 for (t_lin_sss_iter line (m_sss_mngr.get (), pElem,
grid, aaPos, bulk_geo, co);
1151 ! line.is_over (); ++line)
1155 line_sss->compute (line.seg_start (), this->time (), -1);
1156 ass_sss_JA_elem (J, u, pElem, co, line_sss->intensity () * len, line_sss->concentration ());
1163template<
typename TDomain>
1164template<
typename TElem>
1173 number half_fr_width = m_imAperture[0] / 2;
1175 const size_t numSh = m_pFractGeo->num_sh();
1176 const size_t numScvf = m_pFractGeo->num_scvf();
1181 number vDFlux_c [maxFractSideCorners], vDFlux_p [maxFractSideCorners];
1184 number vConcentration [maxFractSideCorners];
1185 for (
size_t sh = 0; sh < numSh; sh++)
1187 size_t co = m_innerSideCo[sh];
1188 vConcentration[sh] = u(_C_, co);
1192 MatSet (Diffusion[0], 0);
1193 MatDiagSet (Diffusion[0], m_imPorosity[0] * m_imFractDiffusion[0]);
1194 for (
size_t ip = 1; ip < numScvf; ip++)
1195 Diffusion[ip] = Diffusion[0];
1199 if(!m_spUpwind->update(m_pFractGeo, m_imFractDarcyVelIP.values(), Diffusion,
true))
1200 UG_THROW(
"FractDDF_FV1::fract_ass_dA_elem: Cannot compute convection shapes.");
1207 for (
size_t ip = 0; ip < numScvf; ip++)
1210 const typename TFractFVGeom::SCVF& scvf = m_pFractGeo->scvf(ip);
1214 for (
size_t sh = 0; sh < scvf.num_sh(); sh++)
1215 VecScaleAppend (grad_c_ip, vConcentration[sh], scvf.global_grad(sh));
1217 const MathVector<dim>* vDDarcyVel_c = m_imFractDarcyVelIP.deriv(ip, _C_);
1218 const MathVector<dim>* vDDarcyVel_p = m_imFractDarcyVelIP.deriv(ip, _P_);
1225 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1227 size_t co = m_innerSideCo[sh];
1230 vDFlux_c[sh] = convShape(ip, sh);
1234 for(
size_t sh1 = 0; sh1 < scvf.num_sh(); ++sh1)
1236 vDFlux_c[sh] += vConcentration[sh1] *
VecDot(convShape.
D_vel(ip, sh1), vDDarcyVel_c[co]);
1237 vDFlux_p[sh] += vConcentration[sh1] *
VecDot(convShape.
D_vel(ip, sh1), vDDarcyVel_p[co]);
1242 MatVecMult(Dgrad, Diffusion[ip], scvf.global_grad(sh));
1243 vDFlux_c[sh] -=
VecDot(Dgrad, scvf.normal());
1247 if(!m_BoussinesqTransport)
1251 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1252 flux += convShape(ip, sh) * vConcentration[sh];
1256 flux -=
VecDot(Dgrad, scvf.normal());
1259 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1261 vDFlux_c[sh] = m_imDensityIP[ip] * vDFlux_c[sh] +
1262 (m_imDensityIP.constant() ? 0.0 : m_imDensityIP.deriv(ip, _C_, m_innerSideCo[sh])) * flux;
1263 vDFlux_p[sh] *= m_imDensityIP[ip];
1268 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1270 vDFlux_c[sh] *= half_fr_width; vDFlux_p[sh] *= half_fr_width;
1274 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1276 size_t co = m_innerSideCo[sh];
1277 size_t co_from = m_innerSideCo[scvf.from()];
1278 size_t co_to = m_innerSideCo[scvf.to()];
1280 J(_C_, co_from, _C_, co) += vDFlux_c[sh];
1281 J(_C_, co_to, _C_, co) -= vDFlux_c[sh];
1282 J(_C_, co_from, _P_, co) += vDFlux_p[sh];
1283 J(_C_, co_to, _P_, co) -= vDFlux_p[sh];
1291 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1293 size_t co = m_innerSideCo[sh];
1294 vDFlux_c[sh] =
VecDot(vDDarcyVel_c[co], scvf.normal());
1295 vDFlux_p[sh] =
VecDot(vDDarcyVel_p[co], scvf.normal());
1298 number flux =
VecDot(m_imFractDarcyVelIP[ip], scvf.normal());
1300 if(!m_BoussinesqFlow)
1302 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1304 vDFlux_c[sh] = m_imDensityIP[ip] * vDFlux_c[sh] +
1305 (m_imDensityIP.constant() ? 0.0 : m_imDensityIP.deriv(ip, _C_, m_innerSideCo[sh])) * flux;
1306 vDFlux_p[sh] *= m_imDensityIP[ip];
1309 flux *= m_imDensityIP[ip];
1313 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1315 vDFlux_c[sh] *= half_fr_width; vDFlux_p[sh] *= half_fr_width;
1319 for(
size_t sh = 0; sh < scvf.num_sh(); ++sh)
1321 size_t co = m_innerSideCo[sh];
1322 size_t co_from = m_innerSideCo[scvf.from()];
1323 size_t co_to = m_innerSideCo[scvf.to()];
1325 J(_P_, co_from, _C_, co) += vDFlux_c[sh];
1326 J(_P_, co_to, _C_, co) -= vDFlux_c[sh];
1327 J(_P_, co_from, _P_, co) += vDFlux_p[sh];
1328 J(_P_, co_to, _P_, co) -= vDFlux_p[sh];
1333 if(m_bVolStabDataActive)
1335 flux *= half_fr_width;
1336 m_spVolStabData->stiff(pElem->vertex(m_innerSideCo[scvf.from()])) -= flux;
1337 m_spVolStabData->stiff(pElem->vertex(m_innerSideCo[scvf.to()])) += flux;
1344 if (m_sss_mngr.valid () && m_sss_mngr->num_lines () != 0)
1346 typedef typename domain_type::position_accessor_type t_pos_accessor;
1348 line_iterator<side_type,t_pos_accessor,TFractFVGeom> t_lin_sss_iter;
1350 t_pos_accessor& aaPos = this->domain()->position_accessor ();
1353 for(
size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
1356 size_t side_co = m_pFractGeo->scv(ip).node_id ();
1358 size_t co = m_innerSideCo [m_pFractGeo->scv(ip).node_id ()];
1361 for (t_lin_sss_iter line (m_sss_mngr.get (), m_innerFractSide,
grid, aaPos, *m_pFractGeo, side_co);
1362 ! line.is_over (); ++line)
1365 if (! line_sss->marked_for (m_innerFractSide, side_co))
1367 line_sss->compute (line.seg_start (), this->time (), -1);
1368 ass_sss_JA_elem (J, u, pElem, co, line_sss->intensity () / 2, line_sss->concentration ());
1376template<
typename TDomain>
1377template<
typename TElem>
1388 if (m_imOrthoPermeability.data_given ())
1389 orthPermeability = m_imOrthoPermeability[0];
1393 MatVecMult (orthPermeabilityVec, m_imPermeability[0], m_unitOuterNormal);
1394 orthPermeability =
VecDot (orthPermeabilityVec, m_unitOuterNormal);
1399 if (m_imOrthoDiffusion.data_given())
1400 orthDiffusion = m_imPorosity[0] * m_imOrthoDiffusion[0];
1404 MatVecMult (orthDiffusionVec, m_imDiffusion[0], m_unitOuterNormal);
1405 orthDiffusion = m_imPorosity[0] *
VecDot (orthDiffusionVec, m_unitOuterNormal);
1409 const number half_fr_width = m_imAperture[0] / 2;
1412 for (
size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
1415 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
1419 const int co = m_innerSideCo [scv.node_id()];
1422 const number orthC_f = u(_C_, co);
1423 const number orthC_m = u(_C_, m_assCo[co]);
1424 const number orthP_f = u(_P_, co);
1425 const number orthP_m = u(_P_, m_assCo[co]);
1427 const number fractDensity = m_imDensityCo[co];
1428 const number orthDensity = m_imDensityCo [m_assCo[co]];
1429 number D_fractDensity, D_orthDensity;
1430 if (! m_imDensityCo.constant())
1432 D_fractDensity = m_imDensityCo.deriv (co, _C_, co);
1433 D_orthDensity = m_imDensityCo.deriv (m_assCo[co], _C_, m_assCo[co]);
1435 else D_fractDensity = D_orthDensity = 0;
1437 const number orthViscosity = m_imViscosityCo [m_assCo[co]];
1438 const number D_orthViscosity = (m_imViscosityCo.constant())? 0.0
1439 : m_imViscosityCo.deriv (m_assCo[co], _C_, m_assCo[co]);
1443 number orthVelocity = (m_orthGravity * (orthDensity - fractDensity)
1444 - (orthP_m - orthP_f) / half_fr_width)
1447 number D_orthVelocity [2], D_orthVelocity_fr [2];
1449 D_orthVelocity [_C_] = (m_orthGravity * D_orthDensity
1450 * orthPermeability * orthViscosity
1451 - orthVelocity * D_orthViscosity) / orthViscosity / orthViscosity;
1453 D_orthVelocity_fr [_C_] = - m_orthGravity * D_fractDensity
1454 * orthPermeability / orthViscosity;
1456 D_orthVelocity [_P_] = - orthPermeability / half_fr_width / orthViscosity;
1458 D_orthVelocity_fr [_P_] = - D_orthVelocity [_P_];
1460 orthVelocity /= orthViscosity;
1463 number flux, D_flux [2], D_flux_fr [2];
1469 D_flux [_C_] = orthDiffusion / half_fr_width;
1470 D_flux_fr [_C_] = - D_flux [_C_];
1472 if (orthVelocity >= 0)
1474 D_flux [_C_] -= D_orthVelocity [_C_] * orthC_f;
1475 D_flux_fr [_C_] -= orthVelocity + D_orthVelocity_fr [_C_] * orthC_f;
1476 D_flux [_P_] = - D_orthVelocity [_P_] * orthC_f;
1477 D_flux_fr [_P_] = - D_orthVelocity_fr [_P_] * orthC_f;
1481 D_flux [_C_] -= orthVelocity + D_orthVelocity [_C_] * orthC_m;
1482 D_flux_fr [_C_] -= D_orthVelocity_fr [_C_] * orthC_m;
1483 D_flux [_P_] = - D_orthVelocity [_P_] * orthC_m;
1484 D_flux_fr [_P_] = - D_orthVelocity_fr [_P_] * orthC_m;
1487 if (! m_BoussinesqTransport)
1489 flux = orthDiffusion * (orthC_m - orthC_f) / half_fr_width;
1491 flux -= orthVelocity * ((orthVelocity >= 0)? orthC_f : orthC_m);
1493 D_flux [_C_] = D_flux [_C_] * orthDensity + flux * D_orthDensity;
1494 D_flux_fr [_C_] *= orthDensity;
1495 D_flux [_P_] *= orthDensity;
1496 D_flux_fr [_P_] *= orthDensity;
1499 J(_C_, m_assCo [co], _C_, m_assCo [co]) += D_flux [_C_] *
s;
1500 J(_C_, m_assCo [co], _P_, m_assCo [co]) += D_flux [_P_] *
s;
1501 J(_C_, m_assCo [co], _C_, co) += D_flux_fr [_C_] *
s;
1502 J(_C_, m_assCo [co], _P_, co) += D_flux_fr [_P_] *
s;
1504 J(_C_, co, _C_, m_assCo [co]) -= D_flux [_C_] *
s;
1505 J(_C_, co, _P_, m_assCo [co]) -= D_flux [_P_] *
s;
1506 J(_C_, co, _C_, co) -= D_flux_fr [_C_] *
s;
1507 J(_C_, co, _P_, co) -= D_flux_fr [_P_] *
s;
1513 if (! m_BoussinesqFlow)
1515 D_flux [_C_] = (D_orthVelocity [_C_] * orthDensity
1516 + orthVelocity * D_orthDensity) *
s;
1517 D_flux_fr [_C_] = D_orthVelocity_fr [_C_] * orthDensity *
s;
1521 D_flux [_C_] = D_orthVelocity [_C_] *
s;
1522 D_flux_fr [_C_] = D_orthVelocity_fr [_C_] *
s;
1524 J(_P_, m_assCo [co], _C_, m_assCo [co]) -= D_flux [_C_];
1525 J(_P_, co, _C_, m_assCo [co]) += D_flux [_C_];
1526 J(_P_, m_assCo [co], _C_, co) -= D_flux_fr [_C_];
1527 J(_P_, co, _C_, co) += D_flux_fr [_C_];
1529 if (! m_BoussinesqFlow)
s *= orthDensity;
1531 flux = D_orthVelocity [_P_] *
s;
1532 J(_P_, m_assCo [co], _P_, m_assCo [co]) -= flux;
1533 J(_P_, co, _P_, m_assCo [co]) += flux;
1535 flux = D_orthVelocity_fr [_P_] *
s;
1536 J(_P_, m_assCo [co], _P_, co) -= flux;
1537 J(_P_, co, _P_, co) += flux;
1541 if(m_bVolStabDataActive)
1543 flux = orthVelocity *
s;
1544 m_spVolStabData->stiff(pElem->vertex(m_assCo[co])) += flux;
1545 m_spVolStabData->stiff(pElem->vertex(co)) -= flux;
1553template<
typename TDomain>
1554template<
typename TElem>
1568 number density = 1000 + 000 * concentration;
1569 d(_C_, co) -= m_BoussinesqTransport? intensity * concentration : intensity * density * concentration;
1570 d(_P_, co) -= m_BoussinesqFlow? intensity : intensity * density;
1571 if(m_bVolStabDataActive)
1572 m_spVolStabData->stiff(pElem->vertex(co)) -= m_BoussinesqFlow? intensity : intensity * density;
1577 d(_C_, co) -= m_BoussinesqTransport? intensity * u(_C_, co) : intensity * m_imDensityCo[co] * u(_C_, co);
1578 d(_P_, co) -= m_BoussinesqFlow? intensity : intensity * m_imDensityCo[co];
1579 if(m_bVolStabDataActive)
1580 m_spVolStabData->stiff(pElem->vertex(co))
1581 -= m_BoussinesqFlow? intensity : intensity * m_imDensityCo[co];
1586template<
typename TDomain>
1587template<
typename TElem>
1601 number density = 1000 + 000 * concentration;
1602 if(m_bVolStabDataActive)
1603 m_spVolStabData->stiff(pElem->vertex(co))
1604 -= m_BoussinesqFlow? intensity : intensity * density;
1609 if (! m_BoussinesqTransport)
1611 if (!m_imDensityCo.constant ())
1613 -= intensity * (m_imDensityCo[co] + m_imDensityCo.deriv (co, _C_, co) * u (_C_, co));
1615 J(_C_, co, _C_, co) -= intensity * m_imDensityCo[co];
1618 J(_C_, co, _C_, co) -= intensity;
1620 if (! m_BoussinesqFlow && ! m_imDensityCo.constant ())
1621 J(_P_, co, _C_, co) -= intensity * m_imDensityCo.deriv (co, _C_, co);
1623 if(m_bVolStabDataActive)
1624 m_spVolStabData->stiff(pElem->vertex(co))
1625 -= m_BoussinesqFlow? intensity : intensity * m_imDensityCo[co];
1630template<
typename TDomain>
1631template<
typename TElem>
1640 TElem * pElem =
static_cast<TElem*
> (elem);
1644 this->
template bulk_ass_dM_elem<TElem> (d, u, pElem, vCornerCoords);
1646 this->
template fract_ass_dM_elem<TElem> (d, u, pElem, vCornerCoords);
1650template<
typename TDomain>
1651template<
typename TElem>
1666 number porosity = m_imPorosity [0];
1669 for (
size_t ip = 0; ip < bulk_geo.num_scv(); ip++)
1672 const typename TBulkFVGeom::SCV& scv = bulk_geo.scv(ip);
1675 const int co = scv.node_id();
1678 if(m_BoussinesqTransport)
1679 d(_C_,co) += porosity * u(_C_,co) * scv.volume();
1681 d(_C_,co) += porosity * m_imDensityCo[ip] * u(_C_,co) * scv.volume();
1683 if(m_BoussinesqFlow)
1684 d(_P_,co) += porosity * scv.volume();
1687 d(_P_,co) += porosity * m_imDensityCo[ip] * scv.volume();
1689 if (m_bVolStabDataActive)
1693 m_spVolStabData->mass(pElem->vertex(co))
1694 -= porosity * (m_imDensityCo[ip] - m_imOldDensityCo[ip])
1702template<
typename TDomain>
1703template<
typename TElem>
1713 number porosity = m_imPorosity[0] * m_imAperture[0] / 2;
1716 for (
size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
1719 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
1722 const int co = m_innerSideCo [scv.node_id()];
1725 if(m_BoussinesqTransport)
1726 d(_C_,co) += porosity * u(_C_,co) * scv.volume();
1728 d(_C_,co) += porosity * m_imDensityCo[co] * u(_C_,co) * scv.volume();
1730 if(m_BoussinesqFlow)
1731 d(_P_,co) += porosity * scv.volume();
1734 d(_P_,co) += porosity * m_imDensityCo[co] * scv.volume();
1736 if (m_bVolStabDataActive)
1740 m_spVolStabData->mass(pElem->vertex(co))
1741 -= porosity * (m_imDensityCo[co] - m_imOldDensityCo[co])
1749template<
typename TDomain>
1750template<
typename TElem>
1759 TElem * pElem =
static_cast<TElem*
> (elem);
1763 this->
template bulk_ass_JM_elem<TElem> (J, u, pElem, vCornerCoords);
1765 this->
template fract_ass_JM_elem<TElem> (J, u, pElem, vCornerCoords);
1769template<
typename TDomain>
1770template<
typename TElem>
1785 number porosity = m_imPorosity [0];
1788 for (
size_t ip = 0; ip < bulk_geo.num_scv(); ip++)
1791 const typename TBulkFVGeom::SCV& scv = bulk_geo.scv(ip);
1794 const int co = scv.node_id();
1797 if(m_BoussinesqTransport)
1798 J(_C_, co, _C_, co) += porosity * scv.volume();
1800 J(_C_, co, _C_, co) +=
1801 porosity * scv.volume() *
1802 (m_imDensityCo[ip] + (m_imDensityCo.constant() ? 0.0 : m_imDensityCo.deriv(ip, _C_, co)) * u(_C_, co));
1804 if(!m_BoussinesqFlow)
1806 J(_P_, co, _C_, co) += porosity * (m_imDensityCo.constant() ? 0.0 : m_imDensityCo.deriv(ip, _C_, co)) * scv.volume();
1808 if (m_bVolStabDataActive)
1812 m_spVolStabData->mass(pElem->vertex(co))
1813 -= porosity * scv.volume() * (m_imDensityCo[ip] - m_imOldDensityCo[ip]);
1837template<
typename TDomain>
1838template<
typename TElem>
1848 number porosity = m_imPorosity[0] * m_imAperture[0] / 2;
1851 for (
size_t ip = 0; ip < m_pFractGeo->num_scv(); ip++)
1854 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
1857 const int co = m_innerSideCo [scv.node_id()];
1860 if(m_BoussinesqTransport)
1861 J(_C_, co, _C_, co) += porosity * scv.volume();
1863 J(_C_, co, _C_, co) +=
1864 porosity * scv.volume() *
1865 (m_imDensityCo[ip] + (m_imDensityCo.constant() ? 0.0 : m_imDensityCo.deriv(co, _C_, co)) * u(_C_, co));
1867 if(!m_BoussinesqFlow)
1869 J(_P_, co, _C_, co) += porosity * (m_imDensityCo.constant() ? 0.0 : m_imDensityCo.deriv(co, _C_, co)) * scv.volume();
1871 if (m_bVolStabDataActive)
1875 m_spVolStabData->mass(pElem->vertex(co))
1876 -= porosity * scv.volume() * (m_imDensityCo[co] - m_imOldDensityCo[co]);
1900template<
typename TDomain>
1901template<
typename TElem>
1916template<
typename TDomain>
1917template<
typename TElem>
1930 std::vector<std::vector<number> > vvvDeriv[]
1937 static const size_t numSH = ref_elem_type::numCorners;
1946 for(
size_t ip = 0; ip < nip; ++ip)
1949 rTrialSpace.
shapes(vShape, vLocIP[ip]);
1953 for(
size_t sh = 0; sh < numSH; ++sh)
1954 vValue[ip] += u(_C_, sh) * vShape[sh];
1958 for(
size_t sh = 0; sh < numSH; ++sh)
1960 vvvDeriv[ip][_C_][sh] = vShape[sh];
1961 vvvDeriv[ip][_P_][sh] = 0.0;
1967template<
typename TDomain>
1968template<
typename TElem>
1981 std::vector<std::vector<number> > vvvDeriv[]
1988 static const size_t numSH = ref_elem_type::numCorners;
1997 for(
size_t ip = 0; ip < nip; ++ip)
2000 rTrialSpace.
shapes(vShape, vLocIP[ip]);
2004 for(
size_t sh = 0; sh < numSH; ++sh)
2005 vValue[ip] += u(_P_, sh) * vShape[sh];
2009 for(
size_t sh = 0; sh < numSH; ++sh)
2011 vvvDeriv[ip][_C_][sh] = 0;
2012 vvvDeriv[ip][_P_][sh] = vShape[sh];
2018template<
typename TDomain>
2019template<
typename TElem>
2040 if (nip != m_pFractGeo->num_scvf())
2041 UG_THROW (
"FractDDF_FV1: The Darcy velocity export parameter is only implemented for the standard set of IPs.");
2044 const size_t numSh = m_pFractGeo->num_sh();
2047 MathVector<dim> Vel_c[maxFractSideCorners], Vel_p[maxFractSideCorners];
2048 number vViscosity_c [maxFractSideCorners], * pViscosity_c;
2051 number vDensity [maxFractSideCorners];
2052 number vPressure [maxFractSideCorners];
2053 for (
size_t sh = 0; sh < numSh; sh++)
2055 size_t co = m_innerSideCo[sh];
2056 vDensity[sh] = m_imDensityCo[co];
2057 vPressure[sh] = u(_P_, co);
2061 TConsGravity ConsGravityMethod;
2068 ConsGravityMethod.template prepare<dim>
2069 (vConsGravity, numSh, m_pFractGeo->corners(), vDensity, m_Gravity);
2073 number co_density [maxFractSideCorners];
2074 memset (co_density, 0, numSh *
sizeof (
number));
2075 for (
size_t sh = 0; sh < numSh; sh++)
2077 size_t co = m_innerSideCo[sh];
2078 co_density[sh] = (m_imDensityCo.constant()) ? 0.0 : m_imDensityCo.deriv (co, _C_, co);
2079 ConsGravityMethod.template prepare<dim>
2080 (vConsGravity_c[sh], numSh, m_pFractGeo->corners(), co_density, m_Gravity);
2081 co_density[sh] = 0.0;
2085 UG_CATCH_THROW (
"FractDDF_FV1::fract_ass_dA_elem: Cannot prepare Consistent Gravity.");
2088 for (
size_t ip = 0; ip < nip; ip++)
2094 this->
template compute_ip_Darcy_velocity<TFractFVGeom, TConsGravity>
2095 (Vel, ip, *m_pFractGeo, ConsGravityMethod, vConsGravity, vPressure,
2096 m_imViscosityIP[ip]);
2097 VecScale (DarcyVel, Vel, m_imFractPermeability[0]);
2107 for (
size_t co = 0; co < vvvDeriv[ip][_C_].size(); co++)
2108 DarcyVel_c[co] = 0.0;
2109 for (
size_t co = 0; co < vvvDeriv[ip][_P_].size(); co++)
2110 DarcyVel_p[co] = 0.0;
2113 if (m_imViscosityIP.constant ())
2114 pViscosity_c = NULL;
2117 for (
size_t sh = 0; sh < numSh; sh++)
2119 size_t co = m_innerSideCo[sh];
2120 vViscosity_c[sh] = m_imViscosityIP.deriv(ip, _C_, co);
2122 pViscosity_c = vViscosity_c;
2126 this->
template compute_J_ip_Darcy_velocity <TFractFVGeom, TConsGravity, maxFractSideCorners>
2127 (Vel, Vel_c, Vel_p, ip, *m_pFractGeo, ConsGravityMethod, vConsGravity_c, vPressure,
2128 m_imViscosityIP[ip], pViscosity_c);
2129 for (
size_t sh = 0; sh < numSh; sh++)
2131 size_t co = m_innerSideCo[sh];
2132 VecScale (DarcyVel_c[co], Vel_c[sh], m_imFractPermeability[0]);
2133 VecScale (DarcyVel_p[co], Vel_p[sh], m_imFractPermeability[0]);
2139 UG_THROW (
"FractDDF_FV1: The Darcy velocity export parameter is currently implemented only for fractures.");
2143template<
typename TDomain>
2144template<
typename TElem>
2157 std::vector<std::vector<number> > vvvDeriv[]
2163 if (nip != m_pFractGeo->num_scv())
2164 UG_THROW (
"FractDDF_FV1: The Darcy velocity export parameter is only implemented for the standard set of IPs.");
2166 const number half_fr_width = m_imAperture[0] / 2;
2170 if (m_imOrthoPermeability.data_given ())
2171 orthPermeability = m_imOrthoPermeability[0];
2175 MatVecMult (orthPermeabilityVec, m_imPermeability[0], m_unitOuterNormal);
2176 orthPermeability =
VecDot (orthPermeabilityVec, m_unitOuterNormal);
2180 for (
size_t ip = 0; ip < nip; ip++)
2183 const typename TFractFVGeom::SCV& scv = m_pFractGeo->scv(ip);
2184 number& orthVelocity = vValue[ip];
2187 const int co = m_innerSideCo [scv.node_id()];
2190 const number orthP_f = u(_P_, co);
2191 const number orthP_m = u(_P_, m_assCo[co]);
2192 const number fractDensity = m_imDensityCo[co];
2193 const number orthDensity = m_imDensityCo [m_assCo[co]];
2194 const number orthViscosity = m_imViscosityCo [m_assCo[co]];
2197 orthVelocity = (m_orthGravity * (orthDensity - fractDensity)
2198 - (orthP_m - orthP_f) / half_fr_width)
2205 number* DarcyVel_c = &vvvDeriv[ip][_C_][0];
2206 number* DarcyVel_p = &vvvDeriv[ip][_P_][0];
2209 for (
size_t i = 0; i < vvvDeriv[ip][_C_].size(); i++) DarcyVel_c[i] = 0;
2210 for (
size_t i = 0; i < vvvDeriv[ip][_P_].size(); i++) DarcyVel_p[i] = 0;
2213 number D_fractDensity, D_orthDensity;
2214 if (! m_imDensityCo.constant())
2216 D_fractDensity = m_imDensityCo.deriv (co, _C_, co);
2217 D_orthDensity = m_imDensityCo.deriv (m_assCo[co], _C_, m_assCo[co]);
2219 else D_fractDensity = D_orthDensity = 0;
2221 const number D_orthViscosity = (m_imViscosityCo.constant())? 0.0
2222 : m_imViscosityCo.deriv (m_assCo[co], _C_, m_assCo[co]);
2224 number D_orthVelocity [2], D_orthVelocity_fr [2];
2226 D_orthVelocity [_C_] = (m_orthGravity * D_orthDensity
2227 * orthPermeability * orthViscosity
2228 - orthVelocity * D_orthViscosity) / orthViscosity / orthViscosity;
2230 D_orthVelocity_fr [_C_] = - m_orthGravity * D_fractDensity
2231 * orthPermeability / orthViscosity;
2233 D_orthVelocity [_P_] = - orthPermeability / half_fr_width / orthViscosity;
2235 D_orthVelocity_fr [_P_] = - D_orthVelocity [_P_];
2237 DarcyVel_c[co] = D_orthVelocity_fr[_C_];
2238 DarcyVel_p[co] = D_orthVelocity_fr[_P_];
2240 DarcyVel_c[m_assCo[co]] = D_orthVelocity[_C_];
2241 DarcyVel_p[m_assCo[co]] = D_orthVelocity[_P_];
2245 orthVelocity /= orthViscosity;
2249 UG_THROW (
"FractDDF_FV1: The orthogonal Darcy velocity export parameter is implemented only for fractures.");
2257template<
typename TDomain>
2258template<
typename TElem>
2264 this->clear_add_fct(
id);
2266 this->set_prep_elem_loop_fct(
id, & this_type::template prepare_element_loop<TElem>);
2267 this->set_prep_elem_fct (
id, & this_type::template prepare_element<TElem>);
2268 this->set_fsh_elem_loop_fct (
id, & this_type::template finish_element_loop<TElem>);
2269 this->set_add_jac_A_elem_fct(
id, & this_type::template ass_JA_elem<TElem>);
2270 this->set_add_jac_M_elem_fct(
id, & this_type::template ass_JM_elem<TElem>);
2271 this->set_add_def_A_elem_fct(
id, & this_type::template ass_dA_elem<TElem>);
2272 this->set_add_def_M_elem_fct(
id, & this_type::template ass_dM_elem<TElem>);
2273 this->set_add_rhs_elem_fct (
id, & this_type::template ass_rhs_elem<TElem>);
2275 m_exBrine->template set_fct<this_type, refDim> (
id,
this, &this_type::template ex_brine<TElem>);
2276 m_exPressure->template set_fct<this_type, refDim> (
id,
this, &this_type::template ex_pressure<TElem>);
2277 m_exFractDarcyVel->template set_fct<this_type,refDim>(
id,
this, &this_type::template ex_darcy_fract<TElem>);
2278 m_exOrthoFractDarcyVel->template set_fct<this_type,refDim>(
id,
this, &this_type::template ex_darcy_ortho_fract<TElem>);
2284template <
typename TDomain>
2287 const char* functions,
2290:
IElemDisc<TDomain> (functions, subsets)
2295template <
typename TDomain>
2298 const std::vector<std::string>& vFct,
2299 const std::vector<std::string>& vSubset
2306template <
typename TDomain>
2309 set_boussinesq (
false);
2311 m_imDensityCo.set_comp_lin_defect (
false);
2312 m_imOldDensityCo.set_comp_lin_defect (
false);
2313 m_imDensityIP.set_comp_lin_defect (
false),
2314 m_imViscosityCo.set_comp_lin_defect (
false);
2315 m_imViscosityIP.set_comp_lin_defect (
false);
2316 m_imConstGravity.set_comp_lin_defect (
false);
2317 m_imPorosity.set_comp_lin_defect (
false);
2318 m_imPermeability .set_comp_lin_defect(
false);
2319 m_imDiffusion.set_comp_lin_defect (
false);
2320 m_imAperture.set_comp_lin_defect (
false);
2321 m_imFractPermeability.set_comp_lin_defect (
false);
2322 m_imOrthoPermeability.set_comp_lin_defect (
false);
2323 m_imFractDiffusion.set_comp_lin_defect (
false);
2324 m_imOrthoDiffusion.set_comp_lin_defect (
false);
2326 m_imFractDarcyVelIP.set_comp_lin_defect (
false);
2328 m_spVolStabData =
SPNULL;
2330 std::string functions;
2331 for(
size_t i = 0; i < this->symb_fcts().size(); ++i)
2333 if(i > 0) functions.append(
",");
2334 functions.append(this->symb_fcts()[i]);
2343 if (this->num_fct () != 2)
2344 UG_THROW (
"Wrong number of functions: The ElemDisc 'FractDDF_FV1'"
2345 " needs exactly 2 symbolic function"
2346 " (one for the mass fraction and one for the pressure).");
2350 this->register_import (m_imDensityCo);
2351 this->register_import (m_imOldDensityCo);
2352 this->register_import (m_imDensityIP);
2353 this->register_import (m_imViscosityCo);
2354 this->register_import (m_imViscosityIP);
2355 this->register_import (m_imConstGravity);
2357 this->register_import (m_imPorosity);
2359 this->register_import (m_imPermeability);
2360 this->register_import (m_imDiffusion);
2362 this->register_import (m_imAperture);
2363 this->register_import (m_imFractPermeability);
2364 this->register_import (m_imOrthoPermeability);
2365 this->register_import (m_imFractDiffusion);
2366 this->register_import (m_imOrthoDiffusion);
2368 this->register_import(m_imFractDarcyVelIP);
parameterString s
Definition Biogas.lua:2
void shapes(shape_type *vShape, const MathVector< dim > &x) const
virtual void local_to_global(MathVector< worldDim > &globPos, const MathVector< dim > &locPos) const=0
virtual void update(const MathVector< worldDim > *vCornerCoord)=0
const MathVector< dim > & position()
const MathVector< dim > & D_vel(size_t scvf, size_t sh) const
virtual void prep_assemble_loop()
called once bevore assembling
Definition fract_ddf_fv1_impl.h:64
void ex_darcy_ortho_fract(number vValue[], const MathVector< dim > vGlobIP[], number time, int si, const LocalVector &u, GridObject *elem, const MathVector< dim > vCornerCoords[], const MathVector< dim > vLocIP[], const size_t nip, bool bDeriv, std::vector< std::vector< number > > vvvDeriv[])
export parameter for the orthogonal Darcy velocity
Definition fract_ddf_fv1_impl.h:2147
void fract_ass_JM_elem(LocalMatrix &J, const LocalVector &u, TElem *elem, const position_type vCornerCoords[])
computes the mass matrix of a time-dependent problem on a fracture element
Definition fract_ddf_fv1_impl.h:1840
void bulk_ass_dM_elem(LocalVector &d, const LocalVector &u, TElem *elem, const position_type vCornerCoords[])
computes the mass part of the defect of a time-dependent problem on a bulk element
Definition fract_ddf_fv1_impl.h:1653
void ass_JA_elem(LocalMatrix &J, const LocalVector &u, GridObject *elem, const position_type vCornerCoords[])
computes the local stiffness matrix
Definition fract_ddf_fv1_impl.h:890
virtual void prepare_setting(const std::vector< LFEID > &vLfeID, bool bNonRegular)
check type of the grid and the trial space
Definition fract_ddf_fv1_impl.h:39
void bulk_ass_dA_elem(LocalVector &d, const LocalVector &u, TElem *elem, const position_type vCornerCoords[])
computes the stiffness part of the local defect on a bulk element
Definition fract_ddf_fv1_impl.h:466
FractDDF_FV1(const char *functions, const char *subsets)
class constructor
Definition fract_ddf_fv1_impl.h:2286
void register_loc_discr_func()
registers the local assembler functions for a given element
Definition fract_ddf_fv1_impl.h:2259
void ass_dA_elem(LocalVector &d, const LocalVector &u, GridObject *elem, const position_type vCornerCoords[])
computes the stiffness part of the local defect
Definition fract_ddf_fv1_impl.h:441
void fract_bulk_ass_JA_elem(LocalMatrix &J, const LocalVector &u, TElem *elem, const position_type vCornerCoords[])
computes the local stiffness matrix of the fracture-bulk interaction terms on a fracture element
Definition fract_ddf_fv1_impl.h:1379
void ex_brine(number vValue[], const MathVector< dim > vGlobIP[], number time, int si, const LocalVector &u, GridObject *elem, const MathVector< dim > vCornerCoords[], const MathVector< dim > vLocIP[], const size_t nip, bool bDeriv, std::vector< std::vector< number > > vvvDeriv[])
export parameter for the concentration (to compute density and viscosity)
Definition fract_ddf_fv1_impl.h:1920
void bulk_prepare_element(const LocalVector &u, TElem *elem, const position_type vCornerCoords[])
prepares a given bulk element for assembling
Definition fract_ddf_fv1_impl.h:255
void bulk_ass_JA_elem(LocalMatrix &J, const LocalVector &u, TElem *elem, const position_type vCornerCoords[])
computes the local stiffness matrix on a bulk element
Definition fract_ddf_fv1_impl.h:913
void fract_prepare_element_loop(ReferenceObjectID roid, int si)
prepares the loop over the elements: the 'fracture' version
Definition fract_ddf_fv1_impl.h:183
void bulk_prepare_element_loop(ReferenceObjectID roid, int si)
prepares the loop over the elements: the 'bulk' version
Definition fract_ddf_fv1_impl.h:133
void bulk_ass_JM_elem(LocalMatrix &J, const LocalVector &u, TElem *elem, const position_type vCornerCoords[])
computes the mass matrix of a time-dependent problem on a bulk element
Definition fract_ddf_fv1_impl.h:1772
void compute_ip_Darcy_velocity(MathVector< dim > &Vel, size_t ip, const TFVGeom &bulk_geo, TConsGravity &ConsGravityMethod, MathVector< TFVGeom::dim > vConsGravity[], number vPressure[], number Viscosity)
computes the Darcy velocity (not scaled with the permeability)
Definition fract_ddf_fv1_impl.h:413
void fract_bulk_ass_dA_elem(LocalVector &d, const LocalVector &u, TElem *elem, const position_type vCornerCoords[])
computes the stiffness fracture-bulk interaction terms of the local defect on a fracture element
Definition fract_ddf_fv1_impl.h:758
void finish_element_loop()
finalizes the loop over the elements
Definition fract_ddf_fv1_impl.h:227
void fract_ass_JA_elem(LocalMatrix &J, const LocalVector &u, TElem *elem, const position_type vCornerCoords[])
computes the local stiffness matrix on a fracture element
Definition fract_ddf_fv1_impl.h:1166
void ass_sss_JA_elem(LocalMatrix &J, const LocalVector &u, TElem *pElem, size_t co, number intensity, number concentration)
assembles a singular source or sink in the jacobian
Definition fract_ddf_fv1_impl.h:1589
void compute_J_ip_Darcy_velocity(MathVector< dim > &Vel, MathVector< dim > Vel_c[], MathVector< dim > Vel_p[], size_t ip, const TFVGeom &geo, TConsGravity &ConsGravityMethod, MathVector< TFVGeom::dim > vConsGravity_c[][maxCorners], number vPressure[], number Viscosity, number Viscosity_c[])
computes the derivatives of the Darcy velocity (not scaled with the permeability)
Definition fract_ddf_fv1_impl.h:852
void ass_rhs_elem(LocalVector &d, GridObject *elem, const position_type vCornerCoords[])
computes the right-hand side due to the sources
Definition fract_ddf_fv1_impl.h:1903
void fract_ass_dA_elem(LocalVector &d, const LocalVector &u, TElem *elem, const position_type vCornerCoords[])
computes the stiffness part of the local defect on a fracture element
Definition fract_ddf_fv1_impl.h:627
void prepare_element_loop(ReferenceObjectID roid, int si)
prepares the loop over the elements: checks whether the parameters are set, ...
Definition fract_ddf_fv1_impl.h:82
base_type::position_type position_type
position type
Definition fract_ddf_fv1.h:78
void ass_JM_elem(LocalMatrix &J, const LocalVector &u, GridObject *elem, const position_type vCornerCoords[])
computes the mass matrix of a time-dependent problem
Definition fract_ddf_fv1_impl.h:1752
void ex_darcy_fract(MathVector< dim > vValue[], const MathVector< dim > vGlobIP[], number time, int si, const LocalVector &u, GridObject *elem, const MathVector< dim > vCornerCoords[], const MathVector< dim > vLocIP[], const size_t nip, bool bDeriv, std::vector< std::vector< MathVector< dim > > > vvvDeriv[])
export parameter for the Darcy velocity in the fracture
Definition fract_ddf_fv1_impl.h:2022
void ass_dM_elem(LocalVector &d, const LocalVector &u, GridObject *elem, const position_type vCornerCoords[])
computes the mass part of the defect of a time-dependent problem
Definition fract_ddf_fv1_impl.h:1633
void ex_pressure(number vValue[], const MathVector< dim > vGlobIP[], number time, int si, const LocalVector &u, GridObject *elem, const MathVector< dim > vCornerCoords[], const MathVector< dim > vLocIP[], const size_t nip, bool bDeriv, std::vector< std::vector< number > > vvvDeriv[])
export parameter for the pressure
Definition fract_ddf_fv1_impl.h:1971
void init()
Definition fract_ddf_fv1_impl.h:2307
void fract_prepare_element(const LocalVector &u, TElem *elem, const position_type vCornerCoords[])
prepares a given fracture element for assembling
Definition fract_ddf_fv1_impl.h:294
void fract_ass_dM_elem(LocalVector &d, const LocalVector &u, TElem *elem, const position_type vCornerCoords[])
computes the mass part of the defect of a time-dependent problem on a fracture element
Definition fract_ddf_fv1_impl.h:1705
void prepare_element(const LocalVector &u, GridObject *elem, ReferenceObjectID roid, const position_type vCornerCoords[])
prepares a given element for assembling
Definition fract_ddf_fv1_impl.h:235
void ass_sss_dA_elem(LocalVector &d, const LocalVector &u, TElem *pElem, size_t co, number intensity, number concentration)
assembles a singular source or sink in the defect
Definition fract_ddf_fv1_impl.h:1556
function util d3f parse Viscosity(ViscosityDesc, w)
SmartPtr< TSubsetHandler > subset_handler()
void MatSet(matrix_t &mInOut, typename matrix_t::value_type s)
void MatDiagSet(matrix_t &mInOut, typename matrix_t::value_type s)
void MatScale(matrix_t &mOut, typename matrix_t::value_type s, const matrix_t &m)
const NullSmartPtr SPNULL
#define UG_CATCH_THROW(msg)
void MatVecMult(vector_t_out &vOut, const matrix_t &m, const vector_t_in &v)
vector_t::value_type VecLength(const vector_t &v)
void VecScaleAppend(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1)
vector_t::value_type VecDistance(const vector_t &v1, const vector_t &v2)
void VecScale(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)
void VecSet(vector_t &dest, number alpha, const std::vector< size_t > vIndex)
SmartPtr< T, FreePolicy > make_sp(T *inst)
Definition fract_ddf_fv1.h:601