Skip to content

Commit

Permalink
Enhancements in the composite_user_data.h
Browse files Browse the repository at this point in the history
  • Loading branch information
LogashenkoDL committed Nov 4, 2024
1 parent 93e58a8 commit 2290f3e
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 84 deletions.
12 changes: 8 additions & 4 deletions ugbase/bridge/disc_bridges/user_data_bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,10 @@ static void Dimension(Registry& reg, string grp)
string name = string("CompositeUserNumber").append(dimSuffix);
typedef CompositeUserData<number, dim, void> T;
reg.add_class_<T,typename T::base_type>(name, grp)
.template add_constructor<void (*)(bool) >("")
.add_method("add", &T::add)
.template add_constructor<void (*)()>()
.template add_constructor<void (*)(bool)>("continuous")
.add_method("add", static_cast<void (T::*)(int, typename T::ref_type)>(&T::add), "assign a user data object to a subset index", "si#userdata")
.add_method("add", static_cast<void (T::*)(ConstSmartPtr<ISubsetHandler>, const char *, typename T::ref_type)>(&T::add), "assign a user data object to subsets by names", "names#userdata")
.add_method("has", &T::has)
.add_method("get", &T::get)
.add_method("is_coupled", &T::is_coupled)
Expand All @@ -476,8 +478,10 @@ static void Dimension(Registry& reg, string grp)
string name = string("CompositeUserVector").append(dimSuffix);
typedef CompositeUserData<MathVector<dim>, dim, void> T;
reg.add_class_<T,typename T::base_type>(name, grp)
.template add_constructor<void (*)(bool) >("")
.add_method("add", &T::add)
.template add_constructor<void (*)()>()
.template add_constructor<void (*)(bool)>("continuous")
.add_method("add", static_cast<void (T::*)(int, typename T::ref_type)>(&T::add), "assign a user data object to a subset index", "si#userdata")
.add_method("add", static_cast<void (T::*)(ConstSmartPtr<ISubsetHandler>, const char *, typename T::ref_type)>(&T::add), "assign a user data object to subsets by names", "names#userdata")
.add_method("has", &T::has)
.add_method("get", &T::get)
.add_method("is_coupled", &T::is_coupled)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,61 +33,95 @@
#ifndef __LIB_DISC__COMPOSITE_USER_DATA_H_
#define __LIB_DISC__COMPOSITE_USER_DATA_H_

// UG4
#include <vector>
#include <string>

// UG4 headers
#include "lib_grid/tools/subset_group.h"
#include "lib_disc/spatial_disc/user_data/linker/linker.h"

