NUMCXX  0.13.20181108
Numerical library for small projects and teaching purposes
All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
Functions | Variables
fem2d Namespace Reference

Functions

void assemble_heat_problem (const numcxx::SimpleGrid &Grid, const numcxx::DArray1 &BCfac, const numcxx::DArray1 &BCval, const numcxx::DArray1 &Source, const numcxx::DArray1 &Kappa, numcxx::DSparseMatrix &SGlobal, numcxx::DArray1 &Rhs)
 
void assemble_transient_heat_problem (const numcxx::SimpleGrid &grid, const numcxx::DArray1 &bcfac, const numcxx::DArray1 &bcval, const numcxx::DArray1 &source, const numcxx::DArray1 &kappa, double tau, double theta, bool lump, numcxx::DArray1 &OldSol, numcxx::DSparseMatrix &SGlobal, numcxx::DArray1 &Rhs)
 
double l2norm (const numcxx::SimpleGrid &grid, const numcxx::DArray1 &u)
 
double h1norm (const numcxx::SimpleGrid &grid, const numcxx::DArray1 &u)
 
void compute_cell_volume (const int icell, const numcxx::DArray2 &points, const numcxx::IArray2 &cells, double &vol)
 
void compute_local_stiffness_matrix (const int icell, const numcxx::DArray2 &points, const numcxx::IArray2 &cells, numcxx::DArray2 &SLocal, double &vol)
 

Variables

const double Dirichlet =1.0e30
 BC value marking Dirichlet boundary condition. More...
 

Function Documentation

void fem2d::assemble_heat_problem ( const numcxx::SimpleGrid Grid,
const numcxx::DArray1 BCfac,
const numcxx::DArray1 BCval,
const numcxx::DArray1 Source,
const numcxx::DArray1 Kappa,
numcxx::DSparseMatrix SGlobal,
numcxx::DArray1 Rhs 
)
Examples:
40-stationary-heat-fe.cxx, and 42-convtest-fem-sin.cxx.

Definition at line 74 of file fem2d.cxx.

82  {
83 
84  auto ndim=grid.spacedim(); // space dimension
85  assert(ndim==2);
86  auto points=grid.get_points(); // Array of global nodes
87  auto cells=grid.get_cells(); // Local-global dof map
88 
89  int npoints=grid.npoints();
90  int ncells=grid.ncells();
91  double vol=0.0;
92 
93  // Local stiffness matrix,
94  numcxx::DArray2 SLocal{{0,0,0},{0,0,0},{0,0,0}};
95  numcxx::DArray2 MLocal0{{2,1,1},{1,2,1},{1,1,2}};
96  MLocal0*=1.0/12.0;
97  Rhs=0.0;
98  SGlobal(0,0)=0;
99  SGlobal.clear();
100  double third=1.0/3.0;
101 
102 
103  // Loop over all elements (cells) of the triangulation
104  for (int icell=0; icell<ncells; icell++)
105  {
106  compute_local_stiffness_matrix(icell, points,cells, SLocal, vol);
107 
108  // Assemble into global stiffness matrix
109  double klocal=(kappa(cells(icell,0))+kappa(cells(icell,1))+kappa(cells(icell,2)))/3.0;
110 
111  for (int i=0;i<=ndim;i++)
112  for (int j=0;j<=ndim;j++)
113  {
114  Rhs(cells(icell,i))+=vol*MLocal0(i,j)*source(cells(icell,j));
115  SGlobal(cells(icell,i),cells(icell,j))+=klocal*SLocal(i,j);
116  }
117  }
118 
119 
120  // Assemble boundary conditions (Dirichlet penalty method)
121  int nbfaces=grid.nbfaces();
122  auto bfaces=grid.get_bfaces();
123  auto bfaceregions=grid.get_bfaceregions();
124 
125  for (int ibface=0; ibface<nbfaces; ibface++)
126  {
127  // Obtain number of boundary condition
128  int ireg=bfaceregions(ibface);
129  int i0=bfaces(ibface,0);
130  int i1=bfaces(ibface,1);
131 
132  // Check if it is "Dirichlet"
133  if (bcfac(ireg)>=Dirichlet)
134  {
135  // Assemble penalty values
136  SGlobal(i0,i0)+=bcfac(ireg);
137  Rhs(i0)+=bcfac(ireg)*bcval(ireg);
138 
139  SGlobal(i1,i1)+=bcfac(ireg);
140  Rhs(i1)+=bcfac(ireg)*bcval(ireg);
141 
142  }
143  else if (bcfac(ireg)>0.0)
144  {
145 
146  double dx= points(bfaces(ibface,1),0)-points(bfaces(ibface,0),0);
147  double dy= points(bfaces(ibface,1),1)-points(bfaces(ibface,0),1);
148  double h=sqrt(dx*dx+dy*dy);
149 
150  SGlobal(i0,i0)+=h*bcfac(ireg)/3.0;
151  SGlobal(i0,i1)+=h*bcfac(ireg)/6.0;
152 
153  SGlobal(i1,i0)+=h*bcfac(ireg)/6.0;
154  SGlobal(i1,i1)+=h*bcfac(ireg)/3.0;
155 
156  Rhs(i0)+=0.5*h*bcval(ireg);
157  Rhs(i1)+=0.5*h*bcval(ireg);
158  }
159  }
160  SGlobal.flush();
161  }
void compute_local_stiffness_matrix(const int icell, const numcxx::DArray2 &points, const numcxx::IArray2 &cells, numcxx::DArray2 &SLocal, double &vol)
Definition: fem2d.cxx:33
void flush()
Re-create the internal data structure in order to accomodated all newly created elements.
const double Dirichlet
BC value marking Dirichlet boundary condition.
Definition: fem2d.hxx:11
Two-dimensional array class.
Definition: tarray2.hxx:31

