123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- // This simple code shows how to setup a 3D mechanical problem with a periodic condition.
- // A central 1.3 um thick, 50 um diameter polysilicon micromembrane stands above a 300 nm deep cavity.
- // The central micromembrane is surrounded by 6 identical ones, one every 60 degrees.
- // Assuming a periodic vibration with 60 degrees periodicity allows to reduce the problem to only a 1/6 of the geometry.
- //
- // In the .nas mesh used the meshes on both faces of the periodic condition do not match.
- #include "sparselizardbase.h"
- using namespace mathop;
- void processmesh(void);
- void sparselizard(void)
- {
- // Name the regions for the inner and outer electrode, the clamp and the regions 'gamma' on which to apply the periodic condition:
- int electrodein = 1, electrodeout = 2, clamp = 3, gamma1 = 4, gamma2 = 5, cavity = 4007, solid = 4008, all = 4009;
- // Define all regions needed in the source .nas mesh and save it in .msh format.
- processmesh();
- mesh mymesh("cmutperiodic.msh");
- // The periodic condition is only applied to the solid region:
- gamma1 = regionintersection({gamma1, solid});
- gamma2 = regionintersection({gamma2, solid});
- wallclock clk;
- // Harmonic simulation at f0 = 1 MHz:
- setfundamentalfrequency(1e6);
- // Nodal shape functions 'h1' with 3 components for u, the membrane deflection.
- // Use harmonic 2 to have u = U*sin(2pi*f0*t).
- field u("h1xyz", {2});
- // Use interpolation order 2 everywhere:
- u.setorder(all, 2);
- // Clamp on surface 'clamp' (i.e. 0 valued-Dirichlet conditions):
- u.setconstraint(clamp);
- // E is Young's modulus. nu is Poisson's ratio.
- double E = 160e9, nu = 0.22, rho = 2320;
- formulation elasticity;
- // The linear elasticity formulation is classical and thus predefined:
- elasticity += integral(solid, predefinedelasticity(dof(u), tf(u), E, nu));
- // Add a pressure load at frequency f0 on both inner and outer electrodes:
- double p = 1e5;
- elasticity += integral(electrodein, -p*compz(tf(u.harmonic(2))));
- elasticity += integral(electrodeout, -p*compz(tf(u.harmonic(2))));
- // Add the inertia term:
- elasticity += integral(solid, -rho*dtdt(dof(u))*tf(u));
- // Add the periodic condition between gamma1 and gamma2.
- // Region gamma2 is obtained from gamma1 by a 60 degrees rotation around z (rotation center is the origin).
- elasticity += periodicitycondition(gamma1, gamma2, u, {0,0,0}, {0,0,60});
- // Generate, solve and store the solution to field u:
- solve(elasticity);
- // Write the deflection to ParaView .vtk format. Write with an order 2 interpolation.
- u.write(solid, "u.vtk", 2);
- // Confirm that the periodic condition is correct by comparing the inner and outer cavity deflection:
- double ucenterin = 1e9 * norm(u.harmonic(2)).interpolate(solid,{0,0,1.5e-6})[0];
- double ucenterout = 1e9 * norm(u.harmonic(2)).interpolate(solid,{60e-6,0,1.5e-6})[0];
- std::cout << "Deflection at center of inner/outer cavity is " << ucenterin << " / " << ucenterout << " nm" << std::endl;
- clk.print();
- // Code validation line. Can be removed.
- std::cout << (ucenterin < 26.5977 && ucenterin > 26.5975);
- }
- void processmesh(void)
- {
- // Define the central electrode, outer electrode and clamp regions as well as the regions to apply the periodic condition.
- int elecc = 1, eleco = 2, clamp = 3, gamma1 = 4, gamma2 = 5;
- setphysicalregionshift(1000);
- mesh mymesh1;
- mymesh1.load("cmutperiodic.nas", 0);
- int vac = regionunion({4001,4005});
- int solid = regionunion({4002,4003,4004,4006});
- int all = regionunion({vac,solid});
- // Rotate the mesh to easily select the bottom side for the periodic condition:
- mymesh1.rotate(0,0,30);
- mymesh1.write("cmutperiodic.msh", 0);
-
- setphysicalregionshift(0);
- mesh mymesh2;
- mymesh2.boxselection(elecc, 4001, 2, {-10,10,-10,10,0.3e-6-1e-10,0.3e-6+1e-10});
- mymesh2.boxselection(eleco, 4006, 2, {-10,10,-10,10,0.3e-6-1e-10,0.3e-6+1e-10});
- mymesh2.boxselection(clamp, all, 2, {-10,10,-10,10,-1e-10,1e-10});
- mymesh2.boxselection(gamma1, all, 2, {-10,10,-1e-10,1e-10,-10,10});
- mymesh2.load("cmutperiodic.msh", 0);
- // Rotate to the other direction to align the other region for the periodic condition:
- mymesh2.rotate(0,0,-60);
- mymesh2.write("cmutperiodic.msh", 0);
- mesh mymesh3;
- mymesh3.boxselection(gamma2, all, 2, {-10,10,-1e-10,1e-10,-10,10});
- mymesh3.load("cmutperiodic.msh", 0);
- // Bring the mesh back to its original angle:
- mymesh3.rotate(0,0,30);
- // Write the processed mesh:
- mymesh3.write("cmutperiodic.msh", 0);
- }
- int main(void)
- {
- SlepcInitialize(0,{},0,0);
- sparselizard();
- SlepcFinalize();
- return 0;
- }
|