[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Periodic problem

From: Konstantinos Poulios
Subject: Re: Periodic problem
Date: Wed, 20 Jul 2022 11:34:58 +0200

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.)

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_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

On Wed, Jul 20, 2022 at 9:42 AM Bourriche Lahoussaine <> wrote:

For periodic condition i do something like :

ConstraintMatrix = gf.Spmat('empty',1 ,mfu.nb_basic_dof())
for i in range(len(leftDof)):
      # 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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]