+ Here is the call graph for this function:

void fem2d::assemble_transient_heat_problem ( const numcxx::SimpleGrid grid,
const numcxx::DArray1 bcfac,
const numcxx::DArray1 bcval,
const numcxx::DArray1 source,
const numcxx::DArray1 kappa,
double  tau,
double  theta,
bool  lump,
numcxx::DArray1 OldSol,
numcxx::DSparseMatrix SGlobal,
numcxx::DArray1 Rhs 
)
Examples:
44-transient-heat-fe.cxx.

Definition at line 165 of file fem2d.cxx.

177  {
178 
179  auto ndim=grid.spacedim();
180  auto points=grid.get_points(); // Array of global nodes
181  auto cells=grid.get_cells(); // Local-global dof map
182  int npoints=grid.npoints();
183  int ncells=grid.ncells();
184  double tauinv=1.0/tau;
185 
186  // Local stiffness matrix
187  numcxx::DArray2 SLocal{{0,0,0},{0,0,0},{0,0,0}};
188  numcxx::DArray2 MFull{{2,1,1},{1,2,1},{1,1,2}}; // from Stroud quadrature...
189  numcxx::DArray2 MLumped{{4,0,0},{0,4,0},{0,0,4}}; // mass lumping
190  numcxx::DArray2 MLocal(3,3);
191 
192  if (lump)
193  MLocal=MLumped/12.0;
194  else
195  MLocal=MFull/12.0;
196 
197  // Loop over all elements (cells) of the triangulation
198  Rhs=0.0;
199  SGlobal(0,0)=0;
200  SGlobal.clear();
201  double vol;
202  for (int icell=0; icell<ncells; icell++)
203  {
204  compute_local_stiffness_matrix(icell, points,cells, SLocal, vol);
205  double klocal=(kappa(cells(icell,0))+kappa(cells(icell,1))+kappa(cells(icell,2)))/3.0;
206 
207  // Quadrature for heat transfer coefficient
208  double KLocal=(kappa(cells(icell,0))+kappa(cells(icell,1))+kappa(cells(icell,2)))/3.0;
209 
210 
211  int i;
212  for (int i=0;i<=ndim;i++)
213  for (int j=0;j<=ndim;j++)
214  {
215  SGlobal(cells(icell,i),cells(icell,j))+=theta*KLocal*SLocal(i,j)+ tauinv*vol*MLocal(i,j);
216 
217  Rhs(cells(icell,i))+=((theta-1)*KLocal*SLocal(i,j)+tauinv*vol*MLocal(i,j))*
218  OldSol(cells(icell,j))+vol*MLocal(i,j)*source(cells(icell,j));
219  }
220  }
221 
222  // Assemble boundary conditions (Dirichlet penalty method)
223  int nbfaces=grid.nbfaces();
224  auto bfaces=grid.get_bfaces();
225  auto bfaceregions=grid.get_bfaceregions();
226 
227  for (int ibface=0; ibface<nbfaces; ibface++)
228  {
229  // Obtain number of boundary condition
230  int ireg=bfaceregions(ibface);
231  int i0=bfaces(ibface,0);
232  int i1=bfaces(ibface,1);
233 
234  // Check if it is "Dirichlet"
235  if (bcfac(ireg)>=Dirichlet)
236  {
237  // Assemble penalty values
238  SGlobal(i0,i0)+=bcfac(ireg);
239  Rhs(i0)+=bcfac(ireg)*bcval(ireg);
240 
241  SGlobal(i1,i1)+=bcfac(ireg);
242  Rhs(i1)+=bcfac(ireg)*bcval(ireg);
243  }
244  else if (bcfac(ireg)>0.0)
245  {
246 
247  double dx= points(bfaces(ibface,1),0)-points(bfaces(ibface,0),0);
248  double dy= points(bfaces(ibface,1),1)-points(bfaces(ibface,0),1);
249  double h=sqrt(dx*dx+dy*dy);
250  // first oder quadrature, needs to be replaced by second order
251  int i0=bfaces(ibface,0);
252  int i1=bfaces(ibface,1);
253 
254  SGlobal(i0,i0)+=theta*h*bcfac(ireg)/3.0;
255  SGlobal(i0,i1)+=theta*h*bcfac(ireg)/6.0;
256 
257  SGlobal(i1,i0)+=theta*h*bcfac(ireg)/6.0;
258  SGlobal(i1,i1)+=theta*h*bcfac(ireg)/3.0;
259 
260  Rhs(i0)+=OldSol(i0)*(1.0-theta)*h*bcfac(ireg)/3.0;
261  Rhs(i0)+=OldSol(i1)*(1.0-theta)*h*bcfac(ireg)/6.0;
262  Rhs(i1)+=OldSol(i0)*(1.0-theta)*h*bcfac(ireg)/6.0;
263  Rhs(i1)+=OldSol(i1)*(1.0-theta)*h*bcfac(ireg)/3.0;
264 
265  Rhs(i0)+=0.5*h*bcval(ireg);
266  Rhs(i0)+=0.5*h*bcval(ireg);
267  }
268  }
269  SGlobal.flush();
270  }
const int ncells() const
Return number of cells.
Definition: simplegrid.hxx:63
const int nbfaces() const
Return number of boundary faces.
Definition: simplegrid.hxx:69
void compute_local_stiffness_matrix(const int icell, const numcxx::DArray2 &points, const numcxx::IArray2 &cells, numcxx::DArray2 &SLocal, double &vol)
Definition: fem2d.cxx:33
const TArray2< int > & get_bfaces() const
Get array of point indices describing boundary faces.
Definition: simplegrid.hxx:51
void flush()
Re-create the internal data structure in order to accomodated all newly created elements.
const TArray2< double > & get_points() const
Get array of point coordinates.
Definition: simplegrid.hxx:42
const TArray1< int > & get_bfaceregions() const
Get array of boundary markers.
Definition: simplegrid.hxx:54
const double Dirichlet
BC value marking Dirichlet boundary condition.
Definition: fem2d.hxx:11
Two-dimensional array class.
Definition: tarray2.hxx:31
const int npoints() const
Return number of points.
Definition: simplegrid.hxx:66
const TArray2< int > & get_cells() const
Get array of point indices describing cells.
Definition: simplegrid.hxx:45
const int spacedim() const
Return dimension of space.
Definition: simplegrid.hxx:57

