示例#1
0
void FV1InnerBoundaryElemDisc<TDomain>::
prep_err_est_elem(const LocalVector& u, GridObject* elem, const MathVector<dim> vCornerCoords[])
{
	// get error estimator
	err_est_type* err_est_data = dynamic_cast<err_est_type*>(this->m_spErrEstData.get());

	// set local positions
	if (TFVGeom::usesHangingNodes)
	{
		static const int refDim = TElem::dim;
		ReferenceObjectID roid = elem->reference_object_id();

		size_t numSideIPs;
		const MathVector<refDim>* sideIPs;
		try
		{
			numSideIPs = err_est_data->get(0)->num_side_ips(roid);
			sideIPs = err_est_data->get(0)->template side_local_ips<refDim>(roid);
		}
		UG_CATCH_THROW("Integration points for error estimator cannot be set.");

		// store values of shape functions in local IPs
		LagrangeP1<typename reference_element_traits<TElem>::reference_element_type> trialSpace
					= Provider<LagrangeP1<typename reference_element_traits<TElem>::reference_element_type> >::get();

		m_shapeValues.resize(numSideIPs, trialSpace.num_sh());
		for (size_t ip = 0; ip < numSideIPs; ip++)
			trialSpace.shapes(m_shapeValues.shapesAtSideIP(ip), sideIPs[ip]);
	}
}
void ConvectionDiffusionFE<TDomain>::
prep_err_est_elem_loop(const ReferenceObjectID roid, const int si)
{
	//	get the error estimator data object and check that it is of the right type
	//	we check this at this point in order to be able to dispense with this check later on
	//	(i.e. in prep_err_est_elem and compute_err_est_A_elem())
	if (this->m_spErrEstData.get() == NULL)
	{
		UG_THROW("No ErrEstData object has been given to this ElemDisc!");
	}

	err_est_type* err_est_data = dynamic_cast<err_est_type*>(this->m_spErrEstData.get());

	if (!err_est_data)
	{
		UG_THROW("Dynamic cast to SideAndElemErrEstData failed."
				<< std::endl << "Make sure you handed the correct type of ErrEstData to this discretization.");
	}

//	set local positions
	static const int refDim = TElem::dim;

	// get local IPs
	size_t numSideIPs, numElemIPs;
	const MathVector<refDim>* sideIPs;
	const MathVector<refDim>* elemIPs;
	try
	{
		numSideIPs = err_est_data->num_all_side_ips(roid);
		numElemIPs = err_est_data->num_elem_ips(roid);
		sideIPs = err_est_data->template side_local_ips<refDim>(roid);
		elemIPs = err_est_data->template elem_local_ips<refDim>(roid);

		if (!sideIPs || !elemIPs) return;	// are NULL if TElem is not of the same dim as TDomain
	}
	UG_CATCH_THROW("Integration points for error estimator cannot be set.");

	// set local IPs in imports
	m_imDiffusion.template 		set_local_ips<refDim>(sideIPs, numSideIPs, false);
	m_imVelocity.template 		set_local_ips<refDim>(sideIPs, numSideIPs, false);
	m_imFlux.template 			set_local_ips<refDim>(sideIPs, numSideIPs, false);
	m_imSource.template 		set_local_ips<refDim>(elemIPs, numElemIPs, false);
	m_imVectorSource.template 	set_local_ips<refDim>(sideIPs, numSideIPs, false);
	m_imReactionRate.template 	set_local_ips<refDim>(elemIPs, numElemIPs, false);
	m_imReaction.template 		set_local_ips<refDim>(elemIPs, numElemIPs, false);
	m_imMassScale.template 		set_local_ips<refDim>(elemIPs, numElemIPs, false);
	m_imMass.template 			set_local_ips<refDim>(elemIPs, numElemIPs, false);

	// store values of shape functions in local IPs
	LagrangeP1<typename reference_element_traits<TElem>::reference_element_type> trialSpace
				= Provider<LagrangeP1<typename reference_element_traits<TElem>::reference_element_type> >::get();

	m_shapeValues.resize(numElemIPs, numSideIPs, trialSpace.num_sh());
	for (size_t ip = 0; ip < numElemIPs; ip++)
		trialSpace.shapes(m_shapeValues.shapesAtElemIP(ip), elemIPs[ip]);
	for (size_t ip = 0; ip < numSideIPs; ip++)
		trialSpace.shapes(m_shapeValues.shapesAtSideIP(ip), sideIPs[ip]);
}
示例#3
0
void FV1InnerBoundaryElemDisc<TDomain>::
prep_err_est_elem_loop(const ReferenceObjectID roid, const int si)
{
	//	get the error estimator data object and check that it is of the right type
	//	we check this at this point in order to be able to dispense with this check later on
	//	(i.e. in prep_err_est_elem and compute_err_est_A_elem())
	if (this->m_spErrEstData.get() == NULL)
	{
		UG_THROW("No ErrEstData object has been given to this ElemDisc!");
	}

	err_est_type* err_est_data = dynamic_cast<err_est_type*>(this->m_spErrEstData.get());

	if (!err_est_data)
	{
		UG_THROW("Dynamic cast to MultipleSideAndElemErrEstData failed."
				<< std::endl << "Make sure you handed the correct type of ErrEstData to this discretization.");
	}

	if (!err_est_data->equal_side_order())
	{
		UG_THROW("The underlying error estimator data objects of this discretization's "
				 "error estimator do not all have the same integration orders. This case "
				 "is not supported by the implementation. If you need it, implement!");
	}

	if (err_est_data->num() < 1)
	{
		UG_THROW("No underlying error estimator data objects present. No IPs can be determined.");
	}

	//	set local positions
	if (!TFVGeom::usesHangingNodes)
	{
		static const int refDim = TElem::dim;

		// get local IPs
		size_t numSideIPs;
		const MathVector<refDim>* sideIPs;
		try
		{
			numSideIPs = err_est_data->get(0)->num_side_ips(roid);
			sideIPs = err_est_data->get(0)->template side_local_ips<refDim>(roid);
		}
		UG_CATCH_THROW("Integration points for error estimator cannot be set.");

		// store values of shape functions in local IPs
		LagrangeP1<typename reference_element_traits<TElem>::reference_element_type> trialSpace
					= Provider<LagrangeP1<typename reference_element_traits<TElem>::reference_element_type> >::get();

		m_shapeValues.resize(numSideIPs, trialSpace.num_sh());
		for (size_t ip = 0; ip < numSideIPs; ip++)
			trialSpace.shapes(m_shapeValues.shapesAtSideIP(ip), sideIPs[ip]);
	}
}
void ConvectionDiffusionFVCR<TDomain>::
ex_value(number vValue[],
         const MathVector<dim> vGlobIP[],
         number time, int si,
         const LocalVector& u,
         GridObject* elem,
         const MathVector<dim> vCornerCoords[],
         const MathVector<TFVGeom::dim> vLocIP[],
         const size_t nip,
         bool bDeriv,
         std::vector<std::vector<number> > vvvDeriv[])
{
//  get finite volume geometry
	static const TFVGeom& geo = GeomProvider<TFVGeom>::get();

//	reference element
	typedef typename reference_element_traits<TElem>::reference_element_type
			ref_elem_type;

//	number of shape functions
	static const size_t numSH =	ref_elem_type::numCorners;

//	CRFV SCVF ip
	if(vLocIP == geo.scvf_local_ips())
	{
	//	Loop Sub Control Volume Faces (SCVF)
		for(size_t ip = 0; ip < geo.num_scvf(); ++ip)
		{
		// 	Get current SCVF
			const typename TFVGeom::SCVF& scvf = geo.scvf(ip);

		//	compute concentration at ip
			vValue[ip] = 0.0;
			for(size_t sh = 0; sh < scvf.num_sh(); ++sh)
				vValue[ip] += u(_C_, sh) * scvf.shape(sh);

		//	compute derivative w.r.t. to unknowns iff needed
			if(bDeriv)
				for(size_t sh = 0; sh < scvf.num_sh(); ++sh)
					vvvDeriv[ip][_C_][sh] = scvf.shape(sh);
		}
	}
//	CRFV SCV ip
	else if(vLocIP == geo.scv_local_ips())
	{
	//	solution at ip
		for(size_t sh = 0; sh < numSH; ++sh)
			vValue[sh] = u(_C_, sh);

	//	set derivatives if needed
		if(bDeriv)
			for(size_t sh = 0; sh < numSH; ++sh)
				for(size_t sh2 = 0; sh2 < numSH; ++sh2)
					vvvDeriv[sh][_C_][sh2] = (sh==sh2) ? 1.0 : 0.0;
	}
// 	general case
	else
	{
	//	get trial space
		LagrangeP1<ref_elem_type> rTrialSpace = Provider<LagrangeP1<ref_elem_type> >::get();

	//	storage for shape function at ip
		number vShape[numSH];

	//	loop ips
		for(size_t ip = 0; ip < nip; ++ip)
		{
		//	evaluate at shapes at ip
			rTrialSpace.shapes(vShape, vLocIP[ip]);

		//	compute concentration at ip
			vValue[ip] = 0.0;
			for(size_t sh = 0; sh < numSH; ++sh)
				vValue[ip] += u(_C_, sh) * vShape[sh];

		//	compute derivative w.r.t. to unknowns iff needed
		//	\todo: maybe store shapes directly in vvvDeriv
			if(bDeriv)
				for(size_t sh = 0; sh < numSH; ++sh)
					vvvDeriv[ip][_C_][sh] = vShape[sh];
		}
	}
}