TQMesh icon indicating copy to clipboard operation
TQMesh copied to clipboard

Feature Request: Adding Fixed Edges Within The Domain

Open angelmusonda opened this issue 1 year ago • 8 comments

Hi Flo,

I find your library extremely useful for my work.

I would like to suggest adding a feature to define fixed edges within the boundary. This would enhance control by allowing users to preserve critical edges for certain purposes.

Angel

angelmusonda avatar May 10 '24 21:05 angelmusonda

Hey Angel,

thanks for your kind feedback. Your idea sounds very promising! I put it on my to-do-list and I will try to add that feature as soon as possible :-)

Cheers Flo

FloSewn avatar May 13 '24 05:05 FloSewn

Great! Thanks @FloSewn

angelmusonda avatar May 13 '24 06:05 angelmusonda

Hey Angel,

the "fixed-edges" feature is now available in the newest release v1.3.3. I also included a new example (input-file and cpp-file).

It is not yet possible to add fixed edges via CSV files, but I want to add that as soon as possible.

Maybe you can try it out if you want and tell me about possible bugs ;-)

Thanks again for your idea!

Cheers, Flo

FloSewn avatar Jul 05 '24 16:07 FloSewn

Hi @FloSewn,

Thank you so much for adding this feature. It works well in most cases.

However, I've encountered two limitations:

  1. It doesn't work if one of the fixed vertices lies on the exterior boundary.
  2. The tri2quad_modification breaks the fixed edges.

I'm unsure if these issues can be resolved, especially the second one, as it's still a work in progress.

Regards, Angel

angelmusonda avatar Jul 06 '24 19:07 angelmusonda

Hey Angel,

thank you for mentioning those limitations and sorry for my late response.

Could you provide me a simple example, where you encounter the first problem ("fixed vertex lies on exterior boundary")?

Greetings Flo

FloSewn avatar Sep 20 '24 18:09 FloSewn

Hi Flo,

No trouble at all.

Here is an example. My boundary is four-sided and I am trying to add a fixed edge within it, with one of the fixed points (Vertex v4) lying on the polygon's boundary. I tested putting v4 at [0,0], the same position as one of the external boundary points, and [0,1] which lies on one of the external boundary edges. Both couldn't work and were giving me different error messages.

[ERROR] MeshBuilder::prepare_mesh(): Missing vertex property "is_fixed". If I use [0,0]

[ERROR] Mesh generation failed: If I use [0,1]

bool fixed_edges()
{
  UserSizeFunction f = [](const Vec2d& p) { return 0.2; };

  Domain domain { f };

  // Vertices
  Vertex& v0 = domain.add_vertex( 0,  0.0 );
  Vertex& v1 = domain.add_vertex( 6.0,  0.0 );
  Vertex& v2 = domain.add_vertex( 7.0,  5.0 );
  Vertex& v3 = domain.add_vertex(0.0,  6 );

  Boundary&  b_ext = domain.add_exterior_boundary();
  b_ext.add_edge( v0, v1, 1 ); 
  b_ext.add_edge( v1, v2, 2 ); 
  b_ext.add_edge( v2, v3, 3 ); 
  b_ext.add_edge( v3, v0, 4 ); 

  // Fixed vertices
  Vertex& v4 = domain.add_fixed_vertex(0, 0,  0.05, 1.0);
  Vertex& v5 = domain.add_fixed_vertex(3, 3,  0.05, 1.0);


  // Define fixed edges
  domain.add_fixed_edge( v4, v5 );


  /*------------------------------------------------------------------
  | Mesh generation
  ------------------------------------------------------------------*/
  MeshGenerator generator {};
  Mesh& mesh = generator.new_mesh( domain );

  generator.triangulation(mesh).generate_elements();
  //generator.tri2quad_modification(mesh).modify();

  //generator.quad_refinement(mesh).refine();

  generator.mixed_smoothing(mesh)
    .epsilon(0.7)
    .smooth(5);

  /*------------------------------------------------------------------
  | Check if the meshing generation process succeeded
  ------------------------------------------------------------------*/
  MeshChecker checker { mesh, domain };
  if ( !checker.check_completeness() )
  {
    LOG(ERROR) << "Mesh generation failed";
    return false;
  }

  /*------------------------------------------------------------------
  | Finally, we export the mesh to a file in VTU / TXT format.
  ------------------------------------------------------------------*/

  std::string file_name { "fixed_edges" };

  LOG(INFO) << "Writing mesh output to: " << file_name << ".vtu";
  generator.write_mesh(mesh, file_name, MeshExportType::VTU );

  LOG(INFO) << "Writing mesh output to: " << file_name << ".txt";
  generator.write_mesh(mesh, file_name, MeshExportType::TXT );

  return true;

} // fixed_edges()


