double evalFunctional2D(pInstance instance, double step){ double J; pTria pt; int k, icase, ret, ielem, i,ref; double cb[3], area, *a, *b, *c, ag[3], bg[3], cg[3], q[2], dist; /* evaluate J*/ J = 0; for (k = 1; k <= instance->mesh_omega0.nt; k++) { pt = &instance->mesh_omega0.tria[k]; ref = getRefel(&instance->mesh_omega0,pt->ref); if(!ref){ a = &instance->mesh_omega0.point[pt->v[0]].c[0]; b = &instance->mesh_omega0.point[pt->v[1]].c[0]; c = &instance->mesh_omega0.point[pt->v[2]].c[0]; for (i = 0; i < 2; i++) { ag[i] = a[i] + step*instance->sol_omega0.u[2*(pt->v[0]-1)+i]; bg[i] = b[i] + step*instance->sol_omega0.u[2*(pt->v[1]-1)+i]; cg[i] = c[i] + step*instance->sol_omega0.u[2*(pt->v[2]-1)+i]; } area = area_2d(ag, bg, cg); if (area <= 0) { return 1; } /* Gauss rule with 1 node */ q[0] = (ag[0]+bg[0]+cg[0])/3; q[1] = (ag[1]+bg[1]+cg[1])/3; if (q[0] < 0 || q[0] > 1 || q[1] < 0 || q[1] > 1) { J += area; } else { icase = buckin(&instance->mesh_distance,&instance->bucket,q); ielem = locelt(&instance->mesh_distance,icase,q,cb); if (ielem) { ret = intpp1(&instance->sol_distance,instance->mesh_distance.tria[ielem].v,&dist,ielem,cb); if (!ret) exit(1); instance->sol_omega0.d[pt->v[0]] = dist; } J += area*dist; } } } fprintf(out,"%e \n",J); return J; }
/* build right hand side vector and set boundary conds. */ static double *rhsF_P1_2d(LSst *lsst) { pTria pt; pEdge pa; pPoint ppt; pCl pcl; double *F,*vp,area,lon,n[2],w[2],*a,*b,*c; int i,k,nc; if ( lsst->info.verb == '+' ) fprintf(stdout," gravity and body forces\n"); F = (double*)calloc(lsst->info.dim * lsst->info.np,sizeof(double)); assert(F); /* gravity as external force */ if ( lsst->sol.cltyp & Gravity ) { nc = 0; for (k=1; k<=lsst->info.nt; k++) { pt = &lsst->mesh.tria[k]; /* measure of K */ a = &lsst->mesh.point[pt->v[0]].c[0]; b = &lsst->mesh.point[pt->v[1]].c[0]; c = &lsst->mesh.point[pt->v[2]].c[0]; area = area_2d(a,b,c) / 3.0; for (i=0; i<3; i++) { F[2*(pt->v[i]-1)+0] += area * lsst->sol.gr[0]; F[2*(pt->v[i]-1)+1] += area * lsst->sol.gr[1]; } nc++; } if ( lsst->info.verb == '+' ) fprintf(stdout," %d gravity values assigned\n",nc); } /* nodal boundary conditions */ if ( lsst->sol.clelt & LS_ver ) { nc = 0; for (k=1; k<=lsst->info.np; k++) { ppt = &lsst->mesh.point[k]; pcl = getCl(&lsst->sol,ppt->ref,LS_ver); if ( !pcl ) continue; else if ( pcl->typ == Dirichlet ) { vp = pcl->att == 'f' ? &lsst->sol.u[2*(k-1)] : &pcl->u[0]; F[2*(k-1)+0] = LS_TGV * vp[0]; F[2*(k-1)+1] = LS_TGV * vp[1]; } else if ( pcl->typ == Load ) { vp = pcl->att == 'f' ? &lsst->sol.u[2*(k-1)] : &pcl->u[0]; F[2*(k-1)+0] = vp[0]; F[2*(k-1)+1] = vp[1]; } nc++; } if ( lsst->info.verb == '+' && nc > 0 ) fprintf(stdout," %d nodal values\n",nc); } /* external load along boundary edges */ if ( lsst->sol.clelt & LS_edg ) { nc = 0; for (k=1; k<=lsst->info.na; k++) { pa = &lsst->mesh.edge[k]; pcl = getCl(&lsst->sol,pa->ref,LS_edg); if ( !pcl ) continue; else if ( pcl->typ == Dirichlet ) { for (i=0; i<2; i++) { vp = pcl->att == 'f' ? &lsst->sol.u[2*(pa->v[i]-1)] : &pcl->u[0]; F[2*(pa->v[i]-1)+0] = LS_TGV * vp[0]; F[2*(pa->v[i]-1)+1] = LS_TGV * vp[1]; } nc++; } /* load along normal direction (normal component) */ else if ( pcl->typ == Load ) { a = &lsst->mesh.point[pa->v[0]].c[0]; b = &lsst->mesh.point[pa->v[1]].c[0]; lon = length(a,b,n); if ( pcl->att == 'n' ) { w[0] = 0.5 * lon * pcl->u[0] * n[0]; w[1] = 0.5 * lon * pcl->u[0] * n[1]; } else { vp = pcl->att == 'f' ? &lsst->sol.u[2*(k-1)] : &pcl->u[0]; w[0] = 0.5 * lon * vp[0]; w[1] = 0.5 * lon * vp[1]; } F[2*(pa->v[0]-1)+0] += w[0]; F[2*(pa->v[0]-1)+1] += w[1]; F[2*(pa->v[1]-1)+0] += w[0]; F[2*(pa->v[1]-1)+1] += w[1]; nc++; } } if ( lsst->info.verb == '+' && nc > 0 ) fprintf(stdout," %d load values\n",nc); } return(F); }