Skip to content

Commit

Permalink
Merge pull request #70 from vincentcasseau/main
Browse files Browse the repository at this point in the history
KCore, Transform :
  • Loading branch information
vincentcasseau authored Jun 27, 2024
2 parents a48f09c + 9b974f7 commit 2d56dcb
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 168 deletions.
25 changes: 20 additions & 5 deletions Cassiopee/KCore/test/compareSessionLogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ def stringify(test='', ref='', new=''):
compStr += stringify(*diffTest(test, refDict[test], newDict[test]))
if len(compStr):
compStr = commonTestsHeader + compStr
baseState = 'FAIL'
baseState = 'FAILED'
else: compStr = commonTestsHeader + "[none]\n"

newTestsHeader = "\nNew tests:\n{}\n".format('-'*9)
Expand All @@ -170,7 +170,7 @@ def stringify(test='', ref='', new=''):
compStr += deletedTestsHeader
for test in deletedTests:
compStr += stringify(test)
baseState = 'FAIL'
baseState = 'FAILED'
else: compStr += deletedTestsHeader + "[none]\n"

failedTestsHeader = "\nReminder - Failed tests:\n{}\n".format('-'*23)
Expand Down Expand Up @@ -203,16 +203,15 @@ def stringify(test='', ref='', new=''):
if baseState in ['OK', 'NEW ADDITIONS'] and 'REF-' in script_args.logs[0]:
if os.access(script_args.logs[0], os.W_OK):
import shutil
shutil.copyfile(script_args.logs[0],
script_args.logs[0].replace('REF-', ''))
os.remove(script_args.logs[0])
newRef = os.path.join(os.path.dirname(script_args.logs[1]),
'REF-' + os.path.basename(script_args.logs[1]))
shutil.copyfile(script_args.logs[1], newRef)
else: exitStatus = 2

prod = getProd(script_args.logs[1])
tlog, tlog2 = getTimeFromLog(script_args.logs[1])
if script_args.email:
prod = getProd(script_args.logs[1])
if baseStateMsg: baseStateMsg = '\n\n'+baseStateMsg
try:
from KCore.notify import notify
Expand All @@ -227,4 +226,20 @@ def stringify(test='', ref='', new=''):
if os.access('./', os.W_OK):
print("Writing comparison to {}".format(filename))
with open(filename, 'w') as f: f.write(header + compStr + baseStateMsg)

# Amend state of the base in logs/validation_status.txt
logAllValids = "/stck/cassiope/git/logs/validation_status.txt"
entry = "{} - {} - {}\n".format(prod, tlog2, baseState)
if os.access(os.path.dirname(logAllValids), os.W_OK):
with open(logAllValids, 'r') as f: contents = f.readlines()
prodFound = False
for i, line in enumerate(contents):
if line.startswith(prod):
contents[i] = entry
prodFound = True
break

if not prodFound: contents.append(entry)
with open(logAllValids, 'w') as f: f.writelines(contents)

sys.exit(exitStatus)
48 changes: 48 additions & 0 deletions Cassiopee/KCore/test/notifyValid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Send a notification by email to a list of recipients about the validation
# status of different prods. Please set the environment variable CASSIOPEE_EMAIL
# Usage: python notifyValid.py --recipients='[email protected] [email protected]'
import os
import sys
from time import strptime, strftime

# Parse command-line arguments
def parseArgs():
import argparse
# Create argument parser
parser = argparse.ArgumentParser()
parser.add_argument("-r", "--recipients", type=str, default='',
help="Single-quoted space-separated list of recipients")
# Parse arguments
return parser.parse_args()

# Main
if __name__ == '__main__':
script_args = parseArgs()
recipients = script_args.recipients.split(' ')
if not recipients[0]: recipients = []

# Check valid status
log_entries = []
with open('/stck/cassiope/git/logs/validation_status.txt', 'r') as f:
for line in f:
log_entries.append(line.strip().split(' - '))
log_entries.sort(key=lambda x: x[1], reverse=True)

vnvState = 'OK'
messageText = "Non-regression testing of Cassiopee, Fast and all PModules:\n{}\n\n".format(58*'-')
for log_machine in log_entries:
prod = log_machine[0]
date = strptime(log_machine[1], "%y%m%d-%H%M%S")
date = strftime("%d/%m/%y at %T", date)
status = log_machine[2]
messageText += '{:>20} | {} | {:>10}\n'.format(prod, date, status)
if 'FAILED' in log_machine: vnvState = 'FAILED'