int main()
{
    fixed_edges();
    return 0;
}

Regards, Angel

angelmusonda avatar Sep 20 '24 20:09 angelmusonda

Hey Angel,

thank you so much for pointing out this bug.

Generally, fixed vertices are supposed to be placed only inside the domain (so not on top of any boundary edges or vertices). However, it should be possible to generate fixed edges from both normal vertices and fixed vertices. So instead of generating v4 as in your example, you can simply use v0 when defining the fixed edge.

I noticed, that when TQMesh is compiled in debug-mode, there are some assertions called which trigger your mentioned error message and hence prevent us from using normal vertices to define fixed edges. To get rid of this, I simply needed to remove these assert() functions.

The updated code is accessible in the development branch, if you want to check it out.

However, I also noticed that when TQMesh is compiled in release-mode, the assertions are ignored, so it should also work with the current version from the main branch.

To compile in release mode, simply use the following command when setting up your build directory with cmake:

cmake -DCMAKE_BUILD_TYPE=Release ..

This should also significantly speed up the meshing process.

Below is an adjusted example, which should work when compiled in release mode and where fixed vertices and normal vertices are combined to generate fixed edges:

/*********************************************************************
* Test fixed edges 
*********************************************************************/
bool fixed_edges()
{
  UserSizeFunction f = [](const Vec2d& p) { return 0.3; };

  Domain domain { f };

  // Vertices
  Vertex& v0 = domain.add_vertex(0.0,  0.0 );
  Vertex& v1 = domain.add_vertex(3.0,  0.0 );
  Vertex& v2 = domain.add_vertex(6.0,  0.0 );
  Vertex& v3 = domain.add_vertex(7.0,  5.0 );
  Vertex& v4 = domain.add_vertex(0.0,  6.0 );

  Boundary&  b_ext = domain.add_exterior_boundary();
  b_ext.add_edge( v0, v1, 1 );
  b_ext.add_edge( v1, v2, 1 );
  b_ext.add_edge( v2, v3, 2 );
  b_ext.add_edge( v3, v4, 3 );
  b_ext.add_edge( v4, v0, 4 );

  // Fixed vertices
  Vertex& v5 = domain.add_fixed_vertex(3, 3,  0.05, 1.0);

  // Define fixed edges
  domain.add_fixed_edge( v0, v5 );
  domain.add_fixed_edge( v1, v5 );

  // Setup the generator
  MeshGenerator generator {};
  Mesh& mesh = generator.new_mesh( domain );
  generator.triangulation(mesh).generate_elements();

  generator.mixed_smoothing(mesh)
    .epsilon(0.7)
    .smooth(5);

  /*------------------------------------------------------------------
  | Check if the meshing generation process succeeded
  ------------------------------------------------------------------*/
  MeshChecker checker { mesh, domain };
  if ( !checker.check_completeness() )
  {
    LOG(ERROR) << "Mesh generation failed";
    return false;
  }

  /*------------------------------------------------------------------
  | Finally, we export the mesh to a file in VTU / TXT format.
  ------------------------------------------------------------------*/
  std::string file_name { "fixed_edges" };

  LOG(INFO) << "Writing mesh output to: " << file_name << ".vtu";
  generator.write_mesh(mesh, file_name, MeshExportType::VTU );

  LOG(INFO) << "Writing mesh output to: " << file_name << ".txt";
  generator.write_mesh(mesh, file_name, MeshExportType::TXT );

  return true;

  return true;

} // fixed_edges()

int main()
{
    fixed_edges();
    return 0;
}

I will update the fixed edge example to account for that usage. Again, thanks for reporting that bug ;-)

Also, concerning your point that tri2quad_modification breaks the fixed edges - I also noticed this but had no time to fix it yet. I also noticed that the fixed edges sometimes break in the vicinity of boundary edges - even without that modification. In those cases, reducing the element size in that region might help to prevent that behavior.

Greetings Flo

FloSewn avatar Sep 21 '24 08:09 FloSewn

Hi Flo,

I tested your solution and it worked perfectly.

Thank you! Looking forward to the other implementations.

Regards Angel

angelmusonda avatar Sep 21 '24 10:09 angelmusonda