Dear Lahoussaine,

Before answering your question, I would like to give you an alternative to
Lagrange multipliers for imposing simple periodicity conditions. You can
have a look at this code snippet:

# Periodicity and horizontal top surface conditions
dofsL = mfu.basic_dof_on_region(L_RG)
dofsR = mfu.basic_dof_on_region(R_RG)
dofsT = np.setdiff1d(mfu.basic_dof_on_region(T_RG),np.union1d(dofsL, dofsR))
xdofsL = dofsL[0::N]; ydofsL = dofsL[1::N]
xdofsR = dofsR[0::N]; ydofsR = dofsR[1::N]
xdofsT = dofsT[0::N]; ydofsT = dofsT[1::N]

xy = mfu.basic_dof_nodes();
perm = np.argsort(np.abs(xy[1,xdofsL]))
xdofsL = xdofsL[perm]; ydofsL = ydofsL[perm]
perm = np.argsort(np.abs(xy[1,xdofsR]))
xdofsR = xdofsR[perm]; ydofsR = ydofsR[perm]

fullsize = mfu.nb_basic_dof()
kept_dofs = np.setdiff1d(np.arange(fullsize),
                         np.union1d(dofsR, dofsT))
newsize = len(kept_dofs)
origdofs = np.arange(fullsize)[kept_dofs]
newdofs = -np.ones(fullsize, np.int_)
newdofs[kept_dofs] = np.arange(len(kept_dofs))

RR = gf.Spmat("empty", newsize, fullsize)
EE = gf.Spmat("empty", fullsize, newsize)
for i in range(len(origdofs)):
   RR.assign(i, origdofs[i], 1.)
   EE.assign(origdofs[i], i, 1.)
for i in range(len(xdofsR)):
   EE.assign(xdofsR[i], newdofs[xdofsL[i]], 1.)
   EE.assign(ydofsR[i], newdofs[ydofsL[i]], 1.)
topxdof = newdofs[xdofsL[-1]]
topydof = newdofs[ydofsL[-1]]
for i in range(len(xdofsT)):
   EE.assign(xdofsT[i], topxdof, 1.)
   EE.assign(ydofsT[i], topydof, 1.)
mfu.reduction_matrices(RR,EE)

The snippet is a bit more complex because it deals also with the top
surface and with the special corner cases, but it should give you an idea
about this solution.

Regarding your actual question, you need to use the Interpolate operator of
the GWFL. Assume that you want to implement a periodicity condition on some
gradients between two faces L_RG and R_RG of the model md, that are at a
distance LX from each other. Then you start by defining an interpolate
transformation between L_RG and R__RG, let's call it "L2R", you define a
multiplier on the left face L_RG, let's call it "mult", and then you add a
term to the L_RG region of the model that corresponds to the condition you
want to impose. E.g. for restricting the component of the gradient normal
to the faces, you can use something like:
md.add_initialized_data("LX",LX)
md.add_interpolate_transformation_from_expression("L2R", m, m, "X+[LX;0;0]")
md.add_filtered_fem_variable('mult', mfu, L_RG)
md.add_linear_term(mim, "mult.((Grad_u-Interpolate(Grad_T,L2R))*Normal)",
L_RG)

I hope this is enough to give you an idea, but if you have additional
questions, feel free to ask.

Sometimes the interpolate transformation suffers from precision errors and
you might need to use some correction like
md.add_interpolate_transformation_from_expression("L2R", m, m,
"X+[LX-1e-10;0;0]")
But don't bother with that, unless you get some error message about the
transformation having failed.

Best regards
Kostas



On Wed, Jul 20, 2022 at 9:42 AM Bourriche Lahoussaine <
lahoussaine.bourri...@etu.toulouse-inp.fr> wrote:

> Hy;
>
> For periodic condition i do something like :
>
>
> --------------------------------------------------------------------------------------------------------------------
> ConstraintMatrix = gf.Spmat('empty',1 ,mfu.nb_basic_dof())
> L=np.zeros((mfu.nb_basic_dof(),1))
>
> for i in range(len(leftDof)):
>       ConstraintMatrix[0,leftDof[i]]=1
>       ConstraintMatrix[0,rightDof[i]]=1
>       md.add_variable('mult_spec'+str(i),1)
>       # print(i)
>       md.add_constraint_with_multipliers( 'u','mult_spec'+str(i),
> ConstraintMatrix,0)
>
>
> --------------------------------------------------------------------------------------------------------------------
> And it worked perfectly;
> Now i want to add another periodic condition: this new on derivatives
> The derivative of u in leftDof  must equal the derivative of T in rightDOF
>
> Do you have ideas
>
>
>
> Best regards
> Lahoussaine
>

Reply via email to