Commit 125b412e authored by Spencer Sherwin's avatar Spencer Sherwin

Merge branch 'master' into feature/SumFacPyr

parents f265759f 236cb5f9
......@@ -3,3 +3,8 @@
path = docs/tutorial
url = git@gitlab.nektar.info:nektar/tutorial
ignore = all
[submodule "docs/developer-guide"]
branch = master
path = docs/developer-guide
url = git@gitlab.nektar.info:nektar/developer-guide
ignore = all
......@@ -4,11 +4,32 @@ Changelog
v4.5.0
------
**NekMesh**:
- Add periodic boundary condition meshing in 2D (!733)
- Adjust boundary layer thickness in corners in 2D (!739)
**Library**
- Added in sum factorisation version for pyramid expnasions and orthogonal expansion in pyramids (!750)
**Documentation**:
- Added the developer-guide repository as a submodule (!751)
v4.4.1
------
**Library**
- Remove the duplicate output of errorutil (!756)
**FieldConvert**:
- Fix issue with FieldConvert when range flag used (!761)
**NekMesh**:
- Fix memory consumption issue with Gmsh output (!747, !762)
- Rework meshing control so that if possible viewable meshes will be dumped
when some part of the system fails (!756)
- Add manifold meshing option (!756)
**FieldConvert:**
- Fix issue with field ordering in the interppointdatatofld module (!754)
v4.4.0
------
**Library**:
......@@ -50,6 +71,7 @@ v4.4.0
- Fix bug in FieldUtils when using half mode expansions (!734)
- Do not read the same fld/pts files again for every variable (!670)
- Fix bug in CMake PETSc detection for Ubuntu 16.04/Debian 9 (!735)
- Fix warnings with Intel compiler (!742)
**ADRSolver:**
- Add a projection equation system for C^0 projections (!675)
......@@ -108,9 +130,9 @@ v4.4.0
- Change variable names in mcf file to make more sense (!736)
- Fix issues in varopti module so that in can be compiled without meshgen on
(!736)
- Replace LAPACK Eigenvalue calculation with handwritten function in
- Replace LAPACK Eigenvalue calculation with handwritten function in
varopti (!738)
- Improved node-colouring algorithm for better load-balancing
- Improved node-colouring algorithm for better load-balancing
in varopti (!738)
- Simplified calculation of the energy functional in varopti for improved
performance (!738)
......
ADD_SUBDIRECTORY(user-guide)
ADD_SUBDIRECTORY(developer-guide)
IF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/developer-guide/CMakeLists.txt)
ADD_SUBDIRECTORY(developer-guide)
ENDIF ()
IF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tutorial/CMakeLists.txt)
ADD_SUBDIRECTORY(tutorial)
......
Subproject commit e128cfaffbbd37c734a667cdc2a07b6f06291615
SET(DEVGUIDESRC ${CMAKE_CURRENT_SOURCE_DIR})
SET(DEVGUIDE ${CMAKE_BINARY_DIR}/docs/developer-guide)
FILE(MAKE_DIRECTORY ${DEVGUIDE}/html)
FIND_PROGRAM(HTLATEX htlatex)
ADD_CUSTOM_TARGET(developer-guide-html
export TEXINPUTS=${CMAKE_SOURCE_DIR}//:${DEVGUIDESRC}//: &&
${HTLATEX} ${DEVGUIDESRC}/developer-guide.tex
"${DEVGUIDESRC}/styling.cfg,html,3,next,NoFonts"
WORKING_DIRECTORY ${DEVGUIDE}/html
)
# If tex4ht successful, create img dir and copy images across
FILE(GLOB_RECURSE imgfiles "img/*.png" "img/*.jpg" "*/img/*.png" "*/img/*.jpg")
ADD_CUSTOM_COMMAND(TARGET developer-guide-html
POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${DEVGUIDE}/html/img)
FOREACH(img ${imgfiles})
ADD_CUSTOM_COMMAND(TARGET developer-guide-html
POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${img} ${DEVGUIDE}/html/img)
ENDFOREACH()
FILE(GLOB_RECURSE pdffiles "*/img/*.pdf")
FIND_PROGRAM(CONVERT convert)
FOREACH(pdf ${pdffiles})
GET_FILENAME_COMPONENT(BASENAME ${pdf} NAME_WE)
ADD_CUSTOM_COMMAND(TARGET developer-guide-html
POST_BUILD COMMAND
${CONVERT} ${pdf} ${DEVGUIDE}/html/img/${BASENAME}.png)
ENDFOREACH()
FIND_PROGRAM(PDFLATEX pdflatex)
FIND_PROGRAM(BIBTEX bibtex)
FIND_PROGRAM(MAKEINDEX makeindex)
ADD_CUSTOM_TARGET(developer-guide-pdf
export TEXINPUTS=${CMAKE_SOURCE_DIR}//: &&
${PDFLATEX} --output-directory ${DEVGUIDE} ${DEVGUIDESRC}/developer-guide.tex
COMMAND TEXMFOUTPUT=${DEVGUIDE} ${BIBTEX} ${DEVGUIDE}/developer-guide.aux
COMMAND TEXMFOUTPUT=${DEVGUIDE} ${MAKEINDEX} ${DEVGUIDE}/developer-guide.idx
COMMAND TEXINPUTS=${CMAKE_SOURCE_DIR}//:
${PDFLATEX} --output-directory ${DEVGUIDE} ${DEVGUIDESRC}/developer-guide.tex
COMMAND TEXINPUTS=${CMAKE_SOURCE_DIR}//:
${PDFLATEX} --output-directory ${DEVGUIDE} ${DEVGUIDESRC}/developer-guide.tex
WORKING_DIRECTORY ${DEVGUIDESRC}
)
\chapter{Coding Standard}
The purpose of this page is to detail the coding standards of the project which
all contributers are requested to follow.
This page describes the coding style standard for C++. A coding style standard
defines the visual layout of source code. Presenting source code in a uniform
fashion facilitates the use of code by different developers. In addition,
following a standard prevents certain types of coding errors.
All of the items below, unless otherwise noted, are guidelines. They are
recommendations about how to lay out a given block of code. Use common sense and
provide comments to describe any deviation from the standard. Sometimes,
violating a guideline may actually improve readability.
If you are working with code that does not follow the standard, bring the code
up-to-date or follow the existing style. Don’t mix styles.
\section{Code Layout}
The aim here is to maximise readability on all platforms and editors.
\begin{itemize}
\item Code width of 80 characters maximum - hard-wrap longer lines.
\item Use sensible wrapping for long statements in a way which maximises
readability.
\item Do not put multiple statements on the same line.
\item Do not declare multiple variables on the same line.
\item Provide a default value on all variable declarations.
\item Enclose every program block (if, else, for, while, etc) in braces, even if
empty or just a single line.
\item Opening braces (\{) should be on their own line.
\item Braces at same indentation as preceeding statement.
\item One class per .cpp and .h file only, unless nested.
\item Define member functions in the .cpp file in the same order as defined in
the .h file.
\item Templated classes defined and implemented in a single .hpp file.
\item Do not put inline functions in the header file unless the function is
trivial (e.g. accessor, empty destructor), or profiling explicitly suggests to.
\item Inline functions should be declared within the class declaration but
defined outside the class declaration at the bottom of the header file.
\begin{notebox}
Virtual and inline are mutually exclusive. Virtual functions should therefore be
implemented in the .cpp file.
\end{notebox}
\end{itemize}
\section{Space}
Adding an appropriate amount of white space enhances readability. Too much white
space, on the other hand, detracts from that readability.
\begin{itemize}
\item Indent using a four-space tab. Consistent tab spacing is necessary to
maintain formatting. Note that this means when a tab is pressed, four physical spaces are
inserted into the source instead.
\item Put a blank line at the end of a public/protected/private block.
\item Put a blank line at the end of every file.
\item Put a space after every keyword (if, while, for, etc.).
\item Put a space after every comma, unless the comma is at the end of the line.
\item Do not put a space before the opening parenthesis of an argument list to a
function.
\item Declare pointers and references with the * or \& symbol next to the
declarator, not the type; e.g., Object *object. Do not put multiple variables in the same
declaration.
\item Place a space on both sides of a binary operator.
\item Do not use a space to separate a unary operator from its operand.
\item Place open and close braces on their own line. No executable statements
should appear on the line with the brace, but comments are allowed. Indent opening
braces at the same level as the statement above and indent the closing brace at
the same level as the corresponding opening brace.
\item Indent all statements following an open brace by one tab. Developer Studio
puts any specifier terminated with a colon at the same indentation level as the
enclosing brace. Examples of such specifiers include case statements, access
specifiers (public, private, protected), and goto labels. This is not acceptable
and should be manually corrected so that all statements appearing within a block
and delineated by braces are indented.
\item Break a line into multiple lines when it becomes too long to read. Use at
least two tabs to start the new line, so it does not look like the start of a
block.
\item Follow C++ style comments with one space. It is also preferable to
consider any text that follows C++ style comments as a sentence and to begin this text
with a capital letter. This helps to distinguish the line from a continuation of
a previous line; i.e., \inlsh{// This is my comment.}
\item As a general rule, don’t keep commented out source code in the final
baselined product. Such code leads the reader to believe there was uncertainty
in the code as it currently exists.
\item Place the \# of a preprocessor directive at column one. An exception is
the use of nested ifdefs where the bodies only contain other preprocessor directives.
Add tabs to enhance readability:
\begin{lstlisting}[style=C++Style]
void foo() {
for(int i = 0; i < 10; ++i)
{
#ifdef BAR
do_something();
#endif
for_loop_code();
}
}
\end{lstlisting}
\item Use tabular white space if it enhances
readability.
\item Use only one return statement. Structure the code so that only one return
statement is necessary.
\end{itemize}
\section{Naming Conventions}
Keep variable and function names meaningful but concise.
\begin{itemize}
\item Begin variable names with lower-case letter.
\item Begin function names and class names with upper-case letter.
\item All function, class and variable names should be written in CamelCase,
e.g. \inlsh{MyClass, DoFunction() or myVariableName}.
\item All preprocessor definitions written in UPPER\_CASE with words separated
by underscores, e.g. USE\_SPECIFIC\_FEATURE.
\item All member variables prefixed with m\_.
\item All constants prefixed with a k.
\item All function parameters prefixed with a p.
\item All enumerations prefixed with an e.
\item Do not use leading underscores.
\end{itemize}
\section{Namespaces}
The top-level namespace is "Nektar". All code should reside in this namespace or
a sub-space of this.
\begin{itemize}
\item Namespaces correspond to code structure.
\item Namespaces should be kept to a minimum to simplify the interface to their
contents.
\end{itemize}
\section{Documentation}
\begin{itemize}
\item Briefs for classes, functions and types in header files using
\inlsh{///} notation.
\item Full documentation with implementation using \inlsh{/** ... *\/}
notation.
\item Use @ symbol for @class, @param, @returns, etc for ease of identification.
\item Any separate documentation pages not directly associated with a portion of
the code should be in a separate file in /docs/html/doxygen.
\end{itemize}
This diff is collapsed.
\chapter{Data Structures and Algorithms}
\label{ch:data}
\input{connectivity}
\input{time-integration}
\input{preconditioners}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% memoir.4ht 2009-05-21-09:32 %
% Copyright (C) 2003--2009 Eitan M. Gurari %
% %
% This work may be distributed and/or modified under the %
% conditions of the LaTeX Project Public License, either %
% version 1.3c of this license or (at your option) any %
% later version. The latest version of this license is %
% in %
% http://www.latex-project.org/lppl.txt %
% and version 1.3c or later is part of all distributions %
% of LaTeX version 2005/12/01 or later. %
% %
% This work has the LPPL maintenance status "maintained".%
% %
% This Current Maintainer of this work %
% is Eitan M. Gurari. %
% %
% If you modify this program your changing its signature %
% with a directive of the following form will be %
% appreciated. %
% \message{signature} %
% %
% gurari@cse.ohio-state.edu %
% http://www.cse.ohio-state.edu/~gurari %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\immediate\write-1{version 2009-05-21-09:32}
\input book.4ht
\input verse.4ht
% Tables Handling
\input array.4ht
\input dcolumn.4ht
\input tabularx.4ht
\input booktabs.4ht
\let\rm\empty
\let\sf\empty
\let\tt\empty
\let\bf\empty
\let\it\empty
\def\@chapter[#1]#2{%
\gHAdvance\:mpNum by 1
\HAssign\minipageNum=\:mpNum \relax
%
{\SkipRefstepAnchor \let\addcontentsline\:gobbleIII\no@chapter[#1]{}%
\global\let\f@rtoc\f@rtoc
\global\let\f@rhdr\f@rhdr }%
\HtmlEnv \Toc:Title{#1}\:chapter{#2}}
\NewConfigure{poemline}{2}
\ifx \memgobble\:UnDef
\pend:defI\getthelinenumber{%
\let\sv:thepoemline\thepoemline
\pend:def\thepoemline{\a:poemline}%
\append:def\thepoemline{\b:poemline}}
\append:defI\getthelinenumber{\let\thepoemline\sv:thepoemline}
\else
\pend:defII\getthelinenumber{%
\let\sv:thepoemline\thepoemline
\pend:def\thepoemline{\a:poemline}%
\append:def\thepoemline{\b:poemline}}
\append:defII\getthelinenumber{\let\thepoemline\sv:thepoemline}
\fi
\Hinput{memoir}
\endinput
\Preamble{html}
\Configure{graphics*}
{pdf}
{\Picture[pict]{\csname Gin@base\endcsname.png}}
%% Use HTML for italics and bold
\Configure{emph}{\ifvmode\ShowPar\fi\HCode{<em>}}{\HCode{</em>}}
\Configure{textbf}{\ifvmode\ShowPar\fi\HCode{<b>}}{\HCode{</b>}}
\Configure{texttt}{\ifvmode\ShowPar\fi\HCode{<code>}}{\HCode{</code>}}
\ConfigureEnv{notebox}{\ifvmode\ShowPar\fi\HCode{<div class="notebox">}}{\HCode{</div>}} {} {}
\ConfigureEnv{warningbox}{\ifvmode\ShowPar\fi\HCode{<div class="warningbox">}}{\HCode{</div>}} {} {}
\ConfigureEnv{tipbox}{\ifvmode\ShowPar\fi\HCode{<div class="tipbox">}}{\HCode{</div>}} {} {}
%% Remove div indents
\Configure{HtmlPar}
{\EndP\Tg<p>}
{\EndP\Tg<p>}
{\HCode{</p>\Hnewline}}
{\HCode{</p>\Hnewline}}
\begin{document}
\DeclareGraphicsExtensions{.pdf,.eps,.png,.jpg,.mp,.mps}
\Css{
body {
margin: 0 auto;
max-width: 800px;
background: \#ffffff;
font-family: "Helvetica Neue", Arial, Freesans, clean, sans-serif;
}
h2 {color: \#000000; text-align: right; font-size: 32pt;}
.chapterHead .titlemark {
font-size: 20pt;
}
a {
color: \#000066;
text-decoration: none;
}
a:hover {
color: \#0000ff;
}
img {
max-width: 800px;
}
.figure {
text-align: center;
}
div .caption {
text-align: center;
}
.author {
font-size: 14pt;
}
.lstlisting {
background: \#eeeeee;
margin-left: 20px;
margin-right: 20px;
padding: 5px;
font-family: "Lucida Console", Monaco, monospace;
}
.lstinline {
padding: 2px;
font-family: "Lucida Console", Monaco, monospace;
}
.notebox {
border: 1px solid \#999999;
border-radius: 10px;
background: \#bbbbbb;
padding: 10px;
margin: 10px;
}
.warningbox {
border: 1px solid \#999999;
border-radius: 10px;
background: \#ffbbbb;
padding: 10px;
margin: 10px;
}
.tipbox {
border: 1px solid \#999999;
border-radius: 10px;
background: \#bbffbb;
padding: 10px;
margin: 10px;
}
}
\EndPreamble
......@@ -91,7 +91,7 @@ void ProcessInterpPointDataToFld::Process(po::variables_map &vm)
ASSERTL0(nFields > 0, "No field values provided in input");
// assume one field is already defined from input file.
m_f->m_exp.resize(nFields + 1);
m_f->m_exp.resize(nFields);
for (i = 1; i < nFields; ++i)
{
m_f->m_exp[i] = m_f->AppendExpList(0);
......@@ -128,7 +128,7 @@ void ProcessInterpPointDataToFld::Process(po::variables_map &vm)
{
for (j = 0; j < nFields; ++j)
{
m_f->m_exp[j]->SetPhys(i, outPts->GetPointVal(j, i));
m_f->m_exp[j]->SetPhys(i, outPts->GetPointVal(3 + j, i));
}
}
......
......@@ -75,19 +75,19 @@ namespace Nektar
template<typename SparseStorageType>
const IndexType NekSparseMatrix<SparseStorageType>::GetRows() const
IndexType NekSparseMatrix<SparseStorageType>::GetRows() const
{
return m_sparseStorage->GetRows();
}
template<typename SparseStorageType>
const IndexType NekSparseMatrix<SparseStorageType>::GetColumns() const
IndexType NekSparseMatrix<SparseStorageType>::GetColumns() const
{
return m_sparseStorage->GetColumns();
}
template<typename SparseStorageType>
const IndexType NekSparseMatrix<SparseStorageType>::GetNumNonZeroEntries() const
IndexType NekSparseMatrix<SparseStorageType>::GetNumNonZeroEntries() const
{
return m_sparseStorage->GetNumNonZeroEntries();
}
......@@ -137,7 +137,7 @@ namespace Nektar
}
template<typename SparseStorageType>
const size_t NekSparseMatrix<SparseStorageType>::GetMemoryFootprint() const
size_t NekSparseMatrix<SparseStorageType>::GetMemoryFootprint() const
{
return m_sparseStorage->GetMemoryUsage(
m_sparseStorage->GetNumNonZeroEntries(),
......@@ -148,7 +148,7 @@ namespace Nektar
}
template<typename SparseStorageType>
const unsigned long NekSparseMatrix<SparseStorageType>::GetMulCallsCounter() const
unsigned long NekSparseMatrix<SparseStorageType>::GetMulCallsCounter() const
{
return m_mulCallsCounter;
}
......@@ -161,7 +161,7 @@ namespace Nektar
}
template<typename SparseStorageType>
const IndexType NekSparseMatrix<SparseStorageType>::GetBandwidth()
IndexType NekSparseMatrix<SparseStorageType>::GetBandwidth()
{
int bandwidth = 0;
......
......@@ -73,15 +73,15 @@ namespace Nektar
LIB_UTILITIES_EXPORT NekSparseMatrix(const NekSparseMatrix& src);
LIB_UTILITIES_EXPORT ~NekSparseMatrix();
LIB_UTILITIES_EXPORT const IndexType GetRows() const;
LIB_UTILITIES_EXPORT const IndexType GetColumns() const;
LIB_UTILITIES_EXPORT const IndexType GetNumNonZeroEntries() const;
LIB_UTILITIES_EXPORT IndexType GetRows() const;
LIB_UTILITIES_EXPORT IndexType GetColumns() const;
LIB_UTILITIES_EXPORT IndexType GetNumNonZeroEntries() const;
LIB_UTILITIES_EXPORT const DataType GetFillInRatio() const;
LIB_UTILITIES_EXPORT const size_t GetMemoryFootprint() const;
LIB_UTILITIES_EXPORT const unsigned long GetMulCallsCounter() const;
LIB_UTILITIES_EXPORT size_t GetMemoryFootprint() const;
LIB_UTILITIES_EXPORT unsigned long GetMulCallsCounter() const;
LIB_UTILITIES_EXPORT const DataType GetAvgRowDensity() const;
LIB_UTILITIES_EXPORT const IndexType GetBandwidth();
LIB_UTILITIES_EXPORT IndexType GetBandwidth();
LIB_UTILITIES_EXPORT COOMatTypeSharedPtr GetCooStorage();
......
......@@ -40,6 +40,8 @@
#include <LibUtilities/BasicUtils/ParseUtils.hpp>
#include <LibUtilities/BasicUtils/Progressbar.hpp>
#include <boost/algorithm/string.hpp>
using namespace std;
namespace Nektar
{
......@@ -56,6 +58,8 @@ Generator2D::Generator2D(MeshSharedPtr m) : ProcessModule(m)
ConfigOption(false, "", "Generate parallelograms on these curves");
m_config["blthick"] =
ConfigOption(false, "0.0", "Parallelogram layer thickness");
m_config["periodic"] =
ConfigOption(false, "", "Set of pairs of periodic curves");
m_config["bltadjust"] =
ConfigOption(false, "2.0", "Boundary layer thickness adjustment");
m_config["adjustblteverywhere"] =
......@@ -73,12 +77,9 @@ void Generator2D::Process()
cout << endl << "2D meshing" << endl;
cout << endl << "\tCurve meshing:" << endl << endl;
}
m_mesh->m_numNodes = m_mesh->m_cad->GetNumVerts();
m_thickness_ID =
m_thickness.DefineFunction("x y z", m_config["blthick"].as<string>());
ParseUtils::GenerateSeqVector(m_config["blcurves"].as<string>().c_str(),
m_blCurves);
......@@ -90,10 +91,8 @@ void Generator2D::Process()
LibUtilities::PrintProgressbar(i, m_mesh->m_cad->GetNumCurve(),
"Curve progress");
}
vector<unsigned int>::iterator f =
find(m_blCurves.begin(), m_blCurves.end(), i);
if (f == m_blCurves.end())
{
m_curvemeshes[i] =
......@@ -104,17 +103,24 @@ void Generator2D::Process()
m_curvemeshes[i] = MemoryManager<CurveMesh>::AllocateSharedPtr(
i, m_mesh, m_config["blthick"].as<string>());
}
m_curvemeshes[i]->Mesh();
}
////////
// consider periodic curves
if (m_config["periodic"].beenSet)
{
PeriodicPrep();
MakePeriodic();
}
////////////////////////////////////////
if (m_config["blcurves"].beenSet)
{
// we need to do the boundary layer generation in a face by face basis
MakeBLPrep();
for (int i = 1; i <= m_mesh->m_cad->GetNumSurf(); i++)
{
MakeBL(i);
......@@ -125,7 +131,6 @@ void Generator2D::Process()
{
cout << endl << "\tFace meshing:" << endl << endl;
}
// linear mesh all surfaces
for (int i = 1; i <= m_mesh->m_cad->GetNumSurf(); i++)
{
......@@ -148,28 +153,25 @@ void Generator2D::Process()
vector<NodeSharedPtr> ns;
ns.push_back((*it)->m_n1);
ns.push_back((*it)->m_n2);
// for each iterator create a LibUtilities::eSegement
// push segment into m_mesh->m_element[1]
// tag for the elements shoudl be the CAD number of the curves
ElmtConfig conf(LibUtilities::eSegment, 1, false, false);
vector<int> tags;
tags.push_back((*it)->m_parentCAD->GetId());
ElementSharedPtr E2 = GetElementFactory().CreateInstance(
LibUtilities::eSegment, conf, ns, tags);
m_mesh->m_element[1].push_back(E2);
}
// m_mesh->m_expDim = 1;
// m_mesh->m_element[2].clear();
ProcessVertices();
ProcessEdges();
ProcessFaces();
ProcessElements();
ProcessComposites();
Report();
}
......@@ -197,17 +199,13 @@ void Generator2D::MakeBLPrep()
void Generator2D::MakeBL(int faceid)
{
map<int, Array<OneD, NekDouble> > edgeNormals;
int eid = 0;
for (vector<unsigned>::iterator it = m_blCurves.begin();
it != m_blCurves.end(); ++it)
{
CADOrientation::Orientation edgeo =
m_mesh->m_cad->GetCurve(*it)->GetOrienationWRT(faceid);
vector<EdgeSharedPtr> es = m_curvemeshes[*it]->GetMeshEdges();
// on each !!!EDGE!!! calculate a normal
// always to the left unless edgeo is 1
// normal must be done in the parametric space (and then projected back)
......@@ -218,30 +216,27 @@ void Generator2D::MakeBL(int faceid)
Array<OneD, NekDouble> p1, p2;
p1 = es[j]->m_n1->GetCADSurfInfo(faceid);
p2 = es[j]->m_n2->GetCADSurfInfo(faceid);
Array<OneD, NekDouble> n(2);
n[0] = p1[1] - p2[1];
n[1] = p2[0] - p1[0];
if (edgeo == CADOrientation::eBackwards)
{
swap(p1, p2);
n[0] *= -1.0;
n[1] *= -1.0;
}
Array<OneD, NekDouble> n(2);
n[0] = p1[1] - p2[1];
n[1] = p2[0] - p1[0];
NekDouble mag = sqrt(n[0] * n[0] + n[1] * n[1]);
n[0] /= mag;
n[1] /= mag;
Array<OneD, NekDouble> np = es[j]->m_n1->GetCADSurfInfo(faceid);
np[0] += n[0];
np[1] += n[1];
Array<OneD, NekDouble> np(2);
np[0] = p1[0] + n[0];
np[1] = p1[1] + n[1];
Array<OneD, NekDouble> loc = es[j]->m_n1->GetLoc();