123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- // This code simulates the harmonic mechanical deflection of a 3D monocrystalline silicon - PZT microbilayer when
- // the PZT (a piezoelectric material) is sandwiched between two electrically actuated electrodes.
- //
- // The anisotropic behavior of both silicon and PZT is fully taken into account.
- // The silicon and PZT crystals are rotated to align with a selected orientation.
- #include "sparselizardbase.h"
- using namespace mathop;
- void sparselizard(void)
- {
- // The domain regions as defined in 'bilayer.geo':
- int pztlayer = 1, siliconlayer = 2, electrode = 3, ground = 4, clamp = 6, freeside = 7, elecbox = 8, mecabox = 9;
-
- mesh mymesh("bilayer.msh");
-
- int wholedomain = regionunion({pztlayer, siliconlayer});
-
- // Harmonic analysis. Set the fundamental frequency [Hz]:
- setfundamentalfrequency(1e4);
-
- // Nodal shape functions 'h1' for v (the electric potential) and u
- // (the mechanical displacement). Three components are used for u.
- // Use harmonic 2, i.e. u(x,t) = U(x)*sin(2pi*f0*t) for u and
- // v(x,t) = V(x)*sin(2pi*f0*t) for v.
- //
- field u("h1xyz",{2}), v("h1",{2});
-
- // Use interpolation order 2 on 'wholedomain' for u and 1 for v in the PZT layer:
- u.setorder(wholedomain, 2);
- v.setorder(pztlayer, 1);
-
- // Clamp on surface 'clamp' (i.e. 0 valued-Dirichlet conditions):
- u.setconstraint(clamp);
-
- v.harmonic(2).setconstraint(electrode, 10);
- v.setconstraint(ground, 0);
-
-
- // Silicon and PZT density [kg/m^3]:
- double rhosi = 2330, rhopzt = 7500;
-
- // Diagonal relative permittivity matrix for PZT:
- expression K(3,3,{1704,1704,1433});
- K = K * 8.854e-12;
-
- // Coupling matrix [C/m^2] for PZT (6 rows, 3 columns):
- expression C(6,3,{0,0,-6.62, 0,0,-6.62, 0,0,23.24, 0,17.03,0, 17.03,0,0, 0,0,0});
-
- // Anisotropic elasticity matrix [Pa] for silicon and PZT. Ordering is [exx,eyy,ezz,gyz,gxz,gxy] (Voigt form).
- // Only the lower triangular part (top to bottom and left to right) is provided since it is symmetric.
- expression Hsi(6,6, {194.5e9, 35.7e9,194.5e9, 64.1e9,64.1e9,165.7e9, 0,0,0,79.6e9, 0,0,0,0,79.6e9, 0,0,0,0,0,50.9e9});
- expression Hpzt(6,6, {1.27e11, 8.02e10,1.27e11, 8.46e10,8.46e10,1.17e11, 0,0,0,2.29e10, 0,0,0,0,2.29e10, 0,0,0,0,0,2.34e10});
-
- // Rotate the silicon and PZT crystals first by -30 degrees around y then by 45 degrees around z.
- // Refer to the documentation to make sure you understand how to use 'rotate'!
- Hsi.rotate(0,-30,45,"K","KT"); Hpzt.rotate(0,-30,45,"K","KT"); C.rotate(0,-30,45,"K","RT"); K.rotate(0,-30,45);
-
-
- formulation piezo;
-
- // Orthotropic elasticity in the silicon (not piezoelectric):
- piezo += integral(siliconlayer, predefinedelasticity(dof(u), tf(u), Hsi) );
- // Inertia term:
- piezo += integral(siliconlayer, -rhosi*dtdt(dof(u))*tf(u) );
-
- // The classical weak formulation for piezoelectricity below can be found e.g. in paper:
- //
- // "A new fnite-element formulation for electromechanical boundary value problems"
-
- // Define the mechanical equations of the problem in the piezo.
- // strain(u) returns the strain vector [exx,eyy,ezz,gyz,gxz,gxy] of u.
- piezo += integral(pztlayer, -( Hpzt*strain(dof(u)) )*strain(tf(u)) - ( C*grad(dof(v)) )*strain(tf(u)) );
- // Inertia term for PZT:
- piezo += integral(pztlayer, -rhopzt*dtdt(dof(u))*tf(u) );
- // Define the electrical equations of the problem in the piezo:
- piezo += integral(pztlayer, ( transpose(C)*strain(dof(u)) )*grad(tf(v)) - ( K*grad(dof(v)) )*grad(tf(v)) );
-
- solve(piezo);
-
- // Display the peak displacement:
- double umax = norm(u.harmonic(2)).max(wholedomain, 5)[0];
- std::cout << "Peak deflection is " << umax << " m" << std::endl;
-
- // Write the deflection and electric potential on the volume boundary.
- u.write(mecabox, "u.vtk", 2);
- v.write(elecbox, "v.vtk", 1);
- // Harmonic fields can be saved in time. Use 50 time steps:
- u.write(mecabox, "utime.vtk", 2, 50);
- v.write(elecbox, "vtime.vtk", 1, 50);
-
- // Code validation line. Can be removed.
- std::cout << (umax < 1.7386e-07 && umax > 1.7384e-07);
- }
- int main(void)
- {
- SlepcInitialize(0,{},0,0);
- sparselizard();
- SlepcFinalize();
- return 0;
- }
|