function handle as boundary condition

sorry if this is a very silly question as I am quite new using matlab. So I apologise in advance.
I have a vector with accelerations corresponding to time intances. I need to use a interpolation function to interpolate values of accelerations at different times, and I need to pass this function as boundary condition in specific edges.
len=length(accel_filt);
%Create a time vector with the total length of the vector of acceleration
%measure every time instance
tlist=linspace(0,len,len);
%Create the interpolation function to use as boundary condition
bc = griddedInterpolant(tlist,accel_filt',"linear","nearest");
%--APPLY BOUNDARY CONDITION TO INNER EDGES-- 19/04/23----------------------
for j = 1:numel(edges) %for every value store in perimeter
edge=edges(j);
applyBoundaryCondition(modelTwoDomain,"dirichlet","Edge",edge,"u",@bcfundcD);
end
function defined at the end of code:
function bc=bcfundcD(location,bc)
state.u = bc(location.x);
end
What am I doing wrong?

13 Comments

What am I doing wrong?
Can you tell us what leads you to believe you're doing something wrong? What does "wrong" mean in this context?
  • Do you receive warning and/or error messages? If so the full and exact text of those messages (all the text displayed in orange and/or red in the Command Window) may be useful in determining what's going on and how to avoid the warning and/or error.
  • Does it do something different than what you expected? If so, what did it do and what did you expect it to do?
  • Did MATLAB crash? If so please send the crash log file (with a description of what you were running or doing in MATLAB when the crash occured) to Technical Support so we can investigate.
yes, I forgot to post it. the Error:
Index exceeds the number of array elements. Index must not exceed 1.
Error in DomainsharedEdge_WorkingVersion>bcfundcD (line 269)
state.u = bc(location.x);
Error in pde.internal.pde3DBCImpl/callValueFuncOnFace (line 37)
bci = func(appRegion, state);
Error in pde.internal.pde3DBCImpl/setValueBCOnFace (line 79)
uVec = self.callValueFuncOnFace(bci, bci.nodes, bci.term1, faceNormals);
Error in pde.internal.pde3DBCImpl/getBCMatrices (line 56)
self.setValueBCOnFace(bcsi, dirBoundaryConditions);
Error in pde.EquationModel/assembleBoundary (line 74)
bcmat = bcImpl.getBCMatrices(u,time,gmat);
Error in pde.EquationModel/assembleSelectedFEMatrices (line 30)
bmat = self.assembleBoundary(u,time,gmatrix);
Error in pde.DiscretizedPDEModel/initialDiscretization (line 50)
femat0 = self.thePde.assembleSelectedFEMatrices(self.p, self.t, self.coefstruct, u0, tdummy, requiredMats, false);
Error in pde.DiscretizedPDEModel (line 33)
obj = obj.initialDiscretization(u0,tdummy);
Error in pde.DynamicDiscretizedPDEModel (line 32)
obj=obj@pde.DiscretizedPDEModel(thePde,p,e,t,coefstruct,u0,false);
Error in pde.EquationModel/solveTimeDependent (line 27)
femodel=pde.DynamicDiscretizedPDEModel(self,p,e,t,coefstruct,u0,tlist,tsecondOrder);
Error in pde.PDEModel/solvepde (line 57)
[u,dudt] = self.solveTimeDependent(coefstruct, u0, ut0, tlist, ...
Error in DomainsharedEdge_WorkingVersion (line 249)
res=solvepde(modelTwoDomain,tlist);
If you have a time-dependent problem such that you have to interpolate from a time list, why do you use a position variable location.x as input to your griddedInterpolant ?
Maybe
bcfundcD = @(location,state) bc(state.time)
applyBoundaryCondition(modelTwoDomain,"dirichlet","Edge",edge,"u",bcfundcD);
works.
Thanks for the suggestion, I did it as I am really not sure what I am doing. How do i pass the time and the values of acceleration that I have in the matrix to the function though? (sorry again, I apologise about my lack of experience/knowledge)
You define everything you need by the function handle bcfuncD I wrote in the first line of my response:
bcfundcD = @(location,state) bc(state.time)
, provided that the interpolant bc in your code
bc = griddedInterpolant(tlist,accel_filt',"linear","nearest");
can just be called as bc(t) where t is some time value in between the minimum and maximum value in your time list.
Check it out for some time value.
thanks! Will give it a go... I am useless with coding :D
I must admit that I find the PDE Toolbox a very complicated tool to work with. In my opinion, COMSOL is much easier to handle in this respect. But maybe it's more a question of usage.
i just started with this last year for my PhD without previous knowledge in coding...so... I am not sure about what to do or how to do it
Now the issue it says is:
The "u" parameter has length 1 so the "EquationIndex" vector must also have length 1 instead of length 2.
I guess it needs to be 2 as I have a system of 2 partial differential equations?
Yes, if you have two PDEs, I think your function "bcfundcD" must return two values instead of only one.
Maybe there is a way to only address a certain equation in the command
applyBoundaryCondition(modelTwoDomain,"dirichlet","Edge",edge,"u",@bcfundcD);
instead of the complete vector u of unknowns.
You should look it up in the documentation (or just additionally supply the boundary value for your second equation).
I looked into the documentation of "applyBoundaryCondition" and found the Name-Value pair EquationIndex where you can specify the solution component in your vector of unknowns for which you specify the boundary value in the function "bcfundcD".
Thanks!! will check it out. And thanks for all your guidance! Will let you know what happens :D
Hello again
I have been some days trying the following:
tshort= tlist(1:2); %reduce the selection to 2 secs
tshort=tshort'; %transforms tlist into column vector to be like accel
ashort=accel_filt(1:2); %reduce acceleration to short time of test
%bcfund = @(location,state) [bc(state.time); 0];
bc = griddedInterpolant(tshort,ashort,"linear","nearest");
% Define the time at which to evaluate the boundary condition
t = 0.05;
% Evaluate the acceleration at time t
accel_bc = bc(t);
bcfund = @(location,state) [0;accel_bc];
% Apply the modified boundary condition to the PDE model
for j = 1:numel(edges)
edge = edges(j);
applyBoundaryCondition(modelTwoDomain, "dirichlet", "Edge", edge, "u", bcfund)
end
I think it kills matlab and it keeps executing but does not solve the system
res=solvepde(modelTwoDomain,tshort);
I am useless. Any clues?

Sign in to comment.

Answers (1)

Hi,
I understand that you are trying to pass function handle as an argument to the ‘applyBoundaryCondition’ function in MATLAB. Here is an example of how you can achieve this:
Method 1:
bcfundcD = @(location, state) yourCustomBoundaryCondition(region, state);
% Apply the boundary condition using the function handle
applyBoundaryCondition(model, 'face', 1:4, 'u', bcfundcD);
‘yourCustomBoundaryCondition’ is a function that you have defined to implement your specific boundary condition logic. The bcfoundcD’ function handle is created using an anonymous function that calls ‘yourCustomBoundaryCondition’ with the appropriate arguments. i.e location, state.
Method 2:
% Define the named function
function bcfundcD = yourCustomBoundaryCondition(region, state)
% Implement your boundary condition logic here
% ...
end
% Apply the boundary condition using the function handle
applyBoundaryCondition(model, 'face', 1:4, 'u', @yourCustomBoundaryCondition);
In this case, the ‘@’ symbol is used to create a function handle to the named function ‘yourCustomBoundaryCondition’.
Take a look at this documentation for better understanding:
I hope this helps.

Asked:

on 19 Apr 2023

Answered:

on 16 Nov 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!