Non-polynomial Shape Functions

84 views
Skip to first unread message

Alex Quinlan

unread,
Jun 8, 2023, 11:40:05 AM6/8/23
to deal.II User Group
Hi everyone,

I am looking to modify the FE_Q element to have non-polynomial shape functions.  It looks like FE_Q_Base takes an argument of type ScalarPolynomialBase<dim> (fe_q_base.cc: line 418).

I am looking at a 2D element and instead of 2D polynomial shape functions like this:

        N = (1 - ξ)(1 - η)

I would like to add some additional terms like this:

    N = (1 - ξ)(1 - η) + ζ

where ζ changes at different quadrature points.

It seems that I would need to access the values of ζ before computing fe_values, since the shape functions and their derivatives would be dependent on ζ.

Any thoughts on how feasible this would be to implement?

Thanks for your input,
Alex

Wolfgang Bangerth

unread,
Jun 8, 2023, 6:57:44 PM6/8/23
to dea...@googlegroups.com
Alex:
if your shape functions are not polynomial, then this is the wrong approach --
FE_Q_Base is derived from FE_Poly, which is specifically built to create
polynomial bases.

I'm not sure we have a particularly good starting point for a completely
general choice of ζ(ξ,η), but you might want to take a look at what
FE_Enriched is doing.

Best
W.

--
------------------------------------------------------------------------
Wolfgang Bangerth email: bang...@colostate.edu
www: http://www.math.colostate.edu/~bangerth/


Alex Quinlan

unread,
Jun 9, 2023, 8:27:37 AM6/9/23
to deal.II User Group
Thanks, Wolfgang.  I'll dig into FE_Enriched!

Alex Quinlan

unread,
Jun 12, 2023, 4:41:18 PM6/12/23
to deal.II User Group
Hi Wolfgang,

I've been looking at a few sources regarding FE_Enriched:


I've been trying to get my problem class to work with a placeholder enrichment function from example (B), but I'm getting tripped up.
I looked at the formatting on Line 146 of fe_enriched.cc:

FE_Enriched<dim, spacedim>::FE_Enriched(
  const FiniteElement<dim, spacedim> &fe_base,
  const FiniteElement<dim, spacedim> &fe_enriched,
  const Function<spacedim> *          enrichment_function)


I have tried to implement this format in the constructor for my problem class.  I am trying to set fe_base as FE_Q, and then fe_enriched as another FE_Q multiplied
by the enrichment function.

template <int dim, int spacedim>
shElast<dim, spacedim>::shElast(
    const std::string &  initial_mesh_filename,
    const std::string &  output_filename)

    : fe( FE_Q<dim>(1)  ,
  FE_Q<dim>(1) ,
  enrichment)

, dof_handler(triangulation)
    , quadrature_formula(fe.degree + 1)
    , initial_mesh_filename(initial_mesh_filename)
    , output_filename(output_filename)
, mapping( FE_Q<dim>(1))

{}

  where I've previously declared:

  Triangulation<dim>             triangulation; 
  const FE_Enriched<dim>         fe;
  DoFHandler<dim>                dof_handler;
  const QGauss<dim>              quadrature_formula;
  const MappingFE<dim>           mapping;
  EnrichmentFunction<dim>        enrichment;

When I try to compile my program, I get this error:

dealii/examples/enrich/enrich9.cc:324:25: error: no matching function for call to ‘dealii::FE_Enriched<3, 3>::FE_Enriched(dealii::FE_Q<3, 3>, dealii::FE_Q<3, 3>, problem_namespace::EnrichmentFunction<3>&)’
  324 |  , mapping( FE_Q<dim>(1))

Then I get the following notes about my arguments and failure to find conversions:

