F_Geometry.cpp (getdp-3.4.0-source.tgz) | : | F_Geometry.cpp (getdp-3.5.0-source.tgz) | ||
---|---|---|---|---|
// GetDP - Copyright (C) 1997-2021 P. Dular and C. Geuzaine, University of Liege | // GetDP - Copyright (C) 1997-2022 P. Dular and C. Geuzaine, University of Liege | |||
// | // | |||
// See the LICENSE.txt file for license information. Please report all | // See the LICENSE.txt file for license information. Please report all | |||
// issues on https://gitlab.onelab.info/getdp/getdp/issues. | // issues on https://gitlab.onelab.info/getdp/getdp/issues. | |||
#include <math.h> | #include <math.h> | |||
#include "GetDPConfig.h" | #include "GetDPConfig.h" | |||
#include "ProData.h" | #include "ProData.h" | |||
#include "ProDefine.h" | #include "ProDefine.h" | |||
#include "F.h" | #include "F.h" | |||
#include "NumericUtils.h" | #include "NumericUtils.h" | |||
#include "MallocUtils.h" | #include "MallocUtils.h" | |||
#include "Message.h" | #include "Message.h" | |||
#if defined(HAVE_KERNEL) | #if defined(HAVE_KERNEL) | |||
#include "GeoData.h" | #include "GeoData.h" | |||
#include "DofData.h" | #include "DofData.h" | |||
#include "Get_Geometry.h" | #include "Get_Geometry.h" | |||
#endif | #endif | |||
#define SQU(a) ((a)*(a)) | #define SQU(a) ((a) * (a)) | |||
extern struct CurrentData Current ; | extern struct CurrentData Current; | |||
void F_Normal(F_ARG) | void F_Normal(F_ARG) | |||
{ | { | |||
#if !defined(HAVE_KERNEL) | #if !defined(HAVE_KERNEL) | |||
Message::Error("F_Normal requires Kernel"); | Message::Error("F_Normal requires Kernel"); | |||
#else | #else | |||
int k ; | int k; | |||
if(!Current.Element || Current.Element->Num == NO_ELEMENT) | if(!Current.Element || Current.Element->Num == NO_ELEMENT) | |||
Message::Error("No element on which to compute 'F_Normal'"); | Message::Error("No element on which to compute 'F_Normal'"); | |||
Geo_CreateNormal(Current.Element->Type, | Geo_CreateNormal(Current.Element->Type, Current.Element->x, | |||
Current.Element->x, | Current.Element->y, Current.Element->z, V->Val); | |||
Current.Element->y, | ||||
Current.Element->z, | if(Current.NbrHar != 1) { | |||
V->Val); | V->Val[MAX_DIM] = 0.; | |||
V->Val[MAX_DIM + 1] = 0.; | ||||
if (Current.NbrHar != 1) { | V->Val[MAX_DIM + 2] = 0.; | |||
V->Val[MAX_DIM] = 0. ; | for(k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | |||
V->Val[MAX_DIM+1] = 0. ; | V->Val[MAX_DIM * k] = V->Val[0]; | |||
V->Val[MAX_DIM+2] = 0. ; | V->Val[MAX_DIM * k + 1] = V->Val[1]; | |||
for (k = 2 ; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar) ; k += 2) { | V->Val[MAX_DIM * k + 2] = V->Val[2]; | |||
V->Val[MAX_DIM* k ] = V->Val[0] ; | V->Val[MAX_DIM * (k + 1)] = 0.; | |||
V->Val[MAX_DIM* k +1] = V->Val[1] ; | V->Val[MAX_DIM * (k + 1) + 1] = 0.; | |||
V->Val[MAX_DIM* k +2] = V->Val[2] ; | V->Val[MAX_DIM * (k + 1) + 2] = 0.; | |||
V->Val[MAX_DIM*(k+1) ] = 0. ; | ||||
V->Val[MAX_DIM*(k+1)+1] = 0. ; | ||||
V->Val[MAX_DIM*(k+1)+2] = 0. ; | ||||
} | } | |||
} | } | |||
V->Type = VECTOR ; | V->Type = VECTOR; | |||
#endif | #endif | |||
} | } | |||
void F_NormalSource(F_ARG) | void F_NormalSource(F_ARG) | |||
{ | { | |||
#if !defined(HAVE_KERNEL) | #if !defined(HAVE_KERNEL) | |||
Message::Error("F_NormalSource requires Kernel"); | Message::Error("F_NormalSource requires Kernel"); | |||
#else | #else | |||
int k ; | int k; | |||
if(!Current.ElementSource || Current.ElementSource->Num == NO_ELEMENT) | if(!Current.ElementSource || Current.ElementSource->Num == NO_ELEMENT) | |||
Message::Error("No element on which to compute 'F_NormalSource'"); | Message::Error("No element on which to compute 'F_NormalSource'"); | |||
Geo_CreateNormal(Current.ElementSource->Type, | Geo_CreateNormal(Current.ElementSource->Type, Current.ElementSource->x, | |||
Current.ElementSource->x, | Current.ElementSource->y, Current.ElementSource->z, V->Val); | |||
Current.ElementSource->y, | ||||
Current.ElementSource->z, | if(Current.NbrHar != 1) { | |||
V->Val); | V->Val[MAX_DIM] = 0.; | |||
V->Val[MAX_DIM + 1] = 0.; | ||||
if (Current.NbrHar != 1) { | V->Val[MAX_DIM + 2] = 0.; | |||
V->Val[MAX_DIM] = 0. ; | for(k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | |||
V->Val[MAX_DIM+1] = 0. ; | V->Val[MAX_DIM * k] = V->Val[0]; | |||
V->Val[MAX_DIM+2] = 0. ; | V->Val[MAX_DIM * k + 1] = V->Val[1]; | |||
for (k = 2 ; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar) ; k += 2) { | V->Val[MAX_DIM * k + 2] = V->Val[2]; | |||
V->Val[MAX_DIM* k ] = V->Val[0] ; | V->Val[MAX_DIM * (k + 1)] = 0.; | |||
V->Val[MAX_DIM* k +1] = V->Val[1] ; | V->Val[MAX_DIM * (k + 1) + 1] = 0.; | |||
V->Val[MAX_DIM* k +2] = V->Val[2] ; | V->Val[MAX_DIM * (k + 1) + 2] = 0.; | |||
V->Val[MAX_DIM*(k+1) ] = 0. ; | ||||
V->Val[MAX_DIM*(k+1)+1] = 0. ; | ||||
V->Val[MAX_DIM*(k+1)+2] = 0. ; | ||||
} | } | |||
} | } | |||
V->Type = VECTOR ; | V->Type = VECTOR; | |||
#endif | #endif | |||
} | } | |||
void F_Tangent(F_ARG) | void F_Tangent(F_ARG) | |||
{ | { | |||
int k ; | int k; | |||
double tx, ty, tz, norm ; | double tx, ty, tz, norm; | |||
if(!Current.Element || Current.Element->Num == NO_ELEMENT) | if(!Current.Element || Current.Element->Num == NO_ELEMENT) | |||
Message::Error("No element on which to compute 'F_Tangent'"); | Message::Error("No element on which to compute 'F_Tangent'"); | |||
switch (Current.Element->Type) { | switch(Current.Element->Type) { | |||
case LINE: | ||||
case LINE : | tx = Current.Element->x[1] - Current.Element->x[0]; | |||
tx = Current.Element->x[1] - Current.Element->x[0] ; | ty = Current.Element->y[1] - Current.Element->y[0]; | |||
ty = Current.Element->y[1] - Current.Element->y[0] ; | tz = Current.Element->z[1] - Current.Element->z[0]; | |||
tz = Current.Element->z[1] - Current.Element->z[0] ; | norm = sqrt(SQU(tx) + SQU(ty) + SQU(tz)); | |||
norm = sqrt(SQU(tx)+SQU(ty)+SQU(tz)) ; | V->Val[0] = tx / norm; | |||
V->Val[0] = tx/norm ; | V->Val[1] = ty / norm; | |||
V->Val[1] = ty/norm ; | V->Val[2] = tz / norm; | |||
V->Val[2] = tz/norm ; | break; | |||
break ; | ||||
default: Message::Error("Function 'Tangent' only valid for Line Elements"); | ||||
default : | } | |||
Message::Error("Function 'Tangent' only valid for Line Elements"); | ||||
} | if(Current.NbrHar != 1) { | |||
V->Val[MAX_DIM] = 0.; | ||||
if (Current.NbrHar != 1) { | V->Val[MAX_DIM + 1] = 0.; | |||
V->Val[MAX_DIM] = 0. ; | V->Val[MAX_DIM + 2] = 0.; | |||
V->Val[MAX_DIM+1] = 0. ; | for(k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | |||
V->Val[MAX_DIM+2] = 0. ; | V->Val[MAX_DIM * k] = V->Val[0]; | |||
for (k = 2 ; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar) ; k += 2) { | V->Val[MAX_DIM * k + 1] = V->Val[1]; | |||
V->Val[MAX_DIM* k ] = V->Val[0] ; | V->Val[MAX_DIM * k + 2] = V->Val[2]; | |||
V->Val[MAX_DIM* k +1] = V->Val[1] ; | V->Val[MAX_DIM * (k + 1)] = 0.; | |||
V->Val[MAX_DIM* k +2] = V->Val[2] ; | V->Val[MAX_DIM * (k + 1) + 1] = 0.; | |||
V->Val[MAX_DIM*(k+1) ] = 0. ; | V->Val[MAX_DIM * (k + 1) + 2] = 0.; | |||
V->Val[MAX_DIM*(k+1)+1] = 0. ; | ||||
V->Val[MAX_DIM*(k+1)+2] = 0. ; | ||||
} | } | |||
} | } | |||
V->Type = VECTOR ; | V->Type = VECTOR; | |||
} | } | |||
void F_TangentSource(F_ARG) | void F_TangentSource(F_ARG) | |||
{ | { | |||
int k ; | int k; | |||
double tx, ty, tz, norm ; | double tx, ty, tz, norm; | |||
if(!Current.ElementSource || Current.ElementSource->Num == NO_ELEMENT) | if(!Current.ElementSource || Current.ElementSource->Num == NO_ELEMENT) | |||
Message::Error("No element on which to compute 'F_TangentSource'"); | Message::Error("No element on which to compute 'F_TangentSource'"); | |||
switch (Current.ElementSource->Type) { | switch(Current.ElementSource->Type) { | |||
case LINE: | ||||
case LINE : | tx = Current.ElementSource->x[1] - Current.ElementSource->x[0]; | |||
tx = Current.ElementSource->x[1] - Current.ElementSource->x[0] ; | ty = Current.ElementSource->y[1] - Current.ElementSource->y[0]; | |||
ty = Current.ElementSource->y[1] - Current.ElementSource->y[0] ; | tz = Current.ElementSource->z[1] - Current.ElementSource->z[0]; | |||
tz = Current.ElementSource->z[1] - Current.ElementSource->z[0] ; | norm = sqrt(SQU(tx) + SQU(ty) + SQU(tz)); | |||
norm = sqrt(SQU(tx)+SQU(ty)+SQU(tz)) ; | V->Val[0] = tx / norm; | |||
V->Val[0] = tx/norm ; | V->Val[1] = ty / norm; | |||
V->Val[1] = ty/norm ; | V->Val[2] = tz / norm; | |||
V->Val[2] = tz/norm ; | break; | |||
break ; | ||||
default : | default: | |||
Message::Error("Function 'TangentSource' only valid for Line Elements"); | Message::Error("Function 'TangentSource' only valid for Line Elements"); | |||
} | } | |||
if (Current.NbrHar != 1) { | if(Current.NbrHar != 1) { | |||
V->Val[MAX_DIM] = 0. ; | V->Val[MAX_DIM] = 0.; | |||
V->Val[MAX_DIM+1] = 0. ; | V->Val[MAX_DIM + 1] = 0.; | |||
V->Val[MAX_DIM+2] = 0. ; | V->Val[MAX_DIM + 2] = 0.; | |||
for (k = 2 ; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar) ; k += 2) { | for(k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | |||
V->Val[MAX_DIM* k ] = V->Val[0] ; | V->Val[MAX_DIM * k] = V->Val[0]; | |||
V->Val[MAX_DIM* k +1] = V->Val[1] ; | V->Val[MAX_DIM * k + 1] = V->Val[1]; | |||
V->Val[MAX_DIM* k +2] = V->Val[2] ; | V->Val[MAX_DIM * k + 2] = V->Val[2]; | |||
V->Val[MAX_DIM*(k+1) ] = 0. ; | V->Val[MAX_DIM * (k + 1)] = 0.; | |||
V->Val[MAX_DIM*(k+1)+1] = 0. ; | V->Val[MAX_DIM * (k + 1) + 1] = 0.; | |||
V->Val[MAX_DIM*(k+1)+2] = 0. ; | V->Val[MAX_DIM * (k + 1) + 2] = 0.; | |||
} | } | |||
} | } | |||
V->Type = VECTOR ; | V->Type = VECTOR; | |||
} | } | |||
void F_ElementVol(F_ARG) | void F_ElementVol(F_ARG) | |||
{ | { | |||
#if !defined(HAVE_KERNEL) | #if !defined(HAVE_KERNEL) | |||
Message::Error("F_ElementVol requires Kernel"); | Message::Error("F_ElementVol requires Kernel"); | |||
#else | #else | |||
int k; | int k; | |||
double Vol = 0.; | double Vol = 0.; | |||
MATRIX3x3 Jac; | MATRIX3x3 Jac; | |||
if(!Current.Element || Current.Element->Num == NO_ELEMENT) | if(!Current.Element || Current.Element->Num == NO_ELEMENT) | |||
Message::Error("No element on which to compute 'F_ElementVol'"); | Message::Error("No element on which to compute 'F_ElementVol'"); | |||
/* It would be more efficient to compute the volumes directly from | /* It would be more efficient to compute the volumes directly from | |||
the node coordinates, but I'm lazy... */ | the node coordinates, but I'm lazy... */ | |||
Get_NodesCoordinatesOfElement(Current.Element) ; | Get_NodesCoordinatesOfElement(Current.Element); | |||
Get_BFGeoElement(Current.Element, Current.u, Current.v, Current.w) ; | Get_BFGeoElement(Current.Element, Current.u, Current.v, Current.w); | |||
/* we use the most general case (3D embedding) */ | /* we use the most general case (3D embedding) */ | |||
switch(Current.Element->Type){ | switch(Current.Element->Type) { | |||
case LINE: | case LINE: Vol = 2. * JacobianLin3D(Current.Element, &Jac); break; | |||
Vol = 2. * JacobianLin3D(Current.Element,&Jac); | case TRIANGLE: Vol = 0.5 * JacobianSur3D(Current.Element, &Jac); break; | |||
break; | case QUADRANGLE: Vol = 4. * JacobianSur3D(Current.Element, &Jac); break; | |||
case TRIANGLE: | case TETRAHEDRON: Vol = 1. / 6. * JacobianVol3D(Current.Element, &Jac); break; | |||
Vol = 0.5 * JacobianSur3D(Current.Element,&Jac) ; | case HEXAHEDRON: Vol = 8. * JacobianVol3D(Current.Element, &Jac); break; | |||
break; | case PRISM: Vol = JacobianVol3D(Current.Element, &Jac); break; | |||
case QUADRANGLE: | case PYRAMID: Vol = 4. / 3. * JacobianVol3D(Current.Element, &Jac); break; | |||
Vol = 4. * JacobianSur3D(Current.Element,&Jac) ; | default: | |||
break; | ||||
case TETRAHEDRON: | ||||
Vol = 1./6. * JacobianVol3D(Current.Element,&Jac) ; | ||||
break; | ||||
case HEXAHEDRON: | ||||
Vol = 8. * JacobianVol3D(Current.Element,&Jac) ; | ||||
break; | ||||
case PRISM: | ||||
Vol = JacobianVol3D(Current.Element,&Jac) ; | ||||
break; | ||||
case PYRAMID: | ||||
Vol = 4./3. * JacobianVol3D(Current.Element,&Jac) ; | ||||
break; | ||||
default : | ||||
Message::Error("F_ElementVol not implemented for %s", | Message::Error("F_ElementVol not implemented for %s", | |||
Get_StringForDefine(Element_Type, Current.Element->Type)); | Get_StringForDefine(Element_Type, Current.Element->Type)); | |||
} | } | |||
V->Type = SCALAR ; | V->Type = SCALAR; | |||
V->Val[0] = fabs(Vol); | V->Val[0] = fabs(Vol); | |||
V->Val[MAX_DIM] = 0.; | V->Val[MAX_DIM] = 0.; | |||
for (k = 2 ; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar) ; k += 2) { | for(k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | |||
V->Val[MAX_DIM* k] = V->Val[0] ; | V->Val[MAX_DIM * k] = V->Val[0]; | |||
V->Val[MAX_DIM* (k+1)] = 0. ; | V->Val[MAX_DIM * (k + 1)] = 0.; | |||
} | } | |||
#endif | #endif | |||
} | } | |||
void F_SurfaceArea(F_ARG) | void F_SurfaceArea(F_ARG) | |||
{ | { | |||
#if !defined(HAVE_KERNEL) | #if !defined(HAVE_KERNEL) | |||
Message::Error("F_SurfaceArea requires Kernel"); | Message::Error("F_SurfaceArea requires Kernel"); | |||
#else | #else | |||
struct Element Element ; | struct Element Element; | |||
// check if the cache can be reused | // check if the cache can be reused | |||
if (Fct->Active) { | if(Fct->Active) { | |||
bool recompute = false; | bool recompute = false; | |||
if(Fct->NbrParameters != List_Nbr(Fct->Active->Case.SurfaceArea.RegionList)) | if(Fct->NbrParameters != | |||
{ | List_Nbr(Fct->Active->Case.SurfaceArea.RegionList)) { | |||
recompute = true; | recompute = true; | |||
} | } | |||
else if(Fct->NbrParameters >= 1) { | else if(Fct->NbrParameters >= 1) { | |||
for(int i = 0; i < Fct->NbrParameters; i++) { | for(int i = 0; i < Fct->NbrParameters; i++) { | |||
int num ; List_Read(Fct->Active->Case.SurfaceArea.RegionList, i, &num); | int num; | |||
List_Read(Fct->Active->Case.SurfaceArea.RegionList, i, &num); | ||||
if(num != (int)(Fct->Para[i])) { | if(num != (int)(Fct->Para[i])) { | |||
recompute = true; | recompute = true; | |||
break; | break; | |||
} | } | |||
} | } | |||
} | } | |||
else if(Current.Region == -1) { | ||||
// in case e.g. of Print OnGlobal: stay on the safe side and always | ||||
// recompute | ||||
recompute = true; | ||||
} | ||||
else if(Current.Region != Fct->Active->Case.SurfaceArea.RegionCurrent) { | else if(Current.Region != Fct->Active->Case.SurfaceArea.RegionCurrent) { | |||
recompute = true; | recompute = true; | |||
} | } | |||
if(recompute) { | if(recompute) { | |||
List_Delete(Fct->Active->Case.SurfaceArea.RegionList); | List_Delete(Fct->Active->Case.SurfaceArea.RegionList); | |||
Free(Fct->Active); | Free(Fct->Active); | |||
Fct->Active = NULL; | Fct->Active = NULL; | |||
} | } | |||
} | } | |||
if (!Fct->Active) { | if(!Fct->Active) { | |||
Fct->Active = (struct FunctionActive *)Malloc(sizeof(struct FunctionActive)) | Fct->Active = | |||
; | (struct FunctionActive *)Malloc(sizeof(struct FunctionActive)); | |||
List_T *InitialList_L = NULL; | List_T *InitialList_L = NULL; | |||
if (Fct->NbrParameters >= 1) { | if(Fct->NbrParameters >= 1) { | |||
InitialList_L = List_Create(Fct->NbrParameters,1,sizeof(int)); | InitialList_L = List_Create(Fct->NbrParameters, 1, sizeof(int)); | |||
for (int i = 0; i < Fct->NbrParameters; i++) { | for(int i = 0; i < Fct->NbrParameters; i++) { | |||
int Index_Region = (int)(Fct->Para[i]) ; | int Index_Region = (int)(Fct->Para[i]); | |||
List_Add(InitialList_L, &Index_Region); | List_Add(InitialList_L, &Index_Region); | |||
} | } | |||
} | } | |||
double Val_Surface = 0. ; | double Val_Surface = 0.; | |||
int Nbr_Element = Geo_GetNbrGeoElements() ; | int Nbr_Element = Geo_GetNbrGeoElements(); | |||
int Nbr_Found_Element = 0; | int Nbr_Found_Element = 0; | |||
for (int i_Element = 0 ; i_Element < Nbr_Element; i_Element++) { | for(int i_Element = 0; i_Element < Nbr_Element; i_Element++) { | |||
Element.GeoElement = Geo_GetGeoElement(i_Element) ; | Element.GeoElement = Geo_GetGeoElement(i_Element); | |||
if ((InitialList_L && | if((InitialList_L && | |||
List_Search(InitialList_L, &(Element.GeoElement->Region), fcmp_int)) | | List_Search(InitialList_L, &(Element.GeoElement->Region), | |||
| | fcmp_int)) || | |||
(!InitialList_L && Element.GeoElement->Region == Current.Region)) { | (!InitialList_L && Element.GeoElement->Region == Current.Region)) { | |||
Nbr_Found_Element++; | Nbr_Found_Element++; | |||
Element.Num = Element.GeoElement->Num ; | Element.Num = Element.GeoElement->Num; | |||
Element.Type = Element.GeoElement->Type ; | Element.Type = Element.GeoElement->Type; | |||
if (Element.Type == TRIANGLE || Element.Type == QUADRANGLE || | ||||
Element.Type == TRIANGLE_2) { | ||||
Get_NodesCoordinatesOfElement(&Element) ; | if(Element.Type == TRIANGLE || Element.Type == QUADRANGLE || | |||
Get_BFGeoElement(&Element, 0., 0., 0.) ; | Element.Type == TRIANGLE_2) { | |||
double c11 = 0., c21 = 0., c12 = 0., c22 = 0., c13 = 0., c23 = 0.; | Get_NodesCoordinatesOfElement(&Element); | |||
for (int i = 0 ; i < Element.GeoElement->NbrNodes ; i++ ) { | Get_BFGeoElement(&Element, 0., 0., 0.); | |||
c11 += Element.x[i] * Element.dndu[i][0] ; | double c11 = 0., c21 = 0., c12 = 0., c22 = 0., c13 = 0., c23 = 0.; | |||
c21 += Element.x[i] * Element.dndu[i][1] ; | for(int i = 0; i < Element.GeoElement->NbrNodes; i++) { | |||
c12 += Element.y[i] * Element.dndu[i][0] ; | c11 += Element.x[i] * Element.dndu[i][0]; | |||
c22 += Element.y[i] * Element.dndu[i][1] ; | c21 += Element.x[i] * Element.dndu[i][1]; | |||
c13 += Element.z[i] * Element.dndu[i][0] ; | c12 += Element.y[i] * Element.dndu[i][0]; | |||
c23 += Element.z[i] * Element.dndu[i][1] ; | c22 += Element.y[i] * Element.dndu[i][1]; | |||
} | c13 += Element.z[i] * Element.dndu[i][0]; | |||
double DetJac = sqrt(SQU(c11 * c22 - c12 * c21) + | c23 += Element.z[i] * Element.dndu[i][1]; | |||
SQU(c13 * c21 - c11 * c23) + | } | |||
SQU(c12 * c23 - c13 * c22)); | double DetJac = | |||
sqrt(SQU(c11 * c22 - c12 * c21) + SQU(c13 * c21 - c11 * c23) + | ||||
if (Element.Type == TRIANGLE || Element.Type == TRIANGLE_2) | SQU(c12 * c23 - c13 * c22)); | |||
Val_Surface += fabs(DetJac) * 0.5 ; | ||||
else if (Element.Type == QUADRANGLE) | if(Element.Type == TRIANGLE || Element.Type == TRIANGLE_2) | |||
Val_Surface += fabs(DetJac) * 4. ; | Val_Surface += fabs(DetJac) * 0.5; | |||
else if(Element.Type == QUADRANGLE) | ||||
} | Val_Surface += fabs(DetJac) * 4.; | |||
else if (Element.Type == LINE || Element.Type == LINE_2) { | } | |||
Get_NodesCoordinatesOfElement(&Element) ; | else if(Element.Type == LINE || Element.Type == LINE_2) { | |||
Get_BFGeoElement(&Element, 0., 0., 0.) ; | Get_NodesCoordinatesOfElement(&Element); | |||
Get_BFGeoElement(&Element, 0., 0., 0.); | ||||
double c11 = 0., c12 = 0., c13 = 0.; | ||||
for (int i = 0; i < Element.GeoElement->NbrNodes; i++) { | double c11 = 0., c12 = 0., c13 = 0.; | |||
c11 += Element.x[i] * Element.dndu[i][0] ; | for(int i = 0; i < Element.GeoElement->NbrNodes; i++) { | |||
c12 += Element.y[i] * Element.dndu[i][0] ; | c11 += Element.x[i] * Element.dndu[i][0]; | |||
c13 += Element.z[i] * Element.dndu[i][0] ; | c12 += Element.y[i] * Element.dndu[i][0]; | |||
} | c13 += Element.z[i] * Element.dndu[i][0]; | |||
double DetJac = sqrt(SQU(c11)+SQU(c12)+SQU(c13)); | } | |||
double DetJac = sqrt(SQU(c11) + SQU(c12) + SQU(c13)); | ||||
Val_Surface += fabs(DetJac) * 2 ; // SurfaceArea of LINE x 1m | Val_Surface += fabs(DetJac) * 2; // SurfaceArea of LINE x 1m | |||
} | ||||
else { | ||||
Message::Error( | ||||
"Function 'SurfaceArea' only valid for line, triangle or " | ||||
"quandrangle elements"); | ||||
} | } | |||
else { | ||||
Message::Error("Function 'SurfaceArea' only valid for line, triangle or | ||||
" | ||||
"quandrangle elements"); | ||||
} | ||||
} | } | |||
} | } | |||
Fct->Active->Case.SurfaceArea.RegionList = InitialList_L ; | Fct->Active->Case.SurfaceArea.RegionList = InitialList_L; | |||
Fct->Active->Case.SurfaceArea.RegionCurrent = Current.Region ; | Fct->Active->Case.SurfaceArea.RegionCurrent = Current.Region; | |||
Fct->Active->Case.SurfaceArea.Value = Val_Surface ; | Fct->Active->Case.SurfaceArea.Value = Val_Surface; | |||
if(!Nbr_Found_Element) | if(!Nbr_Found_Element) Message::Info("No element found in SurfaceArea[]"); | |||
Message::Info("No element found in SurfaceArea[]"); | ||||
} | } | |||
V->Type = SCALAR ; | V->Type = SCALAR; | |||
V->Val[0] = Fct->Active->Case.SurfaceArea.Value ; | V->Val[0] = Fct->Active->Case.SurfaceArea.Value; | |||
V->Val[MAX_DIM] = 0.; | V->Val[MAX_DIM] = 0.; | |||
for (int k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | for(int k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | |||
V->Val[MAX_DIM* k] = V->Val[0] ; | V->Val[MAX_DIM * k] = V->Val[0]; | |||
V->Val[MAX_DIM* (k+1)] = 0. ; | V->Val[MAX_DIM * (k + 1)] = 0.; | |||
} | } | |||
#endif | #endif | |||
} | } | |||
void F_GetVolume(F_ARG) | void F_GetVolume(F_ARG) | |||
{ | { | |||
#if !defined(HAVE_KERNEL) | #if !defined(HAVE_KERNEL) | |||
Message::Error("F_GetVolume requires Kernel"); | Message::Error("F_GetVolume requires Kernel"); | |||
#else | #else | |||
struct Element Element ; | struct Element Element; | |||
List_T * InitialList_L; | List_T *InitialList_L; | |||
int Nbr_Element, i_Element ; | int Nbr_Element, i_Element; | |||
double Val_Volume ; | double Val_Volume; | |||
double c11, c21, c31, c12, c22, c32, c13, c23, c33 ; | double c11, c21, c31, c12, c22, c32, c13, c23, c33; | |||
double DetJac ; | double DetJac; | |||
int i, k ; | int i, k; | |||
if(!Fct->Active) { | ||||
Fct->Active = | ||||
(struct FunctionActive *)Malloc(sizeof(struct FunctionActive)); | ||||
if (!Fct->Active) { | if(Fct->NbrParameters == 1) { | |||
Fct->Active = (struct FunctionActive *)Malloc(sizeof(struct FunctionActive)) | int Index_Region = (int)(Fct->Para[0]); | |||
; | ||||
if (Fct->NbrParameters == 1) { | ||||
int Index_Region = (int)(Fct->Para[0]) ; | ||||
InitialList_L = List_Create(1, 1, sizeof(int)); | InitialList_L = List_Create(1, 1, sizeof(int)); | |||
List_Add(InitialList_L,&Index_Region); | List_Add(InitialList_L, &Index_Region); | |||
} | } | |||
else { | else { | |||
InitialList_L = NULL ; | InitialList_L = NULL; | |||
} | } | |||
Val_Volume = 0. ; | Val_Volume = 0.; | |||
Nbr_Element = Geo_GetNbrGeoElements() ; | Nbr_Element = Geo_GetNbrGeoElements(); | |||
for (i_Element = 0 ; i_Element < Nbr_Element; i_Element++) { | for(i_Element = 0; i_Element < Nbr_Element; i_Element++) { | |||
Element.GeoElement = Geo_GetGeoElement(i_Element) ; | Element.GeoElement = Geo_GetGeoElement(i_Element); | |||
if ((InitialList_L && | if((InitialList_L && | |||
List_Search(InitialList_L, &(Element.GeoElement->Region), fcmp_int)) | | List_Search(InitialList_L, &(Element.GeoElement->Region), | |||
| | fcmp_int)) || | |||
(!InitialList_L && Element.GeoElement->Region == Current.Region)) { | (!InitialList_L && Element.GeoElement->Region == Current.Region)) { | |||
Element.Num = Element.GeoElement->Num ; | Element.Num = Element.GeoElement->Num; | |||
Element.Type = Element.GeoElement->Type ; | Element.Type = Element.GeoElement->Type; | |||
if (Element.Type == TETRAHEDRON || Element.Type == TETRAHEDRON_2 || | if(Element.Type == TETRAHEDRON || Element.Type == TETRAHEDRON_2 || | |||
Element.Type == HEXAHEDRON || | Element.Type == HEXAHEDRON || Element.Type == PRISM || | |||
Element.Type == PRISM) { | Element.Type == PYRAMID) { | |||
Get_NodesCoordinatesOfElement(&Element); | ||||
Get_NodesCoordinatesOfElement(&Element) ; | Get_BFGeoElement(&Element, 0., 0., 0.); | |||
Get_BFGeoElement(&Element, 0., 0., 0.) ; | ||||
c11 = c21 = c31 = c12 = c22 = c32 = c13 = c23 = c33 = 0; | ||||
c11 = c21 = c31 = c12 = c22 = c32 = c13 = c23 = c33 = 0; | for(i = 0; i < Element.GeoElement->NbrNodes; i++) { | |||
for ( i = 0 ; i < Element.GeoElement->NbrNodes ; i++ ) { | c11 += Element.x[i] * Element.dndu[i][0]; | |||
c11 += Element.x[i] * Element.dndu[i][0] ; | c21 += Element.x[i] * Element.dndu[i][1]; | |||
c21 += Element.x[i] * Element.dndu[i][1] ; | c31 += Element.x[i] * Element.dndu[i][2]; | |||
c31 += Element.x[i] * Element.dndu[i][2] ; | ||||
c12 += Element.y[i] * Element.dndu[i][0]; | ||||
c12 += Element.y[i] * Element.dndu[i][0] ; | c22 += Element.y[i] * Element.dndu[i][1]; | |||
c22 += Element.y[i] * Element.dndu[i][1] ; | c32 += Element.y[i] * Element.dndu[i][2]; | |||
c32 += Element.y[i] * Element.dndu[i][2] ; | ||||
c13 += Element.z[i] * Element.dndu[i][0]; | ||||
c13 += Element.z[i] * Element.dndu[i][0] ; | c23 += Element.z[i] * Element.dndu[i][1]; | |||
c23 += Element.z[i] * Element.dndu[i][1] ; | c33 += Element.z[i] * Element.dndu[i][2]; | |||
c33 += Element.z[i] * Element.dndu[i][2] ; | } | |||
} | ||||
DetJac = c11 * c22 * c33 + c13 * c21 * c32 | ||||
+ c12 * c23 * c31 - c13 * c22 * c31 | ||||
- c11 * c23 * c32 - c12 * c21 * c33 ; | ||||
switch(Element.Type){ | DetJac = c11 * c22 * c33 + c13 * c21 * c32 + c12 * c23 * c31 - | |||
c13 * c22 * c31 - c11 * c23 * c32 - c12 * c21 * c33; | ||||
switch(Element.Type) { | ||||
case TETRAHEDRON: | case TETRAHEDRON: | |||
case TETRAHEDRON_2: | case TETRAHEDRON_2: Val_Volume += 1. / 6. * fabs(DetJac); break; | |||
Val_Volume += 1./6. * fabs(DetJac); | case HEXAHEDRON: Val_Volume += 8. * fabs(DetJac); break; | |||
break; | case PRISM: Val_Volume += fabs(DetJac); break; | |||
case HEXAHEDRON: | case PYRAMID: Val_Volume += 4. / 3. * fabs(DetJac); break; | |||
Val_Volume += 8. * fabs(DetJac); | ||||
break; | ||||
case PRISM: | ||||
Val_Volume += fabs(DetJac); | ||||
break; | ||||
} | } | |||
} | } | |||
else { | else { | |||
Message::Error("Function 'GetVolume' not valid for %s", | Message::Error("Function 'GetVolume' not valid for %s", | |||
Get_StringForDefine(Element_Type, Element.Type)); | Get_StringForDefine(Element_Type, Element.Type)); | |||
} | } | |||
} | } | |||
} | } | |||
Fct->Active->Case.GetVolume.Value = Val_Volume ; | Fct->Active->Case.GetVolume.Value = Val_Volume; | |||
} | } | |||
V->Type = SCALAR ; | V->Type = SCALAR; | |||
V->Val[0] = Fct->Active->Case.GetVolume.Value ; | V->Val[0] = Fct->Active->Case.GetVolume.Value; | |||
V->Val[MAX_DIM] = 0.; | V->Val[MAX_DIM] = 0.; | |||
for (k = 2 ; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar) ; k += 2) { | for(k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | |||
V->Val[MAX_DIM* k] = V->Val[0] ; | V->Val[MAX_DIM * k] = V->Val[0]; | |||
V->Val[MAX_DIM* (k+1)] = 0. ; | V->Val[MAX_DIM * (k + 1)] = 0.; | |||
} | } | |||
#endif | #endif | |||
} | } | |||
void F_GetNumElement(F_ARG) | void F_GetNumElement(F_ARG) | |||
{ | { | |||
int k; | int k; | |||
V->Type = SCALAR ; | V->Type = SCALAR; | |||
V->Val[0] = (double)Current.Element->Num; | V->Val[0] = (double)Current.Element->Num; | |||
V->Val[MAX_DIM] = 0.; | V->Val[MAX_DIM] = 0.; | |||
for (k = 2 ; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar) ; k += 2) { | for(k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | |||
V->Val[MAX_DIM* k] = V->Val[0] ; | V->Val[MAX_DIM * k] = V->Val[0]; | |||
V->Val[MAX_DIM* (k+1)] = 0 ; | V->Val[MAX_DIM * (k + 1)] = 0; | |||
} | } | |||
} | } | |||
void F_GetNumElements(F_ARG) | void F_GetNumElements(F_ARG) | |||
{ | { | |||
#if !defined(HAVE_KERNEL) | #if !defined(HAVE_KERNEL) | |||
Message::Error("F_GetNumElements requires Kernel"); | Message::Error("F_GetNumElements requires Kernel"); | |||
#else | #else | |||
struct Element Element ; | struct Element Element; | |||
if (!Fct->Active) { | if(!Fct->Active) { | |||
Fct->Active = (struct FunctionActive *)Malloc(sizeof(struct FunctionActive)) | Fct->Active = | |||
; | (struct FunctionActive *)Malloc(sizeof(struct FunctionActive)); | |||
List_T * InitialList_L; | List_T *InitialList_L; | |||
if (Fct->NbrParameters == 1) { | if(Fct->NbrParameters == 1) { | |||
int Index_Region = (int)(Fct->Para[0]) ; | int Index_Region = (int)(Fct->Para[0]); | |||
InitialList_L = List_Create(1, 1, sizeof(int)); | InitialList_L = List_Create(1, 1, sizeof(int)); | |||
List_Add(InitialList_L, &Index_Region); | List_Add(InitialList_L, &Index_Region); | |||
} | } | |||
else if (Fct->NbrParameters > 1) { | else if(Fct->NbrParameters > 1) { | |||
InitialList_L = List_Create(Fct->NbrParameters,1,sizeof(int)); | InitialList_L = List_Create(Fct->NbrParameters, 1, sizeof(int)); | |||
List_Reset(InitialList_L); | List_Reset(InitialList_L); | |||
for (int i=0; i<Fct->NbrParameters; i++) { | for(int i = 0; i < Fct->NbrParameters; i++) { | |||
int Index_Region = (int)(Fct->Para[i]) ; | int Index_Region = (int)(Fct->Para[i]); | |||
List_Add(InitialList_L, &Index_Region); | List_Add(InitialList_L, &Index_Region); | |||
} | } | |||
} | } | |||
else { | else { | |||
InitialList_L = NULL ; | InitialList_L = NULL; | |||
} | } | |||
int Count = 0. ; | int Count = 0.; | |||
int Nbr_Element = Geo_GetNbrGeoElements() ; | int Nbr_Element = Geo_GetNbrGeoElements(); | |||
if(!InitialList_L){ | if(!InitialList_L) { Count = Nbr_Element; } | |||
Count = Nbr_Element ; | else { | |||
} | for(int i_Element = 0; i_Element < Nbr_Element; i_Element++) { | |||
else{ | Element.GeoElement = Geo_GetGeoElement(i_Element); | |||
for (int i_Element = 0 ; i_Element < Nbr_Element; i_Element++) { | if((InitialList_L && | |||
Element.GeoElement = Geo_GetGeoElement(i_Element) ; | List_Search(InitialList_L, &(Element.GeoElement->Region), | |||
if ((InitialList_L && | fcmp_int)) || | |||
List_Search(InitialList_L, &(Element.GeoElement->Region), fcmp_int) | (!InitialList_L && Element.GeoElement->Region == Current.Region)) { | |||
) || | ||||
(!InitialList_L && Element.GeoElement->Region == Current.Region)) { | ||||
Count++; | Count++; | |||
} | } | |||
} | } | |||
} | } | |||
Fct->Active->Case.GetNumElements.Value = Count ; | Fct->Active->Case.GetNumElements.Value = Count; | |||
} | } | |||
V->Type = SCALAR ; | V->Type = SCALAR; | |||
V->Val[0] = Fct->Active->Case.GetNumElements.Value ; | V->Val[0] = Fct->Active->Case.GetNumElements.Value; | |||
V->Val[MAX_DIM] = 0.; | V->Val[MAX_DIM] = 0.; | |||
for (int k = 2 ; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar) ; k += 2) { | for(int k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | |||
V->Val[MAX_DIM* k] = V->Val[0] ; | V->Val[MAX_DIM * k] = V->Val[0]; | |||
V->Val[MAX_DIM* (k+1)] = 0. ; | V->Val[MAX_DIM * (k + 1)] = 0.; | |||
} | } | |||
#endif | #endif | |||
} | } | |||
void F_GetNumNodes(F_ARG) | void F_GetNumNodes(F_ARG) | |||
{ | { | |||
#if !defined(HAVE_KERNEL) | #if !defined(HAVE_KERNEL) | |||
Message::Error("F_GetNumNodes requires Kernel"); | Message::Error("F_GetNumNodes requires Kernel"); | |||
#else | #else | |||
// TODO: accept arguments to limit to some regions | // TODO: accept arguments to limit to some regions | |||
V->Type = SCALAR ; | V->Type = SCALAR; | |||
V->Val[0] = Geo_GetNbrGeoNodes() ; | V->Val[0] = Geo_GetNbrGeoNodes(); | |||
V->Val[MAX_DIM] = 0.; | V->Val[MAX_DIM] = 0.; | |||
for (int k = 2 ; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar) ; k += 2) { | for(int k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | |||
V->Val[MAX_DIM* k] = V->Val[0] ; | V->Val[MAX_DIM * k] = V->Val[0]; | |||
V->Val[MAX_DIM* (k+1)] = 0. ; | V->Val[MAX_DIM * (k + 1)] = 0.; | |||
} | } | |||
#endif | #endif | |||
} | } | |||
void F_CellSize(F_ARG) | void F_CellSize(F_ARG) | |||
{ | { | |||
#if !defined(HAVE_KERNEL) | #if !defined(HAVE_KERNEL) | |||
Message::Error("F_CellSize requires Kernel"); | Message::Error("F_CellSize requires Kernel"); | |||
#else | #else | |||
double cellSize, Vol; | double cellSize, Vol; | |||
MATRIX3x3 Jac; | MATRIX3x3 Jac; | |||
double c11, c21, c12, c22, DetJac; | double c11, c21, c12, c22, DetJac; | |||
int i, k ; | int i, k; | |||
if(!Current.Element || Current.Element->Num == NO_ELEMENT) | if(!Current.Element || Current.Element->Num == NO_ELEMENT) | |||
Message::Error("No element on which to compute 'CellSize'"); | Message::Error("No element on which to compute 'CellSize'"); | |||
Get_NodesCoordinatesOfElement(Current.Element) ; | Get_NodesCoordinatesOfElement(Current.Element); | |||
Get_BFGeoElement(Current.Element, 0., 0., 0.) ; | Get_BFGeoElement(Current.Element, 0., 0., 0.); | |||
switch(Current.Element->Type){ | switch(Current.Element->Type) { | |||
case LINE: | case LINE: cellSize = 2. * JacobianLin3D(Current.Element, &Jac); break; | |||
cellSize = 2. * JacobianLin3D(Current.Element,&Jac); | ||||
break; | ||||
case TRIANGLE: | case TRIANGLE: | |||
c11 = c21 = c12 = c22 = 0. ; | c11 = c21 = c12 = c22 = 0.; | |||
for ( i = 0 ; i < Current.Element->GeoElement->NbrNodes ; i++ ) { | for(i = 0; i < Current.Element->GeoElement->NbrNodes; i++) { | |||
c11 += Current.Element->x[i] * Current.Element->dndu[i][0] ; | c11 += Current.Element->x[i] * Current.Element->dndu[i][0]; | |||
c21 += Current.Element->x[i] * Current.Element->dndu[i][1] ; | c21 += Current.Element->x[i] * Current.Element->dndu[i][1]; | |||
c12 += Current.Element->y[i] * Current.Element->dndu[i][0] ; | c12 += Current.Element->y[i] * Current.Element->dndu[i][0]; | |||
c22 += Current.Element->y[i] * Current.Element->dndu[i][1] ; | c22 += Current.Element->y[i] * Current.Element->dndu[i][1]; | |||
} | } | |||
DetJac = c11 * c22 - c12 * c21 ; | DetJac = c11 * c22 - c12 * c21; | |||
cellSize = | cellSize = sqrt(SQU(Current.Element->x[1] - Current.Element->x[0]) + | |||
sqrt(SQU(Current.Element->x[1]-Current.Element->x[0]) | SQU(Current.Element->y[1] - Current.Element->y[0]) + | |||
+SQU(Current.Element->y[1]-Current.Element->y[0]) | SQU(Current.Element->z[1] - Current.Element->z[0])) * | |||
+SQU(Current.Element->z[1]-Current.Element->z[0])) | sqrt(SQU(Current.Element->x[2] - Current.Element->x[1]) + | |||
* | SQU(Current.Element->y[2] - Current.Element->y[1]) + | |||
sqrt(SQU(Current.Element->x[2]-Current.Element->x[1]) | SQU(Current.Element->z[2] - Current.Element->z[1])) * | |||
+SQU(Current.Element->y[2]-Current.Element->y[1]) | sqrt(SQU(Current.Element->x[0] - Current.Element->x[2]) + | |||
+SQU(Current.Element->z[2]-Current.Element->z[1])) | SQU(Current.Element->y[0] - Current.Element->y[2]) + | |||
* | SQU(Current.Element->z[0] - Current.Element->z[2])) / | |||
sqrt(SQU(Current.Element->x[0]-Current.Element->x[2]) | fabs(DetJac); | |||
+SQU(Current.Element->y[0]-Current.Element->y[2]) | ||||
+SQU(Current.Element->z[0]-Current.Element->z[2])) | ||||
/ fabs(DetJac) ; | ||||
break; | break; | |||
case QUADRANGLE: | case QUADRANGLE: | |||
// Message::Warning("Function CellSize not ready for QUADRANGLE") ; | // Message::Warning("Function CellSize not ready for QUADRANGLE") ; | |||
Vol = 4. * JacobianSur3D(Current.Element,&Jac) ; | Vol = 4. * JacobianSur3D(Current.Element, &Jac); | |||
cellSize = sqrt(Vol); | cellSize = sqrt(Vol); | |||
break; | break; | |||
case TETRAHEDRON: | case TETRAHEDRON: | |||
cellSize = 0.; | cellSize = 0.; | |||
Message::Warning("Function CellSize not ready for TETRAHEDRON") ; | Message::Warning("Function CellSize not ready for TETRAHEDRON"); | |||
break; | break; | |||
case HEXAHEDRON: | case HEXAHEDRON: | |||
cellSize = 0.; | cellSize = 0.; | |||
Message::Warning("Function CellSize not ready for HEXAHEDRON") ; | Message::Warning("Function CellSize not ready for HEXAHEDRON"); | |||
break; | break; | |||
case PRISM: | case PRISM: | |||
cellSize = 0.; | cellSize = 0.; | |||
Message::Warning("Function CellSize not ready for PRISM") ; | Message::Warning("Function CellSize not ready for PRISM"); | |||
break; | break; | |||
default : | default: | |||
cellSize = 0.; | cellSize = 0.; | |||
Message::Error("Function 'CellSize' not valid for %s", | Message::Error("Function 'CellSize' not valid for %s", | |||
Get_StringForDefine(Element_Type, Current.Element->Type)); | Get_StringForDefine(Element_Type, Current.Element->Type)); | |||
} | } | |||
V->Type = SCALAR ; | V->Type = SCALAR; | |||
V->Val[0] = cellSize ; | V->Val[0] = cellSize; | |||
V->Val[MAX_DIM] = 0. ; | V->Val[MAX_DIM] = 0.; | |||
for (k = 2 ; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar) ; k += 2) { | for(k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | |||
V->Val[MAX_DIM* k] = V->Val[0] ; | V->Val[MAX_DIM * k] = V->Val[0]; | |||
V->Val[MAX_DIM* (k+1)] = 0. ; | V->Val[MAX_DIM * (k + 1)] = 0.; | |||
} | } | |||
#endif | #endif | |||
} | } | |||
void F_SquNormEdgeValues(F_ARG) | void F_SquNormEdgeValues(F_ARG) | |||
{ | { | |||
#if !defined(HAVE_KERNEL) | #if !defined(HAVE_KERNEL) | |||
Message::Error("F_SquNormEdgeValues requires Kernel"); | Message::Error("F_SquNormEdgeValues requires Kernel"); | |||
#else | #else | |||
struct Geo_Element *GeoElement; | struct Geo_Element *GeoElement; | |||
int i, *NumNodes; | int i, *NumNodes; | |||
double x [NBR_MAX_NODES_IN_ELEMENT] ; | double x[NBR_MAX_NODES_IN_ELEMENT]; | |||
double y [NBR_MAX_NODES_IN_ELEMENT] ; | double y[NBR_MAX_NODES_IN_ELEMENT]; | |||
double z [NBR_MAX_NODES_IN_ELEMENT] ; | double z[NBR_MAX_NODES_IN_ELEMENT]; | |||
double xe[2], ye[2], ze[2]; | double xe[2], ye[2], ze[2]; | |||
int numDofData, Code_BasisFunction, CodeExist = 0; | int numDofData, Code_BasisFunction, CodeExist = 0; | |||
struct Dof * Dof_P = NULL; | struct Dof *Dof_P = NULL; | |||
double Val_Dof, Val_Dof_i, valSum, sizeEdge ; | double Val_Dof, Val_Dof_i, valSum, sizeEdge; | |||
int k; | int k; | |||
if(!Current.Element || Current.Element->Num == NO_ELEMENT) | if(!Current.Element || Current.Element->Num == NO_ELEMENT) | |||
Message::Error("No element on which to compute 'SquNormEdgeValues'"); | Message::Error("No element on which to compute 'SquNormEdgeValues'"); | |||
numDofData = (int)Fct->Para[0]; | numDofData = (int)Fct->Para[0]; | |||
Code_BasisFunction = (int)Fct->Para[1]; | Code_BasisFunction = (int)Fct->Para[1]; | |||
GeoElement = Current.Element->GeoElement; | GeoElement = Current.Element->GeoElement; | |||
Geo_GetNodesCoordinates | Geo_GetNodesCoordinates(GeoElement->NbrNodes, GeoElement->NumNodes, x, y, z); | |||
(GeoElement->NbrNodes, GeoElement->NumNodes, x, y, z) ; | ||||
valSum = 0.; | valSum = 0.; | |||
if(!GeoElement->NbrEdges) Geo_CreateEdgesOfElement(GeoElement) ; | if(!GeoElement->NbrEdges) Geo_CreateEdgesOfElement(GeoElement); | |||
for(i=0 ; i<GeoElement->NbrEdges ; i++){ | for(i = 0; i < GeoElement->NbrEdges; i++) { | |||
NumNodes = Geo_GetNodesOfEdgeInElement(GeoElement, i) ; | NumNodes = Geo_GetNodesOfEdgeInElement(GeoElement, i); | |||
xe[0] = x[abs(NumNodes[0])-1]; xe[1] = x[abs(NumNodes[1])-1]; | xe[0] = x[abs(NumNodes[0]) - 1]; | |||
ye[0] = y[abs(NumNodes[0])-1]; ye[1] = y[abs(NumNodes[1])-1]; | xe[1] = x[abs(NumNodes[1]) - 1]; | |||
ze[0] = z[abs(NumNodes[0])-1]; ze[1] = z[abs(NumNodes[1])-1]; | ye[0] = y[abs(NumNodes[0]) - 1]; | |||
ye[1] = y[abs(NumNodes[1]) - 1]; | ||||
CodeExist = | ze[0] = z[abs(NumNodes[0]) - 1]; | |||
((Dof_P = | ze[1] = z[abs(NumNodes[1]) - 1]; | |||
Dof_GetDofStruct(Current.DofData_P0+ numDofData, | ||||
Code_BasisFunction, abs(GeoElement->NumEdges[i]), 0)) | CodeExist = ((Dof_P = Dof_GetDofStruct( | |||
!= NULL) ; | Current.DofData_P0 + numDofData, Code_BasisFunction, | |||
abs(GeoElement->NumEdges[i]), 0)) != NULL); | ||||
if (CodeExist) { | ||||
sizeEdge = sqrt( SQU(xe[1]-xe[0]) + SQU(ye[1]-ye[0]) + SQU(ze[1]-ze[0]) ); | if(CodeExist) { | |||
sizeEdge = | ||||
if(Current.NbrHar==1){ | sqrt(SQU(xe[1] - xe[0]) + SQU(ye[1] - ye[0]) + SQU(ze[1] - ze[0])); | |||
Dof_GetRealDofValue(Current.DofData_P0+ numDofData, Dof_P, &Val_Dof) ; | ||||
Val_Dof = Val_Dof/sizeEdge; | if(Current.NbrHar == 1) { | |||
Dof_GetRealDofValue(Current.DofData_P0 + numDofData, Dof_P, &Val_Dof); | ||||
Val_Dof = Val_Dof / sizeEdge; | ||||
valSum += SQU(Val_Dof) * sizeEdge; | valSum += SQU(Val_Dof) * sizeEdge; | |||
} | } | |||
else{ | else { | |||
for (k = 0 ; k < Current.NbrHar ; k+=2) { | for(k = 0; k < Current.NbrHar; k += 2) { | |||
Dof_GetComplexDofValue | Dof_GetComplexDofValue(Current.DofData_P0 + numDofData, | |||
(Current.DofData_P0+ numDofData, | Dof_P + k / 2 * gCOMPLEX_INCREMENT, &Val_Dof, | |||
Dof_P + k/2*gCOMPLEX_INCREMENT, | &Val_Dof_i); | |||
&Val_Dof, &Val_Dof_i) ; | Val_Dof = Val_Dof / sizeEdge; | |||
Val_Dof = Val_Dof /sizeEdge; | Val_Dof_i = Val_Dof_i / sizeEdge; | |||
Val_Dof_i = Val_Dof_i/sizeEdge; | valSum += (SQU(Val_Dof) + SQU(Val_Dof_i)) * sizeEdge; | |||
valSum += (SQU(Val_Dof)+SQU(Val_Dof_i)) * sizeEdge; | ||||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
V->Type = SCALAR ; | V->Type = SCALAR; | |||
V->Val[0] = valSum ; | V->Val[0] = valSum; | |||
V->Val[MAX_DIM] = 0. ; | V->Val[MAX_DIM] = 0.; | |||
for (k = 2 ; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar) ; k += 2) { | for(k = 2; k < std::min(NBR_MAX_HARMONIC, Current.NbrHar); k += 2) { | |||
V->Val[MAX_DIM* k] = V->Val[0] ; | V->Val[MAX_DIM * k] = V->Val[0]; | |||
V->Val[MAX_DIM* (k+1)] = 0. ; | V->Val[MAX_DIM * (k + 1)] = 0.; | |||
} | } | |||
#endif | #endif | |||
} | } | |||
static double POINT_TO_PROJECT[3], ELLIPSE_PARAMETERS[2]; | static double POINT_TO_PROJECT[3], ELLIPSE_PARAMETERS[2]; | |||
static double dist_ellipse(double t) | static double dist_ellipse(double t) | |||
{ | { | |||
double x, y; | double x, y; | |||
x = ELLIPSE_PARAMETERS[0] * cos(t); | x = ELLIPSE_PARAMETERS[0] * cos(t); | |||
skipping to change at line 704 | skipping to change at line 676 | |||
void F_ProjectPointOnEllipse(F_ARG) | void F_ProjectPointOnEllipse(F_ARG) | |||
{ | { | |||
int k; | int k; | |||
double t1 = 0., t2 = 1.e-6, t3, f1, f2, f3, tol = 1.e-4; | double t1 = 0., t2 = 1.e-6, t3, f1, f2, f3, tol = 1.e-4; | |||
double t, x, y; | double t, x, y; | |||
POINT_TO_PROJECT[0] = A->Val[0]; | POINT_TO_PROJECT[0] = A->Val[0]; | |||
POINT_TO_PROJECT[1] = A->Val[1]; | POINT_TO_PROJECT[1] = A->Val[1]; | |||
POINT_TO_PROJECT[2] = A->Val[2]; | POINT_TO_PROJECT[2] = A->Val[2]; | |||
ELLIPSE_PARAMETERS[0] = Fct->Para[0] ; | ELLIPSE_PARAMETERS[0] = Fct->Para[0]; | |||
ELLIPSE_PARAMETERS[1] = Fct->Para[1] ; | ELLIPSE_PARAMETERS[1] = Fct->Para[1]; | |||
mnbrak(&t1, &t2, &t3, &f1, &f2, &f3, dist_ellipse); | mnbrak(&t1, &t2, &t3, &f1, &f2, &f3, dist_ellipse); | |||
if(t1 > t2){ | if(t1 > t2) { | |||
t = t1; | t = t1; | |||
t1 = t3; | t1 = t3; | |||
t3 = t; | t3 = t; | |||
} | } | |||
brent(t1, t2, t3, dist_ellipse, tol, &t); | brent(t1, t2, t3, dist_ellipse, tol, &t); | |||
x = ELLIPSE_PARAMETERS[0] * cos(t); | x = ELLIPSE_PARAMETERS[0] * cos(t); | |||
y = ELLIPSE_PARAMETERS[1] * sin(t); | y = ELLIPSE_PARAMETERS[1] * sin(t); | |||
/* printf("SL(%g,%g,0,%g,%g,0){1,1};\n", A->Val[0], A->Val[1], x, y); */ | /* printf("SL(%g,%g,0,%g,%g,0){1,1};\n", A->Val[0], A->Val[1], x, y); */ | |||
for (k = 0 ; k < Current.NbrHar ; k++) { | for(k = 0; k < Current.NbrHar; k++) { | |||
V->Val[MAX_DIM*k ] = 0. ; | V->Val[MAX_DIM * k] = 0.; | |||
V->Val[MAX_DIM*k+1] = 0. ; | V->Val[MAX_DIM * k + 1] = 0.; | |||
V->Val[MAX_DIM*k+2] = 0. ; | V->Val[MAX_DIM * k + 2] = 0.; | |||
} | } | |||
V->Val[0] = x; | V->Val[0] = x; | |||
V->Val[1] = y; | V->Val[1] = y; | |||
V->Type = VECTOR ; | V->Type = VECTOR; | |||
} | } | |||
End of changes. 85 change blocks. | ||||
406 lines changed or deleted | 370 lines changed or added |