Improving mesh and NDSolve solution convergence

I have developed the code below to solve two PDEs; first mu[x,y] is solved for, then the results of mu are used to solve for phi[x,y]. The code works and converges on a solution as is, however, I would like to decrease the size of a, b, and d even further. To accurately represent the physical process I am trying to simulate, a, b, and d would need to be ~100-1000x smaller. If I make them smaller, I don’t believe the solution has actually converged because the values for phi along the right boundary change significantly with a change in mesh size (i.e. if I make them smaller and the code below produces a value of phi=-0.764 at the midpoint between y2 and y3 along the right boundary, a change in size1 to 10^-17 and size2 to 10^-15, changes that value of phi to -0.763, and a change in size2 to 10^-16 changes that value again to -0.860), but I cannot make the mesh size any smaller without Mathematica crashing.

Are there any better ways to create the mesh that would be less computationally taxing and allow it to be more refined in the regions of interest? Or are there any ways to make the code in general less computationally expensive so that I can further refine the mesh?

ClearAll["Global`*"] Needs["NDSolve`FEM`"] (* 1) Define Constants*) e = 1.60217662*10^-19; F = 96485; kb = 1.381*10^-23; sigi = 18; sigini = 0; sigeni = 2*10^6; T = 1000; n = -0.02; c = 1;  pH2 = 0.2; pH2O = 1 - pH2; pO2 = 1.52*^-19; l = 10*10^-6; a = 100*10^-7; b = 50*10^-7; d = 300*10^-7; y1 = 0.01; y2 = 0.5*y1; y3 = y2 + a; y4 = y3 + d; y5 = y4 + b; mu1 = 0; mu2 = -5.98392*^-19; phi1 = 0;  (* 2) Create mesh*) m = 0.1*l; size1 = 10^-16; size2 = 10^-15; size3 = 10^-7; mrf = With[{rmf =       RegionMember[       Region@RegionUnion[Disk[{l, y2}, m], Disk[{l, y3}, m],          Disk[{l, y4}, m], Disk[{l, y5}, m]]]},     Function[{vertices, area}, Block[{x, y}, {x, y} = Mean[vertices];      Which[rmf[{x, y}],        area > size1, (0 <= x <= l && y2 - l <= y <= y2 + l),        area > size2, (0 <= x <= l && y3 - l <= y <= y3 + l),        area > size2, (0 <= x <= l && y4 - l <= y <= y4 + l),        area > size2, (0 <= x <= l && y5 - l <= y <= y5 + l),        area > size2, True, area > size3]]]]; mesh = DiscretizeRegion[Rectangle[{0, 0}, {l, y1}],     MeshRefinementFunction -> mrf];  (* 3) Solve for mu*) bcmu = {DirichletCondition[mu[x, y] == mu1, (x == 0 && 0 < y < y1)],    DirichletCondition[     mu[x, y] ==       mu2, (x == l && y2 <=  y <=  y3) || (x == l && y4 <= y <= y5)]}; solmu = NDSolve[{Laplacian[mu[x, y], {x, y}] ==       0 + NeumannValue[0, y == 0 || y == y1 ||         (x == l && 0 <= y < y2) || (x == l &&            y3 < y < y4) || (x == l && y5 < y < y1)], bcmu},     mu, {x, y} \[Element] mesh, WorkingPrecision -> 50];  (* 4) Solve for electronic conductivity everywhere*) pO2data = Exp[(mu[x, y] /. solmu)/kb/T]; sige0 = 2.77*10^-7; sigedata = Piecewise[{{sige0*pO2data^(-1/4), 0 <= x <= l - m},     {sige0*pO2data^(-1/4), (l - m < x <= l && 0 <= y < y2)},     {(sigeni - sige0*(pO2data /. x -> l - m)^(-1/4))/m*(x - (l - m)) +        sige0*(pO2data /. x -> l - m)^(-1/4), (l - m < x <= l &&         y2 <=  y <= y3)},     {sige0*pO2data^(-1/4), (l - m < x <= l && y3 < y < y4)},     {(sigeni - sige0*(pO2data /. x -> l - m)^(-1/4))/m*(x - (l - m)) +        sige0*(pO2data /. x -> l - m)^(-1/4), (l - m < x <= l &&         y4 <= y <= y5)},     {sige0*pO2data^(-1/4), (l - m < x <= l && y5 < y <= y1)}}];  (* 5) Solve for phi*) Irxn = -(2*F)*(c*pO2^n ); A = (Irxn - sigi/(4*e)*(D[mu[x, y] /. solmu, x] /. x -> l))/(-sigi); B = sigi/(4*e)*(D[mu[x, y] /. solmu, x] /.        x -> l)/(sigi + sigedata /. x -> l - m); bcphi = DirichletCondition[phi[x, y] == phi1, (x == 0 && 0 < y < y1)]; solphi = NDSolve[{Laplacian[phi[x, y], {x, y}] ==       0 + NeumannValue[0,         y == 0 ||          y == y1 || (x == l && 0 <= y < y2) || (x == l &&            y3 < y < y4) || (x == l && y5 < y < y1)] +        NeumannValue[-A[[1]], (x == l && y2 <= y <= y3)] +        NeumannValue[-B[[1]], (x == l && y4 <= y <= y5)], bcphi},     phi, {x, y} \[Element] mesh, WorkingPrecision -> 50];  (* 6) Print values to check for convergence*) P[x_, y_] := phi[x, y] /. solphi; P[l, (y3 - y2)/2 + y2] P[l, (y5 - y4)/2 + y4] 

