[dune-pdelab] Evaluate solution through a native DOF vector

Lukas Riedel mail at lukasriedel.com
Thu Nov 24 12:09:46 CET 2016


Hi Christian,

thanks a lot for your reply! I see that your suggestion is what I eventually want to have, because I can use measurements that are not point-like.

Since I’m not that much into numerics, I have a couple of questions:
- How would I implement a ‘narrow’ measurement function (or even a dirac function) in a local operator? How can I circumvent that it is zero at every quadrature point queried?
- I have a DG space. Which pattern assembly and residual assembly flags do I need? Is an ‘alpha_volume()’ implementation sufficient?
- Is it sufficient to place the local operator into a grid operator and call ‘residual()’? Does this give me the vector I’m looking for?

On a side note, I achieved what I originally wanted by taking the first element of the MultiIndex I receive from the containerIndex() function. This works because my GFS is scalar.
Here’s the code (not containing all of the typedefs):

	std::vector<RF> observation_operator (const typename Traits::Domain pos)
	{
		SolutionContainer u_raw = Dune::PDELab::Backend::native(u);
		std::vector<RF> res(u_raw.size());

		typedef LocalFunctionSpace<GFS> LFS;
		typedef LFSIndexCache<LFS> LFSCache;
		typedef typename U::template ConstLocalView<LFSCache> XView;
		typedef FiniteElementInterfaceSwitch<
					typename Dune::PDELab::LocalFunctionSpace<GFS>::Traits::FiniteElementType
			> FESwitch;
		LFS lfs(gfs);
		LFSCache lfs_cache(lfs);
		XView x_view(u);
		std::vector<typename Traits::Scalar> fem_factors(gfs.maxLocalSize()); // FEM coefficient container

		// find entity containing the coordinate
		auto it = gv.template begin<0>();
		auto pos_local = pos;
		for( ; it != gv.template end<0>(); ++it){
			const auto geo_type = it->type();
			const auto& ref = Dune::ReferenceElements<typename Traits::DF,Traits::dim>::general(geo_type);
			pos_local = it->geometry().local(pos);
			if(ref.checkInside(pos_local))
				break;
		}
		if(it == gv.template end<0>())
			DUNE_THROW(Dune::Exception,"Measurement position is not inside grid domain!");

		// evaluate local basis and find appropriate container index
		lfs.bind(*it);
		lfs_cache.update();
		x_view.bind(lfs_cache);
		FESwitch::basis(lfs.finiteElement()).evaluateFunction(pos_local,fem_factors);
		for(std::size_t i = 0; i<fem_factors.size(); ++i){
			const auto index = x_view.cache().containerIndex(i)[0];
			res[index] = fem_factors[i][0];
		}

		return res;
	}


> On 22 Nov 2016, at 23:17, Christian Engwer <christian.engwer at uni-muenster.de> wrote:
> 
> Dear Lukas,
> 
> actually there is a much simpler (and judging from your code snippet
> also more efficient) approach. Although I have to admit that it is not
> obvious ;-)
> 
> If I understand you correctly, what you want to do is to evaluate for
> a given measurement function m (e.g. point evaluation, or
> mean-value). 
> 
> Basically what you want to do is (given your solution u):
> * compute v = \int_\Omega m(x) u(x) dx
> * for a point evaluation m(x) is a dirac function, for the mean it is
>   1/\int_\Omega 1 dx
> 
> You can now the following. You write a new local operator which
> contains the element wise weights, needed to compute the integral:
>   v = \sum_{E\in\Omega} v_E
>   with
>   v_E = \int_E m(x) u(x) dx
>       = \sum_i \sum_j w_i m(x_i) u_j \phi_j(x_i) detJ(x_i)
>       = \sum_j [\sum_j w_i m(x_i) \phi_j(x_i) detJ(x_i)] u_j
> 	   = \sum_j w_j u_j
>   => v = w * u
> 
> You input data is the space of function you want to evaluate and you
> map to the same space, as you want to store one coefficient for each
> of the discrete coefficients of u. This local operator can now be
> written without thinking about local or global numbering and without
> special knowledge of the shape functions, as this is (as always)
> handled by PDELab.
> 
> Then you compute the weights w and the actual evaluation is computed
> as the scalar product v = w*j.
> 
> Hope this helps
> 
> Ciao
> Christian
> 
> 
> On Tue, Nov 22, 2016 at 09:03:15PM +0100, Lukas Riedel wrote:
>> Hi guys,
>> 
>> for my current project I need to create a ‘measurement operator’ for a DOF vector. I.e., I want to multiply the native version (PDELab::Backend::native(u)) of this vector with another vector that contains the factors of the Finite Elements at the appropriate indices. Basically, I want to perform the same task as the evaluate() function of a DiscreteGridFunction outside the PDELab environment for a fixed position.
>> 
>> To do this, I need to know which LocalFunctionSpace index of the given entity maps to which index of the native global DOF vector. I see that I can access the correct element of the global DOF vector directly via the ConstUncachedVectorView, and that I can get the DOFIndex from LFSIndexCache::containerIndex(i), but I cannot access the native container with this data type. Is there a mapping from a local index to the index of the native DOF vector?
>> 
>> Here’s an excerpt from my code:
>> 
>> auto u_native = Dune::PDELab::Backend::native(u); // native DOF vector
>> std::vector<typename Traits::RangeType> evaluator(u_native.size()); // evaluation vector
>> 
>> typedef LocalFunctionSpace<GFS> LFS;
>> typedef LFSIndexCache<LFS> LFSCache;
>> typedef typename U::template ConstLocalView<LFSCache> XView;
>> LFS lfs(gfs);
>> LFSCache lfs_cache(lfs);
>> XView x_view(u);
>> std::vector<typename Traits::RangeFieldType> xl(gfs.maxLocalSize());
>> std::vector<typename Traits::RangeType> yb(gfs.maxLocalSize());
>> typedef FiniteElementInterfaceSwitch<
>> 	typename Dune::PDELab::LocalFunctionSpace<GFS>::Traits::FiniteElementType
>> 	> FESwitch;
>> 
>> auto it = gv.template begin<0>(); // take the first entity for now
>> auto pos_global = it->geometry().center(); // take center position for now
>> auto pos_local = it->geometry().local(pos_global);
>> lfs.bind(*it);
>> lfs_cache.update();
>> x_view.bind(lfs_cache);
>> x_view.read(xl);
>> FESwitch::basis(lfs.finiteElement()).evaluateFunction(pos_local,yb);
>> 
>> for(std::size_t i = 0; i<xl.size(); ++i){
>> 	if(xl[i] == x_view[i]){ // accessing the correct element of the solution vector
>> 		std::cout << “It’s a match!” << std::endl;
>> 	}
>> 	std::cout << “This is a strange object, but its printout contains the index I’m looking for: " << x_view.cache().containerIndex(i) << std::endl;
>> 	// u_native[x_view.cache().containerIndex(i)]; // this doesn’t work
>> 
>> 	/* what I want to have:
>> 	auto global_index = x_view.cache().containerIndex(i) // ???
>> 	evaluator[global_index] = yb[i];
>> 	*/
>> }
>> 
>> 
>> Thank you in advance
>> Cheers,
>> Lukas
>> _______________________________________________
>> dune-pdelab mailing list
>> dune-pdelab at dune-project.org
>> http://lists.dune-project.org/mailman/listinfo/dune-pdelab





More information about the dune-pdelab mailing list