try:
from KCore.notify import notify
notify(recipients=recipients,
messageSubject="[V&V Cassiopee] State: {}".format(vnvState),
messageText=messageText)
except ImportError:
print("Error: KCore is required to import notify.")
sys.exit()
185 changes: 22 additions & 163 deletions Cassiopee/Transform/Transform/subzone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ PyObject* K_TRANSFORM::subzoneElements(PyObject* self, PyObject* args)
vector<E_Int> neltspc(nc+1), neltspc2(nc), nvpe(nc);

char* eltType2 = new char[50]; strcpy(eltType2, "");
std::vector<char*> eltTypes;
vector<char*> eltTypes;
K_ARRAY::extractVars(eltType, eltTypes);

// Compute the cumulative number of elements per connectivity,
Expand All @@ -809,7 +809,7 @@ PyObject* K_TRANSFORM::subzoneElements(PyObject* self, PyObject* args)
}

// Bin input elements
std::vector<std::vector<E_Int> > binnedEltList(nc);
vector<vector<E_Int> > binnedEltList(nc);
for (E_Int i = 0; i < n; i++)
{
E_Int noe = eltList[i];
Expand Down Expand Up @@ -1110,7 +1110,7 @@ PyObject* K_TRANSFORM::subzoneElementsBoth(PyObject* self, PyObject* args)
vector<E_Int> neltspc(nc+1), neltspc2(nc), nvpe(nc);

char* eltType2 = new char[50]; strcpy(eltType2, "");
std::vector<char*> eltTypes;
vector<char*> eltTypes;
K_ARRAY::extractVars(eltType, eltTypes);

// Compute the cumulative number of elements per connectivity,
Expand All @@ -1127,7 +1127,7 @@ PyObject* K_TRANSFORM::subzoneElementsBoth(PyObject* self, PyObject* args)
}