In file included from dealii/examples/enrich/enrich9.cc:53:
fe/fe_enriched.h:263:3: note: candidate: ‘dealii::FE_Enriched<dim, spacedim>::FE_Enriched(const std::vector<const dealii::FiniteElement<dimension_, space_dimension_>*>&, const std::vector<unsigned int>&, const std::vector<std::vector<std::function<const dealii::Function<spacedim>*(const typename dealii::Triangulation<dim, spacedim>::cell_iterator&)> > >&) [with int dim = 3; int spacedim = 3; typename dealii::Triangulation<dim, spacedim>::cell_iterator = dealii::TriaIterator<dealii::CellAccessor<3, 3> >]’
  263 |   FE_Enriched(
      |   ^~~~~~~~~~~

deal.II/fe/fe_enriched.h:264:62: note:   no known conversion for argument 1 from ‘dealii::FE_Q<3, 3>’ to ‘const std::vector<const dealii::FiniteElement<3, 3>*, std::allocator<const dealii::FiniteElement<3, 3>*> >&’
  264 |     const std::vector<const FiniteElement<dim, spacedim> *> &fes,
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~

deal.II/fe/fe_enriched.h:249:3: note: candidate: ‘dealii::FE_Enriched<dim, spacedim>::FE_Enriched(const dealii::FiniteElement<dimension_, space_dimension_>*, const std::vector<const dealii::FiniteElement<dimension_, space_dimension_>*>&, const std::vector<std::vector<std::function<const dealii::Function<spacedim>*(const typename dealii::Triangulation<dim, spacedim>::cell_iterator&)> > >&) [with int dim = 3; int spacedim = 3; typename dealii::Triangulation<dim, spacedim>::cell_iterator = dealii::TriaIterator<dealii::CellAccessor<3, 3> >]’
  249 |   FE_Enriched(
      |   ^~~~~~~~~~~

deal.II/fe/fe_enriched.h:250:62: note:   no known conversion for argument 1 from ‘dealii::FE_Q<3, 3>’ to ‘const dealii::FiniteElement<3, 3>*’
  250 |     const FiniteElement<dim, spacedim> *                     fe_base,
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~

deal.II/fe/fe_enriched.h:200:3: note: candidate: ‘dealii::FE_Enriched<dim, spacedim>::FE_Enriched(const dealii::FiniteElement<dimension_, space_dimension_>&) [with int dim = 3; int spacedim = 3]’
  200 |   FE_Enriched(const FiniteElement<dim, spacedim> &fe_base);
      |   ^~~~~~~~~~~

deal.II/fe/fe_enriched.h:200:3: note:   candidate expects 1 argument, 3 provided

deal.II/fe/fe_enriched.h:186:3: note: candidate: ‘dealii::FE_Enriched<dim, spacedim>::FE_Enriched(const dealii::FiniteElement<dimension_, space_dimension_>&, const dealii::FiniteElement<dimension_, space_dimension_>&, const dealii::Function<spacedim>*) [with int dim = 3; int spacedim = 3]’
  186 |   FE_Enriched(const FiniteElement<dim, spacedim> &fe_base,
      |   ^~~~~~~~~~~

deal.II/fe/fe_enriched.h:188:51: note:   no known conversion for argument 3 from ‘shell::EnrichmentFunction<3>’ to ‘const dealii::Function<3, double>*’
  188 |               const Function<spacedim> *          enrichment_function);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~







It seems that I'm misunderstanding a few things about how FE_Enriched works.  Can you see what I'm doing wrong in constructing the FE_Enriched?  It looks like there's issues with forms I am using for FE_Q and the enrichment function.  Do you have any tips or suggested resources?

Many thanks,
Alex

Wolfgang Bangerth

unread,
Jun 12, 2023, 4:43:12 PM6/12/23
to dea...@googlegroups.com
On 6/12/23 14:41, Alex Quinlan wrote:
>
> It seems that I'm misunderstanding a few things about how FE_Enriched works.
> Can you see what I'm doing wrong in constructing the FE_Enriched?  It looks
> like there's issues with forms I am using for FE_Q and the enrichment
> function.  Do you have any tips or suggested resources?

Alex:
The constructor's third argument is a pointer, but you're passing a reference.

Alex Quinlan

unread,
Jun 20, 2023, 12:00:06 PM6/20/23
to deal.II User Group
Hi Wolfgang,

Thanks for the guidance on the pointer.  I have gotten a compiled program using:

const FE_Enriched<dim>   fenr;
PotentialFunction<dim> potential;

shElast<dim, spacedim>::shElast()
:fenr(
FE_Q<dim>(2),
                       FE_Q<dim>(1),
                       &potential )

However, I am in need of a 3D vector solution. Previously, I have successfully used FE_System for non-enriched 3D vector problems, i.e.:

const FESystem<dim,spacedim>   fesys;

shElast<dim, spacedim>::shElast()
:fesys(
FE_Q<dim>(2), 3)


How can I go about getting a vector solution with FE_Enriched?  I have tried to use vector arguments in FE_Enriched for base elements, enriched elements, and enrichment functions, based on the documentation.  I have also tried to use FE_Enriched as an argument to FE_System:

const FESystem<dim,spacedim>   fesys;
const FE_Enriched<dim>   fenr;

shElast<dim, spacedim>::shElast()
:fesys(
fenr( FE_Q<dim>(2),
                              FE_Q<dim>(1),
                              &potential )
                , 3)


Are either of these directions valid?  I can't tell if I'm failing to use the correct syntax or if I'm completely off base with the approach.

Thanks,
Alex

Wolfgang Bangerth

unread,
Jun 21, 2023, 1:25:44 AM6/21/23
to dea...@googlegroups.com
On 6/20/23 10:00, Alex Quinlan wrote:
>
> How can I go about getting a vector solution with FE_Enriched?  I have tried
> to use vector arguments in FE_Enriched for base elements, enriched elements,
> and enrichment functions, based on the documentation.  I have also tried to
> use FE_Enriched as an argument to FE_System:
>
> const FESystem<dim,spacedim>   fesys;
> const FE_Enriched<dim>   fenr;
>
> shElast<dim, spacedim>::shElast()
> :fesys(fenr(FE_Q<dim>(2),
>                               FE_Q<dim>(1),
>                               &potential )
>                 , 3)

This is the right idea, but the wrong syntax. In constructors, what comes
after the : is a comma-separated list of the form
member_var_name(arg1,arg2,...),
...

So you need to write this list as

shElast<dim, spacedim>::shElast()
:fenr(FE_Q<dim>(2),
FE_Q<dim>(1),
&potential )
,fesys(fenr, 3)
{...}

Alex Quinlan

unread,
Jun 26, 2023, 12:10:59 PM6/26/23
to deal.II User Group
Thanks, Wolfgang.  Your solution worked for me.

Just for posterity, I got stuck again because I created FE_System and FE_Enriched in the wrong order:
const FESystem<dim,spacedim>   fesys;
const FE_Enriched<dim>         fenr;


my problem was resolved when I switched it around to:

const FE_Enriched<dim>         fenr;
const FESystem<dim,spacedim>   fesys;

Cheers,
Alex
Reply all
Reply to author
Forward
0 new messages