+ Here is the call graph for this function:

double fem2d::l2norm ( const numcxx::SimpleGrid grid,
const numcxx::DArray1 u 
)
Examples:
42-convtest-fem-sin.cxx.

Definition at line 275 of file fem2d.cxx.

278  {
279  auto ndim=grid.spacedim();
280  auto points=grid.get_points(); // Array of global nodes
281  auto cells=grid.get_cells(); // Local-global dof map
282  int npoints=grid.npoints();
283  int ncells=grid.ncells();
284 
285  // Local mass matrix
286  numcxx::DArray2 MLocal{{2,1,1},{1,2,1},{1,1,2}}; // from Stroud quadrature...
287  MLocal*=1.0/12.0;
288 
289  double norm=0.0;
290  for (int icell=0; icell<ncells; icell++)
291  {
292  double vol;
293  compute_cell_volume(icell,points,cells,vol);
294 
295  for (int i=0;i<=ndim;i++)
296  for (int j=0;j<=ndim;j++)
297  norm+=u(cells(icell,i))*u(cells(icell,j))*vol*MLocal(i,j);
298  }
299  return sqrt(norm);
300  }
const int ncells() const
Return number of cells.
Definition: simplegrid.hxx:63
const TArray2< double > & get_points() const
Get array of point coordinates.
Definition: simplegrid.hxx:42
void compute_cell_volume(const int icell, const numcxx::DArray2 &points, const numcxx::IArray2 &cells, double &vol)
Definition: fem2d.cxx:11
Two-dimensional array class.
Definition: tarray2.hxx:31
const int npoints() const
Return number of points.
Definition: simplegrid.hxx:66
A::value_type norm(const A &a)
Euklidean norm of array or expression.
Definition: util.hxx:54
const TArray2< int > & get_cells() const
Get array of point indices describing cells.
Definition: simplegrid.hxx:45
const int spacedim() const
Return dimension of space.
Definition: simplegrid.hxx:57