// Bin input elements
std::vector<std::vector<E_Int> > binnedEltList(nc);
vector<vector<E_Int> > binnedEltList(nc);
for (E_Int i = 0; i < n; i++)
{
E_Int noe = eltList[i];
Expand Down Expand Up @@ -1268,166 +1268,29 @@ PyObject* K_TRANSFORM::subzoneFaces(PyObject* self, PyObject* args)
{
PyErr_SetString(PyExc_TypeError,
"subzone: cannot be used on a structured array.");
RELEASESHAREDS(array,f); return NULL;
RELEASESHAREDS(array, f); return NULL;
}

E_Int n = faceList.getSize();
E_Int* faceListp = faceList.begin();
E_Int nf, nt2;

char eltTypeFaces[10];
int fBAR[] = {
1,
2 };
int fTRI[] = {
1, 2,
2, 3,
3, 1 };
int fQUAD[] = {
1, 2,
2, 3,
3, 4,
4, 1 };
int fTETRA[] = {
1, 3, 2,
1, 2, 4,
2, 3, 4,
3, 1, 4 };
int fPENTA[] = {
1, 2, 5, 4,
2, 3, 6, 5,
3, 1, 4, 6,
1, 3, 2, 1,
4, 5, 6, 4
};
int fPYRA[] = {
1, 4, 3, 2,
1, 2, 5, 5,
2, 3, 5, 2,
3, 4, 5, 3,
4, 1, 5, 4
};
int fHEXA[] = {
1, 4, 3, 2,
1, 2, 6, 5,
2, 3, 7, 6,
3, 4, 8, 7,
1, 5, 8, 4,
5, 6, 7, 8 };

int* fPtr = NULL; E_Int type = 0;
nt2 = 0; nf = 0;
// nf: nbre de face de l'element d'entree
// eltTypeFaces: type de l'element de sortie (face de l'elt d'entree)
// nt2: nbre de noeuds de l'element de sortie
// type=0 (les faces de sortie sont a elements basiques
// type=1 (entree: elements basiques, sortie: NGON)
if (K_STRING::cmp(eltType, "BAR") == 0)
{
type = 0; nf = 2; strcpy(eltTypeFaces, "NODE"); nt2 = 1; fPtr = fBAR;
}
else if (K_STRING::cmp(eltType, "TRI") == 0)
{
type = 0; nf = 3; strcpy(eltTypeFaces, "BAR"); nt2 = 2; fPtr = fTRI;
}
else if (K_STRING::cmp(eltType, "QUAD") == 0)
{
type = 0; nf = 4; strcpy(eltTypeFaces, "BAR"); nt2 = 2; fPtr = fQUAD;
}
else if (K_STRING::cmp(eltType, "TETRA") == 0)
{
type = 0; nf = 4; strcpy(eltTypeFaces, "TRI"); nt2 = 3; fPtr = fTETRA;
}
else if (K_STRING::cmp(eltType, "HEXA") == 0)
{
type = 0; nf = 6; strcpy(eltTypeFaces, "QUAD"); nt2 = 4; fPtr = fHEXA;
}
else if (K_STRING::cmp(eltType, "PENTA") == 0)
{
type = 0; nf = 5; strcpy(eltTypeFaces, "QUAD"); nt2 = 4; fPtr = fPENTA;
}
else if (K_STRING::cmp(eltType, "PYRA") == 0)
{
type = 0; nf = 5; strcpy(eltTypeFaces, "QUAD"); nt2 = 4; fPtr = fPYRA;
}
else if (K_STRING::cmp(eltType, "NGON") == 0)
{
type = 2; strcpy(eltTypeFaces, "NGON");
}
else
{
PyErr_SetString(PyExc_TypeError,
"subzone: element type not taken into account.");
RELEASESHAREDU(array, f, cn); return NULL;
}
E_Int nfld = f->getNfld(); E_Int npts = f->getSize();
if (type == 0) // Basic faces
{
FldArrayI* c2n = new FldArrayI(n,nt2);
// Selectionne les faces subzonees
FldArrayI indirNodes(npts); indirNodes.setAllValuesAt(-1);
E_Int* indirNp = indirNodes.begin();
E_Int api = f->getApi();

E_Int ind, indElt, nof, indnode, indnodef;
indnodef = 0;
for (E_Int i = 0; i < n; i++)
{
ind = faceListp[i]-1;
indElt = ind / nf;
nof = ind - indElt*nf;
// printf("elt=%d face=%d\n", indElt, nof);
for (E_Int v = 1; v <= nt2; v++)
{
indnode = (*cn)(indElt, fPtr[nof*nt2+v-1])-1;
if (indirNp[indnode] == -1)
{
indnodef += 1;
indirNp[indnode] = indnodef;
(*c2n)(i,v) = indnodef;
}
else
(*c2n)(i,v) = indirNp[indnode];
}
}

FldArrayF* f2 = new FldArrayF(indnodef, nfld);
E_Int indf;
for(E_Int eq = 1; eq <= nfld; eq++)
{
E_Float* fp = f->begin(eq);
E_Float* fnp = f2->begin(eq);
for (E_Int ind = 0; ind < npts; ind++)
{
indf = indirNp[ind]-1;
if (indf > -1) fnp[indf] = fp[ind];
}
}
// Build array
PyObject* tpl = K_ARRAY::buildArray(*f2, varString,
*c2n, -1, eltTypeFaces);
RELEASESHAREDU(array,f, cn);
delete f2; delete c2n;
return tpl;
}
else if (type == 2) // IN: NGON, OUT: NGON
if (K_STRING::cmp(eltType, "NGON") == 0) // IN: NGON, OUT: NGON
{
E_Int nbnodes, fidx;
E_Int indvertn = 1, indedgen = 1;
E_Int sizeEF2 = 0;
E_Int indedgen = 1;
E_Int npts2 = 0; E_Int sizeEF2 = 0;

// Acces non universel sur les ptrs
E_Int* ngon = cn->getNGon();
E_Int* indPG = cn->getIndPG();
E_Int shift = 1; E_Int api = f->getApi();
E_Int shift = 1;
if (api == 3) shift = 0;

// Calcul du nombre de points et aretes uniques dans la nouvelle
// connectivite
vector<E_Int> indirVertices(npts, -1);
// Les vertices sont mappes pour construire une table d'indirection: leur
// nombre n'est pas connu a priori et ils ne sont pas parcourus
// dans l'ordre.
std::unordered_map<E_Int, E_Int> vertexMap;
// Les aretes sont hashees pour determiner le nombre unique d'aretes et
// construire la nouvelle connectivite 2D
vector<E_Int> edge(2);
Expand All @@ -1448,15 +1311,10 @@ PyObject* K_TRANSFORM::subzoneFaces(PyObject* self, PyObject* args)
edge[0] = face[j]-1; edge[1] = face[(j+1)%nbnodes]-1;
E.set(edge.data(), 2);

// Increment the value associated with the first vertex.
// If it is 1, then first time this vertex is encountered
// The second vertex will be dealt with when considering the next edge
auto resV = vertexMap.insert(std::make_pair(edge[0], 0));
if (++resV.first->second == 1)
{
indirVertices[edge[0]] = indvertn;
indvertn++;
}
// If indirection table is -1 for the first vertex, then first time
// this vertex is encountered. The second vertex will be dealt with
// when considering the next edge
if (indirVertices[edge[0]] == -1) indirVertices[edge[0]] = ++npts2;

// If the value associated with E is -1, then first time this edge
// is encountered, set to current unique edge count
Expand All @@ -1470,7 +1328,6 @@ PyObject* K_TRANSFORM::subzoneFaces(PyObject* self, PyObject* args)
}

// Construction des nouvelles connectivites Elmt/Faces et Face/Noeuds
E_Int npts2 = vertexMap.size();
E_Int nfaces2 = edgeMap.size();
E_Int sizeFN2 = (2+shift)*nfaces2;
E_Int nelts2 = n;
Expand Down Expand Up @@ -1724,7 +1581,8 @@ PyObject* K_TRANSFORM::subzoneFacesBoth(PyObject* self, PyObject* args)
E_Int im, jm, km;
FldArrayF* f; FldArrayI* cn;
char* varString; char* eltType;
E_Int res = K_ARRAY::getFromArray(arrayNodes, varString, f, im, jm, km, cn, eltType, true);
E_Int res = K_ARRAY::getFromArray3(arrayNodes, varString, f,
im, jm, km, cn, eltType);
if (res != 1 && res != 2)
{
PyErr_SetString(PyExc_TypeError,
Expand All @@ -1735,14 +1593,15 @@ PyObject* K_TRANSFORM::subzoneFacesBoth(PyObject* self, PyObject* args)
{
PyErr_SetString(PyExc_TypeError,
"subzone: cannot be used on a structured array.");
RELEASESHAREDS(arrayNodes,f); return NULL;
RELEASESHAREDS(arrayNodes, f); return NULL;
}

// Check array of centers
E_Int imc, jmc, kmc;
FldArrayF* fc; FldArrayI* cnc;
char* varStringc; char* eltTypec;
E_Int resc = K_ARRAY::getFromArray(arrayCenters, varStringc, fc, imc, jmc, kmc, cnc, eltTypec, true);
E_Int resc = K_ARRAY::getFromArray3(arrayCenters, varStringc, fc,
imc, jmc, kmc, cnc, eltTypec);
if (resc != 1 && resc != 2)
{
PyErr_SetString(PyExc_TypeError,
Expand All @@ -1753,7 +1612,7 @@ PyObject* K_TRANSFORM::subzoneFacesBoth(PyObject* self, PyObject* args)
{
PyErr_SetString(PyExc_TypeError,
"subzone: cannot be used on a structured array.");
RELEASESHAREDU(arrayNodes, f, cn); RELEASESHAREDS(arrayCenters,fc); return NULL;
RELEASESHAREDU(arrayNodes, f, cn); RELEASESHAREDS(arrayCenters, fc); return NULL;
}

E_Int n = faceList.getSize();
Expand Down Expand Up @@ -2161,6 +2020,6 @@ PyObject* K_TRANSFORM::subzoneFacesBoth(PyObject* self, PyObject* args)
return l;
}

RELEASESHAREDU(arrayNodes,f, cn); RELEASESHAREDU(arrayCenters, fc, cnc);
RELEASESHAREDU(arrayNodes, f, cn); RELEASESHAREDU(arrayCenters, fc, cnc);
return NULL;
}
}

0 comments on commit 2d56dcb

Please sign in to comment.