1

Topic: ActiveBC with DOFs

We are going to implement an active boundary condition with its own DOFs, basically it will be a condition, allowing to enforce that a given liner combination of other DOFs should be equal to given value. This will be implemented using a Lagrange multipliers, so the additional condition added to the energy functional is:
lambda*(wi*ri + c) = 0,
where wi are the weights, ri linked DOFs, and lambda is associated multiplier, which is a new unknown, introduced by this condition.

I went through the activeBoundaryCondition implementation, it seems that there is some support for internal DOFs, but this is not complete.
I suggest following modifications:
1) the existing (old) boundary conditions already have the possibility to introduce their own DOFs, by managing internal dof managers, see generalboundarycondition.h:

    /// Gives the number of internal dof managers.
    virtual int giveNumberOfInternalDofManagers() { return 0; }
    /// Gives an internal dof manager from receiver.
    virtual DofManager *giveInternalDofManager(int i) { return NULL; }

2) this is already supported byEngngModel:: forceEquationNumbering methods, so the equations are properly allocated to internal BC unknowns.

Therefore I would suggest to keep this (activeBC maintaining internal dofManagers), or optionally derive activeBC from DofManager. This has a logic, if it has DOFs, then it is a dofManager, and we can use this dofManager interface rather than inventing special interface for activeBC DOFs.

Re: ActiveBC with DOFs

Hi Borek,

I was the one who added the support for internal dof managers some time ago (for this exact purpose). I (and Carl) use that in several existing boundary conditions already, so I don't understand what's not complete. You could definitely implement your active b.c. already.
Both 1) and 2) is exactly as you describe it, so what needs to be modified? I can't see any need for any special interface (except for giveInternalDofManager needed for numbering).

I used internal dof managers since I wanted several of them (it's easier to keep track of different components when you have several different additional conditions to be added). This way I can use DofManager::giveCompleteUnknownVector to fetch all my components of one type.

MixedGradientPressureNeumann - Has 1 internal dof managers with 8 components representing the macroscopic deviatoric stresses
MixedGradientPressureDirichlet - Has 2 internal dof managers with 8 and 1 components representing the macroscopic deviatoric strains and volumetric strains respectively.
MixedGradientPressurePeriodic - Currently has some bugs, but should end up with 1 volumetric strain and many tractions.
WeakPeriodicBC - Has 1 internal dof managers with many components representing tractions.

3

Re: ActiveBC with DOFs

Hi Mikael,

I am somehow confused, what is now in ActiveBoundaryCondition. Here I can see methods like
requiresActiveDofs
giveNumberOfMasterDofs
giveMasterDof
which purpose is unclear for me at the moment. It seems to me that to some extend they are redundant to what is provided by GeneralBoundaryCondition interface in terms of internal dof managers.

But I am perfectly happy with the high level interface of GeneralBoundaryCondition and the concept of internal DOFs.

Borek

Re: ActiveBC with DOFs

Hi Borek.

I see what you mean now. I'll try to explain.

I have some very exotic boundary conditions;
In my Dirichlet-type boundary condition (MixedGradientPressureDirichlet) I want to enforce that the velocity on the boundary is

v = d . x = d_dev . x + d_vol/3 * x

where v is the velocity, d_dev is prescribed, d_vol is a global unknown and x is the coordinate. (d is the rate-of-deformation gradient)
The velocity is then essentially a slave dof, but the weights is determined by the boundary condition ( = x ).

I didn't want to set these weights manually, but compute it dynamically inside the code. Therefor I introduced ActiveDof, which can be either a MasterDof or a SlaveDof. This is all determined by the active boundary condition. So all ActiveDof does is to pass the question along to ActiveBoundaryCondition.

I have added some more comments to hopefully describe these better. (The old comment said requiresActiveDof wasn't used, but this isn't the case anymore.)

In short, you might be able to  use these active dofs to strongly enforce the condition
wi*ri = -c
instead of using Lagrange multipliers. If not, then you can ignore them.

5

Re: ActiveBC with DOFs

Hi Mikael,

when implementing the new active boundary condition, I have discovered a strange thing. The ActiveBoundaryCondition declares
giveLocationArrays method with CharType value as parameter. Is this parameter really needed? Some points to consider:
- element class also declares giveLocationArray method, but CharType values is not needed,
- the giveLocationArrays have to be also used by some sparsematrix implementations to prealocate the memory. The corresponding method, buildInternalStructure does not have CharType values as parameter, and I don't see any reason why it should.

Unfortunately, in some active bc implementations depend on this value, but is seems that they just do nothing for some values. So what about to always return location array and rather return zero characteristic components in such case.

By the way, what was the motivation for giveLocationArrays to return vectors of code numbers? Seems as really complex stuff.

Re: ActiveBC with DOFs

Hi Borek

The giveLocationArrays-function is actually only used by buildInternalStructure (which is intended).

It was some time ago I designed this, but I considered the cases where, for example, the boundary condition only had contributions to the damping-matrix (like with non-reflective boundaries).

However, in other parts of the code (elements and sparse matrices) we assume that the nonzero structure is the same for all possible matrices (e.g. stiffness, damping, mass). This isn't necessary always the case.

If we want to keep it as such, then I suppose we consider buildInternalStructure to always take the union of all possible matrices, which is fine by me.  Feel free to remove the CharType argument.


As for the vectors, I can't see any other way to do it. You want to typically add

K    C
C^T  0

where C is the tangent(s) for the the new Lagrange multipliers.
If you construct the entire block as a single (symmetric) intarray of code numbers, you would pre-allocate the entire stiffness matrix in some cases (my "C" matrix is assembled in a loop over element edges, the entire C-matrix is as large as the total system)
So, say K is 5x5, and C is 5x1, then you would want to return the following location arrays
[6] x [1,2,3,4,5]
[1,2,3,4,5] x [6]
and assemble C and C^T in two different function calls.
This is as opposed to doing
[1,2,3,4,5,6] x [1,2,3,4,5,6]
and assembling the total matrix [0 C; C^T,0] (which could be huge)

Re: ActiveBC with DOFs

Borek,
I have some recommendations for the boundary condition you have introduced.

1. "dofs" is already a variable of boundary conditions, no need to add a duplicate there.
2. Use sets instead of keeping another list of dof managers. The "set" field is read by the boundary condition base class, so you only need to use "domain->giveSet(this->setNumber)->giveNodeList()"


( It would also be possible to automatically compute slave dofs using "requiresActiveDofs" )

8

Re: ActiveBC with DOFs

Mikael,

regarding the second point, I am not sure. The sets, as far as I understand, are intended to identify the components to which particular boundary condition is applied. So the boundary condition is applied on each element in the set.
However, in this case we have different situation. I have to specify a set of dofs which are linked by a linear constraint and this relates to a single application of this BC. Of course set can be used for this, but its use is different from the use of sets in other boundary conditions and this may cause some confusion.