// find distance x0 is from triangle x1-x2-x3 float point_triangle_distance( const Vec3f &x0, const Vec3f &x1, const Vec3f &x2, const Vec3f &x3, float * baryCentricCoordinates) { // first find barycentric coordinates of closest point on infinite plane Vec3f x13(x1-x3), x23(x2-x3), x03(x0-x3); float m13=mag2(x13), m23=mag2(x23), d=dot(x13,x23); float invdet=1.f/max(m13*m23-d*d,1e-30f); float a=dot(x13,x03), b=dot(x23,x03); // the barycentric coordinates themselves float w23=invdet*(m23*a-d*b); float w31=invdet*(m13*b-d*a); float w12=1-w23-w31; if(baryCentricCoordinates!=0){ baryCentricCoordinates[0] = w23; baryCentricCoordinates[1] = w31; baryCentricCoordinates[2] = w12; } if(w23>=0 && w31>=0 && w12>=0){ // if we're inside the triangle return dist(x0, w23*x1+w31*x2+w12*x3); }else{ // we have to clamp to one of the edges if(w23>0) // this rules out edge 2-3 for us return min(point_segment_distance(x0,x1,x2), point_segment_distance(x0,x1,x3)); else if(w31>0) // this rules out edge 1-3 return min(point_segment_distance(x0,x1,x2), point_segment_distance(x0,x2,x3)); else // w12 must be >0, ruling out edge 1-2 return min(point_segment_distance(x0,x1,x3), point_segment_distance(x0,x2,x3)); } }
// return a unit-length vector orthogonal to u and v static Vec3d get_normal(const Vec3d& u, const Vec3d& v) { Vec3d c=cross(u,v); double m=mag(c); if(m) return c/m; // degenerate case: either u and v are parallel, or at least one is zero; pick an arbitrary orthogonal vector if(mag2(u)>=mag2(v)){ if(std::fabs(u[0])>=std::fabs(u[1]) && std::fabs(u[0])>=std::fabs(u[2])) c=Vec3d(-u[1]-u[2], u[0], u[0]); else if(std::fabs(u[1])>=std::fabs(u[2])) c=Vec3d(u[1], -u[0]-u[2], u[1]); else c=Vec3d(u[2], u[2], -u[0]-u[1]); }else{ if(std::fabs(v[0])>=std::fabs(v[1]) && std::fabs(v[0])>=std::fabs(v[2])) c=Vec3d(-v[1]-v[2], v[0], v[0]); else if(std::fabs(v[1])>=std::fabs(v[2])) c=Vec3d(v[1], -v[0]-v[2], v[1]); else c=Vec3d(v[2], v[2], -v[0]-v[1]); } m=mag(c); if(m) return c/m; // really degenerate case: u and v are both zero vectors; pick a random unit-length vector c[0]=random()%2 ? -0.577350269189626 : 0.577350269189626; c[1]=random()%2 ? -0.577350269189626 : 0.577350269189626; c[2]=random()%2 ? -0.577350269189626 : 0.577350269189626; return c; }
void create_capsule_signed_distance( const Vec3d& capsule_end_a, const Vec3d& capsule_end_b, double capsule_radius, double dx, const Vec3d& domain_low, const Vec3d& domain_high, Array3d& phi ) { phi.resize( (int) ceil( (domain_high[0]-domain_low[0]) / dx), (int) ceil( (domain_high[1]-domain_low[1]) / dx), (int) ceil( (domain_high[2]-domain_low[2]) / dx) ); std::cout << "Generating signed distance function. Grid resolution: " << phi.ni << " x " << phi.nj << " x " << phi.nk << std::endl; for ( int i = 0; i < phi.ni; ++i ) { for ( int j = 0; j < phi.nj; ++j ) { for ( int k = 0; k < phi.nk; ++k ) { Vec3d pt = domain_low + dx * Vec3d(i,j,k); double distance; Vec3d central_segment(capsule_end_b - capsule_end_a); double m2=mag2(central_segment); // find parameter value of closest point on infinite line double s = dot(capsule_end_b - pt, central_segment)/m2; if ( s < 0.0 ) { // dist = distance to the cylinder disc at end b distance = dist(pt, capsule_end_b); distance -= capsule_radius; } else if ( s > 1.0 ) { // dist = distance to the cylinder disc at end b distance = dist(pt, capsule_end_a ); distance -= capsule_radius; } else { // dist = distance to the cylinder's central axis distance = dist(pt, s*capsule_end_a + (1-s)*capsule_end_b); distance -= capsule_radius; } phi(i,j,k) = distance; } } } }
float ComplexFloatArray::mag(const int i){ float result; #ifdef ARM_CORTEX arm_cmplx_mag_f32((float*)&(data[i]), &result,1); #else result=sqrtf(mag2(i)); #endif return result; }
static float point_segment_dist(const Vec2f &x0, const Vec2f &x1, const Vec2f &x2) { Vec2f dx(x2-x1); float m2=mag2(dx); // find parameter value of closest point on segment float s=clamp(dot(x2-x0, dx)/m2, 0.0f, 1.0f); // and find the distance return dist(x0,s*x1+(1-s)*x2); }
void ComplexFloatArray::getMagnitudeSquaredValues(FloatArray& dest){ #ifdef ARM_CORTEX arm_cmplx_mag_squared_f32((float*)data, (float*)dest, size); #else for(int i=0; i<size; i++){ dest[i]=mag2(i); } #endif }
main(int argc, char *argv[]) { if(argc>1) cx = atof(argv[1]); /* center x */ if(argc>2) cy = atof(argv[2]); /* center y */ if(argc>3) height=width=atof(argv[3]); /* rectangle height and width */ if(argc>4) max=atoi(argv[4]); /* maximum iterations */ timeval start, end; gettimeofday(&start, NULL); #pragma omp parallel for num_threads(num) for (int i=0; i<n; i++) { for(int j=0; j<m; j++) { /* starting point */ float x, y, v; complex c0, c, d; x= i *(width/(n-1)) + cx -width/2; y= j *(height/(m-1)) + cy -height/2; form(0,0,c); form(x,y,c0); /* complex iteration */ for(int k=0; k<max; k++) { mult(c,c,d); add(d,c0,c); v=mag2(c); if(v>4.0) break; /* assume not in set if mag > 4 */ } /* assign gray level to point based on its magnitude */ if(v>1.0) v=1.0; /* clamp if > 1 */ image[i][j]=255*v; } } gettimeofday(&end, NULL); printf("Time: %.3lfms\n", (end.tv_sec - start.tv_sec) * 1000.0 + (end.tv_usec - start.tv_usec) / 1000.0); /*for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) printf("%d%c", image[i][j], j == m-1 ? '\n':' ');*/ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB ); glutInitWindowSize(N, M); glutCreateWindow("mandlebrot"); myinit(); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutMainLoop(); }
int ComplexFloatArray::getMaxMagnitudeIndex(){ //this is probably slower than getMagnitudeSquaredValues() and getMaxIndex() on it float maxMag=-1; int maxInd=-1; for(int n=0; n<size; n++){ float magnitude=mag2(n); //uses mag2 which is faster if(magnitude>maxMag){ maxMag=magnitude; maxInd=n; } } return maxInd; }
static Vec<N,float> sample_sphere(unsigned int &seed) { Vec<N,float> v; float m2; do{ for(unsigned int i=0; i<N; ++i){ v[i]=randhashf(seed++,-1,1); } m2=mag2(v); }while(m2>1 || m2==0); return v/std::sqrt(m2); }
// find distance x0 is from segment x1-x2 static float point_segment_distance(const Vec3f &x0, const Vec3f &x1, const Vec3f &x2) { Vec3f dx(x2-x1); double m2=mag2(dx); // find parameter value of closest point on segment float s12=(float)(dot(x2-x0, dx)/m2); if(s12<0){ s12=0; }else if(s12>1){ s12=1; } // and find the distance return dist(x0, s12*x1+(1-s12)*x2); }
Vec3f Feature::getTangent(const Vec3f& p) const { if (vertices.size() < 2) { return Vec3f(0,0,0); // No tangent exists. } else { // Find the nearest edge and return it. Vec3f tangentEdge(0,0,0); float minDist2 = FLT_MAX; for (size_t i = 0; i < vertices.size()-1; ++i) { const Vec3f& e1 = vertices[i]; const Vec3f& e2 = vertices[i+1]; Vec3f edge(e2 - e1); double edgeLength2 = mag2(edge); float t = static_cast<float>(dot(e2-p, edge)/edgeLength2); // Clamp t-value between 0 and 1. if (t < 0.0) { t = 0.0; } else if (t > 1.0) { t = 1.0; } // Compute distance to closest point Vec3f closestPoint = t*e1 + (1-t)*e2; float d2 = dist2(p, closestPoint); if (d2 < minDist2) { tangentEdge = edge; minDist2 = d2; } } assert(mag2(tangentEdge) > 0.0); // tangentEdge is now the edge vector of the closest edge to the point return normalized(tangentEdge); } }
Vec3f Feature::projectToFeature(const Vec3f &p) const { // Feature defined as sequence of vertices connected by line segments. // Find the closest line segment to the point, and then project onto it. if (vertices.size() == 0) { return p; // Nothing to do here. } else if (vertices.size() == 1) { // The feature is just a point. return vertices[0]; } else { // The feature is comprised of one or more edges. // Find the nearest one and project onto that. Vec3f projectionPoint; float minDist2 = FLT_MAX; for (size_t i = 0; i < vertices.size()-1; ++i) { const Vec3f& e1 = vertices[i]; const Vec3f& e2 = vertices[i+1]; // Compute the closest point on the current edge. Vec3f edge(e2 - e1); double edgeLength2 = mag2(edge); float t = static_cast<float>(dot(e2-p, edge)/edgeLength2); // Clamp t-value between 0 and 1. if (t < 0.0) { t = 0.0; } else if (t > 1.0) { t = 1.0; } // Compute distance to closest point and save if it's smallest. Vec3f closestPoint = t*e1 + (1-t)*e2; float d2 = dist2(p, closestPoint); if (d2 < minDist2) { projectionPoint = closestPoint; minDist2 = d2; } } // projectionPoint now contains the closest point on any of the // edges to the given point. return projectionPoint; } }
bool IntersectRaySphere(const Ray & ray, const float3 & center, float radius, float * outT, float3 * outNormal) { auto delta = center - ray.origin; float b = dot(ray.direction, delta), disc = b*b + radius*radius - mag2(delta); if(disc < 0) return false; float t = b - std::sqrt(disc); if(t <= 0) { float t1 = 2*b - t; if(t1 <= 0) return false; t = 0; } if(outT) *outT = t; if(outNormal) *outNormal = t ? (ray.direction * t - delta) / radius : norm(ray.direction * t - delta); return true; }
void CPlanarGraph::PickClosestNode(float px, float py) { float distSqrMin = std::numeric_limits<float>::max(); v2f p; p[0] = px; p[1] = py; for ( int i=0; i<int(m_nodes.size()); i++ ) { v2f pi = m_nodes[i].GetPos(); float distSqrTmp = mag2(pi - p); if ( distSqrTmp < distSqrMin ) { distSqrMin = distSqrTmp; m_pickedNodeIndex = i; } } std::cout << "Have picked the " << m_pickedNodeIndex << "th node centered at " << GetNodePos(m_pickedNodeIndex) << "!\n"; }
void makeImage(){ int i, j, k; double x, y, v; complex c0, c, d; int choice; /* uncomment to define your own parameters */ printf("Input number of iterations: "); scanf("%d",&max); /* maximum iterations */ printf("Input 1 for inside set, 0 for outside set: "); scanf("%i",&choice); /* scanf("%f", &cx); /* center x */ /* scanf("%f", &cy); /* center y */ /* scanf("%f", &width); /* rectangle width */ /* height=width; /* rectangle height */ for (i=0; i<n; i++) for(j=0; j<m; j++){ /* starting point */ x= i *(dimention[dimIter].width/(n-1)) + dimention[dimIter].cx -dimention[dimIter].width/2; y= j *(dimention[dimIter].height/(m-1)) + dimention[dimIter].cy -dimention[dimIter].height/2; form(0,0,c); form(x,y,c0); /* complex iteration */ for(k=0; k<max; k++){ mult(c,c,d); add(d,c0,c); v=mag2(c); if(v>4.0) break; /* assume not in set if mag > 4 */ } /* assign gray level to point based on its magnitude */ if(v>1.0) v=1.0; /* clamp if > 1 */ if(choice==0){ dimention[dimIter].image[j][i]=k*1.0*255/max; }else{ dimention[dimIter].image[j][i] = 255*v; } } }
float Example2DFancy:: potential(float x, float y) const { Vec2f px(x,y); float numer=(1/sqr(envelope))*cross(px,wind_velocity); float denom=1/sqr(envelope); float minphi=1e36; for(unsigned int r=0; r<rigid.size(); ++r){ Vec2f dx=px-rigid[r].centre; float psi=cross(px,rigid[r].velocity) + (sqr(envelope)-mag2(dx))/2*rigid[r].angular_velocity; float phi=rigid[r].distance(px); if(phi<minphi) minphi=phi; float m=1/(sqr(phi)+1e-18); numer+=m*psi; denom+=m; } float base_psi=numer/denom; float d=minphi/noise_lengthscale; float g=smooth_step(1.1-x); float turb=g*ramp(d)*noise_gain*noise((px-t*wind_velocity)/noise_lengthscale); return base_psi+turb; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(Hermes::Tuple<int>(BDY_BOTTOM, BDY_RIGHT, BDY_TOP, BDY_LEFT)); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_zero(Hermes::Tuple<int>(BDY_BOTTOM, BDY_RIGHT, BDY_TOP, BDY_LEFT)); // Create an H1 space. H1Space* phi_space = new H1Space(&mesh, &bc_types, &bc_values, P_INIT); H1Space* psi_space = new H1Space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(Hermes::Tuple<Space *>(phi_space, psi_space)); info("ndof = %d.", ndof); // Initialize previous time level solutions. Solution phi_prev_time, psi_prev_time; phi_prev_time.set_exact(&mesh, init_cond_phi); psi_prev_time.set_exact(&mesh, init_cond_psi); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, callback(biform_euler_0_0)); wf.add_matrix_form(0, 1, callback(biform_euler_0_1)); wf.add_matrix_form(1, 0, callback(biform_euler_1_0)); wf.add_matrix_form(1, 1, callback(biform_euler_1_1)); wf.add_vector_form(0, callback(liform_euler_0), HERMES_ANY, &phi_prev_time); wf.add_vector_form(1, callback(liform_euler_1), HERMES_ANY, &psi_prev_time); // Time stepping loop: int nstep = T_FINAL; for(int ts = 1; ts <= nstep; ts++) { info("Time step %d:", ts); info("Solving linear system."); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, Hermes::Tuple<Space *>(phi_space, psi_space), is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Assemble the stiffness matrix and right-hand side vector. info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); // Solve the linear system and if successful, obtain the solution. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), Hermes::Tuple<Space *>(phi_space, psi_space), Hermes::Tuple<Solution *>(&phi_prev_time, &psi_prev_time)); else error ("Matrix solver failed.\n"); } AbsFilter mag2(&psi_prev_time); AbsFilter mag3(&phi_prev_time); int success = 1; double eps = 1e-5; double val = std::abs(mag2.get_pt_value(0.0, 0.0)); info("Coordinate ( 0, 0) psi value = %lf", std::abs(mag2.get_pt_value(0.0, 0.0))); if (fabs(val - (0.000008)) > eps) { printf("Coordinate ( 0, 0) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(-0.5, -0.5)); info("Coordinate (-0.5,-0.5) psi value = %lf", std::abs(mag2.get_pt_value(-0.5, -0.5))); if (fabs(val - (0.000004)) > eps) { printf("Coordinate (-0.5,-0.5) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(0.5, -0.5)); info("Coordinate ( 0.5,-0.5) psi value = %lf", std::abs(mag2.get_pt_value(0.5, -0.5))); if (fabs(val - (0.000004)) > eps) { printf("Coordinate ( 0.5,-0.5) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(0.5, 0.5)); info("Coordinate ( 0.5, 0.5) psi value = %lf", std::abs(mag2.get_pt_value(0.5, 0.5))); if (fabs(val - (0.000004)) > eps) { printf("Coordinate ( 0.5, 0.5) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(-0.5, 0.5)); info("Coordinate (-0.5, 0.5) psi value = %lf", std::abs(mag2.get_pt_value(-0.5, 0.5))); if (fabs(val - (0.000004)) > eps) { printf("Coordinate (-0.5, 0.5) psi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(0.0, 0.0)); info("Coordinate ( 0, 0) phi value = %lf", std::abs(mag3.get_pt_value(0.0, 0.0))); if (fabs(val - (0.000003)) > eps) { printf("Coordinate ( 0, 0) phi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(-0.5, -0.5)); info("Coordinate (-0.5,-0.5) phi value = %lf", std::abs(mag3.get_pt_value(-0.5, -0.5))); if (fabs(val - (0.000001)) > eps) { printf("Coordinate (-0.5,-0.5) phi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(0.5, -0.5)); info("Coordinate ( 0.5,-0.5) phi value = %lf", std::abs(mag3.get_pt_value(0.5, -0.5))); if (fabs(val - (0.000001)) > eps) { printf("Coordinate ( 0.5,-0.5) phi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(0.5, 0.5)); info("Coordinate ( 0.5, 0.5) phi value = %lf", std::abs(mag3.get_pt_value(0.5, 0.5))); if (fabs(val - (0.000001)) > eps) { printf("Coordinate ( 0.5, 0.5) phi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(-0.5, 0.5)); info("Coordinate (-0.5, 0.5) phi value = %lf", std::abs(mag3.get_pt_value(-0.5, 0.5))); if (fabs(val - (0.000001)) > eps) { printf("Coordinate (-0.5, 0.5) phi value = %lf\n", val); success = 0; } if (success == 1) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
void show_temp_internal(int num) { int nc, x, y, krp, nm; PARTICLE *p; double cs0[NC], csvs[NC][2], csv[NC], csr[NC]; VECTOR cs[NC], cs2[NC]; nc = 0; for (y = 0; y < KY ; y++) { for (x = 0; x < KX; x++) { for (krp = 0; krp < KRP; krp++) { cdnn[krp] = 0; ctmp[krp] = 0; } for (nc = 0; nc < NC; nc++) { cs0[nc] = 0; csvs[nc][1] = csvs[nc][0] = 0; csv[nc] = 0;csr[nc] = 0; cs[nc].x = cs[nc].y = cs[nc].z = 0; cs2[nc].x = cs2[nc].y = cs2[nc].z = 0; csr[nc] = 0; csv[nc] = 0; for (nm = 0; nm < NM; nm++) { for (krp = 0; krp < KRP; krp++) { p = &camera[krp][x][y][nc][nm]; cs0[nc] += p->weight; cdnn[krp] += p->weight; ctmp[krp] += p->weight*p->mass*mag2(&(p->v)); cs[nc].x += p->v.x * p->weight; cs[nc].y += p->v.y * p->weight; cs[nc].z += p->v.z * p->weight; cs2[nc].x += pow(p->v.x, 2) * p->weight; cs2[nc].y += pow(p->v.y, 2) * p->weight; cs2[nc].z += pow(p->v.z, 2) * p->weight; if (p->rot_degr > 0) {csr[nc] += p->rot_energy * p->weight;} } } } for (krp = 0; krp < KRP; krp++) { ctmp[krp] /= cdnn[krp]*3.0*K; } for (nc = 0; nc < NC; nc++) { cs0[nc] /= KRP; cs[nc].x /= KRP; cs[nc].y /= KRP; cs[nc].z /= KRP; cs2[nc].x /= KRP; cs2[nc].y /= KRP; cs2[nc].z /= KRP; csr[nc] /= KRP; csv[nc] /= KRP; csvs[nc][0] /= KRP; csvs[nc][1] /= KRP; } alfa = cs0[1]/(2.0*cs0[0]+cs0[1]); double sn = 0, sm = 0, smcc = 0, sre = 0, srdf = 0; double tvib[NC]; VECTOR smu; smu.x = smu.y = smu.z = 0.0; for (nc = 0; nc < NC; nc++) { sn += cs0[nc]; sm += mass[nc]*cs0[nc]; smu.x += mass[nc]*cs[nc].x; smu.y += mass[nc]*cs[nc].y; smu.z += mass[nc]*cs[nc].z; smcc += mass[nc]*(cs2[nc].x+cs2[nc].y+cs2[nc].z); sre += csr[nc]; srdf += cs0[nc]*num_rot_degrees[nc]; if (num_vib_degrees[nc] >0) { if (csvs[nc][1] > 0) { tvib[nc] = REF_VIB_TEMP/log(csvs[nc][0]/csvs[nc][1]); svib[nc] = 2.0 * csv[nc] / (cs0[nc] * K * tvib[nc]); } else { tvib[nc] = 1.0E-6; svib[nc] = 0; } } } double denn = sn; double den = denn * sm / sn; VECTOR vel, svel; vel.x = smu.x/sm;vel.y = smu.y/sm;vel.z = smu.z/sm; svel.x = vel.x; svel.y = vel.y; svel.z = vel.z; double uu = pow(vel.x,2) + pow(vel.y,2) + pow(vel.z,2); double tt = (smcc-sm*uu)/(3.0*K*sn); double trot = (2.0 / K) * sre / srdf; double svt = 0; double svdf = 1.0E-8; for (nc = 0; nc < NC; nc++) { if (num_vib_degrees[nc] > 0) { svt += tvib[nc]*svib[nc]*cs0[nc]; svdf += svib[nc]*cs0[nc]; } } double tv = 0, avdf = 0; if (svdf > 1.E-6) { tv = svt/svdf; avdf = svdf / sn;} cell_temp = (3.0 * tt + (srdf / sn) * trot + avdf * tv)/(3.0 + srdf / sn + avdf); cell_density = sn; if (tt < 0 ) {printf("!$! TT = %e, sm*uu = %e\n", tt, (sm*uu/(3.0*K*sn)));} fprintf(plot_file, "%e %.6f; %.6f; %.6f %.6f; %.6f; %.6f; %.6f\n", num*dtp, tt, trot, tv, cell_temp, cell_density, alfa, denn); printf("tr = %.5f; rot = %.5f; vib = %.5f; svib = %.5f; all = %.5f; alfa = %f; den = %e\n", tt, trot, tv, svib[0], cell_temp, alfa, den); } } }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Create an H1 space. H1Space* phi_space = new H1Space(&mesh, bc_types, essential_bc_values, P_INIT); H1Space* psi_space = new H1Space(&mesh, bc_types, essential_bc_values, P_INIT); int ndof = get_num_dofs(Tuple<Space *>(phi_space, psi_space)); info("ndof = %d.", ndof); // Initialize previous time level solutions. Solution phi_prev_time, psi_prev_time; phi_prev_time.set_exact(&mesh, init_cond_phi); psi_prev_time.set_exact(&mesh, init_cond_psi); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, callback(biform_euler_0_0)); wf.add_matrix_form(0, 1, callback(biform_euler_0_1)); wf.add_matrix_form(1, 0, callback(biform_euler_1_0)); wf.add_matrix_form(1, 1, callback(biform_euler_1_1)); wf.add_vector_form(0, callback(liform_euler_0), H2D_ANY, &phi_prev_time); wf.add_vector_form(1, callback(liform_euler_1), H2D_ANY, &psi_prev_time); // Time stepping loop: int nstep = T_FINAL; for(int ts = 1; ts <= nstep; ts++) { info("Time step %d:", ts); // Newton's method. info("Solving linear system."); Solution phi, psi; bool is_complex = true; if (!solve_linear(Tuple<Space *>(phi_space, psi_space), &wf, matrix_solver, Tuple<Solution *>(&phi, &psi), NULL, is_complex)) error("Linear solve failed."); // Update previous time level solution. phi_prev_time.copy(&phi); psi_prev_time.copy(&psi); } AbsFilter mag2(&psi_prev_time); AbsFilter mag3(&phi_prev_time); #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 int success = 1; double eps = 1e-5; double val = std::abs(mag2.get_pt_value(0.0, 0.0)); info("Coordinate ( 0, 0) psi value = %lf", std::abs(mag2.get_pt_value(0.0, 0.0))); if (fabs(val - (0.000008)) > eps) { printf("Coordinate ( 0, 0) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(-0.5, -0.5)); info("Coordinate (-0.5,-0.5) psi value = %lf", std::abs(mag2.get_pt_value(-0.5, -0.5))); if (fabs(val - (0.000004)) > eps) { printf("Coordinate (-0.5,-0.5) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(0.5, -0.5)); info("Coordinate ( 0.5,-0.5) psi value = %lf", std::abs(mag2.get_pt_value(0.5, -0.5))); if (fabs(val - (0.000004)) > eps) { printf("Coordinate ( 0.5,-0.5) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(0.5, 0.5)); info("Coordinate ( 0.5, 0.5) psi value = %lf", std::abs(mag2.get_pt_value(0.5, 0.5))); if (fabs(val - (0.000004)) > eps) { printf("Coordinate ( 0.5, 0.5) psi value = %lf\n", val); success = 0; } val = std::abs(mag2.get_pt_value(-0.5, 0.5)); info("Coordinate (-0.5, 0.5) psi value = %lf", std::abs(mag2.get_pt_value(-0.5, 0.5))); if (fabs(val - (0.000004)) > eps) { printf("Coordinate (-0.5, 0.5) psi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(0.0, 0.0)); info("Coordinate ( 0, 0) phi value = %lf", std::abs(mag3.get_pt_value(0.0, 0.0))); if (fabs(val - (0.000003)) > eps) { printf("Coordinate ( 0, 0) phi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(-0.5, -0.5)); info("Coordinate (-0.5,-0.5) phi value = %lf", std::abs(mag3.get_pt_value(-0.5, -0.5))); if (fabs(val - (0.000001)) > eps) { printf("Coordinate (-0.5,-0.5) phi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(0.5, -0.5)); info("Coordinate ( 0.5,-0.5) phi value = %lf", std::abs(mag3.get_pt_value(0.5, -0.5))); if (fabs(val - (0.000001)) > eps) { printf("Coordinate ( 0.5,-0.5) phi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(0.5, 0.5)); info("Coordinate ( 0.5, 0.5) phi value = %lf", std::abs(mag3.get_pt_value(0.5, 0.5))); if (fabs(val - (0.000001)) > eps) { printf("Coordinate ( 0.5, 0.5) phi value = %lf\n", val); success = 0; } val = std::abs(mag3.get_pt_value(-0.5, 0.5)); info("Coordinate (-0.5, 0.5) phi value = %lf", std::abs(mag3.get_pt_value(-0.5, 0.5))); if (fabs(val - (0.000001)) > eps) { printf("Coordinate (-0.5, 0.5) phi value = %lf\n", val); success = 0; } if (success == 1) { printf("Success!\n"); return ERROR_SUCCESS; } else { printf("Failure!\n"); return ERROR_FAILURE; } }
T tgeVector3T<T>::mag() const { return std::sqrt( mag2() ); }
void MarchingTriangles::improve_mesh() { // first get adjacency information std::vector<Array1ui> nbr(x.size()); for(unsigned int e=0; e<edge.size(); ++e) { unsigned int p = edge[e][0]; unsigned int q = edge[e][1]; nbr[p].add_unique(q); nbr[q].add_unique(p); } // then sweep through the mesh a few times incrementally improving positions for(unsigned int sweep=0; sweep<3; ++sweep) { for(unsigned int p=0; p<x.size(); ++p) { // get a weighted average of neighbourhood positions Vec2f target = x[p]; target += x[ nbr[p][0] ]; target += x[ nbr[p][1] ]; target /= 3.0f; // project onto level set surface with Newton for(int projection_step=0; projection_step<5; ++projection_step) { float i=(target[0]-origin[0])/dx, j=(target[1]-origin[1])/dx; float f=eval(i,j); Vec2f g; eval_gradient(i,j,g); float m2=mag2(g), m=std::sqrt(m2); float alpha = clamp( -f/(m2+1e-10f), -0.25f*m, 0.25f*m ); // clamp to avoid stepping more than a fraction of a grid cell // do line search to make sure we actually are getting closer to the zero level set bool line_search_success=false; for(int line_search_step=0; line_search_step<10; ++line_search_step) { double fnew=eval( i+alpha*g[0], j+alpha*g[1] ); if(std::fabs(fnew) <= std::fabs(f)) { target += Vec2f( (alpha*dx)*g[0], (alpha*dx)*g[0] ); target += Vec2f( (alpha*dx)*g[1], (alpha*dx)*g[1] ); line_search_success=true; break; }else alpha*=0.5f; } if(!line_search_success) // if we stalled trying to find the zero isocontour... { // weight the target closer to the original x[p] std::cout<<"line search failed (p="<<p<<" project="<<projection_step<<" sweep="<<sweep<<")"<<std::endl; target= 0.5f * (x[p]+target); } } x[p]=target; } } }