namespace ug{

//! This is a compositum for user data from different subsets.
/*! This is handy, but the implementation is rather slow. */
/// This is a compositum for user data defined on different subsets
/**
* This combines user data objects defined on several subsets which is handy,
* but may be slow.
*/
template <typename TData, int dim, typename TRet = void>
class CompositeUserData : public UserData<TData, dim, TRet>
{
protected:
typedef CplUserData<TData, dim, TRet> TCplUserData;
public:
typedef UserData<TData, dim, TRet> base_type;
typedef SmartPtr<base_type> ref_type;
typedef std::map<int, ref_type> map_type;
typedef SmartPtr<base_type> ref_type; ///< the attached UserData objects should have the same type as this class (i.e. they are "remapped")

CompositeUserData(bool continuous) : m_continuous(continuous), m_bRequiresGridFunction(false)
{}
CompositeUserData() : m_bContinuous(true), m_bRequiresGridFunction(false) {}

CompositeUserData(bool continuous) : m_bContinuous(continuous), m_bRequiresGridFunction(false) {}

virtual ~CompositeUserData(){}

///! Add 'UserData' for given subset index.
void add(int si, ref_type ref)

/// Add 'UserData' object for given subset index.
void add
(
int si, ///< the subset index
ref_type ref ///< pointer to the user-data object
)
{
// UG_ASSERT(ref->continuous() == m_continuous, "ERROR: Mixing continuous and discontinuous data!");
m_map[si] = ref;
m_continuous = m_continuous && ref->continuous();
UG_ASSERT (si >= 0, "CompositeUserData: Non-existing subset index!");

if ((size_t) si >= m_vData.size ())
m_vData.resize (si + 1);
m_vData[si] = ref;

// UG_ASSERT(ref->continuous() == m_continuous, "CompositeUserData: Mixing continuous and discontinuous data!");
m_bContinuous = m_bContinuous && ref->continuous();
m_bRequiresGridFunction = m_bRequiresGridFunction || ref->requires_grid_fct();
}

/// Add 'UserData' object for all subsets in a given group
void add
(
const SubsetGroup & ssg, ///< the subset group
ref_type ref ///< pointer to the user-data object
)
{
for (size_t i = 0; i < ssg.size (); i++) add (ssg[i], ref);
}

/// Add 'UserData' object for all subsets by their names
void add
(
ConstSmartPtr<ISubsetHandler> ssh, ///< subset handler of the domain
const char * ss_names, ///< names of the subdomains
ref_type ref ///< pointer to the user-data object
)
{
std::vector<std::string> v_ss_names;
SubsetGroup ssg;

TokenizeTrimString (std::string (ss_names), v_ss_names);
ssg.add (v_ss_names);
add (ssg, ref);
}

ref_type get(int si)
{ return (find(si)->second); }

bool has(int si)
{ return find(si) != m_map.end();}


bool is_coupled(int si)
{ return (has(si) && find(si)->second.template is_of_type<TCplUserData>()); }
/// Returns the value assigned to a subset index
ref_type get (int si) const { return find(si); }

SmartPtr<TCplUserData> get_coupled(int si)
{ return find(si)->second.template cast_dynamic<TCplUserData>(); }
/// Checks if anything is assigned to a given subset index
bool has(int si) const { return si >= 0 && (size_t) si < m_vData.size () && find(si).valid ();}


bool is_coupled(int si) { return has(si) && find(si).template is_of_type<TCplUserData>(); }

SmartPtr<TCplUserData> get_coupled(int si) { return find(si).template cast_dynamic<TCplUserData>(); }

// Implementing virtual functions

virtual bool continuous() const
{return m_continuous;}

virtual bool continuous() const {return m_bContinuous;}

//! returns true, if at least one of the underlying UserData requires grid functions.
/// returns true, if at least one of the underlying UserData requires grid functions.
virtual bool requires_grid_fct() const
{
return m_bRequiresGridFunction;
Expand All @@ -97,66 +131,71 @@ class CompositeUserData : public UserData<TData, dim, TRet>
virtual TRet operator() (TData& value,
const MathVector<dim>& globIP,
number time, int si) const
{ return (*find(si)->second)(value, globIP, time, si); }
{ return (*find(si)) (value, globIP, time, si); }

/// returns values for global positions
virtual void operator()(TData vValue[],
const MathVector<dim> vGlobIP[],
number time, int si, const size_t nip) const
{ return (*find(si)) (vValue, vGlobIP, time, si, nip); }

/// returns values for global positions
virtual void operator()(TData vValue[],

virtual void operator()(TData vValue[],
const MathVector<dim> vGlobIP[],
number time, int si, const size_t nip) const
{ return (*find(si)->second)(vValue, vGlobIP, time, si, nip); }


virtual void operator()(TData vValue[],
const MathVector<dim> vGlobIP[],
number time, int si,
GridObject* elem,
const MathVector<dim> vCornerCoords[],
const MathVector<1> vLocIP[],
const size_t nip,
LocalVector* u,
const MathMatrix<1, dim>* vJT = NULL) const
{
return (*find(si)->second)(vValue, vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
}

virtual void operator()(TData vValue[],
const MathVector<dim> vGlobIP[],
number time, int si,
GridObject* elem,
const MathVector<dim> vCornerCoords[],
const MathVector<2> vLocIP[],
const size_t nip,
LocalVector* u,
const MathMatrix<2, dim>* vJT = NULL) const
{
return (*find(si)->second)(vValue, vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
}

virtual void operator()(TData vValue[],
const MathVector<dim> vGlobIP[],
number time, int si,
GridObject* elem,
const MathVector<dim> vCornerCoords[],
const MathVector<3> vLocIP[],
const size_t nip,
LocalVector* u,
const MathMatrix<3, dim>* vJT = NULL) const
{
return (*find(si)->second)(vValue, vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
}
number time, int si,
GridObject* elem,
const MathVector<dim> vCornerCoords[],
const MathVector<1> vLocIP[],
const size_t nip,
LocalVector* u,
const MathMatrix<1, dim>* vJT = NULL) const
{
return (*find(si)) (vValue, vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
}

virtual void operator()(TData vValue[],
const MathVector<dim> vGlobIP[],
number time, int si,
GridObject* elem,
const MathVector<dim> vCornerCoords[],
const MathVector<2> vLocIP[],
const size_t nip,
LocalVector* u,
const MathMatrix<2, dim>* vJT = NULL) const
{
return (*find(si)) (vValue, vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
}

virtual void operator()(TData vValue[],
const MathVector<dim> vGlobIP[],
number time, int si,
GridObject* elem,
const MathVector<dim> vCornerCoords[],
const MathVector<3> vLocIP[],
const size_t nip,
LocalVector* u,
const MathMatrix<3, dim>* vJT = NULL) const
{
return (*find(si)) (vValue, vGlobIP, time, si, elem, vCornerCoords, vLocIP, nip, u, vJT);
}

protected:
typename map_type::const_iterator find(int si) const
private:

// returns the reference to the user data in the given subset
const ref_type & find (int si) const
{
typename map_type::const_iterator it = m_map.find(si);
UG_ASSERT(it != m_map.end(), "ERROR: Subset not found!");
return it;
if (si < 0 || (size_t) si >= m_vData.size ())
{
UG_THROW ("CompositeUserData: No data for subset " << si);
}

return m_vData [si];
}

map_type m_map;
bool m_continuous;
private:

std::vector<ref_type> m_vData;
bool m_bContinuous;
bool m_bRequiresGridFunction;
};

Expand Down

0 comments on commit 2290f3e

Please sign in to comment.