QImage CurveTransform::transform() { for(unsigned int i = 0; i < image_width; i++) { for(unsigned int j = 0; j < image_height; j++) { CartesianPair coords = {i, j}; drawPixels(convertToPixels(convertToCartesian(convertToPolar(coords))),coords); //Lisp, eat your heart out } } return out_image; }
vector geodesicSolidBodyVelocityField::streamfunctionAt ( const point& p, const Time& t ) const { const dimensionedScalar T = (endTime.value() == -1 ) ? t.endTime() : endTime; const scalar u0 = 2 * M_PI * radius.value() / T.value(); const polarPoint& polarp = convertToPolar(p); const scalar lat = polarp.lat(); const scalar lon = polarp.lon(); const scalar psi = - u0 * (Foam::sin(lat) * Foam::cos(alpha) - Foam::cos(lon) * Foam::cos(lat) * Foam::sin(alpha)); return p/mag(p) * psi * radius.value(); }
point geodesicSolidBodyVelocityField::initialPositionOf ( const point& p, const Time& t ) const { // assume alpha = 0 const dimensionedScalar T = (endTime.value() == -1 ) ? t.endTime() : endTime; const scalar u0 = 2 * M_PI * radius.value() / T.value(); const polarPoint& polarp = convertToPolar(p); const scalar lat = polarp.lat(); scalar lon = polarp.lon(); lon -= u0/radius.value() * t.value(); const polarPoint departureP(lon, lat, radius.value()); return departureP.cartesian(); }
/** * Find the equilibrium after placing the cylinders in the domain somewhere. * Iterates until tolerence is met. */ void SwarmCylinders::findEquilibrium() { double dalpha = 2.0 * M_PI / (double) M; vector<double> m; for (int i = 0; i < M; i++) { m.push_back(spline.evaluate(i * dalpha) * dalpha); /// assuming constant density charge on boundary } vector<double> xs; vector<double> ys; for (int i = 0; i < M; i++) { xs.push_back(spline.evaluate(((double) i + 0.5) * dalpha)); ys.push_back(((double) i + 0.5) * dalpha); } convertToCartesian(xs, ys); int nIter = 0; bool steadyState = false; while (!steadyState) { vector<double> xNew; vector<double> yNew; const int xsize = x.size(); for (int i = 0; i < xsize; i++) { xNew.push_back(0.0); yNew.push_back(0.0); } for (int i = 0; i < xsize; i++) { double u = 0.0; double v = 0.0; for (int j = 0; j < xsize; j++) /// from each body { if (i != j) { double norm = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j])); double factor = factorCylinder / (norm * norm * norm); u += (x[i] - x[j]) * factor; v += (y[i] - y[j]) * factor; } } for (int j = 0; j < M; j++) /// from boundary { double norm = sqrt((x[i] - xs[j]) * (x[i] - xs[j]) + (y[i] - ys[j]) * (y[i] - ys[j])); double factor = factorBoundary * m[j] / (norm * norm * norm); u += (x[i] - xs[j]) * factor; v += (y[i] - ys[j]) * factor; } xNew[i] = x[i] + dt * u; yNew[i] = y[i] + dt * v; } convertToPolar(xNew, yNew); for (int i = 0; i < xsize; i++) { const double rMax = spline.evaluate(yNew[i]) - radius; if (rMax < xNew[i]) xNew[i] = 0.1 * rMax; /// move it toward (0,0) // xNew[i] = min(spline.evaluate(yNew[i])-radius, xNew[i]); /// make it sit on the boundary if it is not repelled enough (not exactly correct) } convertToCartesian(xNew, yNew); double maxNorm = 0.0; for (int i = 0; i < xsize; i++) { double norm = sqrt((xNew[i] - x[i]) * (xNew[i] - x[i]) + (yNew[i] - y[i]) * (yNew[i] - y[i])); /// relative difference maxNorm = max(norm, maxNorm); } for (int i = 0; i < xsize; i++) { x[i] = xNew[i]; y[i] = yNew[i]; } // TODO Remove this testing shit, writing the positions each iteration if (nIter % 10 == 0) { FILE* fidx; FILE* fidy; if (nIter == 0) { fidx = fopen("x.txt", "w"); fidy = fopen("y.txt", "w"); } else { fidx = fopen("x.txt", "a"); fidy = fopen("y.txt", "a"); } const int xsize = x.size(); for (int i = 0; i < xsize; ++i) { fprintf(fidx, "%e ", x[i]); fprintf(fidy, "%e ", y[i]); } fprintf(fidx, "\n"); fprintf(fidy, "\n"); fclose(fidx); fclose(fidy); } nIter++; if (maxNorm <= threshold) break; if (nIter % 5000 == 0) printf("** Norm at iteration %d: %e\n", nIter, maxNorm); if (nIter > 50000) { printf("** Something is wrong, swarm shape is not converging quickly enough... aborting... \n"); abort(); } } printf("** Number of iterations to steady state formation: %d\n", nIter); }