package symjava.examples; import static symjava.math.SymMath.dot; import static symjava.math.SymMath.grad; import static symjava.symbolic.Symbol.*; import java.util.HashMap; import java.util.List; import java.util.Map; import Jama.Matrix; import symjava.domains.Domain; import symjava.examples.fem.Element; import symjava.examples.fem.Mesh2D; import symjava.examples.fem.Node; import symjava.examples.fem.RefTriangle; import symjava.examples.fem.WeakForm; import symjava.math.Transformation; import symjava.matrix.SymMatrix; import symjava.numeric.NumInt; import symjava.relational.Eq; import symjava.symbolic.Expr; import symjava.symbolic.Func; import symjava.symbolic.Integrate; import symjava.symbolic.SymConst; import symjava.symbolic.Symbol; /** * Finite Element solver * */ public class Example6 { public static void main(String[] args) { // Func u = new Func("u", x, y); // Func v = new Func("v", x, y); // //// //Our PDE equation //// Eq pde = new Eq(0.5*dot(grad(u), grad(v)) + 0.1*u*v, (x*x+y*y)*v); //// //Read the mesh //// Mesh2D mesh = new Mesh2D("mesh1", x, y); //// mesh.readTriangleMesh("double_hex3.1.node", "double_hex3.1.ele"); //// solve(pde, mesh, null, "double_hex3.1.dat"); // // //Another PDE equation with Dirichlet condition // WeakForm wf = new WeakForm(dot(grad(u), grad(v)), (-2*(x*x+y*y)+36)*v, u, v); // //Eq pde2 = new Eq(u*v, (-2*(x*x+y*y)+36)*v); // Mesh2D mesh2 = new Mesh2D("mesh2"); // //mesh2.readGridGenMesh("patch_triangle.grd"); // mesh2.readGridGenMesh("triangle.grd"); // //Mark boundary nodes // double eps = 0.01; // for(Node n : mesh2.nodes) { // //if(1-Math.abs(n.coords[0]) diri = new HashMap(); // diri.put(1, 0.0); // //solve(pde2, mesh2, diri, "patch_triangle.dat"); // solve(wf, mesh2, diri, "triangle.dat"); // solve2(mesh2, diri, "triangle_hardcode.dat"); peper_example(); } public static void peper_example() { Func u = new Func("u", x, y); Func v = new Func("v", x, y); WeakForm wf = new WeakForm(dot(grad(u), grad(v)), (-2*(x*x+y*y)+36)*v, u, v); Mesh2D mesh = new Mesh2D("Square"); mesh.readGridGenMesh("triangle.grd"); //Mark boundary nodes double eps = 0.01; for(Node n : mesh.nodes) { if(Math.abs(3-Math.abs(n.coords[0])) diri = new HashMap(); diri.put(1, 0.0); solve(wf, mesh, diri, "triangle.dat"); } public static void solve(WeakForm wf, Mesh2D mesh, Map dirichlet, String output) { System.out.println(String.format("PDE Weak Form: %s = %s", wf.lhs(), wf.rhs())); //Create coordinate transformation Symbol x1 = new Symbol("x1"); Symbol x2 = new Symbol("x2"); Symbol x3 = new Symbol("x3"); Symbol y1 = new Symbol("y1"); Symbol y2 = new Symbol("y2"); Symbol y3 = new Symbol("y3"); Transformation trans = new Transformation( new Eq(x, x1*r+x2*s+x3*(1-r-s), new Expr[]{r, s}), new Eq(y, y1*r+y2*s+y3*(1-r-s), new Expr[]{r, s}) ); // jac = (xr xs) // (yr ys) SymMatrix jacMat = trans.getJacobianMatrix(); System.out.println(jacMat); System.out.println(); //Shape functions Func N1 = new Func("R", x, y); Func N2 = new Func("S", x, y); Func N3 = new Func("T", 1 - N1 - N2); Func[] shapeFuns = {N1, N2, N3}; Expr jac = trans.getJacobian(); Expr rx = jacMat[1][1]/jac; //rx = ys/jac Expr ry = -jacMat[0][1]/jac; //ry = -xs/jac //bugfix missed a minus sign! Expr sx = -jacMat[1][0]/jac; //sx = -yr/jac Expr sy = jacMat[0][0]/jac; //sy = xr/jac System.out.println(jac); System.out.println(rx); System.out.println(ry); System.out.println(sx); System.out.println(sy); RefTriangle tri = new RefTriangle("Tri", r, s); Integrate lhsInt[][] = new Integrate[shapeFuns.length][shapeFuns.length]; Integrate rhsInt[] = new Integrate[shapeFuns.length]; for(int i=0; i eles = mesh.getSubDomains(); double[][] matA = new double[mesh.nodes.size()][mesh.nodes.size()]; double[] vecb = new double[mesh.nodes.size()]; for(Domain d : eles) { Element e = (Element)d; double[] nodeCoords = e.getNodeCoords(); for(int i=0; i dirichlet, String output) { //Assemble the system System.out.println("Start assemble the system..."); long begin = System.currentTimeMillis(); List eles = mesh.getSubDomains(); double[][] matA = new double[mesh.nodes.size()][mesh.nodes.size()]; double[] vecb = new double[mesh.nodes.size()]; for(Domain d : eles) { Element e = (Element)d; double[] coords = e.getNodeCoords(); double x1 = coords[0]; double x2 = coords[1]; double x3 = coords[2]; double y1 = coords[3]; double y2 = coords[4]; double y3 = coords[5]; //x = x1*r+x2*s+x3*(1-r-s) //y = y1*r+y2*s+y3*(1-r-s) double xr = x1-x3; double xs = x2-x3; double yr = y1-y3; double ys = y2-y3; // jac = (xr xs) // (yr ys) double jac = xr*ys-xs*yr; double rx = ys/jac; double ry = -xs/jac; double sx = -yr/jac; double sy = xr/jac; double tx = -rx - sx; double ty = -ry - sy; double[][] lhs = { {rx*rx + ry*ry, rx*sx + ry*sy, rx*tx+ry*ty}, {sx*rx + sy*ry, sx*sx + sy*sy, sx*tx+sy*ty}, {tx*rx + ty*ry, tx*sx + ty*sy, tx*tx+ty*ty}, }; for(int i=0; i<3; i++) { int idxI = e.nodes.get(i).getIndex()-1; for(int j=0; j<3; j++) { int idxJ = e.nodes.get(j).getIndex()-1; double t = lhs[i][j]*jac*0.5; matA[idxI][idxJ] += t; } } double[][] intPnW = { {0.5, 0.5, 1.0/6.0}, {0.0, 0.5, 1.0/6.0}, {0.5, 0.0, 1.0/6.0} }; for(int k=0; k