/* * Open Source Physics software is free software as described near the bottom of this code file. * * For additional information and documentation on Open Source Physics please see: * <http://www.opensourcephysics.org/> */ package org.opensourcephysics.display2d; /** * Utility class for two dimensional visualizations. * * @author Wolfgang Christian * @created Feb 20, 2003 * @version 1.0 */ public class Util2D { private Util2D() { // prohibit instantiation } /** * Calculates the Laplacian of a 2d scalar field. * @param input * @param multiplier * @return GridPointData */ public static GridPointData laplacian(GridPointData input, double multiplier) { // algorithm to be written /* double[][][] indata = input.getData(); int nr = indata.length; int nc = indata[0].length; GridPointData output = input.createGridPointData(1); output.left = input.left; output.right = input.right; output.top = input.top; output.bottom = input.bottom; output.dx = input.dx; output.dy = input.dy; double[][][] outdata = output.getData(); double dx2 = 2*input.dx/multiplier; double dy2 = 2*input.dy/multiplier; double dudx, dudy; return output; */ return null; } /** * Calculates the divergence of a 2d vector field and multiplies the divergence by a constant. * @param input * @param multiplier * @return GridPointData */ public static GridPointData divergence(GridPointData input, double multiplier) { double[][][] indata = input.getData(); int nx = indata.length; int ny = indata[0].length; GridPointData output = input.createGridPointData(1); output.left = input.left; output.right = input.right; output.top = input.top; output.bottom = input.bottom; output.dx = input.dx; output.dy = input.dy; double[][][] outdata = output.getData(); double dx2 = 2*input.dx/multiplier; double dy2 = 2*input.dy/multiplier; double dudx, dudy; for(int i = 1; i<nx-1; i++) { for(int j = 1; j<ny-1; j++) { dudx = (indata[i+1][j][2]-indata[i-1][j][2])/dx2; dudy = (indata[i][j+1][2]-indata[i][j-1][2])/dy2; outdata[i][j][0] = indata[i][j][0]; outdata[i][j][1] = indata[i][j][1]; outdata[i][j][2] = dudx+dudy; } } // top row for(int i = 1; i<nx-1; i++) { dudx = (indata[i+1][0][2]-indata[i-1][0][2])/dx2; // 2d order forward difference dudy = (-3*indata[i][0][2]+4*indata[i][1][2]-indata[i][2][2])/dy2; outdata[i][0][2] = dudx+dudy; } // bottom row int my = ny-1; for(int i = 1; i<nx-1; i++) { dudx = (indata[i+1][my][2]-indata[i-1][my][2])/dx2; // 2d order barkward difference dudy = (+3*indata[i][my][2]-4*indata[i][my-1][2]+indata[i][my-2][2])/dy2; outdata[i][my][2] = dudx+dudy; } // left column for(int j = 1; j<ny-1; j++) { // 2d order forward difference dudx = (-3*indata[0][j][2]+4*indata[1][j][2]-indata[2][j][2])/dx2; dudy = (indata[0][j+1][2]-indata[0][j-1][2])/dy2; outdata[0][j][2] = dudx+dudy; } // right column int mx = nx-1; for(int j = 1; j<ny-1; j++) { // 2d order backward difference dudx = (+3*indata[mx][j][2]-4*indata[mx-1][j][2]+indata[mx-2][j][2])/dx2; dudy = (indata[mx][j+1][2]-indata[mx][j-1][2])/dy2; outdata[mx][j][2] = dudx+dudy; } // left top corner dudx = (outdata[1][0][2]*outdata[1][0][3]+outdata[0][1][2]*outdata[0][1][3])/2; dudy = (outdata[1][0][2]*outdata[1][0][4]+outdata[0][1][2]*outdata[0][1][4])/2; outdata[0][0][2] = dudx+dudy; // left bottom corner dudx = (outdata[0][my-1][2]*outdata[0][my-1][3]+outdata[1][my][2]*outdata[1][my][3])/2; dudy = (outdata[0][my-1][2]*outdata[0][my-1][4]+outdata[1][my][2]*outdata[1][my][4])/2; outdata[0][my][2] = dudx+dudy; // right top corner dudx = (outdata[mx][1][2]*outdata[mx][1][3]+outdata[mx-1][0][2]*outdata[mx-1][0][3])/2; dudy = (outdata[mx][1][2]*outdata[mx][1][4]+outdata[mx-1][0][2]*outdata[mx-1][0][4])/2; outdata[mx][0][2] = dudx+dudy; // right bottom corner dudx = (outdata[mx][my-1][2]*outdata[mx][my-1][3]+outdata[mx-1][my][2]*outdata[mx-1][my][3])/2; dudy = (outdata[mx][my-1][2]*outdata[mx][my-1][4]+outdata[mx-1][my][2]*outdata[mx-1][my][4])/2; outdata[mx][my][2] = dudx+dudy; return output; } /** * Calculates the gradient of a 2d scalar field and multiplies the gradient by a constant. * @param input * @param multiplier * @return GridPointData */ public static GridPointData gradient(GridPointData input, double multiplier) { double[][][] indata = input.getData(); int nx = indata.length; int ny = indata[0].length; GridPointData output = input.createGridPointData(3); output.left = input.left; output.right = input.right; output.top = input.top; output.bottom = input.bottom; output.dx = input.dx; output.dy = input.dy; double[][][] outdata = output.getData(); double dx2 = 2*input.dx/multiplier; double dy2 = 2*input.dy/multiplier; double dudx, dudy, mag; for(int i = 1; i<nx-1; i++) { for(int j = 1; j<ny-1; j++) { dudx = (indata[i+1][j][2]-indata[i-1][j][2])/dx2; dudy = (indata[i][j+1][2]-indata[i][j-1][2])/dy2; mag = Math.sqrt(dudx*dudx+dudy*dudy); outdata[i][j][0] = indata[i][j][0]; outdata[i][j][1] = indata[i][j][1]; outdata[i][j][2] = mag; outdata[i][j][3] = dudx/mag; outdata[i][j][4] = dudy/mag; } } // top row for(int i = 1; i<nx-1; i++) { dudx = (indata[i+1][0][2]-indata[i-1][0][2])/dx2; // 2d order forward difference dudy = (-3*indata[i][0][2]+4*indata[i][1][2]-indata[i][2][2])/dy2; mag = Math.sqrt(dudx*dudx+dudy*dudy); outdata[i][0][2] = mag; outdata[i][0][3] = dudx/mag; outdata[i][0][4] = dudy/mag; } // bottom row int my = ny-1; for(int i = 1; i<nx-1; i++) { dudx = (indata[i+1][my][2]-indata[i-1][my][2])/dx2; // 2d order barkward difference dudy = (+3*indata[i][my][2]-4*indata[i][my-1][2]+indata[i][my-2][2])/dy2; mag = Math.sqrt(dudx*dudx+dudy*dudy); outdata[i][my][2] = mag; outdata[i][my][3] = dudx/mag; outdata[i][my][4] = dudy/mag; } // left column for(int j = 1; j<ny-1; j++) { // 2d order forward difference dudx = (-3*indata[0][j][2]+4*indata[1][j][2]-indata[2][j][2])/dx2; dudy = (indata[0][j+1][2]-indata[0][j-1][2])/dy2; mag = Math.sqrt(dudx*dudx+dudy*dudy); outdata[0][j][2] = mag; outdata[0][j][3] = dudx/mag; outdata[0][j][4] = dudy/mag; } // right column int mx = nx-1; for(int j = 1; j<ny-1; j++) { // 2d order backward difference dudx = (+3*indata[mx][j][2]-4*indata[mx-1][j][2]+indata[mx-2][j][2])/dx2; dudy = (indata[mx][j+1][2]-indata[mx][j-1][2])/dy2; mag = Math.sqrt(dudx*dudx+dudy*dudy); outdata[mx][j][2] = mag; outdata[mx][j][3] = dudx/mag; outdata[mx][j][4] = dudy/mag; } // left top corner dudx = (outdata[1][0][2]*outdata[1][0][3]+outdata[0][1][2]*outdata[0][1][3])/2; dudy = (outdata[1][0][2]*outdata[1][0][4]+outdata[0][1][2]*outdata[0][1][4])/2; mag = Math.sqrt(dudx*dudx+dudy*dudy); outdata[0][0][2] = mag; outdata[0][0][3] = dudx/mag; outdata[0][0][4] = dudy/mag; // left bottom corner dudx = (outdata[0][my-1][2]*outdata[0][my-1][3]+outdata[1][my][2]*outdata[1][my][3])/2; dudy = (outdata[0][my-1][2]*outdata[0][my-1][4]+outdata[1][my][2]*outdata[1][my][4])/2; mag = Math.sqrt(dudx*dudx+dudy*dudy); outdata[0][my][2] = mag; outdata[0][my][3] = dudx/mag; outdata[0][my][4] = dudy/mag; // right top corner dudx = (outdata[mx][1][2]*outdata[mx][1][3]+outdata[mx-1][0][2]*outdata[mx-1][0][3])/2; dudy = (outdata[mx][1][2]*outdata[mx][1][4]+outdata[mx-1][0][2]*outdata[mx-1][0][4])/2; mag = Math.sqrt(dudx*dudx+dudy*dudy); outdata[mx][0][2] = mag; outdata[mx][0][3] = dudx/mag; outdata[mx][0][4] = dudy/mag; // right bottom corner dudx = (outdata[mx][my-1][2]*outdata[mx][my-1][3]+outdata[mx-1][my][2]*outdata[mx-1][my][3])/2; dudy = (outdata[mx][my-1][2]*outdata[mx][my-1][4]+outdata[mx-1][my][2]*outdata[mx-1][my][4])/2; mag = Math.sqrt(dudx*dudx+dudy*dudy); outdata[mx][my][2] = mag; outdata[mx][my][3] = dudx/mag; outdata[mx][my][4] = dudy/mag; return output; } } /* * Open Source Physics software is free software; you can redistribute * it and/or modify it under the terms of the GNU General Public License (GPL) as * published by the Free Software Foundation; either version 2 of the License, * or(at your option) any later version. * Code that uses any portion of the code in the org.opensourcephysics package * or any subpackage (subdirectory) of this package must must also be be released * under the GNU GPL license. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA * or view the license online at http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2007 The Open Source Physics project * http://www.opensourcephysics.org */