883 lines
30 KiB
C++
883 lines
30 KiB
C++
|
/********************************************************
|
|||
|
* ██████╗ ██████╗████████╗██╗
|
|||
|
* ██╔════╝ ██╔════╝╚══██╔══╝██║
|
|||
|
* ██║ ███╗██║ ██║ ██║
|
|||
|
* ██║ ██║██║ ██║ ██║
|
|||
|
* ╚██████╔╝╚██████╗ ██║ ███████╗
|
|||
|
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
|||
|
* Geophysical Computational Tools & Library (GCTL)
|
|||
|
*
|
|||
|
* Copyright (c) 2023 Yi Zhang (yizhang-geo@zju.edu.cn)
|
|||
|
*
|
|||
|
* GCTL is distributed under a dual licensing scheme. You can redistribute
|
|||
|
* it and/or modify it under the terms of the GNU Lesser General Public
|
|||
|
* License as published by the Free Software Foundation, either version 2
|
|||
|
* of the License, or (at your option) any later version. You should have
|
|||
|
* received a copy of the GNU Lesser General Public License along with this
|
|||
|
* program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
*
|
|||
|
* If the terms and conditions of the LGPL v.2. would prevent you from using
|
|||
|
* the GCTL, please consider the option to obtain a commercial license for a
|
|||
|
* fee. These licenses are offered by the GCTL's original author. As a rule,
|
|||
|
* licenses are provided "as-is", unlimited in time for a one time fee. Please
|
|||
|
* send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget
|
|||
|
* to include some description of your company and the realm of its activities.
|
|||
|
* Also add information on how to contact you by electronic and paper mail.
|
|||
|
******************************************************/
|
|||
|
|
|||
|
#include "glni.h"
|
|||
|
|
|||
|
using namespace gctl;
|
|||
|
|
|||
|
double tet_volume(double x1, double x2, double x3, double x4,
|
|||
|
double y1, double y2, double y3, double y4,
|
|||
|
double z1, double z2, double z3, double z4)
|
|||
|
{
|
|||
|
double x12 = x2-x1, y12 = y2-y1, z12 = z2-z1;
|
|||
|
double x13 = x3-x1, y13 = y3-y1, z13 = z3-z1;
|
|||
|
double x14 = x4-x1, y14 = y4-y1, z14 = z4-z1;
|
|||
|
double crx = y12*z13-z12*y13;
|
|||
|
double cry = z12*x13-x12*z13;
|
|||
|
double crz = x12*y13-y12*x13;
|
|||
|
double vol = (x14*crx+y14*cry+z14*crz)/6.0;
|
|||
|
if (vol < 0) vol = -1.0*vol;
|
|||
|
return vol;
|
|||
|
}
|
|||
|
|
|||
|
glni::coefficients::coefficients()
|
|||
|
{
|
|||
|
size_ = 0;
|
|||
|
nodes_ = nullptr;
|
|||
|
weights_ = nullptr;
|
|||
|
}
|
|||
|
|
|||
|
glni::coefficients::coefficients(size_t size)
|
|||
|
{
|
|||
|
initiate(size);
|
|||
|
}
|
|||
|
|
|||
|
glni::coefficients::~coefficients()
|
|||
|
{
|
|||
|
clear();
|
|||
|
}
|
|||
|
|
|||
|
void glni::coefficients::initiate(size_t size)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_SIZE
|
|||
|
if (size == 0 || size > 20)
|
|||
|
{
|
|||
|
throw invalid_argument("Invalid initiating order. From glni::coefficients::initiate(...).");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
size_ = size;
|
|||
|
nodes_ = new double [size_];
|
|||
|
weights_ = new double [size_];
|
|||
|
|
|||
|
switch (size_)
|
|||
|
{
|
|||
|
case 1:
|
|||
|
nodes_[0] = 0.0;
|
|||
|
weights_[0] = 2.0;
|
|||
|
break;
|
|||
|
case 2:
|
|||
|
nodes_[0] = -0.577350269189625764509148780502; nodes_[1] = -1.0*nodes_[0];
|
|||
|
weights_[0] = weights_[1] = 1.0;
|
|||
|
break;
|
|||
|
case 3:
|
|||
|
nodes_[0] = -0.774596669241483377035853079956; nodes_[2] = -1.0*nodes_[0];
|
|||
|
nodes_[1] = 0.0;
|
|||
|
weights_[0] = weights_[2] = 0.5555555555555555555555555555565;
|
|||
|
weights_[1] = 0.8888888888888888888888888888889;
|
|||
|
break;
|
|||
|
case 4:
|
|||
|
nodes_[0] = -0.861136311594052575223946488893; nodes_[3] = -1.0*nodes_[0];
|
|||
|
nodes_[1] = -0.339981043584856264802665759103; nodes_[2] = -1.0*nodes_[1];
|
|||
|
weights_[0] = weights_[3] = 0.347854845137453857373063949222;
|
|||
|
weights_[1] = weights_[2] = 0.652145154862546142626936050778;
|
|||
|
break;
|
|||
|
case 5:
|
|||
|
nodes_[0] = -0.906179845938663992797626878299; nodes_[4] = -1.0*nodes_[0];
|
|||
|
nodes_[1] = -0.538469310105683091036314420700; nodes_[3] = -1.0*nodes_[1];
|
|||
|
nodes_[2] = 0.0;
|
|||
|
weights_[0] = weights_[4] = 0.236926885056189087514264040720;
|
|||
|
weights_[1] = weights_[3] = 0.478628670499366468041291514836;
|
|||
|
weights_[2] = 0.568888888888888888888888888889;
|
|||
|
break;
|
|||
|
case 6:
|
|||
|
nodes_[0] = -0.932469514203152027812301554494; nodes_[5] = -1.0*nodes_[0];
|
|||
|
nodes_[1] = -0.661209386466264513661399595020; nodes_[4] = -1.0*nodes_[1];
|
|||
|
nodes_[2] = -0.238619186083196908630501721681; nodes_[3] = -1.0*nodes_[2];
|
|||
|
weights_[0] = weights_[5] = 0.171324492379170345040296142173;
|
|||
|
weights_[1] = weights_[4] = 0.360761573048138607569833513838;
|
|||
|
weights_[2] = weights_[3] = 0.467913934572691047389870343990;
|
|||
|
break;
|
|||
|
case 7:
|
|||
|
nodes_[0] = -0.949107912342758524526189684048; nodes_[6] = -1.0*nodes_[0];
|
|||
|
nodes_[1] = -0.741531185599394439863864773281; nodes_[5] = -1.0*nodes_[1];
|
|||
|
nodes_[2] = -0.405845151377397166906606412077; nodes_[4] = -1.0*nodes_[2];
|
|||
|
nodes_[3] = 0.0;
|
|||
|
weights_[0] = weights_[6] = 0.129484966168869693270611432679;
|
|||
|
weights_[1] = weights_[5] = 0.279705391489276667901467771424;
|
|||
|
weights_[2] = weights_[4] = 0.381830050505118944950369775489;
|
|||
|
weights_[3] = 0.417959183673469387755102040816;
|
|||
|
break;
|
|||
|
case 8:
|
|||
|
nodes_[0] = -0.960289856497536231683560868569; nodes_[7] = -1.0*nodes_[0];
|
|||
|
nodes_[1] = -0.796666477413626739591553936476; nodes_[6] = -1.0*nodes_[1];
|
|||
|
nodes_[2] = -0.525532409916328985817739049189; nodes_[5] = -1.0*nodes_[2];
|
|||
|
nodes_[3] = -0.183434642495649804939476142360; nodes_[4] = -1.0*nodes_[3];
|
|||
|
weights_[0] = weights_[7] = 0.101228536290376259152531354310;
|
|||
|
weights_[1] = weights_[6] = 0.222381034453374470544355994426;
|
|||
|
weights_[2] = weights_[5] = 0.313706645877887287337962201987;
|
|||
|
weights_[3] = weights_[4] = 0.362683783378361982965150449277;
|
|||
|
break;
|
|||
|
case 9:
|
|||
|
nodes_[0] = -0.968160239507626089835576202904; nodes_[8] = -1.0*nodes_[0];
|
|||
|
nodes_[1] = -0.836031107326635794299429788070; nodes_[7] = -1.0*nodes_[1];
|
|||
|
nodes_[2] = -0.613371432700590397308702039341; nodes_[6] = -1.0*nodes_[2];
|
|||
|
nodes_[3] = -0.324253423403808929038538014643; nodes_[5] = -1.0*nodes_[3];
|
|||
|
nodes_[4] = 0.0;
|
|||
|
weights_[0] = weights_[8] = 0.0812743883615744119718921581105;
|
|||
|
weights_[1] = weights_[7] = 0.180648160694857404058472031243;
|
|||
|
weights_[2] = weights_[6] = 0.260610696402935462318742869419;
|
|||
|
weights_[3] = weights_[5] = 0.312347077040002840068630406584;
|
|||
|
weights_[4] = 0.330239355001259763164525069287;
|
|||
|
break;
|
|||
|
case 10:
|
|||
|
nodes_[0] = -0.973906528517171720077964012084; nodes_[9] = -1.0*nodes_[0];
|
|||
|
nodes_[1] = -0.865063366688984510732096688423; nodes_[8] = -1.0*nodes_[1];
|
|||
|
nodes_[2] = -0.679409568299024406234327365115; nodes_[7] = -1.0*nodes_[2];
|
|||
|
nodes_[3] = -0.433395394129247290799265943166; nodes_[6] = -1.0*nodes_[3];
|
|||
|
nodes_[4] = -0.148874338981631210884826001130; nodes_[5] = -1.0*nodes_[4];
|
|||
|
weights_[0] = weights_[9] = 0.0666713443086881375935688098933;
|
|||
|
weights_[1] = weights_[8] = 0.149451349150580593145776339658;
|
|||
|
weights_[2] = weights_[7] = 0.219086362515982043995534934228;
|
|||
|
weights_[3] = weights_[6] = 0.269266719309996355091226921569;
|
|||
|
weights_[4] = weights_[5] = 0.295524224714752870173892994651;
|
|||
|
break;
|
|||
|
case 11:
|
|||
|
nodes_[0]=-0.978228658146056992803938001123; nodes_[10] = -1.0*nodes_[0];
|
|||
|
nodes_[1]=-0.887062599768095299075157769304; nodes_[9] = -1.0*nodes_[1];
|
|||
|
nodes_[2]=-0.730152005574049324093416252031; nodes_[8] = -1.0*nodes_[2];
|
|||
|
nodes_[3]=-0.519096129206811815925725669459; nodes_[7] = -1.0*nodes_[3];
|
|||
|
nodes_[4]=-0.269543155952344972331531985401; nodes_[6] = -1.0*nodes_[4];
|
|||
|
nodes_[5]= 0.0;
|
|||
|
weights_[0]= weights_[10] = 0.0556685671161736664827537204425;
|
|||
|
weights_[1]= weights_[9] = 0.125580369464904624634694299224;
|
|||
|
weights_[2]= weights_[8] = 0.186290210927734251426097641432;
|
|||
|
weights_[3]= weights_[7] = 0.233193764591990479918523704843;
|
|||
|
weights_[4]= weights_[6] = 0.262804544510246662180688869891;
|
|||
|
weights_[5]= 0.272925086777900630714483528336;
|
|||
|
break;
|
|||
|
case 12:
|
|||
|
nodes_[0]=-0.981560634246719250690549090149; nodes_[11] = -1.0*nodes_[0];
|
|||
|
nodes_[1]=-0.904117256370474856678465866119; nodes_[10] = -1.0*nodes_[1];
|
|||
|
nodes_[2]=-0.769902674194304687036893833213; nodes_[9] = -1.0*nodes_[2];
|
|||
|
nodes_[3]=-0.587317954286617447296702418941; nodes_[8] = -1.0*nodes_[3];
|
|||
|
nodes_[4]=-0.367831498998180193752691536644; nodes_[7] = -1.0*nodes_[4];
|
|||
|
nodes_[5]=-0.125233408511468915472441369464; nodes_[6] = -1.0*nodes_[5];
|
|||
|
weights_[0]= weights_[11] = 0.0471753363865118271946159614850;
|
|||
|
weights_[1]= weights_[10] = 0.106939325995318430960254718194;
|
|||
|
weights_[2]= weights_[9] = 0.160078328543346226334652529543;
|
|||
|
weights_[3]= weights_[8] = 0.203167426723065921749064455810;
|
|||
|
weights_[4]= weights_[7] = 0.233492536538354808760849898925;
|
|||
|
weights_[5]= weights_[6] = 0.249147045813402785000562436043;
|
|||
|
break;
|
|||
|
case 13:
|
|||
|
nodes_[0]=-0.984183054718588149472829448807; nodes_[12] = -1.0*nodes_[0];
|
|||
|
nodes_[1]=-0.917598399222977965206547836501; nodes_[11] = -1.0*nodes_[1];
|
|||
|
nodes_[2]=-0.801578090733309912794206489583; nodes_[10] = -1.0*nodes_[2];
|
|||
|
nodes_[3]=-0.642349339440340220643984606996; nodes_[9] = -1.0*nodes_[3];
|
|||
|
nodes_[4]=-0.448492751036446852877912852128; nodes_[8] = -1.0*nodes_[4];
|
|||
|
nodes_[5]=-0.230458315955134794065528121098; nodes_[7] = -1.0*nodes_[5];
|
|||
|
nodes_[6]= 0.0;
|
|||
|
weights_[0]= weights_[12] = 0.0404840047653158795200215922010;
|
|||
|
weights_[1]= weights_[11] = 0.0921214998377284479144217759538;
|
|||
|
weights_[2]= weights_[10] = 0.138873510219787238463601776869;
|
|||
|
weights_[3]= weights_[9] = 0.178145980761945738280046691996;
|
|||
|
weights_[4]= weights_[8] = 0.207816047536888502312523219306;
|
|||
|
weights_[5]= weights_[7] = 0.226283180262897238412090186040;
|
|||
|
weights_[6]= 0.232551553230873910194589515269;
|
|||
|
break;
|
|||
|
case 14:
|
|||
|
nodes_[0]=-0.986283808696812338841597266704; nodes_[13] = -1.0*nodes_[0];
|
|||
|
nodes_[1]=-0.928434883663573517336391139378; nodes_[12] = -1.0*nodes_[1];
|
|||
|
nodes_[2]=-0.827201315069764993189794742650; nodes_[11] = -1.0*nodes_[2];
|
|||
|
nodes_[3]=-0.687292904811685470148019803019; nodes_[10] = -1.0*nodes_[3];
|
|||
|
nodes_[4]=-0.515248636358154091965290718551; nodes_[9] = -1.0*nodes_[4];
|
|||
|
nodes_[5]=-0.319112368927889760435671824168; nodes_[8] = -1.0*nodes_[5];
|
|||
|
nodes_[6]=-0.108054948707343662066244650220; nodes_[7] = -1.0*nodes_[6];
|
|||
|
weights_[0]= weights_[13] = 0.0351194603317518630318328761382;
|
|||
|
weights_[1]= weights_[12] = 0.0801580871597602098056332770629;
|
|||
|
weights_[2]= weights_[11] = 0.121518570687903184689414809072;
|
|||
|
weights_[3]= weights_[10] = 0.157203167158193534569601938624;
|
|||
|
weights_[4]= weights_[9] = 0.185538397477937813741716590125;
|
|||
|
weights_[5]= weights_[8] = 0.205198463721295603965924065661;
|
|||
|
weights_[6]= weights_[7] = 0.215263853463157790195876443316;
|
|||
|
break;
|
|||
|
case 15:
|
|||
|
nodes_[0]=-0.987992518020485428489565718587; nodes_[14] = -1.0*nodes_[0];
|
|||
|
nodes_[1]=-0.937273392400705904307758947710; nodes_[13] = -1.0*nodes_[1];
|
|||
|
nodes_[2]=-0.848206583410427216200648320774; nodes_[12] = -1.0*nodes_[2];
|
|||
|
nodes_[3]=-0.724417731360170047416186054614; nodes_[11] = -1.0*nodes_[3];
|
|||
|
nodes_[4]=-0.570972172608538847537226737254; nodes_[10] = -1.0*nodes_[4];
|
|||
|
nodes_[5]=-0.394151347077563369897207370981; nodes_[9] = -1.0*nodes_[5];
|
|||
|
nodes_[6]=-0.201194093997434522300628303395; nodes_[8] = -1.0*nodes_[6];
|
|||
|
nodes_[7]= 0.0;
|
|||
|
weights_[0]= weights_[14] = 0.0307532419961172683546283935772;
|
|||
|
weights_[1]= weights_[13] = 0.0703660474881081247092674164507;
|
|||
|
weights_[2]= weights_[12] = 0.107159220467171935011869546686;
|
|||
|
weights_[3]= weights_[11] = 0.139570677926154314447804794511;
|
|||
|
weights_[4]= weights_[10] = 0.166269205816993933553200860481;
|
|||
|
weights_[5]= weights_[9] = 0.186161000015562211026800561866;
|
|||
|
weights_[6]= weights_[8] = 0.198431485327111576456118326444;
|
|||
|
weights_[7]= 0.202578241925561272880620199968;
|
|||
|
break;
|
|||
|
case 16:
|
|||
|
nodes_[0]=-0.989400934991649932596154173450; nodes_[15] = -1.0*nodes_[0];
|
|||
|
nodes_[1]=-0.944575023073232576077988415535; nodes_[14] = -1.0*nodes_[1];
|
|||
|
nodes_[2]=-0.865631202387831743880467897712; nodes_[13] = -1.0*nodes_[2];
|
|||
|
nodes_[3]=-0.755404408355003033895101194847; nodes_[12] = -1.0*nodes_[3];
|
|||
|
nodes_[4]=-0.617876244402643748446671764049; nodes_[11] = -1.0*nodes_[4];
|
|||
|
nodes_[5]=-0.458016777657227386342419442984; nodes_[10] = -1.0*nodes_[5];
|
|||
|
nodes_[6]=-0.281603550779258913230460501460; nodes_[9] = -1.0*nodes_[6];
|
|||
|
nodes_[7]=-0.0950125098376374401853193354250; nodes_[8] = -1.0*nodes_[7];
|
|||
|
weights_[0]= weights_[15] = 0.0271524594117540948517805724560;
|
|||
|
weights_[1]= weights_[14] = 0.0622535239386478928628438369944;
|
|||
|
weights_[2]= weights_[13] = 0.0951585116824927848099251076022;
|
|||
|
weights_[3]= weights_[12] = 0.124628971255533872052476282192;
|
|||
|
weights_[4]= weights_[11] = 0.149595988816576732081501730547;
|
|||
|
weights_[5]= weights_[10] = 0.169156519395002538189312079030;
|
|||
|
weights_[6]= weights_[9] = 0.182603415044923588866763667969;
|
|||
|
weights_[7]= weights_[8] = 0.189450610455068496285396723208;
|
|||
|
break;
|
|||
|
case 17:
|
|||
|
nodes_[0]=-0.990575475314417335675434019941; nodes_[16] = -1.0*nodes_[0];
|
|||
|
nodes_[1]=-0.950675521768767761222716957896; nodes_[15] = -1.0*nodes_[1];
|
|||
|
nodes_[2]=-0.880239153726985902122955694488; nodes_[14] = -1.0*nodes_[2];
|
|||
|
nodes_[3]=-0.781514003896801406925230055520; nodes_[13] = -1.0*nodes_[3];
|
|||
|
nodes_[4]=-0.657671159216690765850302216643; nodes_[12] = -1.0*nodes_[4];
|
|||
|
nodes_[5]=-0.512690537086476967886246568630; nodes_[11] = -1.0*nodes_[5];
|
|||
|
nodes_[6]=-0.351231763453876315297185517095; nodes_[10] = -1.0*nodes_[6];
|
|||
|
nodes_[7]=-0.178484181495847855850677493654; nodes_[9] = -1.0*nodes_[7];
|
|||
|
nodes_[8]= 0.0;
|
|||
|
weights_[0]= weights_[16] = 0.0241483028685479319601100262876;
|
|||
|
weights_[1]= weights_[15] = 0.0554595293739872011294401653582;
|
|||
|
weights_[2]= weights_[14] = 0.0850361483171791808835353701911;
|
|||
|
weights_[3]= weights_[13] = 0.111883847193403971094788385626;
|
|||
|
weights_[4]= weights_[12] = 0.135136368468525473286319981702;
|
|||
|
weights_[5]= weights_[11] = 0.154045761076810288081431594802;
|
|||
|
weights_[6]= weights_[10] = 0.168004102156450044509970663788;
|
|||
|
weights_[7]= weights_[9] = 0.176562705366992646325270990113;
|
|||
|
weights_[8]= 0.179446470356206525458265644262;
|
|||
|
break;
|
|||
|
case 18:
|
|||
|
nodes_[0]=-0.991565168420930946730016004706; nodes_[17] = -1.0*nodes_[0];
|
|||
|
nodes_[1]=-0.955823949571397755181195892930; nodes_[16] = -1.0*nodes_[1];
|
|||
|
nodes_[2]=-0.892602466497555739206060591127; nodes_[15] = -1.0*nodes_[2];
|
|||
|
nodes_[3]=-0.803704958972523115682417455015; nodes_[14] = -1.0*nodes_[3];
|
|||
|
nodes_[4]=-0.691687043060353207874891081289; nodes_[13] = -1.0*nodes_[4];
|
|||
|
nodes_[5]=-0.559770831073947534607871548525; nodes_[12] = -1.0*nodes_[5];
|
|||
|
nodes_[6]=-0.411751161462842646035931793833; nodes_[11] = -1.0*nodes_[6];
|
|||
|
nodes_[7]=-0.251886225691505509588972854878; nodes_[10] = -1.0*nodes_[7];
|
|||
|
nodes_[8]=-0.0847750130417353012422618529358; nodes_[9] = -1.0*nodes_[8];
|
|||
|
weights_[0]= weights_[17] = 0.0216160135264833103133427102665;
|
|||
|
weights_[1]= weights_[16] = 0.0497145488949697964533349462026;
|
|||
|
weights_[2]= weights_[15] = 0.0764257302548890565291296776166;
|
|||
|
weights_[3]= weights_[14] = 0.100942044106287165562813984925;
|
|||
|
weights_[4]= weights_[13] = 0.122555206711478460184519126800;
|
|||
|
weights_[5]= weights_[12] = 0.140642914670650651204731303752;
|
|||
|
weights_[6]= weights_[11] = 0.154684675126265244925418003836;
|
|||
|
weights_[7]= weights_[10] = 0.164276483745832722986053776466;
|
|||
|
weights_[8]= weights_[9] = 0.169142382963143591840656470135;
|
|||
|
break;
|
|||
|
case 19:
|
|||
|
nodes_[0]=-0.992406843843584403189017670253; nodes_[18] = -1.0*nodes_[0];
|
|||
|
nodes_[1]=-0.960208152134830030852778840688; nodes_[17] = -1.0*nodes_[1];
|
|||
|
nodes_[2]=-0.903155903614817901642660928532; nodes_[16] = -1.0*nodes_[2];
|
|||
|
nodes_[3]=-0.822714656537142824978922486713; nodes_[15] = -1.0*nodes_[3];
|
|||
|
nodes_[4]=-0.720966177335229378617095860824; nodes_[14] = -1.0*nodes_[4];
|
|||
|
nodes_[5]=-0.600545304661681023469638164946; nodes_[13] = -1.0*nodes_[5];
|
|||
|
nodes_[6]=-0.464570741375960945717267148104; nodes_[12] = -1.0*nodes_[6];
|
|||
|
nodes_[7]=-0.316564099963629831990117328850; nodes_[11] = -1.0*nodes_[7];
|
|||
|
nodes_[8]=-0.160358645640225375868096115741; nodes_[10] = -1.0*nodes_[8];
|
|||
|
nodes_[9]= 0.0;
|
|||
|
weights_[0]= weights_[18] = 0.0194617882297264770363120414644;
|
|||
|
weights_[1]= weights_[17] = 0.0448142267656996003328381574020;
|
|||
|
weights_[2]= weights_[16] = 0.0690445427376412265807082580060;
|
|||
|
weights_[3]= weights_[15] = 0.0914900216224499994644620941238;
|
|||
|
weights_[4]= weights_[14] = 0.111566645547333994716023901682;
|
|||
|
weights_[5]= weights_[13] = 0.128753962539336227675515784857;
|
|||
|
weights_[6]= weights_[12] = 0.142606702173606611775746109442;
|
|||
|
weights_[7]= weights_[11] = 0.152766042065859666778855400898;
|
|||
|
weights_[8]= weights_[10] = 0.158968843393954347649956439465;
|
|||
|
weights_[9]= 0.161054449848783695979163625321;
|
|||
|
break;
|
|||
|
case 20:
|
|||
|
nodes_[0]=-0.993128599185094924786122388471; nodes_[19] = -1.0*nodes_[0];
|
|||
|
nodes_[1]=-0.963971927277913791267666131197; nodes_[18] = -1.0*nodes_[1];
|
|||
|
nodes_[2]=-0.912234428251325905867752441203; nodes_[17] = -1.0*nodes_[2];
|
|||
|
nodes_[3]=-0.839116971822218823394529061702; nodes_[16] = -1.0*nodes_[3];
|
|||
|
nodes_[4]=-0.746331906460150792614305070356; nodes_[15] = -1.0*nodes_[4];
|
|||
|
nodes_[5]=-0.636053680726515025452836696226; nodes_[14] = -1.0*nodes_[5];
|
|||
|
nodes_[6]=-0.510867001950827098004364050955; nodes_[13] = -1.0*nodes_[6];
|
|||
|
nodes_[7]=-0.373706088715419560672548177025; nodes_[12] = -1.0*nodes_[7];
|
|||
|
nodes_[8]=-0.227785851141645078080496195369; nodes_[11] = -1.0*nodes_[8];
|
|||
|
nodes_[9]=-0.0765265211334973337546404093988; nodes_[10] = -1.0*nodes_[9];
|
|||
|
weights_[0]= weights_[19] = 0.0176140071391521183118619623519;
|
|||
|
weights_[1]= weights_[18] = 0.0406014298003869413310399522749;
|
|||
|
weights_[2]= weights_[17] = 0.0626720483341090635695065351870;
|
|||
|
weights_[3]= weights_[16] = 0.0832767415767047487247581432220;
|
|||
|
weights_[4]= weights_[15] = 0.101930119817240435036750135480;
|
|||
|
weights_[5]= weights_[14] = 0.118194531961518417312377377711;
|
|||
|
weights_[6]= weights_[13] = 0.131688638449176626898494499748;
|
|||
|
weights_[7]= weights_[12] = 0.142096109318382051329298325067;
|
|||
|
weights_[8]= weights_[11] = 0.149172986472603746787828737002;
|
|||
|
weights_[9]= weights_[10] = 0.152753387130725850698084331955;
|
|||
|
break;
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
void glni::coefficients::clear()
|
|||
|
{
|
|||
|
size_ = 0;
|
|||
|
if (nodes_ != nullptr) delete[] nodes_;
|
|||
|
if (weights_ != nullptr) delete[] weights_;
|
|||
|
nodes_ = nullptr;
|
|||
|
weights_ = nullptr;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
double glni::coefficients::node(size_t idx)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_SIZE
|
|||
|
if (idx >= size_)
|
|||
|
{
|
|||
|
throw out_of_range("Invalid index. From gctl::glni::coefficients::node(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
return nodes_[idx];
|
|||
|
}
|
|||
|
|
|||
|
double glni::coefficients::weight(size_t idx)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_SIZE
|
|||
|
if (idx >= size_)
|
|||
|
{
|
|||
|
throw out_of_range("Invalid index. From gctl::glni::coefficients::weight(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
return weights_[idx];
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
glni::line::line()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
}
|
|||
|
|
|||
|
glni::line::line(size_t size)
|
|||
|
{
|
|||
|
initiate(size);
|
|||
|
}
|
|||
|
|
|||
|
glni::line::~line()
|
|||
|
{
|
|||
|
clear();
|
|||
|
}
|
|||
|
|
|||
|
void glni::line::clear()
|
|||
|
{
|
|||
|
coeff_.clear();
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
void glni::line::initiate(size_t size)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_SIZE
|
|||
|
if (size == 0 || size > 20)
|
|||
|
{
|
|||
|
throw invalid_argument("Invalid initiating order. From glni::line::initiate(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
initialized_ = true;
|
|||
|
size_ = size;
|
|||
|
coeff_.initiate(size_);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
double glni::line::integral(double low, double hig, void *att)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_BOUNDER
|
|||
|
if (hig <= low)
|
|||
|
{
|
|||
|
throw length_error("Invalid integration range. From glni::line::integral(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if (!initialized_)
|
|||
|
{
|
|||
|
throw runtime_error("The object is not initialized. From gctl::glni::line::integral(...).");
|
|||
|
}
|
|||
|
|
|||
|
double scl = (hig - low)/2.0;
|
|||
|
double gx, inte = 0.0;
|
|||
|
for (int i = 0; i < size_; i++)
|
|||
|
{
|
|||
|
gx = 0.5*(low + hig) + scl*coeff_.node(i);
|
|||
|
inte += coeff_.weight(i)*scl*line_func(gx, low, hig, att);
|
|||
|
}
|
|||
|
return inte;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
glni::quadrilateral::quadrilateral()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
}
|
|||
|
|
|||
|
glni::quadrilateral::quadrilateral(size_t size)
|
|||
|
{
|
|||
|
initiate(size);
|
|||
|
}
|
|||
|
|
|||
|
glni::quadrilateral::~quadrilateral()
|
|||
|
{
|
|||
|
clear();
|
|||
|
}
|
|||
|
|
|||
|
void glni::quadrilateral::clear()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
coeff_.clear();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
void glni::quadrilateral::initiate(size_t size)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_SIZE
|
|||
|
if (size == 0 || size > 20)
|
|||
|
{
|
|||
|
throw invalid_argument("Invalid initiating order. From glni::quadrilateral::initiate(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
initialized_ = true;
|
|||
|
size_ = size;
|
|||
|
coeff_.initiate(size_);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
double glni::quadrilateral::integral(double xlow, double xhig, double ylow, double yhig, void *att)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_BOUNDER
|
|||
|
if (xhig <= xlow || yhig <= ylow)
|
|||
|
{
|
|||
|
throw length_error("Invalid integration range. From glni::quadrilateral::integral(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if (!initialized_)
|
|||
|
{
|
|||
|
throw runtime_error("Un-initialized. From glni::quadrilateral::integral(...)");
|
|||
|
}
|
|||
|
|
|||
|
double scl = (xhig-xlow)*(yhig-ylow)/4.0;
|
|||
|
double gx, gy, inte = 0.0;
|
|||
|
for (int i = 0; i < size_; i++)
|
|||
|
{
|
|||
|
for (int j = 0; j < size_; j++)
|
|||
|
{
|
|||
|
gx = 0.5*(xlow+xhig) + 0.5*(xhig-xlow)*coeff_.node(j);
|
|||
|
gy = 0.5*(ylow+yhig) + 0.5*(yhig-ylow)*coeff_.node(i);
|
|||
|
inte += coeff_.weight(i)*coeff_.weight(j)*scl*quadrilateral_func(gx, gy, xlow, xhig, ylow, yhig, att);
|
|||
|
}
|
|||
|
}
|
|||
|
return inte;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
glni::triangle::triangle()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
}
|
|||
|
|
|||
|
glni::triangle::triangle(size_t size)
|
|||
|
{
|
|||
|
initiate(size);
|
|||
|
}
|
|||
|
|
|||
|
glni::triangle::~triangle()
|
|||
|
{
|
|||
|
clear();
|
|||
|
}
|
|||
|
|
|||
|
void glni::triangle::clear()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
coeff_.clear();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
void glni::triangle::initiate(size_t size)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_SIZE
|
|||
|
if (size == 0 || size > 20)
|
|||
|
{
|
|||
|
throw invalid_argument("Invalid initiating order. From glni::triangle::initiate(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
initialized_ = true;
|
|||
|
size_ = size;
|
|||
|
coeff_.initiate(size_);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
double glni::triangle::integral(double x1, double x2, double x3, double y1,
|
|||
|
double y2, double y3, void *att)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_BOUNDER
|
|||
|
if ((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1) <= GCTL_ZERO) // 这里没有设置为0是为了检测三个点是否共线
|
|||
|
{
|
|||
|
throw length_error("Invalid integration range. From glni::triangle::integral(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if (!initialized_)
|
|||
|
{
|
|||
|
throw runtime_error("Un-initialized. From glni::triangle::integral(...)");
|
|||
|
}
|
|||
|
|
|||
|
double ksi, eta;
|
|||
|
double gx, gy, inte = 0.0;
|
|||
|
double scl = x1*y2+x2*y3+x3*y1-x1*y3-x2*y1-x3*y2;
|
|||
|
for (int i = 0; i < size_; i++)
|
|||
|
{
|
|||
|
for (int j = 0; j < size_; j++)
|
|||
|
{
|
|||
|
ksi = 0.5*(1.0+coeff_.node(j));
|
|||
|
eta = 0.25*(1.0-coeff_.node(j))*(1.0+coeff_.node(i));
|
|||
|
gx = (1.0-ksi-eta)*x1 + ksi*x2 + eta*x3;
|
|||
|
gy = (1.0-ksi-eta)*y1 + ksi*y2 + eta*y3;
|
|||
|
inte += coeff_.weight(i)*coeff_.weight(j)*scl*triangle_func(gx, gy, x1, x2, x3, y1, y2, y3, att)
|
|||
|
*(1.0-coeff_.node(j))*0.125;
|
|||
|
}
|
|||
|
}
|
|||
|
return inte;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
glni::triangle_c::triangle_c()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
}
|
|||
|
|
|||
|
glni::triangle_c::triangle_c(size_t size)
|
|||
|
{
|
|||
|
initiate(size);
|
|||
|
}
|
|||
|
|
|||
|
glni::triangle_c::~triangle_c()
|
|||
|
{
|
|||
|
clear();
|
|||
|
}
|
|||
|
|
|||
|
void glni::triangle_c::clear()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
coeff_.clear();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
void glni::triangle_c::initiate(size_t size)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_SIZE
|
|||
|
if (size == 0 || size > 20)
|
|||
|
{
|
|||
|
throw invalid_argument("Invalid initiating order. From glni::triangle_c::initiate(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
initialized_ = true;
|
|||
|
size_ = size;
|
|||
|
coeff_.initiate(size_);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
std::complex<double> glni::triangle_c::integral(double x1, double x2, double x3, double y1,
|
|||
|
double y2, double y3, void *att)
|
|||
|
{
|
|||
|
#ifndef GCTL_CHECK_BOUNDER
|
|||
|
if ((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1) <= GCTL_ZERO) // 这里没有设置为0是为了检测三个点是否共线
|
|||
|
{
|
|||
|
throw length_error("Invalid integration range. From glni::triangle::integral(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if (!initialized_)
|
|||
|
{
|
|||
|
throw runtime_error("Un-initialized. From glni::triangle::integral(...)");
|
|||
|
}
|
|||
|
|
|||
|
double ksi, eta;
|
|||
|
double gx, gy;
|
|||
|
std::complex<double> inte = std::complex<double>(0.0, 0.0);
|
|||
|
double scl = x1*y2+x2*y3+x3*y1-x1*y3-x2*y1-x3*y2;
|
|||
|
for (int i = 0; i < size_; i++)
|
|||
|
{
|
|||
|
for (int j = 0; j < size_; j++)
|
|||
|
{
|
|||
|
ksi = 0.5*(1.0+coeff_.node(j));
|
|||
|
eta = 0.25*(1.0-coeff_.node(j))*(1.0+coeff_.node(i));
|
|||
|
gx = (1.0-ksi-eta)*x1 + ksi*x2 + eta*x3;
|
|||
|
gy = (1.0-ksi-eta)*y1 + ksi*y2 + eta*y3;
|
|||
|
inte += coeff_.weight(i)*coeff_.weight(j)*scl*triangle_c_func(gx, gy, x1, x2, x3, y1, y2, y3, att)
|
|||
|
*(1.0-coeff_.node(j))*0.125;
|
|||
|
}
|
|||
|
}
|
|||
|
return inte;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
glni::cube::cube()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
}
|
|||
|
|
|||
|
glni::cube::cube(size_t size)
|
|||
|
{
|
|||
|
initiate(size);
|
|||
|
}
|
|||
|
|
|||
|
glni::cube::~cube()
|
|||
|
{
|
|||
|
clear();
|
|||
|
}
|
|||
|
|
|||
|
void glni::cube::clear()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
coeff_.clear();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
void glni::cube::initiate(size_t size)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_SIZE
|
|||
|
if (size == 0 || size > 20)
|
|||
|
{
|
|||
|
throw invalid_argument("Invalid initiating order. From glni::cube::initiate(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
initialized_ = true;
|
|||
|
size_ = size;
|
|||
|
coeff_.initiate(size_);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
double glni::cube::integral(double x1, double x2, double y1, double y2,
|
|||
|
double z1, double z2, void *att)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_BOUNDER
|
|||
|
if (x2 <= x1 || y2 <= y1 || z2 <= z1)
|
|||
|
{
|
|||
|
throw length_error("Invalid integration range. From glni::cube::integral(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if (!initialized_)
|
|||
|
{
|
|||
|
throw runtime_error("Un-initialized. From glni::cube::integral(...)");
|
|||
|
}
|
|||
|
|
|||
|
double gx, gy, gz, inte = 0.0;
|
|||
|
double scl = (x2-x1)*(y2-y1)*(z2-z1)/8.0;
|
|||
|
|
|||
|
for (int i = 0; i < size_; i++)
|
|||
|
{
|
|||
|
for (int j = 0; j < size_; j++)
|
|||
|
{
|
|||
|
for (int k = 0; k < size_; k++)
|
|||
|
{
|
|||
|
gx = 0.5*(x1+x2) + 0.5*(x2-x1)*coeff_.node(k);
|
|||
|
gy = 0.5*(y1+y2) + 0.5*(y2-y1)*coeff_.node(j);
|
|||
|
gz = 0.5*(z1+z2) + 0.5*(z2-z1)*coeff_.node(i);
|
|||
|
inte += coeff_.weight(i)*coeff_.weight(j)*coeff_.weight(k)*scl
|
|||
|
*cube_func(gx, gy, gz, x1, x2, y1, y2, z1, z2, att);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return inte;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
glni::tetrahedron::tetrahedron()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
}
|
|||
|
|
|||
|
glni::tetrahedron::tetrahedron(size_t size)
|
|||
|
{
|
|||
|
initiate(size);
|
|||
|
}
|
|||
|
|
|||
|
glni::tetrahedron::~tetrahedron()
|
|||
|
{
|
|||
|
clear();
|
|||
|
}
|
|||
|
|
|||
|
void glni::tetrahedron::clear()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
coeff_.clear();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
void glni::tetrahedron::initiate(size_t size)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_SIZE
|
|||
|
if (size == 0 || size > 20)
|
|||
|
{
|
|||
|
throw invalid_argument("Invalid initiating order. From glni::tetrahedron::initiate(...)");
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
initialized_ = true;
|
|||
|
size_ = size;
|
|||
|
coeff_.initiate(size_);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
double glni::tetrahedron::integral(double x1, double x2, double x3, double x4,
|
|||
|
double y1, double y2, double y3, double y4,
|
|||
|
double z1, double z2, double z3, double z4,
|
|||
|
void *att)
|
|||
|
{
|
|||
|
if (!initialized_)
|
|||
|
{
|
|||
|
throw runtime_error("Un-initialized. From glni::tetrahedron::integral(...)");
|
|||
|
}
|
|||
|
|
|||
|
double ksi, eta, zta;
|
|||
|
double inte = 0.0;
|
|||
|
double scl = 6.0*tet_volume(x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4);
|
|||
|
|
|||
|
if (scl < GCTL_ZERO)
|
|||
|
{
|
|||
|
throw std::invalid_argument("glni::tetrahedron::integral(...) got an invalid integration range.");
|
|||
|
}
|
|||
|
|
|||
|
for (int i = 0; i < size_; i++)
|
|||
|
{
|
|||
|
for (int j = 0; j < size_; j++)
|
|||
|
{
|
|||
|
for (int k = 0; k < size_; k++)
|
|||
|
{
|
|||
|
ksi = 0.125*(1.0+coeff_.node(k))*(1.0+coeff_.node(j))*(1.0+coeff_.node(i));
|
|||
|
eta = 0.125*(1.0+coeff_.node(k))*(1.0+coeff_.node(j))*(1.0-coeff_.node(i));
|
|||
|
zta = 0.25*(1.0+coeff_.node(k))*(1.0-coeff_.node(j));
|
|||
|
inte += coeff_.weight(i)*coeff_.weight(j)*coeff_.weight(k)*scl
|
|||
|
*tetrahedron_func(ksi, eta, zta, x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4, att)
|
|||
|
*(1.0+coeff_.node(k))*(1.0+coeff_.node(k))*(1.0+coeff_.node(j))/64.0;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return inte;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
glni::triprism::triprism()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
}
|
|||
|
|
|||
|
glni::triprism::triprism(size_t size)
|
|||
|
{
|
|||
|
initiate(size);
|
|||
|
}
|
|||
|
|
|||
|
glni::triprism::~triprism()
|
|||
|
{
|
|||
|
clear();
|
|||
|
}
|
|||
|
|
|||
|
void glni::triprism::clear()
|
|||
|
{
|
|||
|
initialized_ = false;
|
|||
|
size_ = 0;
|
|||
|
coeff_.clear();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
void glni::triprism::initiate(size_t size)
|
|||
|
{
|
|||
|
#ifdef GCTL_CHECK_SIZE
|
|||
|
if (size == 0 || size > 20)
|
|||
|
{
|
|||
|
throw std::invalid_argument("glni::triprism::initiate(...) got an invalid initiating order.");
|
|||
|
}
|
|||
|
#endif // GCTL_CHECK_BOUNDER
|
|||
|
|
|||
|
initialized_ = true;
|
|||
|
size_ = size;
|
|||
|
coeff_.initiate(size_);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
double glni::triprism::integral(double *xs, double *ys, double *zs, void *att)
|
|||
|
{
|
|||
|
if (!initialized_)
|
|||
|
{
|
|||
|
throw std::invalid_argument("glni::triprism is not initialized.");
|
|||
|
}
|
|||
|
|
|||
|
double vol = 0.0;
|
|||
|
for (size_t i = 0; i < 3; i++)
|
|||
|
{
|
|||
|
vol += tet_volume(xs[i], xs[i+1], xs[i+2], xs[i+3],
|
|||
|
ys[i], ys[i+1], ys[i+2], ys[i+3], zs[i], zs[i+1], zs[i+2], zs[i+3]);
|
|||
|
}
|
|||
|
|
|||
|
double scl = 2.0*vol;
|
|||
|
double ksi, eta, zta;
|
|||
|
double inte = 0.0;
|
|||
|
for (int i = 0; i < size_; i++)
|
|||
|
{
|
|||
|
for (int j = 0; j < size_; j++)
|
|||
|
{
|
|||
|
for (int k = 0; k < size_; k++)
|
|||
|
{
|
|||
|
ksi = 0.5*(1.0+coeff_.node(j));
|
|||
|
eta = 0.25*(1.0-coeff_.node(j))*(1.0+coeff_.node(i));
|
|||
|
zta = 0.5*(1.0+coeff_.node(k));
|
|||
|
|
|||
|
inte += coeff_.weight(i)*coeff_.weight(j)*coeff_.weight(k)*scl
|
|||
|
*triprism_func(ksi, eta, zta, xs, ys, zs, att)
|
|||
|
*(1.0-coeff_.node(j))*0.0625;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return inte;
|
|||
|
}
|