Permutation connection - #445

Open
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection
Open

Permutation connection#445
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection

Conversation

@jonathan-macart

Copy link
Copy Markdown

Added:

  1. get_reordering_by_pymetis: Compute mesh element reorderings (permutations) via Metis's nested dissection algorithm.
  2. make_element_permutation_connection: First attempt at generating a connection that permutes the elements of an existing mesh, say from_mesh, to those of a new mesh, to_mesh, using the ND-generated permutation. The goal is to be able to pass to_mesh to a CFD solver. I do not need the mesh nodes to be reordered. My understanding is that all_elements_perm should contain the permuted element tags of from_mesh, though this could be completely incorrect.

Currently, (2) returns a discretization connection containing two identical discretizations/meshes. A few thoughts/questions:

  • Is constructing to_discr = from_discr.copy() a problem? My understanding is that this creates an exact replica of from_discr.mesh, which is not the goal. to_discr.mesh should contain the same nodes and elements of from_discr.mesh, but with the mesh ordering permuted using perm.
  • Is a discretization connection a mapping between two "immutable" meshes? Or is to_discr.mesh actually changed upon creation of the connection?
  • If the answer to the last question is "no," how do I construct a copy of from_discr.mesh with the elements permuted?

Any advice would be appreciated! Thank you!

@inducer

Copy link
Copy Markdown
Owner

Side note: please disregard the RUF052 (astral-sh/ruff#14796) and pylint linter failures (pylint-dev/pylint#10000 (comment)).

@@ -0,0 +1,90 @@
__copyright__ = "Copyright (C) 2014 Andreas Kloeckner"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the copyright notice.

Comment on lines +48 to +49
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the permutation a parameter to this function, rather than unconditionally obtaining it from pymetis?


# Reorder the local mesh using Metis
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will perm, iperm match the return value of get_reordering_by_pymetis? It seems that returns only a single array?


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defmake_element_permutation_connection(actx, from_discr):
defmake_element_permutation_connection(actx: ArrayContext, from_discr: Discretization) ->DirectDiscretizationConnection:



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defget_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):
defget_reordering_by_pymetis(mesh: meshmode.mesh.Mesh, *, connectivity: Literal["facial"] |Literal["nodal"], **kwargs)->np.ndarray:


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From @jonathan-macart's email, my understanding was that the objective of this is a mesh with the elements reordered. This connection instead shuffles DOF data between elements, while leaving the discretization in place.

To achieve the goal I mention above, you would need to make a permuted mesh, then make a discretization based on that.

