- Substitution method: replace the first and last equation by: x = known_value. For instance

- Penalty method: "overwrite" the existing equation with the boundary condition, weighted with a huge value, for instance:

10 views (last 30 days)

Show older comments

kimfet
on 31 Mar 2022

Answered: Fabio Freschi
on 16 May 2022

Riccardo Scorretti
on 31 Mar 2022

Edited: Riccardo Scorretti
on 1 Apr 2022

Basically, you are asking how to impose Dirichlet boundary conditions, right? If so, there are several methods:

- Substitution method: replace the first and last equation by: x = known_value. For instance

A(1,:) = 0 ; A(1,1) = 1; b(1) = known_value_1;

A(n,:) = 0 ; A(n,n) = 1; b(n) = known_value_2;

- Penalty method: "overwrite" the existing equation with the boundary condition, weighted with a huge value, for instance:

TGV = 1E30; % = Terribly Giant Value

A(1,1) = TGV ; b(1) = TGV*known_value_1;

A(n,n) = TGV ; b(n) = TGV*known_value_2;

Assuming that b is the known vector, then you can solve the linear system with an appropriate direct or iterative linear solver.

The penalty method is approximate, but it has the advantage that it is quite simple and (most importantly), it preserves eventual symmetry properties of the matrix. This is the way (I don't know if it is the only way) Dirichlet boundary conditions are implemented in FreeFem++ (see https://doc.freefem.org/references/types.html):

See also this discussion:

By the way, I recently posted a complete program where Dirichlet boundary conditions are imposed by using the first method. The program solves a PDE by using the Finite Difference method, but the way of imposing Dirichlet boundary conditions is exactly the same:

Torsten
on 31 Mar 2022

Use lsqlin for the problem

min : ||A*x||_2

s.c.

x(1) = known_value_1

x(n) = known_value_2

if A has n columns.

Fabio Freschi
on 16 May 2022

The post is old but the question arises many times, so I post here my solution. It is a generalization of @Matt J solution.

Suppose you have a matrix with unknowns partitioned in free x and dirichlet . And by chance the partition is such that the free variables come first

The free unknowns can be obtained by solving the first block row:

The second block row is of no interest, since is known.

In the general case when are not at the end of the unknown vector, but they are identified by the index vector idFix and the corresponding Dirichlet values xFix, you can write the function

function x = solveproblem(A,b,idFix,xFix)

% get number of unknowns

n = length(b);

% move to rhs the Dirichlet values

b = b-A(:,idfix)*xfix;

% get indices of free variables

iFree = setdiff(1:n,idFix);

% reduce stiffness and rhs

A = A(:,iFree);

A = A(iFree,:);

b = b(iFree,:);

% solution

xRed = A\b;

% re-assemble the unknown vector

x(idFree) = xRed;

x(idFix) = xFix;

end

This method preserves the original properties of the original matrix (in particular if it's SPD). There is also an interesting way to include in this approach that a selection of the vector of unknowns has the same value, for example a floating potential of an equipotential object, but it goes beyond the original question

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

Start Hunting!