+ Here is the call graph for this function:

double fem2d::h1norm ( const numcxx::SimpleGrid grid,
const numcxx::DArray1 u 
)
Examples:
42-convtest-fem-sin.cxx.

Definition at line 302 of file fem2d.cxx.

304  {
305  auto ndim=grid.spacedim();
306  auto points=grid.get_points(); // Array of global nodes
307  auto cells=grid.get_cells(); // Local-global dof map
308  int npoints=grid.npoints();
309  int ncells=grid.ncells();
310 
311 
312  numcxx::DArray2 SLocal(ndim+1,ndim+1);
313 
314  double norm=0.0;
315  for (int icell=0; icell<ncells; icell++)
316  {
317  double vol;
318  compute_local_stiffness_matrix(icell, points,cells, SLocal, vol);
319  for (int i=0;i<=ndim;i++)
320  for (int j=0;j<=ndim;j++)
321  norm+=u(cells(icell,i))*u(cells(icell,j))*SLocal(i,j);
322  }
323  return sqrt(norm);
324  }
const int ncells() const
Return number of cells.
Definition: simplegrid.hxx:63
void compute_local_stiffness_matrix(const int icell, const numcxx::DArray2 &points, const numcxx::IArray2 &cells, numcxx::DArray2 &SLocal, double &vol)
Definition: fem2d.cxx:33
const TArray2< double > & get_points() const
Get array of point coordinates.
Definition: simplegrid.hxx:42
Two-dimensional array class.
Definition: tarray2.hxx:31
const int npoints() const
Return number of points.
Definition: simplegrid.hxx:66
A::value_type norm(const A &a)
Euklidean norm of array or expression.
Definition: util.hxx:54
const TArray2< int > & get_cells() const
Get array of point indices describing cells.
Definition: simplegrid.hxx:45
const int spacedim() const
Return dimension of space.
Definition: simplegrid.hxx:57

+ Here is the call graph for this function:

void fem2d::compute_cell_volume ( const int  icell,
const numcxx::DArray2 points,
const numcxx::IArray2 cells,
double &  vol 
)
inline

Definition at line 11 of file fem2d.cxx.

16  {
17  int i0=cells(icell,0);
18  int i1=cells(icell,1);
19  int i2=cells(icell,2);
20 
21  // Fill matrix V
22  double V00= points(i1,0)- points(i0,0);
23  double V01= points(i2,0)- points(i0,0);
24 
25  double V10= points(i1,1)- points(i0,1);
26  double V11= points(i2,1)- points(i0,1);
27 
28  // Compute determinant
29  double det=V00*V11 - V01*V10;
30  vol=0.5*det;
31  }
void fem2d::compute_local_stiffness_matrix ( const int  icell,
const numcxx::DArray2 points,
const numcxx::IArray2 cells,
numcxx::DArray2 SLocal,
double &  vol 
)
inline

Definition at line 33 of file fem2d.cxx.

39  {
40 
41  int i0=cells(icell,0);
42  int i1=cells(icell,1);
43  int i2=cells(icell,2);
44 
45  // Fill matrix V
46  double V00= points(i1,0)- points(i0,0);
47  double V01= points(i2,0)- points(i0,0);
48 
49  double V10= points(i1,1)- points(i0,1);
50  double V11= points(i2,1)- points(i0,1);
51 
52  // Compute determinant
53  double det=V00*V11 - V01*V10;
54  double fac = 0.5/det;
55 
56  // Compute entries of local stiffness matrix
57  SLocal(0,0)= fac * ( ( V10-V11 )*( V10-V11 )+( V01-V00 )*( V01-V00 ) );
58  SLocal(0,1)= fac * ( ( V10-V11 )* V11 - ( V01-V00 )*V01 );
59  SLocal(0,2)= fac * ( -( V10-V11 )* V10 + ( V01-V00 )*V00 );
60 
61  SLocal(1,1)= fac * ( V11*V11 + V01*V01 );
62  SLocal(1,2)= fac * ( -V11*V10 - V01*V00 );
63 
64  SLocal(2,2)= fac * ( V10*V10+ V00*V00 );
65 
66  SLocal(1,0)=SLocal(0,1);
67  SLocal(2,0)=SLocal(0,2);
68  SLocal(2,1)=SLocal(1,2);
69 
70  vol=0.5*det;
71  }

Variable Documentation

const double fem2d::Dirichlet =1.0e30

BC value marking Dirichlet boundary condition.

Examples:
40-stationary-heat-fe.cxx, 42-convtest-fem-sin.cxx, and 44-transient-heat-fe.cxx.

Definition at line 11 of file fem2d.hxx.