What’s the easiest way to animate a (non-player) mesh?

I made a coffin with some animations in Maya, exported it to Unreal, and I want to start the animation from a blueprint, but I can’t for the life of me figure out how.

I tried:

  • Play Animation
  • Get Anim Instance > Cast To AnimBlueprint > call custom event in AnimBlueprint (LiftCoffinInAir)
  • Get Anim Instance > Cast To AnimBlueprint > set boolean (which is what the event would do)
  • A blueprint interface called from here, and with an event in the animation blueprint

enter image description here

The only way I got the animation to play at all was by setting the boolean to true every blueprint update.

enter image description here

This means that my animation graph works fine, but for some reason none of the events in the event graph work.

Any ideas?

How to extrude mesh?

Say we have the following simple mesh data:

// additional data // Vector3(x, y, z) - +x left, +y up, +z forward // triangle indices are in clocwise order  // list of vertices that form a place List<Vector3> vertices = new List<Vector3>() {   new Vector3(2f, 0f, 2f),   new Vector3(-2f, 0f, 2f),   new Vector3(2f, 0f, -2f),   new Vector3(-2f, 0f, -2f), };  List<int> indices = new List<int>() {   0, 3, 2, 3, 0, 1 }; 

How to extrude given plane in a certain direction? E.g 2f in y axis, it should form a bottomless cube.

I’m interested in how it works in general, not only this specific example.

modify the elements numbers of a mesh file

I have loaded the mesh of simulation on Mathematica:

geo = Import["geometry.vtk"]; 

The elements of geo are:

 Import["geo.vtk", "Elements"]   {"CuboidData", "CuboidObjects", "Graphics3D", "GraphicsComplex", "LineData", "LineObjects", "PointData", "PointObjects", "PolygonData", "PolygonObjects", "VertexData"} 

I would like to reduce the number of points of the mesh. The points of the mesh are saved in “PolygonData” and “VertexData”, I do not know If is possible to do that. For example, halve the number of points even if the quality is lost

How do I colour a mesh in Kiss3d? (code example request)

This is a question about the sebcrozet/kiss3d graphics engine. I have managed to create a mesh using group.add_mesh(). Now I want to colour my mesh with a specified colour for each vertex (or face). Does anyone know how I do this?

One possible approach seems to be to define a RgbImage with all my different colours somewhere in the image, turn that into a DynamicImage, turn that into a Texture, somehow associate the texture with the mesh, set up a UV map, and set the UV location for each vertex to map to the relevant colour.

The documentation does not go into enough detail or give a specific example. Does anyone have any example code that works?

Ray casting through terrain mesh + Octree ( Mesh collision )

I’m currently in development of a terrain editor which i will use for my game. One thing that is partially stopping my development is that I don’t have collision detection implemented between mouse ray cast and the terrain mesh.

The terrain is consisted of triangles and can be lowered and raised.Also the x and y values of the mesh don’t change. Of course what i need to do is ray cast through my mouse positions and get intersected triangle. I would get the point on the triangle using Barycentric coordinates. Just I’m not quite sure how does octree come into play here. As far as I understand it it works like a 3d quadtree, splitting the box into smaller box that the ray intersects. But which box do i choose ? How do i know which box is the closest one to the terrain, if either raised or lowered terrain ? How many subdivisions would i have? I was thinking on having as much as i have tiles( basically the last level of subdivisions would correspond to a x^3 box).

Right now i’m just doing collision with the 0 Z-value plane, and it works okay, but if the terrain is a bit raised then this can give faulty results.

Other two methods that i found is to iterate through the mesh, which of course is insanely inefficient; the other is to project the terrain in reverse and then i guess do some checking with the mouse coordinates (think it’s called z-buffer checking or something).

If anyone has any other ideas i’m all ears. Just note that the algorithm should be an efficient one (of course this depends on the implementation) and accurate.

Thanks !