Comment on lines +74 to +75
from_element_indices=all_elements,
to_element_indices=all_elements_perm, ## CHK??

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mishandles meshes/discretizations with multiple element groups (e.g. a mesh that's part-hex-part-tet), in that it is silently broken (by using out-of-bounds indices) in that case. It's fine to assume single-group only, but then the code should error if presented with multiple groups.



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think an argument could be made that the connectivity-getter could be factored into a separate function, since it seems it's duplicated from get_partition_by_pymetis?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathan-macart@inducer@MacRTL
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Permutation connection - #445

Open
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection
Open

Permutation connection#445
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection

Conversation

@jonathan-macart

Copy link
Copy Markdown

Added:

  1. get_reordering_by_pymetis: Compute mesh element reorderings (permutations) via Metis's nested dissection algorithm.
  2. make_element_permutation_connection: First attempt at generating a connection that permutes the elements of an existing mesh, say from_mesh, to those of a new mesh, to_mesh, using the ND-generated permutation. The goal is to be able to pass to_mesh to a CFD solver. I do not need the mesh nodes to be reordered. My understanding is that all_elements_perm should contain the permuted element tags of from_mesh, though this could be completely incorrect.

Currently, (2) returns a discretization connection containing two identical discretizations/meshes. A few thoughts/questions:

  • Is constructing to_discr = from_discr.copy() a problem? My understanding is that this creates an exact replica of from_discr.mesh, which is not the goal. to_discr.mesh should contain the same nodes and elements of from_discr.mesh, but with the mesh ordering permuted using perm.
  • Is a discretization connection a mapping between two "immutable" meshes? Or is to_discr.mesh actually changed upon creation of the connection?
  • If the answer to the last question is "no," how do I construct a copy of from_discr.mesh with the elements permuted?

Any advice would be appreciated! Thank you!

@inducer

Copy link
Copy Markdown
Owner

Side note: please disregard the RUF052 (astral-sh/ruff#14796) and pylint linter failures (pylint-dev/pylint#10000 (comment)).

@@ -0,0 +1,90 @@
__copyright__ = "Copyright (C) 2014 Andreas Kloeckner"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the copyright notice.

Comment on lines +48 to +49
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the permutation a parameter to this function, rather than unconditionally obtaining it from pymetis?


# Reorder the local mesh using Metis
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will perm, iperm match the return value of get_reordering_by_pymetis? It seems that returns only a single array?


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defmake_element_permutation_connection(actx, from_discr):
defmake_element_permutation_connection(actx: ArrayContext, from_discr: Discretization) ->DirectDiscretizationConnection:



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defget_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):
defget_reordering_by_pymetis(mesh: meshmode.mesh.Mesh, *, connectivity: Literal["facial"] |Literal["nodal"], **kwargs)->np.ndarray:


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From @jonathan-macart's email, my understanding was that the objective of this is a mesh with the elements reordered. This connection instead shuffles DOF data between elements, while leaving the discretization in place.

To achieve the goal I mention above, you would need to make a permuted mesh, then make a discretization based on that.

Comment on lines +74 to +75
from_element_indices=all_elements,
to_element_indices=all_elements_perm, ## CHK??

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mishandles meshes/discretizations with multiple element groups (e.g. a mesh that's part-hex-part-tet), in that it is silently broken (by using out-of-bounds indices) in that case. It's fine to assume single-group only, but then the code should error if presented with multiple groups.



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think an argument could be made that the connectivity-getter could be factored into a separate function, since it seems it's duplicated from get_partition_by_pymetis?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathan-macart@inducer@MacRTL
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Permutation connection - #445

Open
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection
Open

Permutation connection#445
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection

Conversation

@jonathan-macart

Copy link
Copy Markdown

Added:

  1. get_reordering_by_pymetis: Compute mesh element reorderings (permutations) via Metis's nested dissection algorithm.
  2. make_element_permutation_connection: First attempt at generating a connection that permutes the elements of an existing mesh, say from_mesh, to those of a new mesh, to_mesh, using the ND-generated permutation. The goal is to be able to pass to_mesh to a CFD solver. I do not need the mesh nodes to be reordered. My understanding is that all_elements_perm should contain the permuted element tags of from_mesh, though this could be completely incorrect.

Currently, (2) returns a discretization connection containing two identical discretizations/meshes. A few thoughts/questions:

  • Is constructing to_discr = from_discr.copy() a problem? My understanding is that this creates an exact replica of from_discr.mesh, which is not the goal. to_discr.mesh should contain the same nodes and elements of from_discr.mesh, but with the mesh ordering permuted using perm.
  • Is a discretization connection a mapping between two "immutable" meshes? Or is to_discr.mesh actually changed upon creation of the connection?
  • If the answer to the last question is "no," how do I construct a copy of from_discr.mesh with the elements permuted?

Any advice would be appreciated! Thank you!

@inducer

Copy link
Copy Markdown
Owner

Side note: please disregard the RUF052 (astral-sh/ruff#14796) and pylint linter failures (pylint-dev/pylint#10000 (comment)).

@@ -0,0 +1,90 @@
__copyright__ = "Copyright (C) 2014 Andreas Kloeckner"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the copyright notice.

Comment on lines +48 to +49
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the permutation a parameter to this function, rather than unconditionally obtaining it from pymetis?


# Reorder the local mesh using Metis
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will perm, iperm match the return value of get_reordering_by_pymetis? It seems that returns only a single array?


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defmake_element_permutation_connection(actx, from_discr):
defmake_element_permutation_connection(actx: ArrayContext, from_discr: Discretization) ->DirectDiscretizationConnection:



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defget_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):
defget_reordering_by_pymetis(mesh: meshmode.mesh.Mesh, *, connectivity: Literal["facial"] |Literal["nodal"], **kwargs)->np.ndarray:


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From @jonathan-macart's email, my understanding was that the objective of this is a mesh with the elements reordered. This connection instead shuffles DOF data between elements, while leaving the discretization in place.

To achieve the goal I mention above, you would need to make a permuted mesh, then make a discretization based on that.

Comment on lines +74 to +75
from_element_indices=all_elements,
to_element_indices=all_elements_perm, ## CHK??

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mishandles meshes/discretizations with multiple element groups (e.g. a mesh that's part-hex-part-tet), in that it is silently broken (by using out-of-bounds indices) in that case. It's fine to assume single-group only, but then the code should error if presented with multiple groups.



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think an argument could be made that the connectivity-getter could be factored into a separate function, since it seems it's duplicated from get_partition_by_pymetis?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathan-macart@inducer@MacRTL
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Permutation connection - #445

Open
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection
Open

Permutation connection#445
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection

Conversation

@jonathan-macart

Copy link
Copy Markdown

Added:

  1. get_reordering_by_pymetis: Compute mesh element reorderings (permutations) via Metis's nested dissection algorithm.
  2. make_element_permutation_connection: First attempt at generating a connection that permutes the elements of an existing mesh, say from_mesh, to those of a new mesh, to_mesh, using the ND-generated permutation. The goal is to be able to pass to_mesh to a CFD solver. I do not need the mesh nodes to be reordered. My understanding is that all_elements_perm should contain the permuted element tags of from_mesh, though this could be completely incorrect.

Currently, (2) returns a discretization connection containing two identical discretizations/meshes. A few thoughts/questions:

  • Is constructing to_discr = from_discr.copy() a problem? My understanding is that this creates an exact replica of from_discr.mesh, which is not the goal. to_discr.mesh should contain the same nodes and elements of from_discr.mesh, but with the mesh ordering permuted using perm.
  • Is a discretization connection a mapping between two "immutable" meshes? Or is to_discr.mesh actually changed upon creation of the connection?
  • If the answer to the last question is "no," how do I construct a copy of from_discr.mesh with the elements permuted?

Any advice would be appreciated! Thank you!

@inducer

Copy link
Copy Markdown
Owner

Side note: please disregard the RUF052 (astral-sh/ruff#14796) and pylint linter failures (pylint-dev/pylint#10000 (comment)).

@@ -0,0 +1,90 @@
__copyright__ = "Copyright (C) 2014 Andreas Kloeckner"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the copyright notice.

Comment on lines +48 to +49
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the permutation a parameter to this function, rather than unconditionally obtaining it from pymetis?


# Reorder the local mesh using Metis
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will perm, iperm match the return value of get_reordering_by_pymetis? It seems that returns only a single array?


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defmake_element_permutation_connection(actx, from_discr):
defmake_element_permutation_connection(actx: ArrayContext, from_discr: Discretization) ->DirectDiscretizationConnection:



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defget_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):
defget_reordering_by_pymetis(mesh: meshmode.mesh.Mesh, *, connectivity: Literal["facial"] |Literal["nodal"], **kwargs)->np.ndarray:


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From @jonathan-macart's email, my understanding was that the objective of this is a mesh with the elements reordered. This connection instead shuffles DOF data between elements, while leaving the discretization in place.

To achieve the goal I mention above, you would need to make a permuted mesh, then make a discretization based on that.

Comment on lines +74 to +75
from_element_indices=all_elements,
to_element_indices=all_elements_perm, ## CHK??

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mishandles meshes/discretizations with multiple element groups (e.g. a mesh that's part-hex-part-tet), in that it is silently broken (by using out-of-bounds indices) in that case. It's fine to assume single-group only, but then the code should error if presented with multiple groups.



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think an argument could be made that the connectivity-getter could be factored into a separate function, since it seems it's duplicated from get_partition_by_pymetis?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathan-macart@inducer@MacRTL
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Permutation connection - #445

Open
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection
Open

Permutation connection#445
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection

Conversation

@jonathan-macart

Copy link
Copy Markdown

Added:

  1. get_reordering_by_pymetis: Compute mesh element reorderings (permutations) via Metis's nested dissection algorithm.
  2. make_element_permutation_connection: First attempt at generating a connection that permutes the elements of an existing mesh, say from_mesh, to those of a new mesh, to_mesh, using the ND-generated permutation. The goal is to be able to pass to_mesh to a CFD solver. I do not need the mesh nodes to be reordered. My understanding is that all_elements_perm should contain the permuted element tags of from_mesh, though this could be completely incorrect.

Currently, (2) returns a discretization connection containing two identical discretizations/meshes. A few thoughts/questions:

  • Is constructing to_discr = from_discr.copy() a problem? My understanding is that this creates an exact replica of from_discr.mesh, which is not the goal. to_discr.mesh should contain the same nodes and elements of from_discr.mesh, but with the mesh ordering permuted using perm.
  • Is a discretization connection a mapping between two "immutable" meshes? Or is to_discr.mesh actually changed upon creation of the connection?
  • If the answer to the last question is "no," how do I construct a copy of from_discr.mesh with the elements permuted?

Any advice would be appreciated! Thank you!

@inducer

Copy link
Copy Markdown
Owner

Side note: please disregard the RUF052 (astral-sh/ruff#14796) and pylint linter failures (pylint-dev/pylint#10000 (comment)).

@@ -0,0 +1,90 @@
__copyright__ = "Copyright (C) 2014 Andreas Kloeckner"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the copyright notice.

Comment on lines +48 to +49
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the permutation a parameter to this function, rather than unconditionally obtaining it from pymetis?


# Reorder the local mesh using Metis
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will perm, iperm match the return value of get_reordering_by_pymetis? It seems that returns only a single array?


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defmake_element_permutation_connection(actx, from_discr):
defmake_element_permutation_connection(actx: ArrayContext, from_discr: Discretization) ->DirectDiscretizationConnection:



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defget_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):
defget_reordering_by_pymetis(mesh: meshmode.mesh.Mesh, *, connectivity: Literal["facial"] |Literal["nodal"], **kwargs)->np.ndarray:


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From @jonathan-macart's email, my understanding was that the objective of this is a mesh with the elements reordered. This connection instead shuffles DOF data between elements, while leaving the discretization in place.

To achieve the goal I mention above, you would need to make a permuted mesh, then make a discretization based on that.

Comment on lines +74 to +75
from_element_indices=all_elements,
to_element_indices=all_elements_perm, ## CHK??

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mishandles meshes/discretizations with multiple element groups (e.g. a mesh that's part-hex-part-tet), in that it is silently broken (by using out-of-bounds indices) in that case. It's fine to assume single-group only, but then the code should error if presented with multiple groups.



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think an argument could be made that the connectivity-getter could be factored into a separate function, since it seems it's duplicated from get_partition_by_pymetis?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathan-macart@inducer@MacRTL
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Permutation connection - #445

Open
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection
Open

Permutation connection#445
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection

Conversation

@jonathan-macart

Copy link
Copy Markdown

Added:

  1. get_reordering_by_pymetis: Compute mesh element reorderings (permutations) via Metis's nested dissection algorithm.
  2. make_element_permutation_connection: First attempt at generating a connection that permutes the elements of an existing mesh, say from_mesh, to those of a new mesh, to_mesh, using the ND-generated permutation. The goal is to be able to pass to_mesh to a CFD solver. I do not need the mesh nodes to be reordered. My understanding is that all_elements_perm should contain the permuted element tags of from_mesh, though this could be completely incorrect.

Currently, (2) returns a discretization connection containing two identical discretizations/meshes. A few thoughts/questions:

  • Is constructing to_discr = from_discr.copy() a problem? My understanding is that this creates an exact replica of from_discr.mesh, which is not the goal. to_discr.mesh should contain the same nodes and elements of from_discr.mesh, but with the mesh ordering permuted using perm.
  • Is a discretization connection a mapping between two "immutable" meshes? Or is to_discr.mesh actually changed upon creation of the connection?
  • If the answer to the last question is "no," how do I construct a copy of from_discr.mesh with the elements permuted?

Any advice would be appreciated! Thank you!

@inducer

Copy link
Copy Markdown
Owner

Side note: please disregard the RUF052 (astral-sh/ruff#14796) and pylint linter failures (pylint-dev/pylint#10000 (comment)).

@@ -0,0 +1,90 @@
__copyright__ = "Copyright (C) 2014 Andreas Kloeckner"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the copyright notice.

Comment on lines +48 to +49
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the permutation a parameter to this function, rather than unconditionally obtaining it from pymetis?


# Reorder the local mesh using Metis
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will perm, iperm match the return value of get_reordering_by_pymetis? It seems that returns only a single array?


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defmake_element_permutation_connection(actx, from_discr):
defmake_element_permutation_connection(actx: ArrayContext, from_discr: Discretization) ->DirectDiscretizationConnection:



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defget_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):
defget_reordering_by_pymetis(mesh: meshmode.mesh.Mesh, *, connectivity: Literal["facial"] |Literal["nodal"], **kwargs)->np.ndarray:


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From @jonathan-macart's email, my understanding was that the objective of this is a mesh with the elements reordered. This connection instead shuffles DOF data between elements, while leaving the discretization in place.

To achieve the goal I mention above, you would need to make a permuted mesh, then make a discretization based on that.

Comment on lines +74 to +75
from_element_indices=all_elements,
to_element_indices=all_elements_perm, ## CHK??

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mishandles meshes/discretizations with multiple element groups (e.g. a mesh that's part-hex-part-tet), in that it is silently broken (by using out-of-bounds indices) in that case. It's fine to assume single-group only, but then the code should error if presented with multiple groups.



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think an argument could be made that the connectivity-getter could be factored into a separate function, since it seems it's duplicated from get_partition_by_pymetis?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathan-macart@inducer@MacRTL
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Permutation connection - #445

Open
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection
Open

Permutation connection#445
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection

Conversation

@jonathan-macart

Copy link
Copy Markdown

Added:

  1. get_reordering_by_pymetis: Compute mesh element reorderings (permutations) via Metis's nested dissection algorithm.
  2. make_element_permutation_connection: First attempt at generating a connection that permutes the elements of an existing mesh, say from_mesh, to those of a new mesh, to_mesh, using the ND-generated permutation. The goal is to be able to pass to_mesh to a CFD solver. I do not need the mesh nodes to be reordered. My understanding is that all_elements_perm should contain the permuted element tags of from_mesh, though this could be completely incorrect.

Currently, (2) returns a discretization connection containing two identical discretizations/meshes. A few thoughts/questions:

  • Is constructing to_discr = from_discr.copy() a problem? My understanding is that this creates an exact replica of from_discr.mesh, which is not the goal. to_discr.mesh should contain the same nodes and elements of from_discr.mesh, but with the mesh ordering permuted using perm.
  • Is a discretization connection a mapping between two "immutable" meshes? Or is to_discr.mesh actually changed upon creation of the connection?
  • If the answer to the last question is "no," how do I construct a copy of from_discr.mesh with the elements permuted?

Any advice would be appreciated! Thank you!

@inducer

Copy link
Copy Markdown
Owner

Side note: please disregard the RUF052 (astral-sh/ruff#14796) and pylint linter failures (pylint-dev/pylint#10000 (comment)).

@@ -0,0 +1,90 @@
__copyright__ = "Copyright (C) 2014 Andreas Kloeckner"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the copyright notice.

Comment on lines +48 to +49
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the permutation a parameter to this function, rather than unconditionally obtaining it from pymetis?


# Reorder the local mesh using Metis
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will perm, iperm match the return value of get_reordering_by_pymetis? It seems that returns only a single array?


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defmake_element_permutation_connection(actx, from_discr):
defmake_element_permutation_connection(actx: ArrayContext, from_discr: Discretization) ->DirectDiscretizationConnection:



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defget_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):
defget_reordering_by_pymetis(mesh: meshmode.mesh.Mesh, *, connectivity: Literal["facial"] |Literal["nodal"], **kwargs)->np.ndarray:


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From @jonathan-macart's email, my understanding was that the objective of this is a mesh with the elements reordered. This connection instead shuffles DOF data between elements, while leaving the discretization in place.

To achieve the goal I mention above, you would need to make a permuted mesh, then make a discretization based on that.

Comment on lines +74 to +75
from_element_indices=all_elements,
to_element_indices=all_elements_perm, ## CHK??

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mishandles meshes/discretizations with multiple element groups (e.g. a mesh that's part-hex-part-tet), in that it is silently broken (by using out-of-bounds indices) in that case. It's fine to assume single-group only, but then the code should error if presented with multiple groups.



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think an argument could be made that the connectivity-getter could be factored into a separate function, since it seems it's duplicated from get_partition_by_pymetis?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathan-macart@inducer@MacRTL
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Permutation connection - #445

Open
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection
Open

Permutation connection#445
jonathan-macart wants to merge 4 commits into
inducer:mainfrom
jonathan-macart:permutation_connection

Conversation

@jonathan-macart

Copy link
Copy Markdown

Added:

  1. get_reordering_by_pymetis: Compute mesh element reorderings (permutations) via Metis's nested dissection algorithm.
  2. make_element_permutation_connection: First attempt at generating a connection that permutes the elements of an existing mesh, say from_mesh, to those of a new mesh, to_mesh, using the ND-generated permutation. The goal is to be able to pass to_mesh to a CFD solver. I do not need the mesh nodes to be reordered. My understanding is that all_elements_perm should contain the permuted element tags of from_mesh, though this could be completely incorrect.

Currently, (2) returns a discretization connection containing two identical discretizations/meshes. A few thoughts/questions:

  • Is constructing to_discr = from_discr.copy() a problem? My understanding is that this creates an exact replica of from_discr.mesh, which is not the goal. to_discr.mesh should contain the same nodes and elements of from_discr.mesh, but with the mesh ordering permuted using perm.
  • Is a discretization connection a mapping between two "immutable" meshes? Or is to_discr.mesh actually changed upon creation of the connection?
  • If the answer to the last question is "no," how do I construct a copy of from_discr.mesh with the elements permuted?

Any advice would be appreciated! Thank you!

@inducer

Copy link
Copy Markdown
Owner

Side note: please disregard the RUF052 (astral-sh/ruff#14796) and pylint linter failures (pylint-dev/pylint#10000 (comment)).

@@ -0,0 +1,90 @@
__copyright__ = "Copyright (C) 2014 Andreas Kloeckner"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the copyright notice.

Comment on lines +48 to +49
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make the permutation a parameter to this function, rather than unconditionally obtaining it from pymetis?


# Reorder the local mesh using Metis
from meshmode.distributed import get_reordering_by_pymetis
perm, iperm = get_reordering_by_pymetis(from_discr.mesh)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will perm, iperm match the return value of get_reordering_by_pymetis? It seems that returns only a single array?


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defmake_element_permutation_connection(actx, from_discr):
defmake_element_permutation_connection(actx: ArrayContext, from_discr: Discretization) ->DirectDiscretizationConnection:



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defget_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):
defget_reordering_by_pymetis(mesh: meshmode.mesh.Mesh, *, connectivity: Literal["facial"] |Literal["nodal"], **kwargs)->np.ndarray:


# {{{ permute mesh elements

def make_element_permutation_connection(actx, from_discr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From @jonathan-macart's email, my understanding was that the objective of this is a mesh with the elements reordered. This connection instead shuffles DOF data between elements, while leaving the discretization in place.

To achieve the goal I mention above, you would need to make a permuted mesh, then make a discretization based on that.

Comment on lines +74 to +75
from_element_indices=all_elements,
to_element_indices=all_elements_perm, ## CHK??

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mishandles meshes/discretizations with multiple element groups (e.g. a mesh that's part-hex-part-tet), in that it is silently broken (by using out-of-bounds indices) in that case. It's fine to assume single-group only, but then the code should error if presented with multiple groups.



# FIXME: Move somewhere else, since it's not strictly limited to distributed?
def get_reordering_by_pymetis(mesh, *, connectivity="facial", **kwargs):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think an argument could be made that the connectivity-getter could be factored into a separate function, since it seems it's duplicated from get_partition_by_pymetis?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jonathan-macart@inducer@MacRTL