// GetDP - Copyright (C) 1997-2021 P. Dular and C. Geuzaine, University of Liege // // See the LICENSE.txt file for license information. Please report all // issues on https://gitlab.onelab.info/getdp/getdp/issues. #include #include #include #include #include #include #include #include "GetDPVersion.h" #include "GetDPConfig.h" #include "ProData.h" #include "ProDefine.h" #include "ProParser.h" #include "GeoData.h" #include "DofData.h" #include "Pos_Iso.h" #include "Pos_Format.h" #include "Pos_Element.h" #include "Pos_Formulation.h" #include "F.h" #include "Cal_Value.h" #include "Cal_Quantity.h" #include "MallocUtils.h" #include "Message.h" #include "kissfft.hh" #if defined(HAVE_GMSH) #include #include #include #endif #define TWO_PI 6.2831853071795865 #define NBR_MAX_ISO 200 #define SQU(a) ((a)*(a)) extern struct Problem Problem_S ; extern struct CurrentData Current ; extern int Flag_BIN, Flag_GMSH_VERSION; extern FILE *PostStream ; static List_T *PostElement_L = NULL ; static List_T *TimeValue_L = NULL ; /* ------------------------------------------------------------------------ */ /* Gmsh formats */ /* ------------------------------------------------------------------------ */ // global static lists for new-style Gmsh output (cannot be saved incrementally // for each element) static int Gmsh_StartNewView = 0 ; static int NbSP, NbVP, NbTP, NbSL, NbVL, NbTL, NbST, NbVT, NbTT; static int NbSQ, NbVQ, NbTQ, NbSS, NbVS, NbTS, NbSH, NbVH, NbTH; static int NbSI, NbVI, NbTI, NbSY, NbVY, NbTY; static int NbT2; static std::vector SP, VP, TP, SL, VL, TL, ST, VT, TT, SQ, VQ, TQ; static std::vector SS, VS, TS1 /* for petsc */, SH, VH, TH; static std::vector SI, VI, TI, SY, VY, TY, T2D; static std::vector T2C; static char CurrentName[256] = ""; static int CurrentPartitionNumber = 0; static void Gmsh_ResetStaticLists() { NbSP = NbVP = NbTP = NbSL = NbVL = NbTL = 0; NbST = NbVT = NbTT = NbSQ = NbVQ = NbTQ = 0; NbSS = NbVS = NbTS = NbSH = NbVH = NbTH = 0; NbSI = NbVI = NbTI = NbSY = NbVY = NbTY = 0; NbT2 = 0; SP.clear(); VP.clear(); TP.clear(); SL.clear(); VL.clear(); TL.clear(); ST.clear(); VT.clear(); TT.clear(); SQ.clear(); VQ.clear(); TQ.clear(); SS.clear(); VS.clear(); TS1.clear(); SH.clear(); VH.clear(); TH.clear(); SI.clear(); VI.clear(); TI.clear(); SY.clear(); VY.clear(); TY.clear(); T2D.clear(); T2C.clear(); if(!TimeValue_L) TimeValue_L = List_Create(100,1000000,sizeof(double)); else List_Reset(TimeValue_L); } static void Gmsh_StringStart(int Format, double x, double y, double style) { if(Flag_BIN){ /* bricolage: should use Format instead */ T2D.push_back(x); T2D.push_back(y); T2D.push_back(style); T2D.push_back(T2C.size()); NbT2++; } else if(PostStream){ fprintf(PostStream, "T2(%g,%g,%g){", x, y, style); } } static void Gmsh_StringAdd(int Format, int first, char *text) { int i; if(Flag_BIN){ /* bricolage: should use Format instead */ for(i = 0; i < (int)strlen(text)+1; i++) T2C.push_back(text[i]); } else if(PostStream){ if(!first) fprintf(PostStream, ","); fprintf(PostStream, "\"%s\"", text); } } static void Gmsh_StringEnd(int Format) { if(Flag_BIN){ /* bricolage: should use Format instead */ } else if(PostStream){ fprintf(PostStream, "};\n") ; } } static void Gmsh_PrintElementNodeData(struct PostSubOperation *PSO_P, int numTimeStep, int numComp, int Nb[8], std::vector *L[8]) { if(!PostStream) return; int N = 0; for(int i = 0; i < 8; i++) N += Nb[i]; if(!N) return; int step = 0; for (int ts = 0; ts < numTimeStep; ts++) { Pos_InitAllSolutions(PSO_P->TimeStep_L, ts); for(int har = 0; har < Current.NbrHar; har++){ fprintf(PostStream, "$ElementNodeData\n"); fprintf(PostStream, "1\n"); fprintf(PostStream, "\"%s\"\n", CurrentName); fprintf(PostStream, "1\n"); fprintf(PostStream, "%.16g\n", Current.Time); fprintf(PostStream, "4\n"); fprintf(PostStream, "%d\n", (PSO_P->OverrideTimeStepValue >= 0) ? PSO_P->OverrideTimeStepValue : (Current.NbrHar > 1 ? step : (int)Current.TimeStep)); fprintf(PostStream, "%d\n", numComp); fprintf(PostStream, "%d\n", N); fprintf(PostStream, "%d\n", CurrentPartitionNumber); for(int i = 0; i < 8; i++){ if(!Nb[i]) continue; int stride = (*L[i]).size() / Nb[i]; for(unsigned int j = 0; j < (*L[i]).size(); j += stride){ double *tmp = &(*L[i])[j]; int num = (int)tmp[0]; int mult = (stride - 1) / numTimeStep / Current.NbrHar / numComp; if(Flag_BIN){ fwrite(&num, sizeof(int), 1, PostStream); fwrite(&mult, sizeof(int), 1, PostStream); fwrite(&tmp[1 + step * mult * numComp], sizeof(double), mult * numComp, PostStream); } else{ fprintf(PostStream, "%d %d", num, mult); for(int k = 0; k < mult * numComp; k++) fprintf(PostStream, " %.16g", tmp[1 + step * mult * numComp + k]); fprintf(PostStream, "\n"); } } } fprintf(PostStream, "$EndElementNodeData\n"); step++; } } } static void GmshParsed_PrintElement(double Time, int TimeStep, int NbTimeStep, int NbHarmonic, int HarmonicToTime, int Type, int NbrNodes, double *x, double *y, double *z, struct Value *Value) { int i,j,k,jj ; double TimeMH ; struct Value TmpValue ; int symIndex[9] = {0, 1, 2, 1, 3, 4, 2, 4, 5} ; int diagIndex[9] = {0, -1, -1, -1, 1, -1, -1, -1, 2} ; if(Gmsh_StartNewView){ Gmsh_StartNewView = 0 ; Gmsh_ResetStaticLists(); } if (HarmonicToTime == 1){ if(NbHarmonic == 2 && NbTimeStep == 1){ // classical complex case double zero = 0., one = 1.; List_Put(TimeValue_L, 0, &zero); List_Put(TimeValue_L, 1, &one); } else{ for(k = 0 ; k < NbHarmonic ; k++) List_Put(TimeValue_L, NbHarmonic*TimeStep+k, &Time); } } else for(k = 0 ; k < HarmonicToTime ; k++) List_Put(TimeValue_L, HarmonicToTime*TimeStep+k, &Time); if(!PostStream) return; switch (Value[0].Type) { case SCALAR : if(TimeStep == 0){ switch(Type){ case POINT_ELEMENT : fprintf(PostStream, "SP("); break; case LINE : fprintf(PostStream, "SL("); break; case TRIANGLE : fprintf(PostStream, "ST("); break; case QUADRANGLE : fprintf(PostStream, "SQ("); break; case TETRAHEDRON : fprintf(PostStream, "SS("); break; case HEXAHEDRON : fprintf(PostStream, "SH("); break; case PRISM : fprintf(PostStream, "SI("); break; case PYRAMID : fprintf(PostStream, "SY("); break; } for(i = 0 ; i < NbrNodes ; i++){ if(i) fprintf(PostStream, ","); fprintf(PostStream, "%.16g,%.16g,%.16g", x[i], y[i], z[i]); } fprintf(PostStream, "){"); } if (HarmonicToTime == 1) { for(k = 0 ; k < NbHarmonic ; k++) { if(k || TimeStep) fprintf(PostStream, ","); for(i = 0 ; i < NbrNodes ; i++){ if(i) fprintf(PostStream, ","); fprintf(PostStream, "%.16g", Value[i].Val[MAX_DIM*k]); } } } else { for(k = 0 ; k < HarmonicToTime ; k++){ if(k || TimeStep) fprintf(PostStream, ","); for(i = 0 ; i < NbrNodes ; i++){ if(i) fprintf(PostStream, ","); F_MHToTime0(k+i, &Value[i], &TmpValue, k, HarmonicToTime, &TimeMH) ; fprintf(PostStream, "%.16g", TmpValue.Val[0]); } } } if(TimeStep == NbTimeStep-1){ fprintf(PostStream, "};\n") ; } break ; case VECTOR : if(TimeStep == 0){ switch(Type){ case POINT_ELEMENT : fprintf(PostStream, "VP("); break; case LINE : fprintf(PostStream, "VL("); break; case TRIANGLE : fprintf(PostStream, "VT("); break; case QUADRANGLE : fprintf(PostStream, "VQ("); break; case TETRAHEDRON : fprintf(PostStream, "VS("); break; case HEXAHEDRON : fprintf(PostStream, "VH("); break; case PRISM : fprintf(PostStream, "VI("); break; case PYRAMID : fprintf(PostStream, "VY("); break; } for(i = 0 ; i < NbrNodes ; i++){ if(i) fprintf(PostStream, ","); fprintf(PostStream, "%.16g,%.16g,%.16g", x[i], y[i], z[i]); } fprintf(PostStream, "){"); } if (HarmonicToTime == 1) { for(k = 0 ; k < NbHarmonic ; k++) { if(k || TimeStep) fprintf(PostStream, ","); for(i = 0 ; i < NbrNodes ; i++){ if(i) fprintf(PostStream, ","); for(j = 0 ; j < 3 ; j++){ if(j) fprintf(PostStream, ","); fprintf(PostStream, "%.16g", Value[i].Val[MAX_DIM*k+j]); } } } } else { for(k = 0 ; k < HarmonicToTime ; k++){ if(k || TimeStep) fprintf(PostStream, ","); for(i = 0 ; i < NbrNodes ; i++){ if(i) fprintf(PostStream, ","); F_MHToTime0(k+i, &Value[i], &TmpValue, k, HarmonicToTime, &TimeMH) ; for(j = 0 ; j < 3 ; j++){ if(j) fprintf(PostStream, ","); fprintf(PostStream, "%.16g", TmpValue.Val[j]); } } } } if(TimeStep == NbTimeStep-1){ fprintf(PostStream, "};\n") ; } break ; case TENSOR_DIAG : case TENSOR_SYM : case TENSOR : if(TimeStep == 0){ switch(Type){ case POINT_ELEMENT : fprintf(PostStream, "TP("); break; case LINE : fprintf(PostStream, "TL("); break; case TRIANGLE : fprintf(PostStream, "TT("); break; case QUADRANGLE : fprintf(PostStream, "TQ("); break; case TETRAHEDRON : fprintf(PostStream, "TS("); break; case HEXAHEDRON : fprintf(PostStream, "TH("); break; case PRISM : fprintf(PostStream, "TI("); break; case PYRAMID : fprintf(PostStream, "TY("); break; } for(i = 0 ; i < NbrNodes ; i++){ if(i) fprintf(PostStream, ","); fprintf(PostStream, "%.16g,%.16g,%.16g", x[i], y[i], z[i]); } fprintf(PostStream, "){"); } if (HarmonicToTime == 1) { for(k = 0 ; k < NbHarmonic ; k++) { if(k || TimeStep) fprintf(PostStream, ","); for(i = 0 ; i < NbrNodes ; i++){ if(i) fprintf(PostStream, ","); for(j = 0 ; j < 9 ; j++){ if(j) fprintf(PostStream, ","); if(Value[0].Type != TENSOR_DIAG) { if(Value[0].Type == TENSOR_SYM) jj = symIndex[j]; else jj = j; fprintf(PostStream, "%.16g", Value[i].Val[MAX_DIM*k+jj]); } else { jj = diagIndex[j]; if(jj == -1) fprintf(PostStream, "%.16g", 0.); else fprintf(PostStream, "%.16g", Value[i].Val[MAX_DIM*k+jj]); } } } } } else { for(k = 0 ; k < HarmonicToTime ; k++){ if(k || TimeStep) fprintf(PostStream, ","); for(i = 0 ; i < NbrNodes ; i++){ if(i) fprintf(PostStream, ","); F_MHToTime0(k+i, &Value[i], &TmpValue, k, HarmonicToTime, &TimeMH) ; for(j = 0 ; j < 9 ; j++){ if(j) fprintf(PostStream, ","); if(Value[0].Type != TENSOR_DIAG) { if(Value[0].Type == TENSOR_SYM) jj = symIndex[j]; else jj = j; jj = symIndex[j]; fprintf(PostStream, "%.16g", TmpValue.Val[jj]); } else { jj = diagIndex[j]; if(jj == -1) fprintf(PostStream, "%.16g", 0.); else fprintf(PostStream, "%.16g", TmpValue.Val[jj]); } } } } } if(TimeStep == NbTimeStep-1){ fprintf(PostStream, "};\n") ; } break ; } } static void Gmsh_PrintElement(double Time, int TimeStep, int NbTimeStep, int NbHarmonic, int HarmonicToTime, int Type, int ElementNum, int NbrNodes, double *x, double *y, double *z, struct Value *Value, struct PostSubOperation *PSO_P, int Store) { int i,j,k,jj ; double TimeMH ; struct Value TmpValue ; static std::vector *Current_L ; int symIndex[9] = {0, 1, 2, 1, 3, 4, 2, 4, 5} ; int diagIndex[9] = {0, -1, -1, -1, 1, -1, -1, -1, 2} ; if(Gmsh_StartNewView){ Gmsh_StartNewView = 0 ; Gmsh_ResetStaticLists(); } switch (Value[0].Type) { case SCALAR : if(TimeStep == 0){ switch(Type){ case POINT_ELEMENT : Current_L = &SP ; NbSP++ ; break ; case LINE : Current_L = &SL ; NbSL++ ; break ; case TRIANGLE : Current_L = &ST ; NbST++ ; break ; case QUADRANGLE : Current_L = &SQ ; NbSQ++ ; break ; case TETRAHEDRON : Current_L = &SS ; NbSS++ ; break ; case HEXAHEDRON : Current_L = &SH ; NbSH++ ; break ; case PRISM : Current_L = &SI ; NbSI++ ; break ; case PYRAMID : Current_L = &SY ; NbSY++ ; break ; case LINE_2 : Current_L = &SL ; NbSL++ ; break ; case TRIANGLE_2 : Current_L = &ST ; NbST++ ; break ; case QUADRANGLE_2 : Current_L = &SQ ; NbSQ++ ; break ; case QUADRANGLE_2_8N: Current_L = &SQ ; NbSQ++ ; break ; case TETRAHEDRON_2 : Current_L = &SS ; NbSS++ ; break ; case HEXAHEDRON_2 : Current_L = &SH ; NbSH++ ; break ; case HEXAHEDRON_2_20N: Current_L = &SH ; NbSH++ ; break ; case PRISM_2 : Current_L = &SI ; NbSI++ ; break ; case PRISM_2_15N : Current_L = &SI ; NbSI++ ; break ; case PYRAMID_2 : Current_L = &SY ; NbSY++ ; break ; case PYRAMID_2_13N : Current_L = &SY ; NbSY++ ; break ; case LINE_3 : Current_L = &SL ; NbSL++ ; break ; case TRIANGLE_3 : Current_L = &ST ; NbST++ ; break ; case QUADRANGLE_3 : Current_L = &SQ ; NbSQ++ ; break ; case TETRAHEDRON_3 : Current_L = &SS ; NbSS++ ; break ; case HEXAHEDRON_3 : Current_L = &SH ; NbSH++ ; break ; case PRISM_3 : Current_L = &SI ; NbSI++ ; break ; case PYRAMID_3 : Current_L = &SY ; NbSY++ ; break ; case LINE_4 : Current_L = &SL ; NbSL++ ; break ; case TRIANGLE_4 : Current_L = &ST ; NbST++ ; break ; case QUADRANGLE_4 : Current_L = &SQ ; NbSQ++ ; break ; case TETRAHEDRON_4 : Current_L = &SS ; NbSS++ ; break ; case HEXAHEDRON_4 : Current_L = &SH ; NbSH++ ; break ; case PRISM_4 : Current_L = &SI ; NbSI++ ; break ; //case PYRAMID_4 : Current_L = &SY ; NbSY++ ; break ; } if(Flag_GMSH_VERSION != 2){ for(i = 0 ; i < NbrNodes ; i++) Current_L->push_back(x[i]); for(i = 0 ; i < NbrNodes ; i++) Current_L->push_back(y[i]); for(i = 0 ; i < NbrNodes ; i++) Current_L->push_back(z[i]); } else{ double tmp = ElementNum; Current_L->push_back(tmp); } } if (HarmonicToTime == 1) for(k = 0 ; k < NbHarmonic ; k++){ List_Put(TimeValue_L, NbHarmonic*TimeStep+k, &Time); for(i = 0 ; i < NbrNodes ; i++) Current_L->push_back(Value[i].Val[MAX_DIM*k]); } else for(k = 0 ; k < HarmonicToTime ; k++){ List_Put(TimeValue_L, HarmonicToTime*TimeStep+k, &Time); for(i = 0 ; i < NbrNodes ; i++){ F_MHToTime0(k+i, &Value[i], &TmpValue, k, HarmonicToTime, &TimeMH) ; Current_L->push_back(TmpValue.Val[0]); } } break ; case VECTOR : if(TimeStep == 0){ switch(Type){ case POINT_ELEMENT : Current_L = &VP ; NbVP++ ; break ; case LINE : Current_L = &VL ; NbVL++ ; break ; case TRIANGLE : Current_L = &VT ; NbVT++ ; break ; case QUADRANGLE : Current_L = &VQ ; NbVQ++ ; break ; case TETRAHEDRON : Current_L = &VS ; NbVS++ ; break ; case HEXAHEDRON : Current_L = &VH ; NbVH++ ; break ; case PRISM : Current_L = &VI ; NbVI++ ; break ; case PYRAMID : Current_L = &VY ; NbVY++ ; break ; case LINE_2 : Current_L = &VL ; NbVL++ ; break ; case TRIANGLE_2 : Current_L = &VT ; NbVT++ ; break ; case QUADRANGLE_2 : Current_L = &VQ ; NbVQ++ ; break ; case QUADRANGLE_2_8N: Current_L = &VQ ; NbVQ++ ; break ; case TETRAHEDRON_2 : Current_L = &VS ; NbVS++ ; break ; case HEXAHEDRON_2 : Current_L = &VH ; NbVH++ ; break ; case HEXAHEDRON_2_20N: Current_L = &VH ; NbVH++ ; break ; case PRISM_2 : Current_L = &VI ; NbVI++ ; break ; case PRISM_2_15N : Current_L = &VI ; NbVI++ ; break ; case PYRAMID_2 : Current_L = &VY ; NbVY++ ; break ; case PYRAMID_2_13N : Current_L = &VY ; NbVY++ ; break ; case LINE_3 : Current_L = &VL ; NbVL++ ; break ; case TRIANGLE_3 : Current_L = &VT ; NbVT++ ; break ; case QUADRANGLE_3 : Current_L = &VQ ; NbVQ++ ; break ; case TETRAHEDRON_3 : Current_L = &VS ; NbVS++ ; break ; case HEXAHEDRON_3 : Current_L = &VH ; NbVH++ ; break ; case PRISM_3 : Current_L = &VI ; NbVI++ ; break ; case PYRAMID_3 : Current_L = &VY ; NbVY++ ; break ; case LINE_4 : Current_L = &VL ; NbVL++ ; break ; case TRIANGLE_4 : Current_L = &VT ; NbVT++ ; break ; case QUADRANGLE_4 : Current_L = &VQ ; NbVQ++ ; break ; case TETRAHEDRON_4 : Current_L = &VS ; NbVS++ ; break ; case HEXAHEDRON_4 : Current_L = &VH ; NbVH++ ; break ; case PRISM_4 : Current_L = &VI ; NbVI++ ; break ; //case PYRAMID_4 : Current_L = &VY ; NbVY++ ; break ; } if(Flag_GMSH_VERSION != 2){ for(i = 0 ; i < NbrNodes ; i++) Current_L->push_back(x[i]); for(i = 0 ; i < NbrNodes ; i++) Current_L->push_back(y[i]); for(i = 0 ; i < NbrNodes ; i++) Current_L->push_back(z[i]); } else{ double tmp = ElementNum; Current_L->push_back(tmp); } } if (HarmonicToTime == 1) for(k = 0 ; k < NbHarmonic ; k++){ List_Put(TimeValue_L, NbHarmonic*TimeStep+k, &Time); for(i = 0 ; i < NbrNodes ; i++) for(j = 0 ; j < 3 ; j++) Current_L->push_back(Value[i].Val[MAX_DIM*k+j]); } else for(k = 0 ; k < HarmonicToTime ; k++){ List_Put(TimeValue_L, HarmonicToTime*TimeStep+k, &Time); for(i = 0 ; i < NbrNodes ; i++){ F_MHToTime0(k+i, &Value[i], &TmpValue, k, HarmonicToTime, &TimeMH) ; for(j = 0 ; j < 3 ; j++) Current_L->push_back(TmpValue.Val[j]); } } break ; case TENSOR_DIAG : case TENSOR_SYM : case TENSOR : if(TimeStep == 0){ switch(Type){ case POINT_ELEMENT : Current_L = &TP ; NbTP++ ; break ; case LINE : Current_L = &TL ; NbTL++ ; break ; case TRIANGLE : Current_L = &TT ; NbTT++ ; break ; case QUADRANGLE : Current_L = &TQ ; NbTQ++ ; break ; case TETRAHEDRON : Current_L = &TS1 ; NbTS++ ; break ; case HEXAHEDRON : Current_L = &TH ; NbTH++ ; break ; case PRISM : Current_L = &TI ; NbTI++ ; break ; case PYRAMID : Current_L = &TY ; NbTY++ ; break ; case LINE_2 : Current_L = &TL ; NbTL++ ; break ; case TRIANGLE_2 : Current_L = &TT ; NbTT++ ; break ; case QUADRANGLE_2 : Current_L = &TQ ; NbTQ++ ; break ; case QUADRANGLE_2_8N: Current_L = &TQ ; NbTQ++ ; break ; case TETRAHEDRON_2 : Current_L = &TS1 ; NbTS++ ; break ; case HEXAHEDRON_2 : Current_L = &TH ; NbTH++ ; break ; case HEXAHEDRON_2_20N: Current_L = &TH ; NbTH++ ; break ; case PRISM_2 : Current_L = &TI ; NbTI++ ; break ; case PRISM_2_15N : Current_L = &TI ; NbTI++ ; break ; case PYRAMID_2 : Current_L = &TY ; NbTY++ ; break ; case PYRAMID_2_13N : Current_L = &TY ; NbTY++ ; break ; case LINE_3 : Current_L = &TL ; NbTL++ ; break ; case TRIANGLE_3 : Current_L = &TT ; NbTT++ ; break ; case QUADRANGLE_3 : Current_L = &TQ ; NbTQ++ ; break ; case TETRAHEDRON_3 : Current_L = &TS1 ; NbTS++ ; break ; case HEXAHEDRON_3 : Current_L = &TH ; NbTH++ ; break ; case PRISM_3 : Current_L = &TI ; NbTI++ ; break ; case PYRAMID_3 : Current_L = &TY ; NbTY++ ; break ; case LINE_4 : Current_L = &TL ; NbTL++ ; break ; case TRIANGLE_4 : Current_L = &TT ; NbTT++ ; break ; case QUADRANGLE_4 : Current_L = &TQ ; NbTQ++ ; break ; case TETRAHEDRON_4 : Current_L = &TS1 ; NbTS++ ; break ; case HEXAHEDRON_4 : Current_L = &TH ; NbTH++ ; break ; case PRISM_4 : Current_L = &TI ; NbTI++ ; break ; //case PYRAMID_4 : Current_L = &TY ; NbTY++ ; break ; } if(Flag_GMSH_VERSION != 2){ for(i = 0 ; i < NbrNodes ; i++) Current_L->push_back(x[i]); for(i = 0 ; i < NbrNodes ; i++) Current_L->push_back(y[i]); for(i = 0 ; i < NbrNodes ; i++) Current_L->push_back(z[i]); } else{ double tmp = ElementNum; Current_L->push_back(tmp); } } if (HarmonicToTime == 1) for(k = 0 ; k < NbHarmonic ; k++){ List_Put(TimeValue_L, NbHarmonic*TimeStep+k, &Time); for(i = 0 ; i < NbrNodes ; i++){ for(j = 0 ; j < 9 ; j++){ if(Value[0].Type != TENSOR_DIAG) { if(Value[0].Type == TENSOR_SYM) jj = symIndex[j]; else jj = j; Current_L->push_back(Value[i].Val[MAX_DIM*k+jj]); } else { jj = diagIndex[j]; if(jj == -1) Current_L->push_back(0.); else Current_L->push_back(Value[i].Val[MAX_DIM*k+jj]); } } } } else for(k = 0 ; k < HarmonicToTime ; k++){ List_Put(TimeValue_L, HarmonicToTime*TimeStep+k, &Time); for(i = 0 ; i < NbrNodes ; i++){ F_MHToTime0(k+i, &Value[i], &TmpValue, k, HarmonicToTime, &TimeMH) ; for(j = 0 ; j < 9 ; j++) { if(Value[0].Type != TENSOR_DIAG) { if(Value[0].Type == TENSOR_SYM) jj = symIndex[j]; else jj = j; Current_L->push_back(TmpValue.Val[jj]); } else { jj = diagIndex[j]; if(jj == -1) Current_L->push_back(0.); else Current_L->push_back(TmpValue.Val[jj]); } } } } } // reduce memory requirements by automatically partitioning large // output views into chunks not larger than 1Gb if(Flag_GMSH_VERSION == 2 && TimeStep == NbTimeStep - 1 && Current_L->size() > (int)(1024 * 1024 * 1024 / sizeof(double))){ Format_PostFooter(PSO_P, Store); CurrentPartitionNumber++; Gmsh_StartNewView = 1; } } static void dVecWrite(std::vector &v, FILE *fp, bool binary) { if(v.empty()) return; if(binary) fwrite(&v[0], sizeof(double), v.size(), fp); else for(unsigned i = 0; i < v.size(); i++) fprintf(fp, " %.16g", v[i]); } static void cVecWrite(std::vector &v, FILE *fp, bool binary) { if(v.empty()) return; if(binary) fwrite(&v[0], sizeof(char), v.size(), fp); else for(unsigned i = 0; i < v.size(); i++) fputc(v[i], fp); } /* ------------------------------------------------------------------------ */ /* Gnuplot format */ /* ------------------------------------------------------------------------ */ static void Gnuplot_PrintElement(int Format, double Time, int TimeStep, int NbrTimeSteps, int NbrHarmonics, int HarmonicToTime, int ElementType, int NumElement, int NbrNodes, double *x, double *y, double *z, double *Dummy, struct Value *Value) { static int Size, TmpIndex ; static double * TmpValues ; int i, j, k, t, i2, k2 ; double TimeMH ; struct Value TmpValue ; if(!PostStream) return; if(TimeStep == 0){ switch(Value->Type){ case SCALAR : Size = 1 ; break ; case VECTOR : Size = 3 ; break ; case TENSOR_DIAG : Size = 3 ; break ; case TENSOR_SYM : Size = 6 ; break ; case TENSOR : Size = 9 ; break ; } TmpValues = (double*) Malloc(NbrTimeSteps*NbrNodes*NbrHarmonics*Size*sizeof(double)); TmpIndex = 0; } for(i = 0 ; i < NbrNodes ; i++) for(k = 0 ; k < NbrHarmonics ; k++) for(j = 0 ; j < Size ; j++) TmpValues[TmpIndex++] = Value[i].Val[MAX_DIM*k+j]; if(TimeStep == NbrTimeSteps-1){ for(i = 0 ; i <= NbrNodes ; i++){ /* New line for each node, closed loop for tri/qua */ if(i != NbrNodes) i2 = i ; else{ if(NbrNodes < 3) break ; else i2 = 0 ; } fprintf(PostStream, "%d %d ", GetDP2Gmsh(ElementType), NumElement); fprintf(PostStream, " %.16g %.16g %.16g ", x[i2], y[i2], z[i2]); if(Dummy){ if(Dummy[3]<0){ if(!i) fprintf(PostStream, " %.16g %.16g 0 ", Dummy[0], Dummy[2]); else fprintf(PostStream, " %.16g %.16g 0 ", Dummy[1], Dummy[2]); } else fprintf(PostStream, " %.16g %.16g %.16g ", Dummy[0], Dummy[1], Dummy[2]); } else fprintf(PostStream, " 0 0 0 "); for(t = 0 ; t < NbrTimeSteps ; t++){ if (HarmonicToTime == 1) { for(k = 0 ; k < NbrHarmonics ; k++) { for(j = 0 ; j < Size ; j++){ fprintf(PostStream, " %.16g", TmpValues[ t*NbrNodes*NbrHarmonics*Size + i2*NbrHarmonics*Size + k*Size + j ]); } fprintf(PostStream, " "); } } else { TmpValue.Type = Value->Type ; for(k = 0 ; k < HarmonicToTime ; k++){ for(k2 = 0 ; k2 < NbrHarmonics ; k2++) for(j = 0 ; j < Size ; j++) TmpValue.Val[MAX_DIM*k2+j] = TmpValues[ t*NbrNodes*NbrHarmonics*Size + i2*NbrHarmonics*Size + k2*Size + j ] ; F_MHToTime0(k, &TmpValue, &TmpValue, k, HarmonicToTime, &TimeMH) ; for(j = 0 ; j < Size ; j++) fprintf(PostStream, "%.16g", TmpValue.Val[0]); fprintf(PostStream, " "); } } fprintf(PostStream, " "); } /* for t */ fprintf(PostStream, "\n"); } /* for i */ if(NbrNodes > 1) fprintf(PostStream, "\n"); Free(TmpValues); } } /* ------------------------------------------------------------------------ */ /* Tabular format */ /* ------------------------------------------------------------------------ */ // global static list for tables output static int TableList_StartNew = 0; static std::list TableList; static void Tabular_PrintElement(struct PostSubOperation *PSO_P, int Format, double Time, int TimeStep, int NbrTimeSteps, int NbrHarmonics, int HarmonicToTime, int ElementType, int NumElement, int NbrNodes, double *x, double *y, double *z, double *Dummy, struct Value *Value) { static int Size ; int i,j,k ; double TimeMH ; struct Value TmpValue ; if(TableList_StartNew){ TableList_StartNew = 0 ; TableList.clear(); } if(!PostStream) return; if(TimeStep == 0){ switch(Value->Type){ case SCALAR : Size = 1 ; break ; case VECTOR : Size = 3 ; break ; case TENSOR_DIAG : Size = 3 ; break ; case TENSOR_SYM : Size = 6 ; break ; case TENSOR : Size = 9 ; break ; } } if(Format == FORMAT_SPACE_TABLE || Format == FORMAT_SIMPLE_SPACE_TABLE || Format == FORMAT_VALUE_ONLY){ if(TimeStep == 0){ if(Format != FORMAT_SIMPLE_SPACE_TABLE && Format != FORMAT_VALUE_ONLY){ fprintf(PostStream, "%d %d ", GetDP2Gmsh(ElementType), NumElement); TableList.push_back(GetDP2Gmsh(ElementType)); TableList.push_back(NumElement); } if(Format != FORMAT_VALUE_ONLY) for(i=0 ; iValueName, j, PSO_P->ValueIndex, Value[i].Val[MAX_DIM*k+j]); TableList.push_back(Value[i].Val[MAX_DIM*k+j]); if (j > NodeTable; static void NodeTable_PrintElement(int TimeStep, int NbTimeStep, int NbrHarmonics, struct PostElement *PE) { if(NodeTable_StartNew){ NodeTable_StartNew = 0 ; NodeTable.clear(); } for(int i = 0 ; i < PE->NbrNodes ; i++){ int n = PE->NumNodes[i]; int Size = 0; switch(PE->Value[0].Type){ case SCALAR : Size = 1 ; break ; case VECTOR : Size = 3 ; break ; case TENSOR_DIAG : Size = 3 ; break ; case TENSOR_SYM : Size = 6 ; break ; case TENSOR : Size = 9 ; break ; } if(n > 0 && Size){ // we have data on an actual node NodeTable[n].resize(NbTimeStep * NbrHarmonics * Size, 0.); for(int k = 0 ; k < NbrHarmonics ; k++){ for(int j = 0 ; j < Size ; j++){ double val = PE->Value[i].Val[MAX_DIM * k + j]; int idx = NbrHarmonics * Size * TimeStep + k * Size + j; NodeTable[n][idx] = val; } } } } } /* ------------------------------------------------------------------------ */ /* ElementTable format */ /* ------------------------------------------------------------------------ */ // global static map for element table output (cannot be saved incrementally for // each element) static int ElementTable_StartNew = 0; static std::map > ElementTable; static void ElementTable_PrintElement(int TimeStep, int NbTimeStep, int NbrHarmonics, struct PostElement *PE) { if(ElementTable_StartNew){ ElementTable_StartNew = 0 ; ElementTable.clear(); } int numEle = -1; if(PE->Index >= 0 && PE->Index < Geo_GetNbrGeoElements()){ numEle = Geo_GetGeoElement(PE->Index)->Num; int Size = 0; switch(PE->Value[0].Type){ case SCALAR : Size = 1 ; break ; case VECTOR : Size = 3 ; break ; case TENSOR_DIAG : Size = 3 ; break ; case TENSOR_SYM : Size = 6 ; break ; case TENSOR : Size = 9 ; break ; } if(Size){ ElementTable[numEle].resize (NbTimeStep * PE->NbrNodes * NbrHarmonics * Size, 0.); for(int i = 0 ; i < PE->NbrNodes ; i++){ for(int k = 0 ; k < NbrHarmonics ; k++){ for(int j = 0 ; j < Size ; j++){ double val = PE->Value[i].Val[MAX_DIM * k + j]; int idx = TimeStep * PE->NbrNodes * NbrHarmonics * Size + i * NbrHarmonics * Size + k * Size + j; ElementTable[numEle][idx] = val; } } } } } } /* ------------------------------------------------------------------------ */ /* S t o r e P o s t O p R e s u l t */ /* ------------------------------------------------------------------------ */ static List_T *PostOpResults_L=NULL; static void StorePostOpResult(int NbrHarmonics, struct PostElement *PE) { int Size; double val; if(!PostOpResults_L) PostOpResults_L = List_Create(1000,1000,sizeof(double)); for(int i = 0 ; i < PE->NbrNodes ; i++){ Size = 0; switch(PE->Value[0].Type){ case SCALAR : Size = 1 ; break ; case VECTOR : Size = 3 ; break ; case TENSOR_DIAG : Size = 3 ; break ; case TENSOR_SYM : Size = 6 ; break ; case TENSOR : Size = 9 ; break ; } if(Size){ // we have data for(int k = 0 ; k < NbrHarmonics ; k++){ for(int j = 0 ; j < Size ; j++){ val = PE->Value[i].Val[MAX_DIM * k + j]; List_Add(PostOpResults_L, &val); } } } } } static void StorePostOpResult(int NbrHarmonics, struct Value *Value) { int Size; double val; if(!PostOpResults_L) PostOpResults_L = List_Create(1000,1000,sizeof(double)); Size = 0; switch(Value[0].Type){ case SCALAR : Size = 1 ; break ; case VECTOR : Size = 3 ; break ; case TENSOR_DIAG : Size = 3 ; break ; case TENSOR_SYM : Size = 6 ; break ; case TENSOR : Size = 9 ; break ; } if(Size){ // we have data for(int k = 0 ; k < NbrHarmonics ; k++){ for(int j = 0 ; j < Size ; j++){ val = Value[0].Val[MAX_DIM * k + j]; List_Add(PostOpResults_L, &val); } } } } /* ------------------------------------------------------------------------ */ /* UNV format */ /* ------------------------------------------------------------------------ */ #if !defined(HAVE_NX) #define NX { Message::Error("UNV export not available in this version"); } #else #define NX ; #endif double NXUnv_UnitFactor = 1; int NXUnv_DatasetLocation = 3; //1: Data at nodes, 2: Data on elements, 3: Data at nodes on elements void Unv_PrintHeader(FILE *PostStream, char *name, double Time, int TimeStep, double& NXUnv_UnitFactor, int& NXUnv_DatasetLocation) NX void Unv_PrintFooter(FILE *PostStream) NX void Unv_PrintElement(FILE *PostStream, int Num_Element, int NbrNodes, struct Value *Value, int NbrHarmonics, int& NXUnv_DatasetLocation, double& NXUnv_UnitFactor) NX void Unv_PrintNodeTable(FILE *PostStream, std::map> &NodeTable, double& NXUnv_UnitFactor) NX void Unv_PrintRegion(FILE *PostStream, int Flag_Comma, int numRegion, int NbrHarmonics, int Size, struct Value *Value, double& NXUnv_UnitFactor) NX #undef NX /* ------------------------------------------------------------------------ */ /* F o r m a t _ P o s t F o r m a t */ /* ------------------------------------------------------------------------ */ void Format_PostFormat(struct PostSubOperation *PSO_P) { if(!PostStream || PSO_P->Type == POP_EXPRESSION) return; int Format = PSO_P->Format; int NoMesh = PSO_P->NoMesh; switch(Format){ case FORMAT_GMSH : if((PSO_P->StoreInField >= 0 || PSO_P->StoreInMeshBasedField >= 0) && !PSO_P->FileOut) break; if(Flag_GMSH_VERSION == 2){ fprintf(PostStream, "$MeshFormat\n") ; fprintf(PostStream, "2.2 %d %d\n", Flag_BIN, (int)sizeof(double)) ; if(Flag_BIN){ int one=1; fwrite(&one, sizeof(int), 1, PostStream); fprintf(PostStream, "\n"); } fprintf(PostStream, "$EndMeshFormat\n") ; if(!NoMesh){ std::vector elements; std::set nodes; if(PSO_P->SubType == PRINT_ONELEMENTSOF){ List_T *Region_L = ((struct Group *)List_Pointer(Problem_S.Group, PSO_P->Case.OnRegion.RegionIndex))->InitialList ; for(int i = 0 ; i < Geo_GetNbrGeoElements() ; i++) { Geo_Element *Geo_Element = Geo_GetGeoElement(i) ; if(List_Search(Region_L, &Geo_Element->Region, fcmp_int)){ elements.push_back(Geo_Element); for (int j = 0 ; j < Geo_Element->NbrNodes ; j++) nodes.insert(Geo_Element->NumNodes[j]) ; } } } else{ for(int i = 0 ; i < Geo_GetNbrGeoElements() ; i++) { Geo_Element *Geo_Element = Geo_GetGeoElement(i) ; elements.push_back(Geo_Element); for (int j = 0 ; j < Geo_Element->NbrNodes ; j++) nodes.insert(Geo_Element->NumNodes[j]) ; } } fprintf(PostStream, "$Nodes\n%d\n", (int)nodes.size()); for (int i = 0 ; i < Geo_GetNbrGeoNodes() ; i++) { Geo_Node *Geo_Node = Geo_GetGeoNode(i); if(nodes.find(Geo_Node->Num) != nodes.end()){ if(Flag_BIN){ fwrite(&Geo_Node->Num, sizeof(int), 1, PostStream); double data[3] = {Geo_Node->x, Geo_Node->y, Geo_Node->z}; fwrite(data, sizeof(double), 3, PostStream); } else{ fprintf(PostStream, "%d %.16g %.16g %.16g\n", Geo_Node->Num, Geo_Node->x, Geo_Node->y, Geo_Node->z) ; } } } fprintf(PostStream, "$EndNodes\n$Elements\n%d\n", (int)elements.size()); for (unsigned int i = 0 ; i < elements.size() ; i++) { Geo_Element *Geo_Element = elements[i]; int Type = GetDP2Gmsh(Geo_Element->Type) ; if(Flag_BIN){ int blob[6] = {Type, 1, 2, Geo_Element->Num, Geo_Element->Region, Geo_Element->ElementaryRegion}; fwrite(blob, sizeof(int), 6, PostStream); std::vector verts(Geo_Element->NbrNodes); for (int j = 0 ; j < Geo_Element->NbrNodes ; j++) verts[j] = Geo_Element->NumNodes[j] ; fwrite(&verts[0], sizeof(int), Geo_Element->NbrNodes, PostStream); } else{ fprintf(PostStream, "%d %d 2 %d %d ", Geo_Element->Num, Type, Geo_Element->Region, Geo_Element->ElementaryRegion) ; for (int j = 0 ; j < Geo_Element->NbrNodes ; j++) fprintf(PostStream, "%d ", Geo_Element->NumNodes[j]) ; fprintf(PostStream, "\n") ; } } fprintf(PostStream, "$EndElements\n"); } } else if(PostStream && Flag_BIN){/* bricolage */ fprintf(PostStream, "$PostFormat /* Gmsh 1.2, %s */\n", Flag_BIN ? "binary" : "ascii") ; fprintf(PostStream, "1.2 %d %d\n", Flag_BIN, (int)sizeof(double)) ; fprintf(PostStream, "$EndPostFormat\n") ; } break ; case FORMAT_GNUPLOT : fprintf(PostStream, "# GetDP %s, %s\n", GETDP_VERSION, Flag_BIN ? "binary" : "ascii") ; break ; } } /* ------------------------------------------------------------------------ */ /* F o r m a t _ P o s t H e a d e r */ /* ------------------------------------------------------------------------ */ void Format_PostHeader(struct PostSubOperation *PSO_P, int NbTimeStep, int Order, char *Name1, char *Name2) { int Format = PSO_P->Format; double Time = Current.Time; int TimeStep = Current.TimeStep; int Contour = PSO_P->Iso; int Type = PSO_P->CombinationType; char name[256] ; CurrentPartitionNumber = 0; if(Contour){ if(!PostElement_L) PostElement_L = List_Create(20, 20, sizeof(struct PostElement*)); else List_Reset(PostElement_L); } if(Name1 && Name2) { strcpy(name, Order ? Name1 : Name2) ; strcat(name, Get_StringForDefine(PostSubOperation_CombinationType, Type)) ; strcat(name, Order ? Name2 : Name1) ; } else if(Name1) strcpy(name, Name1) ; else if(Name2) strcpy(name, Name2) ; else strcpy(name, "unnamed"); strcpy(CurrentName, name); switch(Format){ case FORMAT_GMSH_PARSED : if(PostStream) fprintf(PostStream, "View \"%s\" {\n", name) ; Gmsh_StartNewView = 1 ; break ; case FORMAT_GMSH : Gmsh_StartNewView = 1 ; if((PSO_P->StoreInField >= 0 || PSO_P->StoreInMeshBasedField >= 0) && !PSO_P->FileOut) break; if(PostStream && Flag_GMSH_VERSION != 2){ if(Flag_BIN){ /* bricolage */ fprintf(PostStream, "$View /* %s */\n", name); fprintf(PostStream, "%s ", name); } else { fprintf(PostStream, "View \"%s\" {\n", name) ; } } break ; case FORMAT_NXUNV : if(PostStream){ NodeTable_StartNew = 1 ; Unv_PrintHeader(PostStream, name, Time, TimeStep, NXUnv_UnitFactor, NXUnv_DatasetLocation); } break ; case FORMAT_GNUPLOT : if(PostStream){ fprintf(PostStream, "# PostData '%s'\n", name); fprintf(PostStream, "# Type Num X Y Z N1 N2 N3 Values ...\n"); } break ; case FORMAT_NODE_TABLE : NodeTable_StartNew = 1 ; break ; case FORMAT_ELEMENT_TABLE : ElementTable_StartNew = 1 ; break ; case FORMAT_SPACE_TABLE : case FORMAT_TIME_TABLE : case FORMAT_SIMPLE_SPACE_TABLE : case FORMAT_VALUE_ONLY : TableList_StartNew = 1 ; break ; case FORMAT_ADAPT : if(PostStream) fprintf(PostStream, "$Adapt /* %s */\n", name) ; break ; } } /* ------------------------------------------------------------------------ */ /* F o r m a t _ P o s t F o o t e r */ /* ------------------------------------------------------------------------ */ void Format_PostFooter(struct PostSubOperation *PSO_P, int Store, bool SendToServer) { List_T *Iso_L[NBR_MAX_ISO], *Solutions_L; double IsoMin = 1.e200, IsoMax = -1.e200, IsoVal = 0.0, freq, valr, vali ; int NbrIso = 0 ; int iPost, iNode, iIso, iTime, One=1, i, j, NbTimeStep ; char tmp[1024]; bool PostOpSolutionGenerated; struct PostElement *PE ; struct Solution *Solution_P=NULL, Solution_S; if( !(NbTimeStep = List_Nbr(PSO_P->TimeStep_L)) ) NbTimeStep = List_Nbr(Current.DofData->Solutions); if ( (PSO_P->Format == FORMAT_GMSH || PSO_P->Format == FORMAT_GMSH_PARSED) && Flag_GMSH_VERSION != 2 ){ switch(PSO_P->Legend){ case LEGEND_TIME: Gmsh_StringStart(PSO_P->Format, PSO_P->LegendPosition[0], PSO_P->LegendPosition[1], PSO_P->LegendPosition[2]); for (i = 0 ; i < NbTimeStep ; i++) { Pos_InitAllSolutions(PSO_P->TimeStep_L, i) ; valr = Current.DofData->CurrentSolution->Time ; for (j = 0 ; j < Current.NbrHar ; j++){ sprintf(tmp, "Step %d/%d: Time = %g", i+1, NbTimeStep, valr); Gmsh_StringAdd(PSO_P->Format, (!i && !j), tmp); } } Gmsh_StringEnd(PSO_P->Format); break; case LEGEND_FREQUENCY: if(Current.NbrHar > 1) { Gmsh_StringStart(PSO_P->Format, PSO_P->LegendPosition[0], PSO_P->LegendPosition[1], PSO_P->LegendPosition[2]); for (i = 0 ; i < NbTimeStep ; i++) { Pos_InitAllSolutions(PSO_P->TimeStep_L, i) ; for (j = 0 ; j < Current.NbrHar ; j+=2) { freq = 0.5*Current.DofData->Val_Pulsation[j/2]/M_PI ; sprintf(tmp, "%g Hz (real part: COSINUS)", freq); Gmsh_StringAdd(PSO_P->Format, (!i && !j), tmp); sprintf(tmp, "%g Hz (imag part: -SINUS)", freq); Gmsh_StringAdd(PSO_P->Format, 0, tmp); } } Gmsh_StringEnd(PSO_P->Format); } break; case LEGEND_EIGENVALUES: Gmsh_StringStart(PSO_P->Format, PSO_P->LegendPosition[0], PSO_P->LegendPosition[1], PSO_P->LegendPosition[2]); for (i = 0 ; i < NbTimeStep ; i++) { Pos_InitAllSolutions(PSO_P->TimeStep_L, i) ; valr = Current.DofData->CurrentSolution->Time ; vali = Current.DofData->CurrentSolution->TimeImag ; if(Current.NbrHar == 1){ sprintf(tmp, "Eigenvalue %d/%d: %g", i+1, NbTimeStep, valr); Gmsh_StringAdd(PSO_P->Format, !i, tmp); } else{ for (j = 0 ; j < Current.NbrHar ; j++) { if(!(j % 2)){ sprintf(tmp, "Eigenvalue %d/%d: %g %s i * %g (Real Part)", i+1, NbTimeStep, valr, (vali > 0) ? "+" : "-", (vali > 0) ? vali : -vali); Gmsh_StringAdd(PSO_P->Format, (!i && !j), tmp); } else{ sprintf(tmp, "Eigenvalue %d/%d: %g %s i * %g (Imaginary Part)", i+1, NbTimeStep, valr, (vali > 0) ? "+" : "-", (vali > 0) ? vali : -vali); Gmsh_StringAdd(PSO_P->Format, 0, tmp); } } } } Gmsh_StringEnd(PSO_P->Format); break; } } if(PSO_P->Iso){ for(iPost = 0 ; iPost < List_Nbr(PostElement_L) ; iPost++){ PE = *(struct PostElement**)List_Pointer(PostElement_L, iPost); for (iNode = 0 ; iNode < PE->NbrNodes ; iNode++ ){ IsoMin = std::min(IsoMin, PE->Value[iNode].Val[0]) ; IsoMax = std::max(IsoMax, PE->Value[iNode].Val[0]) ; } } if((NbrIso = PSO_P->Iso) < 0) NbrIso = List_Nbr(PSO_P->Iso_L) ; if(NbrIso > NBR_MAX_ISO){ Message::Error("Too many Iso values"); NbrIso = NBR_MAX_ISO; } if(PostStream && PSO_P->Format == FORMAT_GNUPLOT) fprintf(PostStream, "# NbIso = %d, Min = %g, Max = %g\n", NbrIso, IsoMin, IsoMax) ; for(iIso = 0 ; iIso < NbrIso ; iIso++) Iso_L[iIso] = List_Create(10, 10, sizeof(struct PostElement*)) ; for(iPost = 0 ; iPost < List_Nbr(PostElement_L) ; iPost++){ PE = *(struct PostElement**)List_Pointer(PostElement_L, iPost); for(iIso = 0 ; iIso < NbrIso ; iIso++){ if(PSO_P->Iso > 0){ Cal_Iso(PE, Iso_L[iIso], IsoMin+iIso*(IsoMax-IsoMin)/(double)(NbrIso-1), IsoMin, IsoMax, PSO_P->DecomposeInSimplex) ; } else{ List_Read(PSO_P->Iso_L, iIso, &IsoVal) ; Cal_Iso(PE, Iso_L[iIso], IsoVal, IsoMin, IsoMax, PSO_P->DecomposeInSimplex) ; } } if(!Store) Destroy_PostElement(PE); } for(iIso = 0 ; iIso < NbrIso ; iIso++){ for(iPost = 0 ; iPost < List_Nbr(Iso_L[iIso]) ; iPost++){ PE = *(struct PostElement**)List_Pointer(Iso_L[iIso], iPost) ; Format_PostElement(PSO_P, 0, 0, Current.Time, 0, 1, Current.NbrHar, PSO_P->HarmonicToTime, NULL, PE); Destroy_PostElement(PE) ; } List_Delete(Iso_L[iIso]) ; if(PostStream && PSO_P->Format == FORMAT_GNUPLOT) fprintf(PostStream, "\n") ; } } switch(PSO_P->Format){ case FORMAT_GMSH_PARSED : if(PostStream && List_Nbr(TimeValue_L) > 1){ fprintf(PostStream, "TIME{"); for(iTime = 0; iTime < List_Nbr(TimeValue_L); iTime++){ if(iTime) fprintf(PostStream, ","); fprintf(PostStream, "%.16g", *(double*)List_Pointer(TimeValue_L, iTime)); } fprintf(PostStream, "};\n"); } fprintf(PostStream, "};\n") ; break ; case FORMAT_GMSH : if(Gmsh_StartNewView) Gmsh_ResetStaticLists(); // nothing to print! if(PSO_P->StoreInField >= 0 || PSO_P->StoreInMeshBasedField >= 0){ #if defined(HAVE_GMSH) int field = (PSO_P->StoreInField >= 0) ? PSO_P->StoreInField : PSO_P->StoreInMeshBasedField; Message::Info("Storing data in field %d (%s)", field, PSO_P->StoreInField >= 0 ? "list-based" : "mesh-based"); int NS[24] = {NbSP, NbVP, NbTP, NbSL, NbVL, NbTL, NbST, NbVT, NbTT, NbSQ, NbVQ, NbTQ, NbSS, NbVS, NbTS, NbSH, NbVH, NbTH, NbSI, NbVI, NbTI, NbSY, NbVY, NbTY}; std::vector *LS[24] = {&SP, &VP, &TP, &SL, &VL, &TL, &ST, &VT, &TT, &SQ, &VQ, &TQ, &SS, &VS, &TS1, &SH, &VH, &TH, &SI, &VI, &TI, &SY, &VY, &TY}; PViewData *data; if(PSO_P->StoreInField >= 0) data = new PViewDataList(); else data = new PViewDataGModel(PViewDataGModel::ElementNodeData); data->importLists(NS, LS); new PView(data, field); #else Message::Error("GetDP must be compiled with Gmsh support to store data as field"); #endif if(!PSO_P->FileOut) break; } if(Flag_GMSH_VERSION == 2){ int NS[8] = {NbSP, NbSL, NbST, NbSQ, NbSS, NbSH, NbSI, NbSY}; std::vector *LS[8] = {&SP, &SL, &ST, &SQ, &SS, &SH, &SI, &SY}; Gmsh_PrintElementNodeData(PSO_P, NbTimeStep, 1, NS, LS); int NV[8] = {NbVP, NbVL, NbVT, NbVQ, NbVS, NbVH, NbVI, NbVY}; std::vector *LV[8] = {&VP, &VL, &VT, &VQ, &VS, &VH, &VI, &VY}; Gmsh_PrintElementNodeData(PSO_P, NbTimeStep, 3, NV, LV); int NT[8] = {NbTP, NbTL, NbTT, NbTQ, NbTS, NbTH, NbTI, NbTY}; std::vector *LT[8] = {&TP, &TL, &TT, &TQ, &TS1, &TH, &TI, &TY}; Gmsh_PrintElementNodeData(PSO_P, NbTimeStep, 9, NT, LT); } else if(PostStream && Flag_BIN){ /* bricolage */ fprintf(PostStream, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d " "%d %d %d %d %d %d %d %d %d %d %d 0 0\n", List_Nbr(TimeValue_L), NbSP, NbVP, NbTP, NbSL, NbVL, NbTL, NbST, NbVT, NbTT, NbSQ, NbVQ, NbTQ, NbSS, NbVS, NbTS, NbSH, NbVH, NbTH, NbSI, NbVI, NbTI, NbSY, NbVY, NbTY, NbT2, (int)T2C.size()); fwrite(&One, sizeof(int), 1, PostStream); List_WriteToFile(TimeValue_L, PostStream, LIST_FORMAT_BINARY); bool f = true; dVecWrite(SP, PostStream, f); dVecWrite(VP, PostStream, f); dVecWrite(TP, PostStream, f); dVecWrite(SL, PostStream, f); dVecWrite(VL, PostStream, f); dVecWrite(TL, PostStream, f); dVecWrite(ST, PostStream, f); dVecWrite(VT, PostStream, f); dVecWrite(TT, PostStream, f); dVecWrite(SQ, PostStream, f); dVecWrite(VQ, PostStream, f); dVecWrite(TQ, PostStream, f); dVecWrite(SS, PostStream, f); dVecWrite(VS, PostStream, f); dVecWrite(TS1, PostStream, f); dVecWrite(SH, PostStream, f); dVecWrite(VH, PostStream, f); dVecWrite(TH, PostStream, f); dVecWrite(SI, PostStream, f); dVecWrite(VI, PostStream, f); dVecWrite(TI, PostStream, f); dVecWrite(SY, PostStream, f); dVecWrite(VY, PostStream, f); dVecWrite(TY, PostStream, f); dVecWrite(T2D, PostStream, f); cVecWrite(T2C, PostStream, f); fprintf(PostStream, "\n"); fprintf(PostStream, "$EndView\n"); } else if(PostStream){ if(List_Nbr(TimeValue_L) > 1){ fprintf(PostStream, "TIME{"); for(iTime = 0; iTime < List_Nbr(TimeValue_L); iTime++){ if(iTime) fprintf(PostStream, ","); fprintf(PostStream, "%.16g", *(double*)List_Pointer(TimeValue_L, iTime)); } fprintf(PostStream, "};\n"); } fprintf(PostStream, "};\n") ; } break ; case FORMAT_ADAPT : if(PostStream) fprintf(PostStream, "$EndAdapt\n"); break ; case FORMAT_NXUNV : if(PostStream){ if(NXUnv_DatasetLocation == 1) //Data at nodes Unv_PrintNodeTable(PostStream, NodeTable, NXUnv_UnitFactor); Unv_PrintFooter(PostStream); } break ; case FORMAT_NODE_TABLE : if(PostStream && NodeTable.size()){ fprintf(PostStream, "%d\n", (int)NodeTable.size()); for(std::map >::iterator it = NodeTable.begin(); it != NodeTable.end(); it++){ fprintf(PostStream, "%d", it->first); for(unsigned int i = 0; i < it->second.size(); i++) fprintf(PostStream, " %.16g", it->second[i]); fprintf(PostStream, "\n"); } } { std::vector exp; exp.push_back(NodeTable.size()); for(std::map >::iterator it = NodeTable.begin(); it != NodeTable.end(); it++){ exp.push_back(it->first); for(unsigned int i = 0; i < it->second.size(); i++) exp.push_back(it->second[i]); } GetDPNumbers[CurrentName] = exp; GetDPNumbersMap[CurrentName] = NodeTable; if(SendToServer && PSO_P->SendToServer && strcmp(PSO_P->SendToServer, "No")) Message::AddOnelabNumberChoice(PSO_P->SendToServer, exp, PSO_P->Color, PSO_P->Units, PSO_P->Label, PSO_P->Visible, PSO_P->Closed); } break; case FORMAT_ELEMENT_TABLE : if(PostStream){ fprintf(PostStream, "%d\n", (int)ElementTable.size()); for(std::map >::iterator it = ElementTable.begin(); it != ElementTable.end(); it++){ fprintf(PostStream, "%d", it->first); for(unsigned int i = 0; i < it->second.size(); i++) fprintf(PostStream, " %.16g", it->second[i]); fprintf(PostStream, "\n"); } } { std::vector exp; exp.push_back(ElementTable.size()); for(std::map >::iterator it = ElementTable.begin(); it != ElementTable.end(); it++){ exp.push_back(it->first); for(unsigned int i = 0; i < it->second.size(); i++) exp.push_back(it->second[i]); } GetDPNumbers[CurrentName] = exp; GetDPNumbersMap[CurrentName] = ElementTable; if(SendToServer && PSO_P->SendToServer && strcmp(PSO_P->SendToServer, "No")) Message::AddOnelabNumberChoice(PSO_P->SendToServer, exp, PSO_P->Color, PSO_P->Units, PSO_P->Label, PSO_P->Visible, PSO_P->Closed); } break; case FORMAT_SPACE_TABLE : case FORMAT_TIME_TABLE : case FORMAT_SIMPLE_SPACE_TABLE : case FORMAT_VALUE_ONLY : { if(TableList.size()) { std::vector v(TableList.begin(), TableList.end()); GetDPNumbers[CurrentName] = v; if(SendToServer && PSO_P->SendToServer && strcmp(PSO_P->SendToServer, "No")) Message::AddOnelabNumberChoice(PSO_P->SendToServer, v, PSO_P->Color, PSO_P->Units, PSO_P->Label, PSO_P->Visible, PSO_P->Closed); } } break; case FORMAT_LOOP_ERROR : Solutions_L = ((struct PostOpSolutions*) List_Pointer(Current.PostOpData_L, Current.PostOpDataIndex))->Solutions_L; PostOpSolutionGenerated = false; if(List_Nbr(Solutions_L)>0) { Solution_P = (struct Solution*)List_Pointer(Solutions_L, List_Nbr(Solutions_L)-1); PostOpSolutionGenerated = (Solution_P->TimeStep == (int)Current.TimeStep); } if (!PostOpSolutionGenerated) { Solution_S.Time = Current.Time; Solution_S.TimeImag = Current.TimeImag; Solution_S.TimeStep = Current.TimeStep; Solution_S.SolutionExist = 1; Solution_S.TimeFunctionValues = NULL; LinAlg_CreateVector(&Solution_S.x, &Current.DofData->Solver, List_Nbr(PostOpResults_L)); for(int i=0; ix, i); } List_Delete(PostOpResults_L); PostOpResults_L = NULL; break; } } /* ------------------------------------------------------------------------ */ /* F o r m a t _ P o s t E l e m e n t */ /* ------------------------------------------------------------------------ */ void Format_PostElement(struct PostSubOperation *PSO_P, int Contour, int Store, double Time, int TimeStep, int NbTimeStep, int NbrHarmonics, int HarmonicToTime, double *Dummy, struct PostElement * PE) { int i, j, k, l, Num_Element ; struct PostElement * PE2 ; struct Value Value ; static int Warning_FirstHarmonic = 0 ; /* TODO static int Size = 0 ; int flag_storeAllTimeResults, indexInTmpValues; static struct Value TmpValue, *TmpValues ; static double *Times ; struct Value *FourierValues; flag_storeAllTimeResults = PSO_P->TimeToHarmonic ; indexInTmpValues = flag_storeAllTimeResults? iTime * NbrRegion : 0 ; if(1){ switch(PE->Value[0].Type){ case SCALAR : Size = 1 ; break ; case VECTOR : Size = 3 ; break ; case TENSOR_DIAG : Size = 3 ; break ; case TENSOR_SYM : Size = 6 ; break ; case TENSOR : Size = 9 ; break ; default : Size = 9 ; break ; } } */ if(PE->Index != NO_ELEMENT) Num_Element = Geo_GetGeoElement(PE->Index)->Num ; else Num_Element = 0 ; if(Contour){ if(PE->Value[0].Type != SCALAR){ Message::Error("Non scalar Element %d in contour creation", Num_Element); return; } if(NbTimeStep != 1){ Message::Error("Contour creation not allowed for multiple time steps"); return; } if(Current.NbrHar != 1 && !Warning_FirstHarmonic){ Message::Warning("Contour creation done only for first harmonic (use Re[] or Im[])"); Warning_FirstHarmonic = 1 ; } if(Store) List_Add(PostElement_L, &PE) ; else{ PE2 = PartialCopy_PostElement(PE) ; List_Add(PostElement_L, &PE2) ; } return ; } if(PSO_P->ChangeOfCoordinates[0] >= 0){ for(i=0 ; iNbrNodes ; i++){ Current.x = PE->x[i]; Current.y = PE->y[i]; Current.z = PE->z[i]; for(j = 0; j<9 ; j++) Current.Val[j] = PE->Value[i].Val[j]; Get_ValueOfExpressionByIndex(PSO_P->ChangeOfCoordinates[0], NULL, 0., 0., 0., &Value) ; PE->x[i] = Value.Val[0]; Get_ValueOfExpressionByIndex(PSO_P->ChangeOfCoordinates[1], NULL, 0., 0., 0., &Value) ; PE->y[i] = Value.Val[0]; Get_ValueOfExpressionByIndex(PSO_P->ChangeOfCoordinates[2], NULL, 0., 0., 0., &Value) ; PE->z[i] = Value.Val[0]; } } if(PSO_P->ChangeOfValues && List_Nbr(PSO_P->ChangeOfValues) > 0){ for(i=0 ; i < PE->NbrNodes ; i++){ Current.x = PE->x[i]; Current.y = PE->y[i]; Current.z = PE->z[i]; for(k=0 ; kValue[i].Val[MAX_DIM*k+j]; for(l=0 ; lChangeOfValues) ; l++){ Get_ValueOfExpressionByIndex(*(int*)List_Pointer(PSO_P->ChangeOfValues, l), NULL, 0., 0., 0., &Value) ; PE->Value[i].Val[MAX_DIM*k+l] = Value.Val[0]; } } } } switch(PSO_P->Format){ case FORMAT_GMSH_PARSED : GmshParsed_PrintElement(Time, TimeStep, NbTimeStep, NbrHarmonics, HarmonicToTime, PE->Type, PE->NbrNodes, PE->x, PE->y, PE->z, PE->Value) ; break ; case FORMAT_NXUNV : if(PostStream){ if(NXUnv_DatasetLocation == 1) //Data at nodes NodeTable_PrintElement(TimeStep, NbTimeStep, NbrHarmonics, PE); else if(NXUnv_DatasetLocation == 2 || NXUnv_DatasetLocation == 3) //Data at elements or nodes on elements Unv_PrintElement(PostStream, Num_Element, PE->NbrNodes, PE->Value, NbrHarmonics, NXUnv_DatasetLocation, NXUnv_UnitFactor) ; } break ; case FORMAT_GMSH : if(PSO_P->StoreInField >= 0 || PSO_P->StoreInMeshBasedField >= 0){ Gmsh_PrintElement(Time, TimeStep, NbTimeStep, NbrHarmonics, HarmonicToTime, PE->Type, Num_Element, PE->NbrNodes, PE->x, PE->y, PE->z, PE->Value, PSO_P, Store) ; if(!PSO_P->FileOut || Flag_GMSH_VERSION == 2 || Flag_BIN) break; } if(Flag_GMSH_VERSION == 2 || Flag_BIN){ /* bricolage */ Gmsh_PrintElement(Time, TimeStep, NbTimeStep, NbrHarmonics, HarmonicToTime, PE->Type, Num_Element, PE->NbrNodes, PE->x, PE->y, PE->z, PE->Value, PSO_P, Store) ; } else{ GmshParsed_PrintElement(Time, TimeStep, NbTimeStep, NbrHarmonics, HarmonicToTime, PE->Type, PE->NbrNodes, PE->x, PE->y, PE->z, PE->Value) ; } break ; case FORMAT_GNUPLOT : Gnuplot_PrintElement(PSO_P->Format, Time, TimeStep, NbTimeStep, NbrHarmonics, HarmonicToTime, PE->Type, Num_Element, PE->NbrNodes, PE->x, PE->y, PE->z, Dummy, PE->Value) ; break ; case FORMAT_SPACE_TABLE : case FORMAT_TIME_TABLE : case FORMAT_SIMPLE_SPACE_TABLE : case FORMAT_VALUE_ONLY : Tabular_PrintElement(PSO_P, PSO_P->Format, Time, TimeStep, NbTimeStep, NbrHarmonics, HarmonicToTime, PE->Type, Num_Element, PE->NbrNodes, PE->x, PE->y, PE->z, Dummy, PE->Value) ; break ; case FORMAT_NODE_TABLE : NodeTable_PrintElement(TimeStep, NbTimeStep, NbrHarmonics, PE); break; case FORMAT_ELEMENT_TABLE : ElementTable_PrintElement(TimeStep, NbTimeStep, NbrHarmonics, PE); break; case FORMAT_LOOP_ERROR : StorePostOpResult(NbrHarmonics, PE); break; case FORMAT_ADAPT: if(PostStream){ if(Dummy[4]) fprintf(PostStream, "%d\n", (int)Dummy[4]) ; fprintf(PostStream, "%d %g %g %g\n", (int)Dummy[0], Dummy[1], Dummy[2], Dummy[3]); } break ; default : Message::Error("Unknown format in Format_PostElement"); } if (PE->NbrNodes == 1 && PSO_P->Format != FORMAT_NODE_TABLE && PSO_P->Format != FORMAT_ELEMENT_TABLE){ if(PSO_P->SendToServer && strcmp(PSO_P->SendToServer, "No")){ std::vector v; Export_Value(&PE->Value[0], v, PSO_P->SendToServerList); Message::AddOnelabNumberChoice(PSO_P->SendToServer, v, PSO_P->Color, PSO_P->Units, PSO_P->Label, PSO_P->Visible, PSO_P->Closed); } } } /* ------------------------------------------------------------------------ */ /* F o r m a t _ P o s t V a l u e */ /* ------------------------------------------------------------------------ */ void Format_PostValue(struct PostQuantity *PQ_P, struct PostSubOperation *PSO_P, int Format, char *Comma, int Group_FunctionType, int iTime, double Time, int NbrTimeStep, int iRegion, int numRegion, int NbrRegion, int NbrHarmonics, int HarmonicToTime, int FourierTransform, int Flag_NoNewLine, struct Value * Value) { static int Size ; int j, k ; double TimeMH, Freq ; double x, y, z ; int flag_storeAllTimeResults, indexInTmpValues ; static struct Value TmpValue, *TmpValues ; static double *Times ; flag_storeAllTimeResults = FourierTransform || PSO_P->TimeToHarmonic ; indexInTmpValues = flag_storeAllTimeResults? iTime * NbrRegion : 0 ; if(iRegion == 0){ switch(Value->Type){ case SCALAR : Size = 1 ; break ; case VECTOR : Size = 3 ; break ; case TENSOR_DIAG : Size = 3 ; break ; case TENSOR_SYM : Size = 6 ; break ; case TENSOR : Size = 9 ; break ; } } if (Format == FORMAT_REGION_TABLE) { if(iRegion == 0){ if(PostStream == stdout || PostStream == stderr) { Message::Direct("%d%s", NbrRegion, Comma ? Comma : ""); } else if(PostStream) { fprintf(PostStream, "%d%s\n", NbrRegion, Comma ? Comma : "") ; } } std::ostringstream sstream; sstream.precision(16); sstream << numRegion; for (k = 0 ; k < NbrHarmonics ; k++) { for(j = 0 ; j < Size ; j++) { sstream << " " << Value->Val[MAX_DIM*k+j] ; if (Comma) sstream << Comma; } } if(PostStream == stdout || PostStream == stderr) Message::Direct(sstream.str().c_str()); else if(PostStream) fprintf(PostStream, "%s\n", sstream.str().c_str()) ; } else if (Format == FORMAT_GETDP) { std::ostringstream sstream; sstream.precision(16); sstream << (PSO_P->ValueName? PSO_P->ValueName : PQ_P->Name); if (numRegion != NO_REGION) sstream << "~{" << numRegion << "}"; if (NbrHarmonics >= 2 || Size > 1) sstream << "() = {"; else sstream << " ="; for (k = 0 ; k < NbrHarmonics ; k++) { for(j = 0 ; j < Size ; j++) { if (k || j) sstream << ","; sstream << " " << Value->Val[MAX_DIM*k+j] ; } } if (NbrHarmonics >= 2 || Size > 1) sstream << " };"; if(PostStream == stdout || PostStream == stderr) Message::Direct(sstream.str().c_str()); else if(PostStream) fprintf(PostStream, "%s\n", sstream.str().c_str()) ; } else if (Format == FORMAT_GMSH && Flag_GMSH_VERSION != 2) { if (Group_FunctionType == NODESOF) Geo_GetNodesCoordinates(1, &numRegion, &x, &y, &z) ; else { x = y = z = 0.; Message::Warning("Post Format \'Gmsh\' not adapted for global quantities supported" " by Regions. Zero coordinates are considered.") ; } GmshParsed_PrintElement(Time, 0, 1, NbrHarmonics, HarmonicToTime, POINT_ELEMENT, 1, &x, &y, &z, Value) ; } else if (Format == FORMAT_NXUNV) { if(PostStream) Unv_PrintRegion(PostStream, Comma ? 1 : 0, numRegion, NbrHarmonics, Size, Value, NXUnv_UnitFactor); } else if (Format == FORMAT_LOOP_ERROR) { StorePostOpResult(NbrHarmonics, Value); } else if (Format == FORMAT_NODE_TABLE) { // FIXME: this leads to output files without the total number of nodes at // the beginning (i.e. not compatible with NodeTable obtained e.g. for // OnElementsOf) fprintf(PostStream, "%d", numRegion) ; Geo_GetNodesCoordinates(1, &numRegion, &x, &y, &z) ; fprintf(PostStream, " %.16g %.16g %.16g", x,y,z) ; for (k = 0 ; k < NbrHarmonics ; k++) { for(j = 0 ; j < Size ; j++) { fprintf(PostStream, " %.16g", Value->Val[MAX_DIM*k+j]) ; } } fprintf(PostStream, "\n") ; } // else, for other FORMATs, e.g., FORMAT_FREQUENCY_TABLE else { if(iRegion == 0){ if (!flag_storeAllTimeResults) TmpValues = (struct Value*) Malloc(NbrRegion*sizeof(struct Value)) ; else{ if (iTime == 0){ TmpValues = (struct Value*) Malloc(NbrTimeStep*NbrRegion*sizeof(struct Value)) ; Times = (double*) Malloc(NbrTimeStep*sizeof(double)) ; } Times[iTime] = Time ; } } Cal_CopyValue(Value, &TmpValues[indexInTmpValues+iRegion]) ; if (!flag_storeAllTimeResults && iRegion == NbrRegion-1) { if (PostStream && HarmonicToTime == 1) { switch (Format) { case FORMAT_FREQUENCY_TABLE : case FORMAT_FREQUENCY_REGION_VALUE : if (NbrHarmonics == 1){ Message::Error("FrequencyTable format not allowed (only one harmonic)") ; return; } break ; case FORMAT_VALUE_ONLY : break; default : fprintf(PostStream, " %.16g", Time) ; if (Comma) fprintf(PostStream, "%s", Comma); break ; } for (iRegion = 0 ; iRegion < NbrRegion ; iRegion++) { for (k = 0 ; k < NbrHarmonics ; k++) { if ((Format == FORMAT_FREQUENCY_TABLE || Format == FORMAT_FREQUENCY_REGION_VALUE) && !(k % 2) && iRegion == 0) { Freq = Current.DofData->Val_Pulsation[0] / TWO_PI ; fprintf(PostStream, " %.16g", Freq) ; if (Comma) fprintf(PostStream, "%s", Comma); } for(j = 0 ; j < Size ; j++) { if (Format != FORMAT_REGION_VALUE && Format != FORMAT_FREQUENCY_REGION_VALUE) { fprintf(PostStream, " %.16g", TmpValues[indexInTmpValues+iRegion].Val[MAX_DIM*k+j]) ; if (Comma) fprintf(PostStream, "%s", Comma); } } } } if (Flag_NoNewLine || Format == FORMAT_REGION_VALUE || Format == FORMAT_FREQUENCY_REGION_VALUE) fprintf(PostStream, " ") ; else fprintf(PostStream, "\n") ; } else if(PostStream){ for(k = 0 ; k < HarmonicToTime ; k++) { for (iRegion = 0 ; iRegion < NbrRegion ; iRegion++) { F_MHToTime0(k+iRegion, &TmpValues[indexInTmpValues+iRegion], &TmpValue, k, HarmonicToTime, &TimeMH) ; if (iRegion == 0) { fprintf(PostStream, " %.16g", TimeMH) ; if (Comma) fprintf(PostStream, "%s", Comma); } for(j = 0 ; j < Size ; j++) { fprintf(PostStream, " %.16g", TmpValue.Val[j]) ; if (Comma) fprintf(PostStream, "%s", Comma); } } fprintf(PostStream, "\n") ; } } if (flag_storeAllTimeResults) Free(Times) ; Free(TmpValues) ; } else if (flag_storeAllTimeResults && iTime == NbrTimeStep-1 && iRegion == NbrRegion-1) { Pos_FourierTransform(NbrTimeStep, NbrRegion, Times, TmpValues, Size, 1, PSO_P->TimeToHarmonic, NULL, NULL, NULL); Free(Times); Free(TmpValues) ; } } } /* ------------------------------------------------------------------------ */ /* P o s _ F o u r i e r T r a n s f o r m */ /* ------------------------------------------------------------------------ */ void Pos_FourierTransform(int NbrTimeStep, int NbrRegion, double *Times, struct Value *TmpValues, int Size, int TypeOutput, int Nb_Freq_Select_0, int *NbrFreq, double **Frequencies, struct Value **OutValues) { #if NEW_CODE *NbrFreq = (NbrTimeStep-1)/2+1; *Frequencies = (double *)Malloc(*NbrFreq*sizeof(double)); *OutValues = (struct Value *)Malloc(*NbrFreq*sizeof(struct Value)); int nfft = *NbrFreq; kissfft fft(nfft, false); std::vector > inbuf(nfft); std::vector > outbuf(nfft); for (int k = 0; k < nfft; ++k) inbuf[k]= std::complex(rand()/(double)RAND_MAX - .5, rand()/(double)RAND_MAX - .5); fft.transform(&inbuf[0], &outbuf[0]); #else int iTime, iRegion, k_fc, i_k, j, k; int N, Nhalf, NbrFourierComps; double *val_FourierComps; double val, val_r, val_i, norm, Period, w, v_cos, v_sin; N = NbrTimeStep-1; Nhalf = N/2; // Nhalf = 2; NbrFourierComps = Nhalf*2; Period = Times[NbrTimeStep-1] - Times[0]; w = TWO_PI/Period; val_FourierComps = (double*) Malloc(NbrFourierComps*MAX_DIM*2*sizeof(double)) ; for (k_fc=-Nhalf; k_fc0)? Nb_Freq_Select_0 : Nhalf-1; // Limited to cosine transform now if (TypeOutput == 2){ *NbrFreq = Nhalf+1; *Frequencies = (double *)Malloc(*NbrFreq*sizeof(double)); *OutValues = (struct Value *)Malloc(*NbrFreq*sizeof(struct Value)); } // for (k_fc=-Nhalf; k_fc