One way to achieve it is with glossaries-extra and bib2gls. This requires defining the information in a .bib file. In this case @dualentry can be used, which essentially defines two dependent entries: a primary and a dual. The primary entry can be identified in the document with the label given in @dualentry and the dual entry can be identified by dual.label (where label is the original label given in the .bib file).
If you've used the glossaries package, then
@dualentry{velocity,
name={mean velocity},
description={\ensuremath{\vec{v}}}
}
is essentially like
\newglossaryentry{velocity}{
name={mean velocity},
description={\ensuremath{\vec{v}}}
}
\newglossaryentry{dual.velocity}{
description={mean velocity},
name={\ensuremath{\vec{v}}}
}
but additionally, the two entries are considered dependent on each other, so if one entry is referenced in the document, the other is automatically selected as well.
The primary entry is referenced with \gls{velocity} (which displays "mean velocity") and the dual entry is referenced with \gls{dual.velocity} (which does \ensuremath{\vec{v}}). The prefixing system can be changed. For convenience, the glossaries-extra package provides \glsxtrnewgls, which allows you to define a command that's a shortcut for \gls{prefix.label}. For example:
\glsxtrnewgls{dual.}{\sym}
Now \sym{velocity} can be used instead of \gls{dual.velocity}.
Here's an example of a .bib file called symbols.bib:
% Encoding: UTF-8
@dualentry{velocity,
name={mean velocity},
description={\ensuremath{\vec{v}}}
}
@dualentry{torque,
name={torque},
description = {\ensuremath{\vec{\tau}}}
}
@dualentry{area,
name={area},
description={\ensuremath{A}}
}
@dualentry{momentum,
name={momentum},
description={\ensuremath{\vec{p}}}
}
@index{velocitymean,
name = {velocity, mean},
see = {velocity}
}
Here's a document that uses this file:
\documentclass{article}
\usepackage[
symbols, % create 'symbols' list
record % using bib2gls
]{glossaries-extra}
\GlsXtrLoadResources
[src=symbols, % entries defined in symbols.bib
dual-type=symbols,% put the dual entries in the 'symbols' list
type=main, % put the primary entries in the 'main' list
sort = en, % sort the primary entries according to natural English ordering
dual-sort = letter-nocase, % sort the dual entries according to case-insensitive letter order
save-locations=false % page references not required
]
\glsxtrnewgls{dual.}{\sym}
\begin{document}
The \gls{velocity} is denoted \sym{velocity}.
The \gls{area} is denoted \sym{area}.
The \gls{torque} is denoted \sym{torque}.
The \gls{momentum} is denoted \sym{momentum}.
\printunsrtglossary[type=symbols,style=long]
\printunsrtglossary[type=main,style=long]
\end{document}
If the file is called myDoc.tex then the build process is:
pdflatex myDoc
bib2gls myDoc
pdflatex myDoc
The result is:

The @index entry hasn't been selected as it hasn't been referenced in the document, but the selection criteria can be changed in the \GlsXtrLoadResources options to ensure that it's selected if the label referenced in the see key has been selected:
selection={recorded and deps and see}
Unfortunately, because the location lists have been suppressed (through the use of save-locations=false) the actually cross-reference, which is normally contained in the location list, is also suppressed, so the list appears as:

The cross-reference can instead be added to the post-description hook as in the following:
\documentclass{article}
\usepackage[
symbols, % create 'symbols' list
record, % using bib2gls
nostyles,% don't load default styles
stylemods=long% patch styles and load glossary-long.sty
]{glossaries-extra}
\GlsXtrLoadResources
[src=symbols, % entries defined in symbols.bib
dual-type=symbols,% put the dual entries in the 'symbols' list
type=main, % put the primary entries in the 'main' list
sort = en, % sort the primary entries according to natural English ordering
dual-sort = letter-nocase, % sort the dual entries according to case-insensitive letter order
save-locations=false, % page references not required
selection={recorded and deps and see},% selection criteria
category=general,
dual-category=symbol
]
\glsxtrnewgls{dual.}{\sym}
\renewcommand{\glsxtrpostdescgeneral}{%
\glsxtrifhasfield{see}{\glscurrententrylabel}%
{\glsxtrusesee{\glscurrententrylabel}}%
{}%
}
\begin{document}
The \gls{velocity} is denoted \sym{velocity}.
The \gls{area} is denoted \sym{area}.
The \gls{torque} is denoted \sym{torque}.
The \gls{momentum} is denoted \sym{momentum}.
\printunsrtglossary[type=symbols,style=long]
\printunsrtglossary[type=main,style=long]
\end{document}
The document now looks like:

You can select a different glossary style according to your requirements. (There are many predefined styles to choose from.) If you use the nostyles package option, make sure you adjust the stylemods value to ensure that the appropriate style package is loaded (and patched to ensure that the post-description hook works). For example, if you switch from the long style (which is defined in glossary-long.sty) to the index style (which is defined in glossary-tree.sty) then you need to change stylemods=long to stylemods=tree. (You can also load multiple style packages at the same time, for example stylemods={long,tree}.)
A note on the sorting.
The primary entries (with textual values in the name field) are sorted according to sort=en, which uses the English collation rule. This typically ignores punctuation characters and accents, and orders according to the Latin alphabet. Any characters from other alphabets, for example the Mathematical Greek tau , will be placed at the end according to character code (which is not necessarily their natural order according to that alphabet). Word-ordering is implemented by replacing inter-word material with a marker character (the default is the pipe | character, but this can be changed).
This means that velocity, mean has the sort value set to velocity|mean| and mean velocity has the sort value set to mean|velocity|.
The dual entries are sorted according to dual-sort = letter-nocase which uses a case-insensitive letter order, which essentially means that (after any TeX conversions have been applied) the sort value is converted to lower case and a Unicode character code comparison is made.
This means that \ensuremath{\vec{v}} is first converted to v⃗ (lower case Latin V 0x76 followed by combining right arrow above 0x20D7), which is then converted to lower case (no change, since it's already lower case). Whereas \ensuremath{A} is first converted to "A" (upper case Latin A 0x41), which is then converted to lower case "a" (lower case Latin A 0x61). The basic mathematical Greek commands, such as \tau, are also recognised (including those missing from the LaTeX kernel, such as \omicron) so \ensuremath{\vec{\tau}} is converted to ⃗ (lower case mathematical italic Greek tau 0x1D70F followed by combining right arrow above 0x20D7).
Other sort methods are available. You can also provide your own custom rule. The supplementary package glossaries-extra-bib2gls.sty (which is automatically loaded with the record option) provides some helper commands for custom rules. For example:
dual-sort=custom, % use custom rule for sorting dual entries
dual-sort-rule={% custom rule for dual sorting
\glsxtrcontrolrules
;\glsxtrspacerules
;\glsxtrnonprintablerules
;\glsxtrcombiningdiacriticrules
,\glsxtrhyphenrules
<\glsxtrgeneralpuncrules
<\glsxtrdigitrules
<\glsxtrfractionrules
<\glsxtrGeneralLatinIVrules
<\glsxtrMathItalicGreekIrules
}